Watchkit , openParentApplication 和 WatchKit 扩展
Posted
技术标签:
【中文标题】Watchkit , openParentApplication 和 WatchKit 扩展【英文标题】:Watchkit , openParentApplication with WatchKit Extension 【发布时间】:2015-08-01 16:40:09 【问题描述】:第一次不起作用“Null”(在 iPhone 中打开 App 之前)
有些时候不起作用,但我想要一个循环或计时器来重复此请求以获得结果:
这是我的代码
- (void)application:(UIApplication *)application handleWatchKitExtensionRequest:(NSDictionary *)userInfo reply:(void (^)(NSDictionary *))reply
// Temporary fix, I hope.
// --------------------
__block UIBackgroundTaskIdentifier bogusWorkaroundTask;
bogusWorkaroundTask = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^
[[UIApplication sharedApplication] endBackgroundTask:bogusWorkaroundTask];
];
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^
[[UIApplication sharedApplication] endBackgroundTask:bogusWorkaroundTask];
);
// --------------------
__block UIBackgroundTaskIdentifier realBackgroundTask;
realBackgroundTask = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^
reply(nil);
[[UIApplication sharedApplication] endBackgroundTask:realBackgroundTask];
];
// Kick off a network request, heavy processing work, etc.
// Return any data you need to, obviously.
// reply(nil);
reply(@@"Confirmation" : @"Text was received.");
[[UIApplication sharedApplication] endBackgroundTask:realBackgroundTask];
// NSLog(@"User Info: %@", userInfo);
观看应用代码
- (void)willActivate
// This method is called when watch view controller is about to be visible to user
[super willActivate];
NSDictionary *dictionary = [[NSDictionary alloc] initWithObjectsAndKeys:@"MyCamande", @"OK", nil];
[InterfaceController openParentApplication:dictionary reply:^(NSDictionary *replyInfo, NSError *error)
NSLog(@"Reply received by Watch app: %@", replyInfo);
];
如何回忆才能得到最终结果
【问题讨论】:
我的回答真的对你有帮助吗? :) 【参考方案1】:好吧,我不建议您在手表本身上使用与网络操作相关的任何东西。首先是因为苹果不建议这样做,原因很明显。唯一直接在手表上执行的网络操作是加载图像。
我一直在为网络运营苦苦挣扎,观察了大约一周,得出的结论是,目前最稳定的方法并不明显。
主要问题是WKInterfaceController.openParentApplication(...)
无法按预期工作。不能只请求打开 iPhone 应用程序并按原样返回响应。有很多解决方案表明在- (void)application:(UIApplication *)application handleWatchKitExtensionRequest:(NSDictionary *)userInfo reply:(void (^)(NSDictionary *))reply
中创建后台线程可以正常工作,但实际上并没有。问题是这个方法必须马上发送reply(...);
。即使创建同步请求也无济于事,您将不断收到“错误 -2 iPhone 应用程序未回复..”,就像我们的 10 次中的 5 倍一样。
所以,我的解决方案如下:
你实施:
func requestUserToken()
WKInterfaceController.openParentApplication(["request" : "token"], reply: responseParser)
如果没有来自 iPhone 的响应,则解析响应以查找可能发生的错误。
ios 端
- (void)application:(UIApplication *)application handleWatchKitExtensionRequest:(NSDictionary *)userInfo reply:(void (^)(NSDictionary *))reply
__block UIBackgroundTaskIdentifier watchKitHandler;
watchKitHandler = [[UIApplication sharedApplication] beginBackgroundTaskWithName:@"backgroundTask"
expirationHandler:^
watchKitHandler = UIBackgroundTaskInvalid;
];
NSString *request = userInfo[@"request"];
if ([request isEqualToString:@"token"])
reply(@@"token" : @"OK");
[PSWatchNetworkOperations.shared loginUser];
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];
);
这段代码只是创建了一个后台线程来强制 iPhone 发送网络请求。假设您的 iPhone 应用程序中有一个特殊的类,它会发送这些请求并将答案发送给 watch。目前,这只能使用App Groups 完成。因此,您必须为您的应用程序和 watchkit 扩展创建一个应用程序组。之后,我建议使用MMWormhole 来建立您的应用程序和扩展程序之间的通信。该手册非常不言自明。
现在这一切有什么意义。您必须实现向服务器发送请求并通过虫洞发送响应。我使用 ReactiveCocoa,所以我的代码中的示例是这样的:
- (void)fetchShoppingLists
RACSignal *signal = [PSHTTPClient.sharedAPIClient rac_GET:@"list/my" parameters:@@"limit":@20, @"offset":@0 resultClass:PSShoppingListsModel.class];
[signal subscribeNext:^(PSShoppingListsModel* shoppingLists)
[self.wormHole passMessageObject:shoppingLists identifier:@"shoppingLists"];
];
[signal subscribeError:^(NSError *error)
[self.wormHole passMessageObject:error identifier:@"error"];
];
正如您在此处看到的,我发回响应对象或错误。请注意,您通过 wormhole 发送的所有内容都应该与 NSCoding 兼容。
现在在手表上你可能会像这样解析响应:
override func awakeWithContext(context: AnyObject?)
super.awakeWithContext(context)
PSWatchOperations.sharedInstance.requestUserToken()
PSWatchOperations.sharedInstance.wormhole.listenForMessageWithIdentifier("token", listener: (messageObject) -> Void in
// parse message object here
)
所以,得出一个结论。您向父应用程序发送请求以从后台唤醒并启动异步操作。立即发送回复()。当您收到操作的答复时,发送通知您已收到答复。同时在您的 watchExtension 中收听响应。
对不起,那是很多文字,但我只是希望它有助于保持冷静,因为我为此花费了很多精力。
【讨论】:
【参考方案2】:也许您可以尝试更清楚地解释确切的问题。但无论如何,您可能想做的一件事是在 awakeWithContext: 中调用 openParentApp:而不是 willActivate。
【讨论】:
以上是关于Watchkit , openParentApplication 和 WatchKit 扩展的主要内容,如果未能解决你的问题,请参考以下文章
Apple Watch 和 openParentApplication 在后台
Apple Watch 在 15 分钟后失去与 iOS 应用程序的连接
向 +[WKInterfaceController openParentApplication:reply:] 提供自定义错误