#記事一覧
Swift MkMapViewで地図アプリ作成してみた(記事一覧)
#iOSからwatchOSにデータを送信する
###セッションをアクティブにする
iOSアプリとwatchOSアプリ間の通信に必要なWatchkitのWCSeesionオブジェクトを使用するため、WatchConnectivityをimportする。
import WatchConnectivity
セッションをアクティブにするために、WCSessionDelegateを継承し、デフォルトのセッションオブジェクトにデリゲートを割り当て、activate()メソッドを呼び出す。
class ViewController: UIViewController,
CLLocationManagerDelegate,
UIGestureRecognizerDelegate,
WCSessionDelegate {
var session: WCSession!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
// セッションをアクティブにする
if (WCSession.isSupported()) {
self.session = WCSession.default
self.session.delegate = self
self.session.activate()
}
WCSessionDelegateに次の3つのメソッドを実装しないとエラーになる。
-
public func session(_ session: WCSession, activationDidCompleteWith activationState: WCSessionActivationState, error: Error?)
ViewController.swift:sessionの実装// セッションアクティブ化の結果が通知される public func session(_ session: WCSession, activationDidCompleteWithactivationState:WCSessionActivationState, error: Error?){ switch activationState { case .activated: print("セッションアクティブ") case .inactive: print("セッションはアクティブでデータ受信できる可能性はあるが、相手にはデータ送信できない") case .notActivated: print("セッション非アクティブで通信できない状態") let errStr = error?.localizedDescription.description print("error: " + (errStr?.description)!) } }
errorは問題が発生したことを示すエラーオブジェクト。
アクティブ化が正常に完了した場合はnilで、activationStateパラメーターが.notActivatedの場合、失敗の理由が格納される。
breakは不要。なのは驚いた。。
* public func sessionDidBecomeInactive(_ session: WCSession)
```swift:ViewController.swift:sessionDidBecomeInactiveの実装
public func sessionDidBecomeInactive(_ session: WCSession){
print("sessionDidBecomeInactive")
}
```
* public func sessionDidDeactivate(_ session: WCSession)
```swift:ViewController.swift:sessionDidDeactivateの実装
public func sessionDidDeactivate(_ session: WCSession){
print("sessionDidDeactivate")
}
```
###watchOSにデータを送信する
activationStateプロパティが.activatedに設定されている場合にのみ、以下のいずれかの方法でwatchOSのアプリにデータを送信できる。
* [updateApplicationContext(_:)](https://developer.apple.com/documentation/watchconnectivity/wcsession/1615621-updateapplicationcontext)
* [sendMessage(_:replyHandler:errorHandler:)](https://developer.apple.com/documentation/watchconnectivity/wcsession/1615687-sendmessage)
* [sendMessageData(_:replyHandler:errorHandler:)](https://developer.apple.com/documentation/watchconnectivity/wcsession/1615617-sendmessagedata)
* [transferUserInfo(_:)](https://developer.apple.com/documentation/watchconnectivity/wcsession/1615671-transferuserinfo)
* [transferFile(_:metadata:)](https://developer.apple.com/documentation/watchconnectivity/wcsession/1615667-transferfile)
* [transferCurrentComplicationUserInfo(_:)](https://developer.apple.com/documentation/watchconnectivity/wcsession/1615639-transfercurrentcomplicationuseri)
今回はsendMessageでデータを送信する。
[Swift MkMapViewで地図アプリ作成してみた(10)](https://qiita.com/rain_00_00_09/items/d426a32ab8356a97fc78)で取得した緯度経度をsendMessageで送信する。
```swift:ViewController.swift:watchOSに緯度経度を送信
// UILongPressGestureRecognizerのdelegate:ロングタップを検出する
@IBAction func mapViewDidLongPress(_ sender: UILongPressGestureRecognizer) {
// ロングタップ開始
if sender.state == .began {
// ロングタップ開始時に古いピンを削除する
mapView.removeAnnotation(pointAno)
}
// ロングタップ終了(手を離した)
else if sender.state == .ended {
//
// 処理は割愛、上記の[Swift MkMapViewで地図アプリ作成してみた(6)]をご参照ください。
//
// watchOSに緯度経度を送信
let dlon:Double = center.longitude
let dlat:Double = center.latitude
let contents = ["lon":dlon, "lat":dlat]
self.session.sendMessage(contents, replyHandler: { (replyMessage) -> Void in
print ("receive from apple watch");
}) { (error) -> Void in
print(error)
}
#watchOSでiOSから送信されたデータを受信する
###セッションをアクティブにする
iOSアプリとのセッションを確立するために、watchOS側のInterfaceController.swiftを実装する。
import WatchConnectivity
class InterfaceController: WKInterfaceController,
WCSessionDelegate {
デフォルトのセッションオブジェクトにデリゲートを割り当て、activate()メソッドを呼び出す。
storyboardのlabelとコード上のlabelを紐付ける。
class InterfaceController: WKInterfaceController,
WCSessionDelegate {
var session:WCSession!
@IBOutlet weak var label: WKInterfaceLabel!
override func awake(withContext context: Any?) {
super.awake(withContext: context)
// Configure interface objects here.
if (WCSession.isSupported()) {
self.session = WCSession.default
self.session.delegate = self
self.session.activate()
}
}
WCSessionDelegateに次の1つのメソッドを実装しないとエラーになる。
- func session(_ session: WCSession, activationDidCompleteWith activationState: WCSessionActivationState, error: Error?) {
func session(_ session: WCSession, activationDidCompleteWith activationState: WCSessionActivationState, error: Error?) {
print("session")
}
###iOSからデータを受信する
iOSからsendMessageで送信されたデータを受信する。
// iPhoneからMessage受信
public func session(_ session: WCSession, didReceiveMessage message: [String : Any], replyHandler: @escaping ([String : Any]) -> Swift.Void){
print("receiveMessage::\(message)")
guard let lon = message["lon"] as? Double else {
return
}
guard let lat = message["lat"] as? Double else {
return
}
label.setText("lon: " + lon.description + "\n" + "lat: " + lat.description)
}
#参考文書
WCSession - WatchConnectivity | Apple Developer Documentation