Как загрузить файл изображения в фоновом режиме (iOS)?

Я не могу загрузить изображение из фотографий моего устройства в фоновом режиме. Когда я вызываю [session uploadTaskWithRequest:req fromFile:nsurl], система немедленно жалуется, отправляя

Failed to issue sandbox extension for file file:///var/mobile/Media/DCIM/103APPLE/IMG_3984.JPG, errno = 1

к консоли. (Аналогичная проблема с переполнением стека описана здесь)

Однако, если я создаю свою NSURLSessionConfiguration с [NSURLSessionConfiguration defaultSessionConfiguration] (вместо [NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier:id], который мне нужен) и, если я создаю объект NSData из NSURL и загружаю его вместо загрузки прямо из файла (который требуется для фонового сеанса), после чего загрузка завершается успешно. Кстати, я загружаю файлы в нашу учетную запись Rackspace Cloud и могу сделать это успешно с помощью простого почтового оператора 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]; 

                                   }];

Кстати, я сначала проверяю NSURL, который я отправляю в uploadObject: с вызовом 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

действительно вызывается сервером (хотя ответ не будет анализироваться), поэтому я получаю что-то от сервера, который никогда правильно не получает изображение.


person Alyoshak    schedule 16.11.2017    source источник


Ответы (1)


Решение состоит в том, чтобы сначала скопировать изображение для загрузки в песочницу приложения. Я использовал:

NSError *err;
BOOL bVal = [myNSDataOb writeToURL:myDestinationURL options:0 error:&err];

и скопирован в каталог «Документы» моего приложения, но можно также использовать:

NSError *err;
BOOL bVal = [[NSFileManager defaultManager] copyItemAtURL:myImageURL toURL:myDestinationURL error:&err];
person Alyoshak    schedule 17.11.2017