iPhone应用程序中的UIApplicationDelegate从未调用过回复

我正在尝试使用以下代码从手表模拟器启动我的iPhone应用程序:

WKInterfaceController子类

[WKInterfaceController openParentApplication:[NSDictionary dictionaryWithObject:@"red" forKey:@"color"] reply:^(NSDictionary *replyInfo, NSError *error) { NSLog(@"replyInfo %@",replyInfo); NSLog(@"Error: %@",error); }]; 

AppDelegate.m

 - (void)application:(UIApplication *)application handleWatchKitExtensionRequest:(NSDictionary *)userInfo reply:(void(^)(NSDictionary *replyInfo))reply { NSLog(@"appdelegate handleWatchKitExtensionRequest"); NSLog(@"NSDictionary: %@",userInfo); NSLog(@"replyInfo: %@",replyInfo); } 

我得到的错误是:

错误:错误Domain = com.apple.watchkit.errors Code = 2“iPhone App中的UIApplicationDelegate从未调用reply() – [UIApplicationDelegate application:handleWatchKitExtensionRequest:reply:]”UserInfo = 0x7f8603227730 {NSLocalizedDescription = iPhone中的UIApplicationDelegate应用程序永远不会调用reply() – [UIApplicationDelegate application:handleWatchKitExtensionRequest:reply:]}

你需要调用回复块,即使你返回nil 。 以下将解决您的错误:

 - (void)application:(UIApplication *)application handleWatchKitExtensionRequest:(NSDictionary *)userInfo reply:(void(^)(NSDictionary *replyInfo))reply { NSLog(@"appdelegate handleWatchKitExtensionRequest"); NSLog(@"NSDictionary: %@",userInfo); NSLog(@"replyInfo: %@",replyInfo); reply(nil); } 

有关详细信息,请参阅Apple文档 。 您还可以返回NSDictionary reply(myNSDictionary); 尽管字典只能包含可以序列化到属性列表文件的信息,但是对于返回到Watchkit扩展名的任何信息都是有用的,所以例如你可以传递字符串,但是你不能只传递包含引用的字典。您的自定义类的实例,而不是首先将它们打包为NSData。

除了不调用回复块之外,这可能至少有几个原因:

  1. 您的iPhone应用程序在处理请求时崩溃,因此无法调用回复块。 检查您是否不小心将nil放入NSMutableDictionary中,因为这会导致崩溃。
  2. 你试图将一些无法序列化的东西放入一个plist文件到replyInfo字典中(帽子提示为@duncan-babbage)。 如果需要传递NSAttributedString或自定义对象,请确保它符合NSCoding并执行以下操作:

在手机端构建您的回复词典:

 NSMutableDictionary *reply = [NSMutableDictionary new]; MyCustomObject *myObject = ; reply[@"myKey"] = [NSKeyedArchiver archivedDataWithRootObject: myObject]; NSAttributedString *myString = ; reply[@"otherKey"] = [NSKeyedArchiver archivedDataWithRootObject: myString]; 

然后将其打开放回手表侧:

 NSData *objectData = replyInfo[@"myKey"]; MyCustomObject *myObject = [NSKeyedUnarchiver unarchiveObjectWithData: objectData]; NSData *stringData = replyInfo[@"otherKey"]; NSAttributedString *myString = [NSKeyedUnarchiver unarchiveObjectWithData: stringData]; 

我想补充说,在文档中指定的handleWatchKitExtensionRequest中启动后台任务很重要。 这可以确保iPhone上的主应用程序在发送回复之前不会被暂停。 (不启动后台任务不会在模拟器中或iPhone应用程序处于活动状态时出现问题。但是,当iPhone应用程序处于非活动状态时会导致问题。)

iPhone主应用程序的app代理中的代码:

 - (void)application:(UIApplication *)application handleWatchKitExtensionRequest:(NSDictionary *)userInfo reply:(void ( ^)( NSDictionary * ))reply { __block UIBackgroundTaskIdentifier watchKitHandler; watchKitHandler = [[UIApplication sharedApplication] beginBackgroundTaskWithName:@"backgroundTask" expirationHandler:^{ watchKitHandler = UIBackgroundTaskInvalid; }]; if ( [[userInfo objectForKey:@"request"] isEqualToString:@"getData"] ) { // get data // ... reply( data ); } 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]; } ); }