我已经为iOS 9和WatchOS 2构建了一个应用程序.iOS应用程序会定期将图像文件从iPhone传输到Watch。有时,这些是从应用程序推送的,有时Watch请求(拉动)它们。如果被拉,我将请求异步,并使用完全相同的iOS代码在两种情况下传输图像。
大约一半的时间(可能是2/3),文件传输有效。其他时候,似乎没有任何反应。无论我是推还是拉图像都是一样的。
在iOS方面,我使用类似于此的代码(已激活会话):
if ([WCSession isSupported]) {
WCSession *session = [WCSession defaultSession];
if (session.reachable) {
NSData *imgData = UIImagePNGRepresentation(img);
NSURL *tempFile = [[session watchDirectoryURL] URLByAppendingPathComponent: @"camera.png"];
BOOL success = [imgData writeToFile: [tempFile path] atomically: NO];
if (success) {
NSLog(@"transferFile:metadata:");
[session transferFile: tempFile metadata: nil];
} else {
NSLog(@"will not call transferFile:metadata:");
}
} else {
NSLog(@"Camera watch client not reachable.");
}
}
在手表扩展端,我有一个激活观察会话并接收文件的单例:
- (void)session:(WCSession *)session didReceiveFile:(WCSessionFile *)file {
// pass the data file to the data listener (if any)
[self.dataListener session: session didReceiveFile: file];
}
我的“数据侦听器”将文件转换为UIImage
并将其显示在UI线程上。然而,这可能是无关紧要的,因为不成功的操作永远不会那么远。
在传输失败期间,永远不会调用session:didReceiveFile:
。但是,如果我检查iOS应用程序的日志,我只会在失败的操作期间看到这些消息:
Dec 26 15:10:47 hostname companionappd [74893] :(注)WatchKit: application(com.mycompany.MyApp.watchkitapp),安装状态:2, 消息:应用程序安装成功
Dec 26 15:10:47主机名 companionappd [74893] :(注)WatchKit:清除 来自安装队列的com.mycompany.MyApp.watchkitapp,0个应用程序 其余
这里发生了什么?看起来应用程序正在尝试重新安装Watch应用程序(?)。发生这种情况时,我会不看到监视应用程序崩溃/关闭并重新启动。它什么都不做。没有收到文件。
在iOS方面,我将图像缩小到大约136x170像素,因此PNG文件不应该太大。
任何想法出了什么问题?
我发布了一个完整的,最小的项目来演示问题on Github here
答案 0 :(得分:0)
我现在认为这是模拟器中的一个错误。它似乎在Apple Watch硬件上更可靠。但不确定它是否100%可靠。
提交的Apple bug报告(#24023088)。如果存在,将更新状态,并为可能提供解决方法的任何可能答案留下未解决的。
答案 1 :(得分:0)
这就是我设法将文件从手机传输到手表的方式:
为了使其工作,文件必须位于appGroupFolder和" App Groups "必须从功能标签中启用,才能进行电话和观看。
为了获取appGroup文件夹,请使用以下代码行:
NSURL * myFileLocationFolder = [[NSFileManager defaultManager] containerURLForSecurityApplicationGroupIdentifier: @"myGroupID"]; //something like group.bundle.projName
一旦你用它来发送消息并处理来自watch的响应:
[session sendMessage:@{@"file":myFileURL.absoluteString} replyHandler:^(NSDictionary<NSString *,id> * _Nonnull replyMessage) {
//got reply
} errorHandler:^(NSError * _Nonnull error) {
//got Error
}];
即使WCSession *session = [WCSession defaultSession];
我注意到有时session
已取消分配,因此您可以考虑使用[WCSession defaultSession];
代替。
要在手机上捕捉到这一点:
- (void)session:(WCSession *)session didReceiveMessage:(NSDictionary<NSString *, id> *)message replyHandler:(void(^)(NSDictionary<NSString *, id> *replyMessage))replyHandler{
//message[@"file"] - addres to my file
//do stuff with it here
replyHandler(@{@"myResponse":@"responseData"}); //this call triggers replyHandler block on the watch
}
如果你没有忘记实施WCSessionDelegate
并使用
if ([WCSession isSupported]) {
_session = [WCSession defaultSession];
_session.delegate = self;
[_session activateSession];
}
//here session is @property (strong, nonatomic) WCSession * session;
一切都应该有用。
提出更广泛的答案,希望能够吸引更多人。
答案 2 :(得分:0)
对我来说,不再有任何转移正在起作用。轮询transfer.progress显示为isTransferring == true
,但我从未超过0个已完成的单元。
我结束了:
它有效。