didReceiveApplicationContext不被调用
我刚刚在我的应用程序中使用教程/示例代码设置了WCConnectivity,我觉得我已经正确实施了。我没有使用模拟器来测试。出于某种原因,即使所有设置都正确,didReceiveApplicationContext也不会在手表应用程序中调用。didReceiveApplicationContext不被调用
我试着在ExtensionDelegate中的WatchKit应用程序的接口控制器中调用,并使用NSUserDefaults来设置接口控制器数据。
iOS应用
ViewController.m
- (void) viewDidLoad{
if ([WCSession isSupported]) {
WCSession *session = [WCSession defaultSession];
session.delegate = self;
[session activateSession];
}
}
-(void) saveTrip{
NSMutableArray *currentTrips = [NSMutableArray arrayWithArray:[self.sharedDefaults objectForKey:@"UserLocations"]];
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:newLocation];
[currentTrips addObject:data];
[self.sharedDefaults setObject:currentTrips forKey:@"UserLocations"];
[self.sharedDefaults synchronize];
WCSession *session = [WCSession defaultSession];
NSDictionary *applicationDict = [[NSDictionary alloc] initWithObjects:@[currentTrips] forKeys:@[@"UserLocations"]];;
[session updateApplicationContext:applicationDict error:nil];
}
关注扩展代码
ExtensionDelegate.m
- (void)applicationDidFinishLaunching {
if ([WCSession isSupported]) {
WCSession *session = [WCSession defaultSession];
session.delegate = self;
[session activateSession];
}
}
- (void)session:(nonnull WCSession *)session didReceiveApplicationContext:(nonnull NSDictionary<NSString *,id> *)applicationContext {
self.places= [applicationContext objectForKey:@"UserLocations"];
[[NSUserDefaults standardUserDefaults] setObject:self.places forKey:@"UserLocations"];
[[NSUserDefaults standardUserDefaults] synchronize];
}
InterfaceController.m
- (void)willActivate {
[super willActivate];
self.placesData = [NSMutableArray arrayWithArray:[[NSUserDefaults standardUserDefaults] objectForKey:@"UserLocations"]];
[self loadData];
}
如果它不工作,它可能无法正确执行。
第一眼的几个问题:
在iOS应用中,你得到的共享会话的引用,并激活它,但不要在局部变量分配给任何财产上的视图控制器。这意味着一旦
viewDidLoad
退出,您的本地变量将超出范围。您还需要在您的手表扩展程序中进行更正。在
saveTrip
中,您再次创建另一个本地会话,该会话未激活且没有任何委托。您需要使用您之前设置并激活的第一个会话。在您的手表上,您保存了接收到的数据,但您的界面控制器不会知道应该加载和显示的新数据。
一些提示:
如果在安装和激活
application:didFinishLaunchingWithOptions
会议,这将是可用的应用程序范围内(在您的应用程序的生命周期中更早地激活)。您应该检查您的会话是否有效,因为手表可能未配对,或者手表应用程序可能未安装。这里是a good (Swift) tutorial that covers those cases, and also uses a session manager,以便更轻松地支持在整个应用程序中使用Watch Connectivity。
您可能希望将较少/较轻的数据传递到手表,而不是尝试处理归档自定义对象数组。
另一方面,你想要做什么
NSUserDefaults
是非常复杂的。这实际上意味着在推出期间坚持偏好。将它用作在扩展和控制器之间来回传递模型的方式并不合适。
谢谢。我只是非常*地使用NSUserDefaults,因为这是应用程序的beta版本,而在实际的应用程序中,我将使用数据库和API调用。我认为这可能与我的实际项目有关 - 即使在关闭Watch App时,我的session.reachable也是如此。我也收到一个错误,表示手表二进制文件没有连接到手表扩展,这又是关系。我可能只需要开始一个新项目并重新设置。 – emleeh
它可能被证明是处理任何错误有用的,所以改变:
[session updateApplicationContext:applicationDict error:nil];
到
NSError *error;
if (![session updateApplicationContext:applicationDict error:&error]) {
NSLog(@"updateApplicationContext failed with error %@", error);
}
我有同样的问题和解决。 我忘了在Watch扩展中添加WatchConnectivity框架。
对我来说,这是两件事情:
- 在字典中传递无效值。甚至不能通过
NSNull()
来表示零值。如果您的数据不能在plist中表示,则失败。 -
如果字典不改变,随后以
updateApplicationContext
调用不会触发对didReceiveApplicationContext
相应的呼叫。要强制更新,您可以向有效负载添加UUID,例如context["force_send"] = UUID().uuidString
有没有名为'didReceiveApplicationWithContext'方法。发布您的实际代码。 – dan
@dan更新了原文 – emleeh