Search code examples
iosobjective-ciphoneafnetworkingphasset

PHAsset + AFNetworking. Unable to upload files to the server on a real device


Currently I'm using the following code to upload files to the server

NSURLRequest *urlRequest =  [[AFHTTPRequestSerializer serializer] multipartFormRequestWithMethod:@"POST" URLString:[[entity uploadUrl]absoluteString] parameters:entity.params constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {

    // Get file url 
    [UploadModel getAassetUrl:entity.asset resultHandler:^(NSURL *fileUrl) {

    NSError *fileappenderror;
    // Append
                [formData appendPartWithFileURL:fileUrl name:@"data" error:&fileappenderror];

                if (fileappenderror) {
                  [Sys MyLog: [fileappenderror localizedDescription] ];
                }
            }];

        } error:&urlRequestError];

/*getAassetUrl */

+(void)getAassetUrl: (PHAsset*)mPhasset resultHandler:(void(^)(NSURL *imageUrl))dataResponse{

    PHImageRequestOptions * requestOption = [[PHImageRequestOptions alloc] init];
    requestOption.synchronous = YES;
    requestOption.deliveryMode = PHImageRequestOptionsDeliveryModeFastFormat;

        [[PHImageManager defaultManager] requestImageDataForAsset:mPhasset options:requestOption resultHandler:^(NSData *imageData, NSString *dataUTI, UIImageOrientation orientation, NSDictionary *info) {

        dataResponse([info objectForKey:@"PHImageFileURLKey"]);

    }];
}

This approach works on a simulator, but fails on a real device: empty files are uploaded to the server most likely due to failure to read from the local storage. Log shows the notice

Notice: Sandbox: MyApp(213) deny file-read-data /private/var/mobile/Media/DCIM/101APPLE/IMG_1570.PNG

I believe this note means that app can't access the file by specified path. Also I've tried an alternative approach uploading file by appending with NSData which is returned from request PHAsset data. but this approach is unusable in case of large media files. since the entire file is loaded into the memory.

Any thoughts?


Solution

  • The NSData object returned by requestImageDataForAsset is memory mapped - so the entire file is not loaded into memory. So this method will for without any issues for images.

    For videos you should use the appropriate methods requestExportSessionForVideo or requestAVAssetForVideo If you can limit your deployment target to iOS 9, you should also take a look at the methods of PHAssetResourceManager