2016-07-21 17 views
0

У меня есть категория для моего NSURL, чтобы установить мой DataModel для доступа к моим объектам модели позже. Вот, мой DataModel является подклассы моего лица Core Data (NSManagedObject)NSURL + Категория с NSURLSessionDownloadTask


@implementation NSURL (CustomizedObject) 

static char PROPERTY_KEY; 

@dynamic model; 

- (void)setChunk:(DataModel *)model { 
    objc_setAssociatedObject(self, &PROPERTY_KEY, model, OBJC_ASSOCIATION_RETAIN_NONATOMIC); 
} 

- (DataModel *)model { 
    return (DataModel *)objc_getAssociatedObject(self, &PROPERTY_KEY); 
} 

@end 

Итак, Я загружаю свои данные через NSURLSessionDownloadTask


for (DataModel *model in models) { // Here 985 URLs are there 
    if ([model.status integerValue] == 0) { 
     NSURL *requestURL = [NSURL URLWithString:model.downloadSequence]; 
     [requestURL setModel:model]; 
     NSURLSessionDownloadTask *downloadTask = [self.session downloadTaskWithURL:requestURL]; 
     [downloadTask resume]; 

     [self.arrFileDownloadData addObject:downloadTask]; 
    } 
} 

И, я обращаюсь к моему DataModel в каждой успешной загрузки


- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location 
{ 
    self.downloadSuccessCount++; 

    DownloadModel *model = downloadTask.originalRequest.URL.model; 
    NSString *filePath = [model.content.filePath stringByAppendingPathComponent:[[model.streamingSequence lastPathComponent] stringByDeletingPathExtension]]; 

    NSError *error; 
    NSFileManager *fileManager = [NSFileManager defaultManager]; 

    NSURL *destinationURL = [NSURL fileURLWithPath:filePath]; 

    if ([fileManager fileExistsAtPath:[destinationURL path]]) { 
     [fileManager removeItemAtURL:destinationURL error:nil]; 
    } 

    BOOL success = [fileManager copyItemAtURL:location toURL:destinationURL error:&error]; 

    if (success) { 
     NSError *fetchError = nil; 

     NSFetchRequest *fetch = [NSFetchRequest fetchRequestWithEntityName:ChunkCoreData]; 
     [fetch setPredicate:[NSPredicate predicateWithFormat: @"modelId == %@", model.modelId]]; 

     NSArray *isProductExist = [self.context executeFetchRequest:fetch error:&fetchError]; 

     if ([isProductExist count] != 0) { 
      DataModel *fetchedModel = [isProductExist lastObject]; 
      fetchedModel.status = [NSNumber numberWithInt:2]; 

      // create writer MOC 
      NSManagedObjectContext* _privateWriterContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType]; 
      [_privateWriterContext setPersistentStoreCoordinator:[[self managedObjectContext] persistentStoreCoordinator]]; 

      // create main thread MOC 
      NSManagedObjectContext* _managedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType]; 
      _managedObjectContext.parentContext = _privateWriterContext; 

      NSError *saveError = nil; 
      if (![_privateWriterContext save:&saveError]) { 
       NSLog(@"Couldn't save %@", saveError.localizedDescription); 
      } 
     } 
    } 
} 

Все, работает отлично, за исключением иногда. Я получаю сбой в,

NSURL *destinationURL = [NSURL fileURLWithPath:filePath]; 

к говорит, что filePath равна нулю. Или проблема связана с моим созданием категории NSURL?

Что я здесь делаю неправильно? Предложения, пожалуйста.

+0

Как работает комбинация 'char' и' OBJC_ASSOCIATION_RETAIN_NONATOMIC'? – Droppy

+0

@Droppy Тогда, что еще я должен дать, чтобы получить доступ к моей «DataModel» для доступа через «NSURL», я очень новичок в * Категориих * – Praveenkumar

+0

Да, моя ошибка; смотря на [это] (http://stackoverflow.com/a/8733320/3588973) ответ, что * есть * как это делается с категориями. Я редко использую их, поскольку они просто усложняют вещи, и мне нравится * simple *. – Droppy

ответ

0

Я знаю, что NSURLSession делает не ручки подклассы NSURLRequest; это была катастрофа в iOS 7, пограничная непригодная для использования в iOS 8 и по-прежнему довольно багги в iOS 9.

Я думаю, это связано с тем, что объекты сериализуются на plist, даже когда запросы обрабатываются в процессе. Я подозреваю, что вы нажимаете те же ошибки, что и я, и в этом случае связанные объекты на NSURLRequest или NSURL, вероятно, будут одинаково проблематичными.

В качестве альтернативы, вот некоторые другие методы, которые могли бы работать лучше для вас:

  • Использование setProperty:forKey:inRequest: и property:forKey:inRequest: на NSURLRequest объекта вместо этого.
  • Для не-фоновых сеансов вместо этого добавьте связанные объекты в задачу.
  • Создайте словарь, который отображает объект запроса URL-адреса в нужные вам данные.

HTH.