Search code examples
iosobjective-cbackground-fetch

Background Fetch iOS UIBackgroundFetchResult unrecognize selector


I am following AppCoda:Working with Background Fetch Programming and getting some error. I already created base app that can display table with data from its source, also it UIRefreshControl works well.

Then I started to create its background fetching process. I already enable its background capability, set minimum interval time on appDelegate, and implement application:performFetchWithCompletionHandler: method.

- (void)application:(UIApplication *)application performFetchWithCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
    MyTableViewController *viewController = (MyTableViewController *)self.window.rootViewController;
    [viewController fetchNewDataWithCompletionHandler:^(UIBackgroundFetchResult result) {
        completionHandler(result);
    }];
}

I build this project, and still work well. Then I want to test its background process by duplicating existing project scheme and enable option launch due to a background fetch event. I pressed run, and it give me error due to unrecognize selector.

[UINavigationController fetchNewDataWithCompletionHandler:]: unrecognized selector sent to instance 0x7fb99280b800

This is my fetchNewDataWithCompletionHandler:

- (void)fetchNewDataWithCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
    XMLParser *xmlParser = [[XMLParser alloc] initWithXMLURLString:NewsFeed];
    [xmlParser startParsingWithCompletionHandler:^(BOOL success, NSArray *dataArray, NSError *error) {
        if (success) {
            NSDictionary *latestDict = [dataArray objectAtIndex:0];
            NSString *latestTitle = [latestDict objectForKey:@"title"];

            NSDictionary *existingDict = [self.arrNewsData objectAtIndex:0];
            NSString *existingTilte = [existingDict objectForKey:@"title"];

            if ([latestTitle isEqualToString:existingTilte]) {
                completionHandler(UIBackgroundFetchResultNoData);
                NSLog(@"No new data found");
            }
            else {
                [self performNewFetchedDataActionsWithDataArray:dataArray];
                completionHandler(UIBackgroundFetchResultNewData);
                NSLog(@"New data was fetched");
            }
        }
        else {
            completionHandler(UIBackgroundFetchResultFailed);
            NSLog(@"Failed to fetch");
        }
    }];
}

I don't know what is going on here, what happened with my fetchNewDataWithCompletionHandler?. Any help would be appreciated. Thank you.


Solution

  • You need to set your viewController as rootViewController

    MyTableViewController *viewController = [[MyTableViewController alloc] init];
    self.window.rootViewController = viewController;
    

    Then configure your tableView:cellForRowAtIndexPath: to support dequeue cell identifier

    static NSString *cellIdentifier = @"cellIdentifier";
    
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cellIdentifier"];
    if (cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellIdentifier];
    }
    

    Let me know if that's work.