iOS-WatchKit文件传输工作不可靠

时间:2015-12-27 04:32:18

标签: ios objective-c watchkit watch-os-2

我已经为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

3 个答案:

答案 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个已完成的单元。

我结束了:

  1. 删除手表和iPhone上的应用
  2. 同时重新启动
  3. 重新安装

它有效。