Nat*_*ate 5 objective-c ios watchkit watchos-2
我已经为 iOS 9 和 WatchOS 2 构建了一个应用程序。iOS 应用程序会定期将图像文件从 iPhone 传输到手表。有时,这些是从应用程序推送的,有时是 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.");
}
}
Run Code Online (Sandbox Code Playgroud)
在手表扩展端,我有一个单例来激活手表会话并接收文件:
- (void)session:(WCSession *)session didReceiveFile:(WCSessionFile *)file {
// pass the data file to the data listener (if any)
[self.dataListener session: session didReceiveFile: file];
}
Run Code Online (Sandbox Code Playgroud)
我的“数据侦听器”将文件转换为 aUIImage并将其显示在 UI 线程上。然而,这可能无关紧要,因为失败的操作永远不会那么远。
在不成功的传输期间,session:didReceiveFile:永远不会被调用。但是,如果我检查 iOS 应用程序的日志,我只会在失败的操作期间看到这些消息:
12 月 26 日 15:10:47 主机名伴侣应用程序 [74893]:(注)WatchKit:应用程序(com.mycompany.MyApp.watchkitapp),安装状态:2,消息:应用程序安装成功
12 月 26 日 15:10:47 主机名伴侣应用程序 [74893]:(注意)WatchKit:从安装队列中清除 com.mycompany.MyApp.watchkitapp,剩余 0 个应用程序
这里发生了什么?该应用程序似乎正在尝试重新安装 Watch 应用程序 (?)。当发生这种情况,我也不会看手表应用程序崩溃/关闭并重新启动。它只是什么都不做。没有收到文件。
在 iOS 端,我将图像缩小到大约 136x170 像素,因此 PNG 文件不应太大。
任何想法出了什么问题?
我已经在 Github 上发布了一个完整的、最小的项目来演示这个问题
这就是我设法将文件从手机传输到手表的方法:
为了使其正常工作,文件必须位于 appGroupFolder 中,并且必须从功能选项卡中启用手机和手表的“应用程序组” 。
为了获取 appGroup 文件夹,请使用以下代码行:
NSURL * myFileLocationFolder = [[NSFileManager defaultManager] containerURLForSecurityApplicationGroupIdentifier: @"myGroupID"]; //something like group.bundle.projName
Run Code Online (Sandbox Code Playgroud)
一旦你得到了它,就可以使用它来发送消息并处理来自手表的响应:
[session sendMessage:@{@"file":myFileURL.absoluteString} replyHandler:^(NSDictionary<NSString *,id> * _Nonnull replyMessage) {
//got reply
} errorHandler:^(NSError * _Nonnull error) {
//got Error
}];
Run Code Online (Sandbox Code Playgroud)
尽管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
}
Run Code Online (Sandbox Code Playgroud)
现在,如果您没有忘记实施WCSessionDelegate和使用
if ([WCSession isSupported]) {
_session = [WCSession defaultSession];
_session.delegate = self;
[_session activateSession];
}
//here session is @property (strong, nonatomic) WCSession * session;
Run Code Online (Sandbox Code Playgroud)
这一切都应该有效。
做出了更广泛的回答,希望能够覆盖到更多的人。
| 归档时间: |
|
| 查看次数: |
1159 次 |
| 最近记录: |