はじめに
この記事は、岩手県立大学アドベントカレンダー2016 10日目の記事です。
watchOSアプリを改修するにあたりwatchOS 1で利用可能だったフレームワークのいくつかがwatchOS 2やwatchOS 3で利用不可能だということに気づきました。
例えば、SystemConfiguration.frameworkやCFNetwork.frameworkなどです。
これらのフレームワークの機能を使う方法を考えました。
Watch Connectivity
Watch Connectivity framework(WatchConnectivity.framework)は、iPhone(iOSアプリ)とApple Watch(watchOSアプリ)の間でデータの送受信を提供します。
データの送受信をOSが決めるBackground transfersとデータをすぐに転送するInteractive messagingがあります。
実装
今回は、Interactive messagingを実装します。
実行環境は以下のとおりです。
- Xcode 8.1
- iPhone 7(iOS 10.1.1)
- Apple Watch(watchOS 3.1)
watchOS側の実装は以下のようになります。
import WatchKit
import Foundation
import WatchConnectivity
class InterfaceController: WKInterfaceController, WCSessionDelegate {
override func awake(withContext context: Any?) {
super.awake(withContext: context)
}
override func willActivate() {
super.willActivate()
if WCSession.isSupported() {
// Watch Connectivityをサポートしているとき
let session = WCSession.default()
session.delegate = self
session.activate()
if session.isReachable {
// iPhoneと通信可能のとき
session.sendMessage([:], replyHandler: {(replay) -> Void in
let buttonAction = WKAlertAction(title:"OK", style: .default) { () -> Void in
}
self.presentAlert(withTitle: "タイトル", message: replay.description, preferredStyle: .alert, actions: [buttonAction])
}){(error) -> Void in
print(error)
}
}
}
}
override func didDeactivate() {
super.didDeactivate()
}
func session(_ session: WCSession, activationDidCompleteWith activationState: WCSessionActivationState, error: Error?) {
}
}
次にiOS側の実装です。
import UIKit
import WatchConnectivity
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate, WCSessionDelegate {
@available(iOS 9.3, *)
public func sessionDidDeactivate(_ session: WCSession) {
}
@available(iOS 9.3, *)
public func sessionDidBecomeInactive(_ session: WCSession) {
}
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
if WCSession.isSupported() {
let session = WCSession.default()
session.delegate = self
session.activate()
}
return true
}
func applicationWillResignActive(_ application: UIApplication) {
}
func applicationDidEnterBackground(_ application: UIApplication) {
}
func applicationWillEnterForeground(_ application: UIApplication) {
}
func applicationDidBecomeActive(_ application: UIApplication) {
}
func applicationWillTerminate(_ application: UIApplication) {
}
func session(_ session: WCSession, didReceiveMessage message: [String : Any], replyHandler: @escaping ([String : Any]) -> Void) {
if session.isReachable {
// Apple Watchに結果を送信する
replyHandler(["Hello":"World"])
}
}
func session(_ session: WCSession, activationDidCompleteWith activationState: WCSessionActivationState, error: Error?) {
}
}
実行結果
watchOSアプリを起動します。
アラートが表示されデータが送受信できたことがわかります。
このときiOSアプリは起動していなくてもデータの送受信可能です。
この仕組みを使えばwatchOSで用意されていないフレームワークの機能をiOSアプリで処理してwatchOSアプリに結果を渡すことができそうです。