0
votes

Could use a little help here, as my understanding of blocks and completion handlers is very limited.

I'm trying to implement background fetching in iOS while following along with this tutorial and changing things out as necessary: http://www.appcoda.com/ios7-background-fetch-programming/

I've implemented the necessary precursors to get background fetch enabled and have implemented the following method in to my viewController and have verified that it is being fired when simulating background fetch:

- (void)retrieveMessagesInBackgroundWithHandler:(void (^)(UIBackgroundFetchResult))completionHandler

Inside of my method, I'm calling on a class SoapRequest to perform an asynchronous call out to a web service and that completion handler I am able to determine whether or not I have new data. Ultimately, I'd like to send back the UIBackgroundFetchResult value:

SoapRequest *sr = [SoapRequest createWithURL:[NSURL URLWithString:kServiceURL] soapAction:soapAction postData:soapEnvelope deserializeTo:[NSMutableArray array] completionBlock:^(BOOL succeeded, id output, SoapFault *fault, NSError *error) {

    if( !succeeded ) {
        NSLog(@"method failed: %@", methodName);
        completionHandler = (UIBackgroundFetchResultFailed);
    } else {
        //NSLog(@">>>>>> OUTPUT: %@", output);
        NSDictionary *responseDictionary = output;
        id response = responseDictionary[@"RetrieveMessagesResponse"][@"RetrieveMessagesResult"][@"a:MessagesResult"][@"b:MessageLabel"];
        if ([response isKindOfClass:[NSArray class]]) {
            NSArray *array = response;
            completionHandler = (UIBackgroundFetchResultNewData);
        } else {
            NSLog(@"Nothing new");
            completionHandler = (UIBackgroundFetchResultNoData);
        }
    }
}];

My problem, as you can imagine, is that I'm trying to set completionHandler inside of the block. I'm getting the error: Variable is not assignable (missing __block type specifier)

I'm really unsure of how to implement this properly and am hoping for some insight. Any help would be greatly appreciated.

Thanks in advance!!

1

1 Answers

1
votes

You shouldn't be assigning the completion block, you should be executing it and passing a parameter:

completionHandler(UIBackgroundFetchResultNoData);

Note that to be safe you should also check if completionHandler is nil because it will crash if it is.