iOS 10の新機能のサンプルコード集「iOS 10 Sampler」

iOS 10でも大量のAPIが追加されました。が、<b>新しいAPIはどう使うのか、実際に何がどこまでできるのか</b>、といった具体的なところが、英語のドキュメントやWWDCのセッション動画をながめているだけだと正直あまりピンときません。やはり実際に<b>コードを書いて動かしてみるのが一番わかりやすい</b>・・・ということで恒例の<b>新機能のサンプルコード寄せ集めアプリ</b>をつくりました。


###[iOS 10 Sampler](https://github.com/shu223/iOS-10-Sampler)

![icon_bg.jpg](https://qiita-image-store.s3.amazonaws.com/0/3180/fd46fa57-9c70-af8e-d923-93bfb06c4b52.jpeg)


ソースコードは GitHub に置いてあります。ご自由にご活用ください。

- https://github.com/shu223/iOS-10-Sampler

iOSももうかなり成熟してしまい、「話題になる革新的な新機能」とか、「どの開発者にとっても嬉しい新機能」というのはなかなか**ない**わけですが、

- 実装してみると思ったより簡単なので自分のアプリにも取り入れたくなった
- 他の誰も話題にしてないけど自分的には熱い

</b>みたいな機能もあったので、ぜひ一度お試しいただけると嬉しいです。


今のところ<b>18個</b>のサンプルが入っています。随時追加していきます。機能追加プルリク大歓迎です！


##使い方

<b>Xcode 8 でビルドするだけ</b>です。

![ss.jpg](https://qiita-image-store.s3.amazonaws.com/0/3180/ee0d652d-f166-d4c4-42e6-a85615a152ec.jpeg)


Samplerシリーズでは「<b>余計な実装を混ぜずに、新機能のメリットをできるだけシンプルな実装で伝える</b>」というところに気をつけています [^2]。コピペもしやすいと思うので、自分のアプリに取り入れて動かしてみるとより楽しいかもしれません。

[^2]: Appleによる公式サンプルではアプリとしての体裁を整えるために新機能とは直接は関係ない実装がたくさん入っていたりしてややこしくなっているケースが多々ある


##サンプル一覧


###Speech Recognition

新たに追加された Speech Framework を利用した音声認識のサンプルです。

<img src="https://qiita-image-store.s3.amazonaws.com/0/3180/e20b6fb4-3ebd-cab4-4ce9-bde6ba7516d8.jpeg" width="405">


Appleのサンプルをベースに、<b>全58種類の対応言語</b>を選択する機能を追加しています。

- [【iOS 10】Speechフレームワークで音声認識 - 対応言語は58種類！ - Qiita](http://qiita.com/shu223/items/ca8e62803e83e396c177)


###Looper

AVFoundationに新規追加されたクラス AVPlayerLooper を用いた<b>動画のループ再生</b>のサンプルです。

<img src="https://qiita-image-store.s3.amazonaws.com/0/3180/f8c044c7-91bb-1697-820c-44285c02ea62.gif" align="left"> ![loop_short.gif](https://qiita-image-store.s3.amazonaws.com/0/3180/df5d0596-1001-98a4-4c4c-58b42247658c.gif)

<br clear="all">


このクラス自体はプレイヤー機能は持っておらず、AVQueuePlayer と AVPlayerItem のインスタンス、そしてループする範囲を示す CMTimeRange オブジェクトを渡して使用します。

```swift
public init(player: AVQueuePlayer, templateItem itemToLoop: AVPlayerItem, timeRange loopRange: CMTimeRange)
```


###Live Photo Capturing

写真撮影用に追加された新クラス AVCapturePhotoOutput を使用した<b>ライブフォト撮影</b>サンプルです。[^3]

[^3]: Appleの「AVCam」サンプルをベースに、Live Photo撮影の実装だけを抜き出し、シンプルにしたもの

<img src="https://qiita-image-store.s3.amazonaws.com/0/3180/37c41340-8db2-4648-6c3f-a239fa4f6b4d.jpeg" width="200">


Live Photo のビューワーは iOS 9.1 から使えましたが、今回から撮影もできるようになりました。

- [Live Photos（ライブフォト）を表示するクラス PHLivePhotoView を試す - Qiita](http://qiita.com/shu223/items/e87ea139512ba732997d)


###Audio Fade-in/out

すごーく**地味**だし、このAPIがなくてもできたといえばできたことなんですが、実際に使う人は多いかもしれません。<b>AVAudioPlayerにフォードイン／アウトするためのメソッドが追加</b>されました。

```swift
// Fade In
player.setVolume(1, fadeDuration: 3)

// Fade Out
player.setVolume(0, fadeDuration: 3)
```


これタイマーとかでやってた人は嬉しいんじゃないでしょうか。


###Metal CNN Basic: Digit Detection

Metal Performance Shaders フレームワークに追加されたCNN (Convolutional Neural Network / 畳み込みニューラルネットワーク)を用いた<b>手書き数字認識</b>のサンプルです。[^4]

[^4]: 本サンプルは、Appleの「MPSCNNHelloWorld」サンプルをベースに、不要な実装を除去しシンプルにしたもの


![digit.gif](https://qiita-image-store.s3.amazonaws.com/0/3180/e2cfc688-8812-8771-2fa8-405b4bb0492c.gif)


この「<b>Metal AcceleratedなCNN計算処理</b>」は個人的には今回一番熱い新機能です。

- [iOSDCのリジェクトコンで『iOSとディープラーニング』について話しました - Over&Out その後](http://d.hatena.ne.jp/shu223/20160902/1472771340)

<script async class="speakerdeck-embed" data-id="7f292570058640a3af38e07e01274550" data-ratio="1.33333333333333" src="//speakerdeck.com/assets/embed.js"></script>


###Metal CNN Advanced: Image Recognition

上のサンプルに引き続き、<b>Metal Performance ShadersのCNNを利用したリアルタイム一般物体認識</b>のサンプルです。[^5]

[^5]: 本サンプルのモデルデータと、ネットワークの実装は、Appleの「MetalImageRecognition」サンプルをベースにしています

![imagerecog.gif](https://qiita-image-store.s3.amazonaws.com/0/3180/0c788c23-4559-f966-281b-aa7f75442962.gif)


速くて見づらいかもしれませんが、<b>ノートパソコン（notebook）→ リモコン（remote control） → iPhone（iPod）</b>と認識しています。


Metal Shaderというぐらいなので<b>GPUで処理</b>されます。6s利用ですが、<b>処理速度も申し分なし</b>でした。（ちなみにMetalはAppleのハードウェアに最適化されたグラフィックスAPIで、<b>「OpenGLより最大10倍速い」</b>と言われています）


ちなみにミスリードもあるかもしれないので念のためですが、<b>「一般物体認識」という新機能があるわけではない</b>です。本サンプルで使用しているモデルはImageNetデータセットを用いてInception v3ネットワークをTensorFlowで学習させたもので、新機能はあくまで<b>「Metal（GPU）でCNN処理」</b>という部分になります。


###PropertyAnimator: Position

アニメーション用の新クラス、UIViewPropertyAnimatorを用いて UIView オブジェクトの位置と、背景色をアニメーションさせるサンプルです。


![animator1.gif](https://qiita-image-store.s3.amazonaws.com/0/3180/8610f91e-ec3b-d7f9-d7b1-04b018beed6d.gif)


画面上をタッチしたままグリグリと動かしてみてください。touchMovedが呼ばれるたびにアニメーションが追加するという単純な処理をやっているのですが、いい感じに追随してくれるのが今回のクラスがアニメーションの追加をいい感じにやってくれてる [^6] おかげなのかなと。

[^6]: WWDC16のセッション216でそんな感じのことを言ってました


###PropertyAnimator: Blur

UIViewPropertyAnimator の `fractionComplete` を用いて UIVisualEffectView / UIBlurEffect の<b>ブラーをアニメーション</b>させるサンプルです。


![animator2.gif](https://qiita-image-store.s3.amazonaws.com/0/3180/6a6d3e44-be90-a16a-fb63-51e1048c920a.gif)


やってることは超シンプルで、`effect` プロパティから UIBlurEffect を削除する処理を UIViewPropertyAnimator に登録しておいて、

```swift
animator = UIViewPropertyAnimator(duration: 0, curve: .linear) {
    self.effectView.effect = nil
}
```


スライダーの値に応じて `fractionComplete` を変化させています。[^7]

[^7]: この手法は、こちらのコードで知りました: https://github.com/manuelCarlos/IOS10-Animate

```swift
@IBAction func sliderChanged(sender: UISlider) {
    animator.fractionComplete = CGFloat(sender.value)
}
```


###Preview Interaction

新クラス、UIPreviewInteraction で、<b>3D Touchでピーク＆ポップ</b>するサンプルです。


![peekpop.gif](https://qiita-image-store.s3.amazonaws.com/0/3180/1bf6669d-00e6-948a-f762-f64dccba3d81.gif)


###Notification with Image

新しい通知のフレームワーク、UserNotifications framework を用いて、<b>画像付きローカル通知</b>を発行するサンプルです。


<img src="https://qiita-image-store.s3.amazonaws.com/0/3180/02862650-593b-c1c8-121d-149b6a447e9d.jpeg" width="200" align="left"> <img src="https://qiita-image-store.s3.amazonaws.com/0/3180/e1b63022-c833-145a-b59a-0541501d08c4.jpeg" width="200">
<br clear="all">


###Sticker Pack

iMessage のステッカーパックのサンプルです。

<img src="https://qiita-image-store.s3.amazonaws.com/0/3180/f62217bc-e193-3429-5241-338ec3b2a9c2.jpeg" width="200">


「Messagesってメッセンジャーアプリとしてどれだけのシェアがあるの？」という懐疑的な声も効きますが、ステッカーパックは<b>画像をアセットカタログに入れていくだけの超超簡単実装</b>なので、いい感じの画像を持っているアプリはやっといて損はないのかなと。


###Core Data Stack

NSPersistentContainer を使うと <b>Core Data の実装がシンプルになる</b>よ、というサンプルです。


<img src="https://qiita-image-store.s3.amazonaws.com/0/3180/f11c809f-2078-80c8-21d5-b8c8daddc6f4.jpeg" width="200">


[nolili](https://github.com/nolili)さんよりpull requestいただきました！


###TabBar Customization

UITabBarのバッジをカスタマイズするためのAPIが追加されました。[^8]

[^8]: これらの追加APIについては、[こちらの記事](http://qiita.com/monoqlo/items/13f72c14867565907cab)で知りました


<img src="https://qiita-image-store.s3.amazonaws.com/0/3180/0e3af461-48f5-2d8b-9fb1-3f003c49fad9.jpeg" width="200">


センスがなく、全然いい感じにカスタマイズできてないのが心残りですが。。


###New filters

CIFilterで追加されたフィルタのサンプル。

<img src="https://qiita-image-store.s3.amazonaws.com/0/3180/ec2fc302-ed31-d2ba-7b2e-09499c7c1e05.jpeg" width="200" align="left"> <img src="https://qiita-image-store.s3.amazonaws.com/0/3180/95c38692-9faf-369e-34e5-cbad6df31a6a.jpeg" width="200">
<br clear="all">


前回は豊作だったのですが、今回はちょっとしかありませんでした。。

- [【iOS9】Core Image の新機能：文字認識 ／追加フィルタ47種 - Over&Out その後](http://d.hatena.ne.jp/shu223/20150622/1434924215)
- [【iOS9】Core Imageを用いたリッチな画面遷移アニメーション - Over&Out その後](http://d.hatena.ne.jp/shu223/20151008/1444259843)


###New Fonts

新規追加されたフォントのサンプル。こちらも今回は少なく、4種だけ。[^9]

[^9]: しかもFutura、AmericanTypewriterは従来からあるfamilyの太さ違い

<img src="https://qiita-image-store.s3.amazonaws.com/0/3180/d592f225-f62c-095c-0716-dccd700507cb.jpeg" width="200">


###Proactive: Location Suggestions

NSUserActivityに新たに追加された `mapItem` プロパティを用いた "Location Suggestions" のサンプル。

<img src="https://qiita-image-store.s3.amazonaws.com/0/3180/a2c99080-3301-a8a7-5fa9-67a948621e0e.jpeg" width="200" align="left"> <img src="https://qiita-image-store.s3.amazonaws.com/0/3180/0ce645c4-50c6-df21-607d-a99f35729dee.jpeg" width="200">
<br clear="all">


いわゆる「Proactive」というやつで、Appleから出てるサンプルがあるのですが、<b>どの実装が何に効いているのか</b>、というかこのサンプルをどう試すのか、というのがちょっとわからず（WWDCセッションをちゃんと見ればいいのかもしれませんが）、[こちらの記事](http://blog.fenrir-inc.com/jp/2016/09/proactive-suggestions.html)に助けられました。


###Attributed Speech

AVSpeechUtterance に、NSAttributedStringを渡せるイニシャライザが新たに追加されたので、これを試すデモです。


NSAttributedString は文字列に色んな属性を指定できるわけですが、

- [テキストを装飾する／NSAttributedStringの属性一覧 - Qiita](http://qiita.com/shu223/items/c2eb639976154a491d19)


これを音声合成の「Utterance」に渡せるということは、例えば、NSFontAttributeNameを用いてある範囲のフォントをboldにすると、その部分だけ強調されて発声されるとか、何か別の属性を使ってアクセントを制御できるとか、そういうことを期待したわけです。


が、結果は・・・**何も起こりません**でした。


<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">iOS 10からAVSpeechUtteranceにNSAttributedStringを渡せるようになってて、これはきっと発声の抑揚とかを制御する用だ！って思ってboldにしたりしてみたけど何も変わらない。。何用なんだろう？ <a href="https://t.co/FnSkiCYwyR">https://t.co/FnSkiCYwyR</a></p>&mdash; Shuichi Tsutsumi (@shu223) <a href="https://twitter.com/shu223/status/774910732924182528">2016年9月11日</a></blockquote>
<script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>


同ツイートのメンションで岸川さんから `kCTLanguageAttributeName` で言語を切り替える、`kCTRubyAnnotationAttributeName` でルビをふる、といった<b>文字列だけではなくて音声にも有用そうな属性</b>を示唆いただきましたが、これらを試してみてもやはりあり／なしで違いは発声しませんでした。


何か私の実装が間違っているのかもしれませんし、プルリクをいただけるかもしれないので、サンプルとしては残してあります。


##Haptic Feedback

iPhone 7 の TapticEngine を利用するフィードバックのサンプルです。`UI
ImpactFeedbackGenerator`, `UINotificationFeedbackGenerator`, `UISelectionFeedbackGenerator` の全てのパターンを試せます。

<img src="http://cdn-ak.f.st-hatena.com/images/fotolife/s/shu223/20170103/20170103172859.jpg?1483432972" width="200">

##所感

- Notificationのカスタマイズ、ロック画面でプレビューは嬉しい
- 標準で、ローカルで音声認識ができるようになったのも嬉しい
- MPSCNNは熱いのでここはもっと勉強したい
- iMessage app / Sticker Pack は当初まったく期待してなかったけど自分でやってみるとその簡単さとやっておいて損はない（親アプリがiOS 9でもok）という点で意外と熱い
- UIViewPropertyAnimator、あまりワクワクするような新しさのあるものではなかったが、従来のものよりは便利なのでiOS 10以上のアプリでは普段使いすると思う
- 3D TouchでPeek&Popは3D Touchデバイスが普及するまでは静観
- Proactiveは今は静観
- SiriKitは良いサンプルが思いつかず今回は入れなかった

デュアルカメラとか、Taptic Engine APIとか新デバイス系はまた後ほど。