0
votes

i'm having an issue with a app that uses AFNetworking 2.0 and MagicalRecord. This app downloads data from a little JSON API in a podcast site and stores every podcast episode in a Podcast entity.

This Podcast Entity has another entity called PodcastDownload that keep information when a podcast is downloading (Download status and progress). In this PodcastDownload entity i use KVO to update this information observing the NSProgress object and state from the NSURLSessionDownloadTask. This works fine.

But I have a problem when I try to save the download status in my data context with this method in a singleton instance called PodcastManager:

- (void)saveContext{

  [[NSManagedObjectContext defaultContext] saveToPersistentStoreWithCompletion:^(BOOL success, NSError *error) {

  if (success) {
    NSLog(@"Save OK");
  } else if(error) {
    NSLog(@"Error %@", error.description);
  }

 }];
}

When I call this method I get this EXC_BAD_ACCESS error in the AFURLSessionManager from AFNetworking, but saving seems tu run ok according to my log:

EXC_BAD_ACCESS error

Context BACKGROUND SAVING (ROOT) is about to save. Obtaining permanent IDs for new 1 inserted objects

I don't know what is causing this error. I Also tried using MagicalRecord method saveWithBlock but I got the same result.

This is my source code for my KVO Observer inside PodcastDownload:

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
 {
  if (context == PodcastDownloadContext) {

  if ([object isKindOfClass:[NSURLSessionDownloadTask class]]) {

    NSURLSessionDownloadTask *task = (NSURLSessionDownloadTask *) object;



    if (task.state == NSURLSessionTaskStateRunning) {
      [self setStatus:PodcastDownloadRunning];
      [[PodcastManager sharedManager] saveContext];
    }

    if (task.state == NSURLSessionTaskStateSuspended) {
      [self setStatus:PodcastDownloadSuspended];
      [[PodcastManager sharedManager] saveContext];
    }

    if (task.state == NSURLSessionTaskStateCanceling) {
      [self setStatus:PodcastDownloadCanceling];
      self.downloadTask = nil;
      self.data = nil;
      self.progress = 0;
      [[PodcastManager sharedManager] saveContext];
    }

    if (task.state == NSURLSessionTaskStateCompleted) {

      if (self.status == PodcastDownloadCanceling) {
        [self setStatus:PodcastDownloadNotSet];
      } else {
        [self setStatus:PodcastDownloadCompleted];
        self.downloadTask = nil;
        self.data = nil;
        self.progress = 0;
        [[PodcastManager sharedManager] saveContext];
      }

      @try {
        [object removeObserver:self forKeyPath:NSStringFromSelector(@selector(state)) context:PodcastDownloadContext];
        [object removeObserver:self forKeyPath:NSStringFromSelector(@selector(fractionCompleted)) context:PodcastDownloadContext];
      }
      @catch (NSException * __unused exception) {}
    }

  }
 }
}

Thank you so much

1
This might not have anything to do with the saving operation at all. Have you checked to make sure your self.downloadprogress object has been properly initialized before assigning to its various properties?JiuJitsuCoder
Yes. In fact, if I remove the saving operation, properties in my PodcastDownload object are updated correctly. Notice that the EXC_BAD_ACCESS error occurs in AFURLSessionManager. I edited my question adding this, sorry, my bad.WedgeSparda
Your saveContext method seems right to me. I wish I could help further, but maybe others will chime in with suggestions. I would double check the singleton code to make sure the singleton is properly initialized and check variables to make sure they are all initialized correctly. EXC_BAD_ACCESS is usually thrown when trying to work with an object that isn't properly initialized or sending the wrong type as an argument to some other method (i.e. sending an int to something expecting a pointer). Those are always the first two places I go to diagnose that exception.JiuJitsuCoder

1 Answers

0
votes

Well, making some changes I find out a solution, but not the cause.

I had three entities in my Core Data stack (Podcast, PodcastDownload and PodcastPlayback). The main entity is Podcast and PodcastDownload was used to save information about the download, as I explained in my question.

What I did was take the attributes out from PodcastDownload and put them in the Podcast entity. And now seems to work as it should.

I don't know the exact cause of the error, but I think it was related with threading (sorry, I'm still a little noob with objective-c).

Thanks for all the help.