PerformFetchWithCompletionHandler called twice when simulating with Xcode
Asked Answered
J

1

46

In Xcode 7.0.1 the "simulate background" fetch command causes performFetchWithCompletionHandler to be triggered twice.

Is this an Xcode debugging error, or can this happen on a device running a release build of the application.

Update Now we have Xcode 7.1.1 and still performFetchWithCompletionHandler is called twice. Since I am not sure if this also happens "in the wild" I am keeping a state if my fetch action is already running.

- (void)application:(UIApplication *)application performFetchWithCompletionHandler:(nonnull void (^)(UIBackgroundFetchResult))completionHandler {
    if (self.performingFetch) {
        return completionHandler(UIBackgroundFetchResultNoData);
    }
    self.performingFetch = YES;
    ...
    self.performingFetch = NO;
}
Janeanjaneczka answered 13/10, 2015 at 14:46 Comment(6)
I'm experiencing the same thing (regardless of whether [application setMinimumBackgroundFetchInterval:] is called during launch).Fugleman
Any updates on this? I also experience the same thing.Montespan
same thing here. xcode 7 and ios 9Demmer
Another "me too". Seems to be an iOS 9 bug, because also happens with Xcode 6.4 on iOS 9, doesn't happen with Xcode 7 on iOS 8.4.Pitchblack
same here. @MarcHim: I tried with maintaining a state as well. I though suspect that the second call, that hits the state that Fetch already in progress and triggers completionHandler also completes for the first call that is still processing code. Can this be? (my code, which downloads and NSXML parses an RSS feed, never seems to get executed with background fetch on physical device. And this would be an explanation...)Deangelo
I think this is an iOS 9 bug. Also I can confirm it also happens "in the wild"Filmy
C
1

I got around this issue by declaring a static boolean in the App Delegate, and then using the boolean to get the background fetch to perform once

if (!runOnce)
{
    [submission startSubmissionProcessWithCompletetionHandler:^(UIBackgroundFetchResult result){
        NSDate *fetchStart = [NSDate date];

        completionHandler(result);

        NSDate *fetchEnd = [NSDate date];
        NSTimeInterval timeElapsed = [fetchEnd timeIntervalSinceDate:fetchStart];
        NSLog(@"Background Fetch Duration: %f seconds", timeElapsed);
    }];
    runOnce = YES;
}
else
{
    completionHandler(UIBackgroundFetchResultNoData);
    runOnce = NO;
}
Chavira answered 11/2, 2016 at 9:22 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.