その後のその後

iOSエンジニア 堤 修一のブログ github.com/shu223

iOS 10の新機能のサンプルコード集「iOS-10-Sampler」を公開しました

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


iOS-10-Sampler



恒例の新機能のサンプルコード寄せ集めアプリです。ソースコードは GitHub に置いてあるので、ご自由にご活用いただけると幸いです。


使い方は Xcode 8 でビルドするだけ なので、デザイナーさんやディレクターさんもぜひお近くのエンジニアにビルドしてもらってください。



iOSももうかなり成熟してしまい、話題になる革新的な新機能とか、どの開発者にとっても嬉しい新機能というのはなかなかないわけですが、実装してみると思ったより簡単なので自分のアプリにも取り入れたくなったとか、他の誰も話題にしてないけど自分的には熱いみたいな機能もあったので、ぜひ一度お試しいただけると嬉しいです。


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


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


以下各サンプルの紹介です。

Speech Recognition

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



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

Looper

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





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

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

Live Photo Capturing

写真撮影用に追加された新クラス AVCapturePhotoOutput を使用したライブフォト撮影サンプルです。*2



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

Audio Fade-in/out

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

// 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 / 畳み込みニューラルネットワーク)を用いた手書き数字認識のサンプルです。*3



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


Metal CNN Advanced: Image Recognition

上のサンプルに引き続き、Metal Performance ShadersのCNNを利用したリアルタイム一般物体認識のサンプルです。*4



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


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


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

PropertyAnimator: Position

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



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

PropertyAnimator: Blur

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



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

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


スライダーの値に応じて `fractionComplete` を変化させています。*6

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

Preview Interaction

新クラス、UIPreviewInteraction で、3D Touchでピーク&ポップするサンプルです。


Notification with Image

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




Sticker Pack

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



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

Core Data Stack

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



noliliさんよりpull requestいただきました!

TabBar Customization

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



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

New filters

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





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

New Fonts

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


Proactive: Location Suggestions

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





いわゆる「Proactive」というやつで、Appleから出てるサンプルがあるのですが、どの実装が何に効いているのか、というかこのサンプルをどう試すのか、というのがちょっとわからず(WWDCセッションをちゃんと見ればいいのかもしれませんが)、下記記事に助けられました。

Attributed Speech

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


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


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


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



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


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

Haptic Feedback

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


所感

箇条書きで。。

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

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

おわりに

最初は個人的な勉強として始めたものがすっかり恒例になって、もうかれこれ4年もこれをやっています。



これがまぁなかなか大変で、それなりに時間がかかるので、周りの人には毎年「今年はやらないかも」とか毎年言ってて、なんだかんだやっぱり今年もつくってしまったという。







まぁ自分はやっぱり「新しいAPIが追加されると開発者としてできることが増える」のが好きなのと、(冒頭に毎年書いていることですが)自分で手を動かさないと全然理解できないというのがあるので、これはやっぱり続けた方がいいなと。


そんなわけで Apple Watch Series 2 が届いたら「watchOS-3-Sampler」もつくりたいと思います!


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

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

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

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

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

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

*7:これらの追加APIについては、こちらの記事で知りました: [iOS 10] UITabBarのバッジを少しカスタマイズできるようになった - Qiita

*8:しかもFutura、AmericanTypewriterは従来からあるfamilyの太さ違い