I saw this SO post where apparently data was being fetched and returned to the Watch extension like so:
- (void)application:(UIApplication *)application handleWat
Always refer to official documentation. Official Documentation
The following code works for me.
__block UIBackgroundTaskIdentifier bgTask = [application beginBackgroundTaskWithName:@"MyTask" expirationHandler:^{
// Clean up any unfinished task business by marking where you
// stopped or ending the task outright.
[application endBackgroundTask:bgTask];
bgTask = UIBackgroundTaskInvalid;
}];
// Start the long-running task and return immediately.
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// Do the work associated with the task, preferably in chunks.
[ClassObject getDataWithBlock:^(BOOL succeeded, NSError *error){
if (succeeded)
{
[response setObject:@"update succeded" forKey:@"updateKey"];
reply(response);
}
else
{
if (error)
{
[response setObject:[NSString stringWithFormat:@"update failed: %@", error.description] forKey:@"updateKey"];
reply(response);
}
else
{
[response setObject:@"update failed with no error" forKey:@"updateKey"];
reply(response);
}
}
}];
[application endBackgroundTask:bgTask];
bgTask = UIBackgroundTaskInvalid;
});
To make sure that your asynchronous data fetch does not return immediately (without calling reply), you may try the following:
- (void)application:(UIApplication *)application handleWatchKitExtensionRequest:(NSDictionary *)userInfo reply:(void ( ^)( NSDictionary * ))reply
{
__block UIBackgroundTaskIdentifier watchKitHandler;
watchKitHandler = [[UIApplication sharedApplication] beginBackgroundTaskWithName:@"backgroundTask"
expirationHandler:^{
watchKitHandler = UIBackgroundTaskInvalid;
}];
NSMutableDictionary *response = [NSMutableDictionary dictionary];
dispatch_semaphore_t sema = dispatch_semaphore_create(0);
[ClassObject getDataWithBlock:^(BOOL succeeded, NSError *error){
if (succeeded)
{
[response setObject:@"update succeded" forKey:@"updateKey"];
reply(response);
}
else
{
if (error)
{
[response setObject:[NSString stringWithFormat:@"update failed: %@", error.description] forKey:@"updateKey"];
dispatch_semaphore_signal(sema);
reply(response);
}
else
{
[response setObject:@"update failed with no error" forKey:@"updateKey"];
dispatch_semaphore_signal(sema);
reply(response);
}
}
}];
dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);
dispatch_after(dispatch_time( DISPATCH_TIME_NOW, (int64_t)NSEC_PER_SEC * 1), dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[[UIApplication sharedApplication] endBackgroundTask:watchKitHandler];
});
}
I think you got your code mixed up. You need to move the beginBackgroundTaskWithName
to be inside your handleWatchKitExtensionRequest
Make it the first thing you do, then call your function.
Simplified example:
-(void)application:(UIApplication *)application handleWatchKitExtensionRequest:(NSDictionary *)userInfo reply:(void (^)(NSDictionary *replyInfo))reply{
UIApplication *app = [UIApplication sharedApplication];
UIBackgroundTaskIdentifier bgTask __block = [app beginBackgroundTaskWithName:@"watchAppRequest" expirationHandler:^{
NSLog(@"Background handler called. Background tasks expirationHandler called.");
[[UIApplication sharedApplication] endBackgroundTask:bgTask];
bgTask = UIBackgroundTaskInvalid;
}];
//do your background task(s) here
if([requestString isEqualToString:@“myRequest"]){
//send reply back to watch
reply();
}
//end background task
[app endBackgroundTask:bgTask];
bgTask=UIBackgroundTaskInvalid;
}