Developer David Nottage proposes a slick solution to background fetches on iOS, by decoupling the method calling the completion handler from the actual background fetching code. Background fetches were introduced in iOS 7 and can be used to fetch small amounts of data for a limited time (30 seconds) when the application is in background (i.e. to check if the user has new mail messages). In order for applications to be enabled for background fetch, the “fetch” option needs to be checked in the UIBackgroundModes key in the Version Info section in the project options. The method that handles the background fetching, on iOS, is called performFetchWithCompletionHandler. In FireMonkey, there is no such method, however you can add missing methods to the application delegate, using the Objective-C runtime function class_addmethod.
class procedure TPlatformBackgroundFetch.performFetchWithCompletionHandler(self: id; _cmd: SEL; application: PUIApplication; completionHandler: id); var LResult: TBackgroundFetchResult; LPlatformResult: NSUInteger; begin if FFetch <> nil then begin // Assume no data LResult := TBackgroundFetchResult.NoData; // Call the handler if assigned FFetch.DoFetch(LResult); LPlatformResult := BackgroundFetchResultToPlatform(LResult); // The completion handler *must* be called, if the app is continue to receive background fetch messages CallBlockImplementation(self, _cmd, completionHandler, LPlatformResult); end; end;
You can also set the fetch interval with setMinimumBackgroundFetchInterval, however you should not that the maximum time amount is 30 seconds.
procedure TPlatformBackgroundFetch.UpdateFetchInterval; begin SharedApplication.setMinimumBackgroundFetchInterval(CocoaDoubleConst(libUIKit, 'UIApplicationBackgroundFetchIntervalMinimum')); end;
The demo project implements the background fetch as a platform service (makes use of TPlatformServices), it sets the OnFetch handler, and you have to provide an implementation for it.