API Diffsから見る watchOS 3 の新機能

世間から「コレジャナイ」と見放されつつある印象のある Apple Watch / watchOS ですが、APIの面では<b>改善して欲しかった点がちゃんと改善</b>されて、個人的にはまた久々に触ってみようか、という気になっています。

<img width="641" alt="watch.png" src="https://qiita-image-store.s3.amazonaws.com/0/3180/aa68d512-7ec2-046e-275f-e91084951778.png">

以下、「watchOS 3.0 API Diffs」「What’s New in watchOS」等のプレリリースドキュメントを見て気になった新APIを列挙していきます。


##WKCrownSequencer / WKCrownDelegate

ついに！やっと！デジタルクラウンの状態が取れるようになったようです。watchOS 2ではスクロール系のUI操作に使えるだけで、操作をフックしたり、値を取ったりできなかったですからね。。

```swift
WKCrownDelegate
WKCrownDelegate.crownDidBecomeIdle(_: WKCrownSequencer?)
Added WKCrownDelegate.crownDidRotate(_: WKCrownSequencer?, rotationalDelta: Double)
WKCrownSequencer
WKCrownSequencer.delegate
WKCrownSequencer.focus()
WKCrownSequencer.isIdle
WKCrownSequencer.resignFocus()
WKCrownSequencer.rotationsPerSecond
```

##WKGestureRecognizer

Gesture Recognizer が watchOS でも使えるようになりました。

- WKLongPressGestureRecognizer
- WKPanGestureRecognizer
- WKSwipeGestureRecognizer
- WKTapGestureRecognizer.

いや、これ自体嬉しいのですが、そもそもの不満として、<b>これまでユーザーがタップした座標を開発者が知るすべがなかった</b>のですが、

```swift
WKGestureRecognizer.locationInObject() -> CGPoint
```

や

```swift
WKPanGestureRecognizer.translationInObject() -> CGPoint
```

が追加されて、<b>タップした座標とかパンした移動先とかを取れるようになる</b>ってことがとにかく重要かと。watchOS 2 の頃はこれができないためにあきらめた機能が色々とあった気がします。今すぐに良い例が思い浮かばないのですが、たとえばタップした位置に[Core Graphicsで何かを描画する](http://d.hatena.ne.jp/shu223/20150714/1436875676)とか。


##バックグラウンドタスク

ついに来たという感じです。watchOS 2 のころ色々と辛かったのが、アプリが<b>最大75秒でdeactivateされる</b>という制約で、せっかく「ウェアラブル」、つまり「つけっぱなしにできる」のに、アプリは動かしっぱなしにはできない、という事態になってました。お客さんから「こういうことやりたい」と相談されたアイデアのうち、この制約のせいで実現できないものはかなりありました。

で、watchOS 3 では（いくつかのケースで）バックグラウンドで処理を実行できるようになりました。以下の種類があるそうです。

###Background App Refresh

> Use the `WKApplicationRefreshBackgroundTask` class to update your app’s state in the background. You often use a background app refresh task to drive other tasks. For example, you might use a background app refresh task to start an NSURLSession background transfer or to schedule a background snapshot refresh task.


###Background Snapshot Refresh

> Use the `WKSnapshotRefreshBackgroundTask` class to update your app’s user interface. You can push, pop, or present other interface controllers, and then update the content of the desired interface controller. The system automatically takes a snapshot of your user interface as soon as this task completes.


###Background Watch Connectivity

> When you receive background data from the paired iPhone, the system launches your app in the background, instantiates a `WKWatchConnectivityRefreshBackgroundTask` object, and passes the task object to your extension delegate’s handleBackgroundTasks: method.


###Background URL Session

> When a background transfer requires authorization, or when a background transfer completes (successfully or unsuccessfully), the system creates a background NSURLSession event, instantiates a `WKURLSessionRefreshBackgroundTask` object, and passes the task object to your extension delegate’s handleBackgroundTasks: method
To learn more about handling background tasks in general, see Background Refresh Tasks.


解説を端折ると語弊が生じる気がするのでWhat's Newの記述をそのまま引用しました。それぞれの解説だけざっと読むと結構色んなことができるんじゃ、という気がしてきますが、こういうのは実際に試してみないとわからないですね。

WatchConnectivityを用いた本体側（iOS）との通信は、watchOS 2では [ウォッチ側はフォアグラウンドじゃないと通信できなかった](http://d.hatena.ne.jp/shu223/20150616/1434454680) のでこれは嬉しいアップデート。


##Workoutのバックグラウンドサポート

Workoutもバックグランドで動作させられるようになったとのこと。対応方法は Info.plist の WKBackgroundModes キーに `workout-processing` を追加するだけ。ちなみに Xcode 8 の Capabilities からも On/Off できます。（NDA期間中につきスクショは自粛）


##AVFoundation

watchOS でも AVFoudation が使えるように！

全部のクラスが移行されるわけではないのですが、オーディオファイル再生クラスである `AVAudioPlayerNode` とか、オーディオ処理諸々を司る `AVAudioEngine` （詳しくは[こちら](http://d.hatena.ne.jp/shu223/20140918/1410979802)）とか、音声合成の `AVSpeechSynthesizer` とか、色々入ってます。ちゃんと動くかは実際に試してみないとわかりませんが。[^1]

[^1]: APIとしては存在しても実際はサポートされてない、ということもたまにあります。


##ジャイロスコープの値の取得

API的には2からあったんですが、`gyroAvailable` プロパティで必ず `false` が返ってきて<b>実質的に非サポート</b>でした。Apple Watch 2 とか新しいハードが出たら使えるようになるのかなと思ってましたが、wathcOS 3 で取得できるようになるようです。

ジェスチャー・姿勢認識をやろうと思ったら<b>加速度センサだけじゃなくてジャイロの値も大抵必要になる</b>のでこれも嬉しい更新。


あと、[iOS 10 編](http://d.hatena.ne.jp/shu223/20160614/1465862051) で書いた Significant Elevation関連と、CMPedometer関連のAPIが追加されています。


ちなみに最大100Hz周期で取れるそうです。

> Device Motion, which fuses outputs from the accelerometer and gyroscope into orientation and motion dynamics updates. Apps can register to receive these updates at rates up to 100Hz.


Core Motion の歩数取得イベントは<b>バックグランドでも</b>取れるらしい。

> On supported devices, apps can use CMPedometer APIs to register to receive live pedometer events while running in the foreground or the background.


##WKInterfaceInlineMovie

動画再生インターフェース。watchOS 1 の頃、動画をアプリ側でフレーム毎に分解して間引いてpngシーケンスアニメーション（いわゆるパラパラ漫画）としてウォッチ側で再生する、ということをやってましたが、普通に動画を再生できるようになったようです。


##SceneKit / SpriteKit サポート

- WKInterfaceSCNScene
- WKInterfaceSKScene

詳細は後で読む。


##HomeKit

HomeKitのカメラ・ドアベル（日本で言えば呼び鈴）アクセサリをサポートしたとか。それ用のサービス・キャラクタリスティックが追加されたらしい。

WKInterfaceHMCamera というインターフェースのクラスも追加されていて、これはHomeKitのIPカメラのデータにアクセスするためのインターフェースだそうです。[^2]

[^2]: そもそもHomeKit対応のネットワークカメラがまだ日本では販売されてないわけですが。。（されてたらすみません）


##iOS 10 の新機能

量が多いので別記事としてまとめました。

- [API Diffsから見る iOS 10 の新機能 #WWDC2016 - Qiita](http://qiita.com/shu223/items/9ac3261cdbf2a35468ed)