 Watch开发学习 (三)

Watch应用的数据传输-与iPhone以及网络(WatchOS 1)

iPhone App、WatchKit Extension和Watch App之间的关系

自iOS8起Apple推出一个新的概念-App Extension,可以让开发者开发第三方的键盘、通知中心(Today Widget)等。


 Watch开发学习 (三)_第1张图片

WatchKit Extension是iPhone App和Watch App通信的桥梁,下图展示了三者间的关系:

 Watch开发学习 (三)_第2张图片
  1. WatchKit Extension(Extension)和Watch App(Host App)间的通信
    在Extension中可以获取到Watch App界面元素的数据接口WKInterfaceObject(非控件View本身,更接近于Model),通过修改WKInterfaceObject的数据,来修改对应Watch App的界面。另外通过Xcode将Watch App控件的响应事件绑定到Extension中,可以实现Watch操作响应逻辑的处理。

  2. WatchKit Extension(Extension)和iPhone App(Containing App)的通信

    1. 共享存储空间

      Extension和iPhone App之间的一种通信方式是读写同一块共享存储空间,达到数据交换的目的(见下图)。需要注意的是Extension和iPhone App属于不同的进程,要共享存储空间,需要在工程对应的target中同时打开App Groups的权限,并选择共享的组名(打开权限需要在Xcode中配置开发者账号和密码,同时本地需要有对应的开发证书,本文后面有介绍)。![]
      (http://git.devzeng.com/images/apple_watch_dev_glance/share_container.png)

    2. 直接进行通信(在WatchOS2中更加推荐)

      Extension和iPhone App另外一种通信方式是Extension主动向iPhone App发起请求,进行某种操作,或者请求数据(场景:Watch 收到新邮件通知后,点击已读按钮,在iPhone App上置已读)。

      WatchKit Extension中向iPhone App发送请求:
      + (BOOL)openParentApplication:(NSDictionary * nonnull)userInfo reply:(void (^ nullable)(NSDictionary * nonnull replyInfo, NSError * nullable error))reply;
      在iPhone App的AppDelegate中实现如下方法响应Watch App的请求:
      - (void)application:(UIApplication * nonnull)application handleWatchKitExtensionRequest:(NSDictionary * nullable)userInfo reply:(void (^ nonnull)(NSDictionary * nullable replyInfo))reply;

      在Github上找到一个叫做MMWormhole的开源库,它是专门用于Container App与Extension间传递消息,整个项目非常简洁实用。

      在WatchOS2中,APPLE公司特地做了一个类似于MMWormhole的framework叫做WatchConnectivity其中有一个最为关键的类叫做WCSession:NSObject

      这里贴出WCSession的一些代码和解释:(只支持iOS9及更新版本,在ContainerApp和Extension中使用一致)
      @interface WCSession : NSObject

      硬件是否支持:+ (BOOL)isSupported;

      单例对象:+ (WCSession *)defaultSession;

      拥有的Delegate:@property (nonatomic, weak, nullable) id delegate;(在这里需要)

      delegate中使用较多的有:(接收信息后的一些处理)
      - (void)session:(WCSession * ) session didReceiveMessage:(NSDictionary *)message;
      - (void)session:(WCSession * )session didReceiveMessage:(NSDictionary * )message replyHandler:(void(^)(NSDictionary *replyMessage))replyHandler;

      激活对象:- (void)activateSession;(在APP生命周期中激活越早越好)

      发送信息:
      - (void)sendMessage:(NSDictionary *)message replyHandler:(nullable void (^)(NSDictionary *replyMessage))replyHandler errorHandler:(nullable void (^)(NSError *error))errorHandler;
      - (void)sendMessageData:(NSData *)data replyHandler:(nullable void (^)(NSData *replyMessageData))replyHandler errorHandler:(nullable void (^)(NSError *error))errorHandler;

      一般的使用过程:

      if ([WCSession isSupported]) {
      WCSession *session = [WCSession defaultSession];
      session.delegate = self;
      [session activateSession];
      }
      //接下来开始send或者receive
      

Watch App的启动过程和生命周期

当用户在Apple Watch上运行应用时,用户的iPhone会自行启动相应的WatchKit应用扩展。通过一系列的信号交换,Watch App和WatchKit Extension互相连接,因此消息能够在二者之间流通,直到用户停止与应用进行交互为止。此时,iOS将暂停应用扩展的运行。

在启动的过程中,WatchKit自动为当前界面创建相应的界面控制器。如果用户正在查看glance,WatchKit创建出来的界面控制器将与glance相连接。如果用户直接启动应用,WatchKit将从应用的主故事板文件中加载初始界面控制器。无论哪种情况,WatchKit应用扩展都提供一个名为WKInterfaceController的子类来管理相应的界面。

  1. 启动Watch App的过程


     Watch开发学习 (三)_第3张图片

    当用户在Apple Watch上与应用进行交互时,WatchKit应用扩展将保持运行。如果用户明确退出应用或者停止与Apple Watch进行交互,那么iOS将停用当前界面控制器,并暂停应用扩展的运行。与Apple Watch的互动是非常短暂的,因此这几个步骤都有可能在数秒之间发生。所以,界面控制器应当尽可能简单,并且不要运行长时任务。重点应当放在读取和显示用户想要的信息上来。

  2. 界面控制器的生命周期
    当应用启动时,WatchKit框架自行创建了相应的WKInterfaceController对象并调用initWithContext:方法。使用该方法来初始化界面控制器,然后加载所需的数据,最后设置所有界面对象的值。

     Watch开发学习 (三)_第4张图片

    在应用生命周期的不同阶段,iOS将会调用WKInterfaceController对象的相关方法来让您做出相应的操作。WKInterfaceController的几个主要的方法说明如下:

    • initWithContext:这个方法用来准备显示界面。借助它来加载数据,以及更新标签、图像和其他在Storyboard场景上的界面对象。
    • willActivate:这个方法可以让您知道该界面是否对用户可视。借助它来更新界面对象,以及完成相应的任务,完成任务只能在界面可视时使用。
    • didDeactivate:使用didDeactivate方法来执行所有的清理任务。例如,使用此方法来废止计时器、停止动画或者停止视频流内容的传输。您不能在这个方法中设置界面控制器对象的值,在本方法被调用之后到willActivate方法再次被调用之前,任何更改界面对象的企图都是被忽略的。

说明:glances不支持动作方法。单击应用glance始终会启动应用。

参考资料初识Apple Watch应用开发

你可能感兴趣的:( Watch开发学习 (三))