completion block does not fire for generateGeodatabaseParameters API when app goes to background

3355
5
08-13-2014 10:36 AM
ShankaralingamG
New Contributor

Hi,

Can some one explain how to receive callback on the 'completion' block of 'generateGeodatabaseParameters' API of an AGSGDBSyncTask ?

I have even enabled 'background Fetch' capability in my project settings, and also have set 'allowCallbackWhenAppInBackground' property of AGSGDBSyncTask to true.

If the app goes into background, the callback does not fire, even after the task has downloaded the geoDB completely.

0 Kudos
5 Replies
DiveshGoyal
Esri Regular Contributor

Have you looked at the OfflineFeatureEditing sample? It does the background download and posts a notification in the completion handler -

Screen Shot 2014-08-18 at 2.03.54 PM.png

The key is to handle the background fetch events in the app delegate. The sample provides a convenience class called BackgroundHelper that you can reuse in your own app  -

//This will get called periodically by the system when the app is background'ed if

//the app declares it supports "Background Fetch" capability in XCode project settings

- (void) application:(UIApplication *)application performFetchWithCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler{

    [BackgroundHelper checkJobStatusInBackground:completionHandler];

}

- (void)application:(UIApplication *)application handleEventsForBackgroundURLSession:(NSString *)identifier completionHandler:(void (^)())completionHandler {

    [BackgroundHelper downloadJobResultInBackgroundWithURLSession:identifier completionHandler:completionHandler];

}

0 Kudos
ShankaralingamG
New Contributor

Thanks Divesh for the reply.

I have three questions related to this:-

1) How can i assign the completion block of generateGeodatabaseParameters API inside performFetchWithCompletionHandler delegate ?

Should i declare the completion block as a property of my class and use it inside this delegate ?

2) Will the completion block of generateGeodatabaseParameters API would be called automatically, if we just include these two delegates in our project ?

3) Do we have to create a separate provisioning profile for this purpose, instead of the standard 'wildcard' profile that we normally use ? (As we have added the 'Background Fetch' capability)

0 Kudos
DiveshGoyal
Esri Regular Contributor

Shankar,

Re:1) I wonder why you want to call generateGeodatabase inside performFetchWithCompletion. Typically, you would call generateGeodatabase inside one of your view controllers when the user interacts with your app (say taps on a button to download map data), and then only check its status in performFetch. There isn't any guarantee on when performFetch will be called by the OS. So if you wait to start generating a geodatabase inside performFetch, your user may go for hours without actually starting to generate one. Also, performFetch may be called multiple times by the OS during the course of a day. So if you do decide to start generating a gdb inside that method, you will have to add guards to prevent generating the gdb multiple times. As for declaring the completion block, you could declare it inline when calling generateGeodatabase, or you could declare it as a property in the same class where the AGSGDBSyncTask is declared. It really depends upon what objects you want to access inside the completion block.

Re:2) The completion block will be called automatically by the SDK once the download completes. The BackgroundHelper utility class in the sample uses some coarse grained APIs in the SDK that help to monitor the job status on the server and initiate a download when the job is complete. I suggest you read the API reference associated with those API methods.

Re:3) The wildcard profile should be sufficient.

0 Kudos
ShankaralingamG
New Contributor

Thanks Divesh for the reply again

1) I do not intend to call 'generateGeodatabase' inside 'performFetch'. Am calling that inside one of my viewcontrollers only. But, I wanted to know the significance of 'completionHandler' parameter of 'performFetch'. Does it relate to the calling of 'completion' block of the generateGeodatabase API.

2)  I have used the generateGeodatabase API, according to the 'OfflineFeatureEditing' SDK sample codebase.

I have the 'completion' block of this API defined inline only. Also, i have copied the statements given as part of the 'BackgroundHelper' class's utility function, which gets called from 'performFetch'.

Given this scenario, whenever the app goes into backround mode, am able to receive delegate calls inside the 'status' block, but when the download of geoDB is complete (am getting 'Done' status inside the 'status' block) the 'completion' block does not gets fired from the SDK.

0 Kudos
DiveshGoyal
Esri Regular Contributor

1) The completionHandler passed into performFetch belongs to iOS. Applications are supposed to call that when they're done performing background HTTP requests. The SDK does this for you when it finishes checking status of ongoing jobs ([AGSTask checkStatusForAllResumableTaskJobsWithCompletion:]) or when its done downloading result of those jobs ([AGSURLSessionManager setBackgroundURLSessionCompletionHandler:forIdentifier:]). These calls are in the sample's background helper.

I'm not sure why your completion block does not get called when the download finishes. I'm wondering if the download ever starts. Do you see your app delegate's handleEventsForBackgroundURLSession  method being called? Also check your server's jobs/output folders to see if the geodatabase has been generated

0 Kudos