如何在后台会话中上传图像文件 (iOS)?
How to upload an image file in a background session (iOS)?
我无法在后台会话中从我设备的照片上传图像。当我调用 [session uploadTaskWithRequest:req fromFile:nsurl] 时,系统立即通过发送
进行投诉
Failed to issue sandbox extension for file file:///var/mobile/Media/DCIM/103APPLE/IMG_3984.JPG, errno = 1
到控制台。 (类似的 Stack Overflow 问题是 here)
但是,如果我使用 [NSURLSessionConfiguration defaultSessionConfiguration](而不是我需要的 [NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier:id] 创建我的 NSURLSessionConfiguration) 和 如果我构造一个 NSData 对象从 NSURL 中上传,而不是直接从文件上传(后台会话需要),然后上传成功。顺便说一句,我正在将文件上传到我们的 Rackspace Cloud 帐户,并且能够通过简单的 Postman PUT 成功完成此操作。
问题出现在我的 uploadObject 方法中,看起来像:
-(void) uploadObject:(NSURL*)urlToBeUploadedIn
{
NSDictionary *headers = @{ @"x-auth-token": state.tokenID,
@"content-type": @"image/jpeg",
@"cache-control": @"no-cache" };
// create destination url for Rackspace cloud upload
NSString *sURL = [NSString stringWithFormat:@"%@/testing_folder/%@.jpg", state.publicURL, [state generateImageName]];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:sURL]
cachePolicy:NSURLRequestUseProtocolCachePolicy
timeoutInterval:10.0];
[request setHTTPMethod:@"PUT"];
[request setAllHTTPHeaderFields:headers];
self.sessionIdentifier = [NSString stringWithFormat:@"my-background-session"];
// NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration]; // when I use this instead of the line below the sandbox error goes away
NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier:self.sessionIdentifier];
self.session = [NSURLSession sessionWithConfiguration:configuration delegate:self delegateQueue:nil];
NSURLSessionUploadTask *uploadTask = [self.session uploadTaskWithRequest:request fromFile:urlToBeUploadedIn];
[uploadTask resume];
}
我调用 uploadObject: 的调用看起来像:
PHFetchResult *fetchResult = [PHAsset fetchAssetsWithLocalIdentifiers:state.arrImagesToBeUploaded options:nil];
PHAsset *phAsset = [fetchResult objectAtIndex:0]; // yes the 0th item in array is guaranteed to exist, above.
[phAsset requestContentEditingInputWithOptions:nil
completionHandler:^(PHContentEditingInput *contentEditingInput, NSDictionary *info) {
NSURL *imageURL = contentEditingInput.fullSizeImageURL;
[self uploadObject:imageURL];
}];
顺便说一句,我首先验证了我发送给 uploadObject: 的 NSURL,并调用了 fileExistsAtPath:,所以我知道我对该文件的引用是正确的。最后,我的代表打电话给
(void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)dataIn
(void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error does get invoked, although the data
确实会被服务器调用(尽管响应不会解析)所以,我从服务器返回的东西从未正确接收到图像。
解决方法是先将要上传的图片复制到应用的沙箱中。我用过:
NSError *err;
BOOL bVal = [myNSDataOb writeToURL:myDestinationURL options:0 error:&err];
并复制到我的应用程序的 'Documents' 目录中,但也可以使用:
NSError *err;
BOOL bVal = [[NSFileManager defaultManager] copyItemAtURL:myImageURL toURL:myDestinationURL error:&err];
我无法在后台会话中从我设备的照片上传图像。当我调用 [session uploadTaskWithRequest:req fromFile:nsurl] 时,系统立即通过发送
进行投诉Failed to issue sandbox extension for file file:///var/mobile/Media/DCIM/103APPLE/IMG_3984.JPG, errno = 1
到控制台。 (类似的 Stack Overflow 问题是 here)
但是,如果我使用 [NSURLSessionConfiguration defaultSessionConfiguration](而不是我需要的 [NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier:id] 创建我的 NSURLSessionConfiguration) 和 如果我构造一个 NSData 对象从 NSURL 中上传,而不是直接从文件上传(后台会话需要),然后上传成功。顺便说一句,我正在将文件上传到我们的 Rackspace Cloud 帐户,并且能够通过简单的 Postman PUT 成功完成此操作。
问题出现在我的 uploadObject 方法中,看起来像:
-(void) uploadObject:(NSURL*)urlToBeUploadedIn
{
NSDictionary *headers = @{ @"x-auth-token": state.tokenID,
@"content-type": @"image/jpeg",
@"cache-control": @"no-cache" };
// create destination url for Rackspace cloud upload
NSString *sURL = [NSString stringWithFormat:@"%@/testing_folder/%@.jpg", state.publicURL, [state generateImageName]];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:sURL]
cachePolicy:NSURLRequestUseProtocolCachePolicy
timeoutInterval:10.0];
[request setHTTPMethod:@"PUT"];
[request setAllHTTPHeaderFields:headers];
self.sessionIdentifier = [NSString stringWithFormat:@"my-background-session"];
// NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration]; // when I use this instead of the line below the sandbox error goes away
NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier:self.sessionIdentifier];
self.session = [NSURLSession sessionWithConfiguration:configuration delegate:self delegateQueue:nil];
NSURLSessionUploadTask *uploadTask = [self.session uploadTaskWithRequest:request fromFile:urlToBeUploadedIn];
[uploadTask resume];
}
我调用 uploadObject: 的调用看起来像:
PHFetchResult *fetchResult = [PHAsset fetchAssetsWithLocalIdentifiers:state.arrImagesToBeUploaded options:nil];
PHAsset *phAsset = [fetchResult objectAtIndex:0]; // yes the 0th item in array is guaranteed to exist, above.
[phAsset requestContentEditingInputWithOptions:nil
completionHandler:^(PHContentEditingInput *contentEditingInput, NSDictionary *info) {
NSURL *imageURL = contentEditingInput.fullSizeImageURL;
[self uploadObject:imageURL];
}];
顺便说一句,我首先验证了我发送给 uploadObject: 的 NSURL,并调用了 fileExistsAtPath:,所以我知道我对该文件的引用是正确的。最后,我的代表打电话给
(void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)dataIn
(void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error does get invoked, although the data
确实会被服务器调用(尽管响应不会解析)所以,我从服务器返回的东西从未正确接收到图像。
解决方法是先将要上传的图片复制到应用的沙箱中。我用过:
NSError *err;
BOOL bVal = [myNSDataOb writeToURL:myDestinationURL options:0 error:&err];
并复制到我的应用程序的 'Documents' 目录中,但也可以使用:
NSError *err;
BOOL bVal = [[NSFileManager defaultManager] copyItemAtURL:myImageURL toURL:myDestinationURL error:&err];