2015-05-09 25 views
2

我看到this SO张贴在那里显然数据被取出并返回到监视扩展,像这样:WatchKit在handleWatchKitExtensionRequest返回块内回复():

- (void)application:(UIApplication *)application handleWatchKitExtensionRequest:(NSDictionary *)userInfo reply:(void (^)(NSDictionary *))reply 
{ 
    if ([[userInfo objectForKey:@"request"] isEqualToString:@"getData"]) 
{ 
    // get data 
    // ... 
    reply(data); 
} 
} 

但是,当我尝试调用“回复( )”获取网络数据,像这样经过块内:

__block UIBackgroundTaskIdentifier watchKitHandler; 

watchKitHandler = [[UIApplication sharedApplication] beginBackgroundTaskWithName:@"backgroundTask" 
                   expirationHandler:^{ 
                    watchKitHandler = UIBackgroundTaskInvalid; 
                   }]; 
- (void)application:(UIApplication *)application handleWatchKitExtensionRequest:(NSDictionary *)userInfo reply:(void (^)(NSDictionary *))reply 
{ 

NSMutableDictionary *response = [NSMutableDictionary dictionary]; 
[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); 
      } 
     } 
    }]; 
} 

dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)NSEC_PER_SEC * 180), dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 
    [[UIApplication sharedApplication] endBackgroundTask:watchKitHandler]; 
}); 

我得到这个错误:

"The UIApplicationDelegate in the iPhone App never called reply() in -[UIApplicationDelegate application:handleWatchKitExtensionRequest:reply:]"

所以我想我必须立即调用reply(),并且在WatchKit唤醒父应用后发送新的网络数据的唯一方法是使用MMWormhole?

回答

0

为了确保您的异步数据取不立即返回(不调用回复),你可以尝试以下方法:

- (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]; 
    }); 
} 
+0

我已经包装它在后台任务。我应该清楚地说明并更新了我的问题。我甚至尝试将时间更改为180秒,但仍会立即返回错误。您是否在示例中的“获取数据”中运行了一个块? –

+0

你好,我已经改变了我的答案。通过这种方式,自程序等待dispatch_semaphore_wait(sema,DISPATCH_TIME_FOREVER);直到dispatch_semaphore_signal(sema);被执行后,秒就足够了。它工作吗? – vomako

+0

是的,这工作,谢谢。 –

0

我觉得你有你的代码混淆。您需要将beginBackgroundTaskWithName置于您的handleWatchKitExtensionRequest之内让它成为您的第一件事,然后调用您的功能。

简单的例子:

-(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; 

} 
0

请务必参阅官方文档。 Official Documentation

以下代码适用于我。

__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; 
});