数据共享

WatchOS1的数据通信(已过期)

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

方法1:App Groups

概念

App Group 是一个 App 与其扩展均可以访问的本地文件系统的一块区域。由于 Watch App 与 iOS App 是在不同的沙盒环境下运行,正常情况下他们彼此无法分享数据,因此,我们需要在Developer.apple.com创建一个 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需要设置成一样的

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

方法2:App Delegate

使用App Group方式, 可以异步的共享数据,而通过app delegate方式来同步的共享数据

WatchOS2之后的数据通信

但以上方法在WatchOS2之后都被移除,代替的是:

WCSession

WatchOS 2 提供了Watch Connectivity Framework来进行 经过配对的Watch和iPhone的数据交换,该框架可以后台传输和前台传输。

而WatchConnectivity Framework提供了一个WCSession对象,我们要通过WCSession可以进行消息传输。

先说Watch

1.启动服务

记得先导入 import WatchConnectivity

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

let session = WCSession.default()
session.delegate = self
session.activate()

2.发送消息

@IBAction func sendRndNum() {

    print("发送的随机数是:\(randomNumber)")
    let session = WCSession.default()
    session.sendMessage(["randomNumber" : String(randomNumber)], replyHandler: { (keyValue:[String : Any]) in

        print(keyValue)

    }) { (error:Error) in

        print(error)
    }
}

这里需要注意,即使replyHandler和errorHandler不使用,也不可以设置为nil,否则会造成发送消息不会被接收到。

3.接受消息

接受消息使用代理的方式,所以我们首先要在手机和手表的Controller中,遵守WCSessionDelegate,并且实现代理方法

func session(_ session: WCSession, didReceiveMessage message: [String : Any], replyHandler: @escaping ([String : Any]) -> Void) {

    // 需要注意的是,在手机侧,这个代码似乎不是在主线程被调用,所以如果在方法中更新UI控件,比如修改UILabel的内容,需要使用GCD在主线程中修改
    DispatchQueue.main.async { 
        self.numberLabel.setText(message["stringFromPhone"] as! String?)
    }
 }

// 注意,成为WCSessionDelegate的代理,必须要实现如下方法,否则会报
// Type 'InterfaceController' does not conform to protocol 'WCSessionDelegate'
func session(_ session: WCSession, activationDidCompleteWith activationState: WCSessionActivationState, error: Error?) {

}

下面说iOS:

1.启动服务

记得先导入 import WatchConnectivity

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

let session = WCSession.default()
session.delegate = self
session.activate()

2.发送消息

@IBAction func sendRndNum() {

    print("发送的随机数是:\(randomNumber)")
    let session = WCSession.default()
    session.sendMessage(["randomNumber" : String(randomNumber)], replyHandler: { (keyValue:[String : Any]) in

        print(keyValue)

    }) { (error:Error) in

        print(error)
    }
}

这里需要注意,即使replyHandler和errorHandler不使用,也不可以设置为nil,否则会造成发送消息不会被接收到。

3.接受消息

接受消息使用代理的方式,所以我们首先要在手机和手表的Controller中,遵守WCSessionDelegate,并且实现代理方法

func session(_ session: WCSession, didReceiveMessage message: [String : Any], replyHandler: @escaping ([String : Any]) -> Void) {

    // 需要注意的是,在手机侧,这个代码似乎不是在主线程被调用,所以如果在方法中更新UI控件,比如修改UILabel的内容,需要使用GCD在主线程中修改
    DispatchQueue.main.async { 
        self.numberLabel.setText(message["stringFromPhone"] as! String?)
    }
 }

// 注意,成为WCSessionDelegate的代理,必须要实现如下方法(比Watch要多2该必须实现的方法),否则会报
// Type 'InterfaceController' does not conform to protocol 'WCSessionDelegate'
func session(_ session: WCSession, activationDidCompleteWith activationState: WCSessionActivationState, error: Error?) {

}

func sessionDidBecomeInactive(_ session: WCSession) {

}

func sessionDidDeactivate(_ session: WCSession) {

}

results matching ""

    No results matching ""