Apple Watch(手表)与iPhone(iOS App)通信原理

WatchOS1

在watchOS1中,我们使用AppGroup和AppDelegate在手机和手表之间传递数据,这跟App Extension的原理是一样的。

App Groups

概念

App Group 是一个 App 与其扩展均可以访问的本地文件系统的一块区域。由于 Watch App 与 iOS App 是在不同的沙盒环境下运行,正常情况下他们彼此无法分享数据,因此,我们需要创建一个 App Group,使的它们拥有一个共享的文件区域。


实现

1.  开启App Groups

项目的 target 里分别打开项目本身和 Watch App 的 App Groups,点击加号,添加一个 App Group,输入一个唯一的标识符。我们之后会在 Watch App 和 iOS App 中通过该标识符访问同一个 App Group。

Extension的App Groups:



iOS App的App Groups:


2. 编码

App Groups只能异步同步数据,当手表读取数据的时候,只能读之前手机App保存的数据,相反也是如此。当手机App有新的数据保存时,不能及时的通知手表更新数据,只能是手表下次去主动获取数据。


App Delegate

使用App Group方式, 可以异步的共享数据,下面讲述怎么通过app delegate方式来同步的共享数据
此同步方式的原理是,手表App的InterfaceController调用如下方法:
+ (BOOL)openParentApplication:(NSDictionary *)userInfo reply:
(void(^)(NSDictionary *replyInfo, NSError *error)) reply;

调用此方法后,手机App的AppDelegate会响应,  响应函数:  - application:handleWatchKitExtensionRequest:reply:

- (void)application:(UIApplication *)application
handleWatchKitExtensionRequest:(NSDictionary *)userInfo
              reply:(void (^)(NSDictionary *replyInfo))reply

WatchOS2

WatchOS 2 提供了Watch Connectivity Framework来进行 经过配对的Watch和iPhone的数据交换,该框架可以后台传输和前台传输。
而WatchConnectivity Framework提供了一个WCSession对象,我们要通过WCSession可以进行消息传输。

启动服务

使用WCSession发送和接受消息前,需要先在手机和手表的Controller中分别启动Session,并且尽可能的早:

    WCSession* session = [WCSession defaultSession];
    session.delegate = self;
    [session activateSession];

发送消息

WCSession* session = [WCSession defaultSession];
[session sendMessage:@{@"b":@"goodBye"} replyHandler:^(NSDictionary<NSString *,id> * _Nonnull replyMessage) {

    } errorHandler:^(NSError * _Nonnull error) {

    }];

这里需要注意,即使replyHandler和errorHandler不使用,也不可以设置为nil,否则会造成发送消息不会被接收到,一开始randomize的Objc代码就有这个问题,所以我提交了一次修改,修正了这个问题

[session sendMessage:@{@"b":@"goodBye"} replyHandler:nil errorHandler:nil];//禁止这样调用

接受消息

接受消息使用代理的方式,所以我们首先要在手机和手表的Controller中,遵守如下Delegate

WCSessionDelegate

然后,创建如下方法,接受消息:

- (void) session:(nonnull WCSession *)session didReceiveMessage:(nonnull NSDictionary<NSString *,id> *)message replyHandler:(nonnull void (^)(NSDictionary<NSString *,id> * __nonnull))replyHandler{
    //message即是对方发送的内容
}

需要注意的是,在手机侧,这个代码似乎不是在主线程被调用,所以如果在方法中更新UI控件,比如修改UILabel的内容,需要使用GCD在主线程中修改:

- (void) session:(nonnull WCSession *)session didReceiveMessage:(nonnull NSDictionary<NSString *,id> *)message replyHandler:(nonnull void (^)(NSDictionary<NSString *,id> * __nonnull))replyHandler{
    dispatch_async(dispatch_get_main_queue(), ^{
        self.messageLabel.text = message[@"b"];
        NSLog(@"%@",message);
    });

}

结语

这个通讯方法很简单,使用起来更佳好用,如果涉及多页面通讯,我们可以使用单例来集中管理信息传递,
但是值得注意的是,这个方法的传送速度也不快,这主要是受手表硬件限制,毕竟蓝牙速度不快,还要考虑电池续航


文/Realank(简书作者)
原文链接:http://www.jianshu.com/p/ca5348253c84


  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值