Fork me on GitHub

役立ちぬ開発史、それはただのブログ

覚えておくといい、ブログの時代は終わる。いつかその内、きっとたぶん…

IOSオールスターズ勉強会に行ってきたときのメモまとめ

| Comments

 バレンタインデーですね!そんな日に行われていたIOSオールスターズ勉強会に参加してきました。発表者が名だたるIOSエンジニアの方々で、こんなモンスター級をよく揃えられたなぁっと感心していました。
 勉強会終わってからメモをまとめましたが、もう早速イベントレポートが出ていました。さすがクラスメソッド株式会社さんです!

[イベントレポート] iOS オールスターズ勉強会 #dotsios

『Adaptive Collection View』

  • LINE株式会社 石川洋資氏
    github:ishikawa

 WWDC14の発表で、AdaptiveにView Controllerが変化し、あらゆるインターフェースに対するUIを提供することが簡単になった。

  • UI Collection Viewはどうなのか?

 今まで、iPadにはUI Collection View、iPhoneにはUI Tabel Viewと同じことを2つ書く必要があって大変。デリゲートは似ているが、2つ使っていたら、1つの変更があったときに2箇所変更しないといけない。

 UI Collection Viewで、UI Tabel Viewを作るのは簡単で、UICollectionViewLayoutを使うといい。UICollectionViewFlowLayoutがあり、すごく便利。
 UICollectionViewLayoutをクラスで定義し、モードを作ったら、モードに応じたestimatedItemSizewを用意する。テーブルだったら、画面いっぱい、Flowだったら、画面半分などを設定する。UICollectionViewLayoutAttributesでoriginを指定して、画面いっぱいにしてあげるとUItableViewができる。

 Story ViewにUIViewとテーブルが一個置いてあるだけでiPhoneだとTable Viewっぽく、iPadだと2列のtableviewっぽい物が、デモでできている。長い文章はセルを可変にして高さを調整し、短い文は画像に合わせてセルを調整する。
 1つのView ControllerでiPhoneとiPadを両方を網羅しており、Adaptiveになっている。

 セル分けしたい場合は、Size Classes。SplitViewやPopOverがあるので、CollectionViewを使うといい。
 セルのサイズの計算は、Self Sizing Cell。NSLayputCollectionを適切に配置すると、セルを自動調整してくれる。

 これらはios8から使える。しかし、UICollectionViewでは、罠が多いので気をつけるよう。ios7はSelf Sizing Cellを真似するといい。真似るには、systemLayoutSizeFittingSize:を、itemSizeForPath:で呼べばいい。Interface Builderでセルの出し分けは完結しているので、呼び出せば使える。

 何がいいのか?を体験した話。業務で、急ぎの機能を作ってとお願いされて作ったとき、iPhone版だけを作ったのに、iPad版もできていた。すごい得した。

 明日から、Adaptiveになりましょう!

Q:セルの並べ替えはどうするのか?
A:テーブルビューは用意されているので、そっちを使うか、頑張って自分で作るのかになる。

『Swiftで使いやすいAPIを考える』

  • 株式会社ユビレジ 岸川克己氏

 Swift製のライブラリの良い書き方を覚える。人に使われるコードを作るときに、どうやったら、よく使われるのか。今回の話す内容に対して、色々なことを思う人がいると思うけど、自分がどうするのかを考えるとよい。

 KeychainAccessを初めてSwiftで作った。ロック中には、アクセスできず、解除したら値を取り出せたりできる。メソッドチェーンで、値をこの時だけ変えたいなどできたりもする。取り出すときにだけ、タッチiDの認証を求めたりもできる。

Objective-Cとの違い

  • データ型
  • Optional
  • オーバーロード
  • デフォルト引数
  • メソッドチェーン
  • エラー処理

 Swiftで書くときで、人とやるときに特に気にすること。

  • データ型

 Objective-CはCを使えたりするが、これは互換性のためにだけあるから、なるべく使うものではない。Swiftはその辺をしっかりしている。

  • Optional

 Optionalな人にはnilを渡せるが、Optionalではない人は渡せない。Swiftは型に厳格なので、ちゃんとインターフェースで処理を作ると気持良く書ける。外に出す引数はOptionalではないものを使うといい。特に外に公開している物は、パラメータでなるべくOptionalでないものを使うといい。

  • オーバーロード

 なるべくオーバーロードするといい。KeychainAccessでも、かなりオーバーロードしている。オーバーロードできないときは、バンドルするようにしている。

  • デフォルト引数

 Swiftに用意されているもの。引数を与えても、与えなくてもよく、与えない場合はデフォルト引数が入る。デフォルト引数は、補完がイマイチ。KeychainAccessでは、デフォルト引数を使わずに、オーバーロードだけで作った。今はまだデフォルト引数は使いづらい。例外は、クロージャー。クロージャーでは、デフォルト引数を使うといい。パフォーマンスへの影響はあるにしても、空実数を常に与えるのは、いいんじゃないかと思っている。

 オーバーロードは、戻り値にも使うことが出来る。コンパイラがは判定できない時があるので、型をつけるか、キャストをつけるかになる。そこで、メソッド名を変えて、タプルを返した。タプルを返すことで、取得しやすくすることもできたが、前者のほうがやりやすかった。

  • エラー処理

 NSErrorで返すのが普通だけど、Either型があるので、これを最初に返せないかを、始めに考えると言い。Errorを返すときは、自分で作ったものを返すよりも、NSErrorを返す方でいいと思う。Playgroundで何がダメなのかが簡単に見える。ライブラリ公開時に、一緒につけてあげると優しい。

  • Functional style API

 ファンクショナルにも書けるとよい。

Q:Eithorで返していたが、タプルで返すのはどうなのか?
A:タプルで返すこともできるが、同じ名前のタプルを用意することが同じメソッドではできないので、今回は見送った。Eithorで返し過すぎていると思うので、タプルで返すのもありだと思う。

『let UIWebView as WKWebView』

  • ヤフー株式会社 佐野岳人氏
 WKWebViewがIOS8から追加され、2つのWebViewがある状態。UIWebViewはJavaScriptがSafariよりも遅い。WKのWebViewはハイパフォーマンス。だけど、IOS8からでないと対応していない。  IOS7をまだ切れない。UIWebViewとインターフェースは似ているが、互換性はなし。WKWebViewにしか無いプロパティが多い。WKWebViewの場合、JavaScriptはコールバックで受け取る。  WKWebViewで、ナイーブな下位互換対応をすると汚い。WKWebView、UIWebViewをインスタンス変数で2つを指定できるようにすると、ブロードリクエストなどを呼ぶときは、2つ分岐させないとダメなので汚くなる。 - バージョン分岐は、コントローラに持たせたくない。 - コントローラの本質がわからなくなる - 古いコードが山積みになると、誰も手が負えない - どこをなくしていいのか分からず、不要なコードが残る  IOS7を捨てることは、アップルのデータを見ると100万人の内、28万人はIOS7以前ユーザになるため、サービスの規模によって、切ることなどができなかったりする。  そこで、「複雑性保存の法則」。下位互換対応は、できるだけ見えないようにするといいと思っている。  **今回のお題、WKWebViewとUIWebViewの分岐を隠す** - 方針1:ラッパーで包む  インスタンスの時点で、対応しているのかいないのかを分岐で処理する。目的達成できるが、IOS7以下と分岐が多くなる。 - 方針2:WKWebViewでUIWebViewっぽく見せる  Objective-Cの力を借りる。Swiftだけで出来なかった理由、戻り値が違う。型の違いを判別してしまい、Swiftだけでは実装が難しかった。外だけではSwift、中は混在している。 - WKWebViewのIFをプロトコルで取り出す - WKWebViewの拡張でプロトコルを適合 - UIWebViewに足りないメソッドを実装 - ControllerでWKWebViewプロトコル型として、WebViewを呼び出す - 結果 - ラッパーの方は、何もしていないので安心 - もう一つの方は、裏ワザっぽい Q:WKWebViewとUIWebViewの2つ混同させないようにするが、デリゲートメソッドではどうしているのか? A:スマートサーチでは、統合せずにそのまま並べている。 Q:WKWebViewで実装するメリットはなにか? A:UIWebViewで同じ手続きを踏めばできることはできる。ヒストリーを取るなど、WKWebViewで原理的にできないものはしょうがない。メリットは早い、戻るジェスチャー。ios8で使えるメリットはios8ユーザーに受けて欲しい。しかし、ios7ユーザーも見捨てないために作った。 ###『通信のパフォーマンス改善』 - Wantedly inc 杉上洋平氏  海外でも素敵なウォンテッドリー体験をして欲しい。しかし、海外は通信が良くない。そこで、[NewRelicMobile](http://newrelic.com/mobile-monitoring)で、ざっくりなボトルネックを分析し、[PonyDebugger](https://github.com/square/PonyDebugger)、リクエスト単位で分析した。結果、jsonリクエストよりも画像の量が多い。見せたい順番でもなく、無駄な画像リクエストがあるため、画像を中心に見直す。 - 画像といえばSDWebImage、画像を取ってきてメモリとディスクに分ける - SDWebImagePrefetcherを使い、先にキャッシュを読みに行くようになっている - 画像表示の優先度はSDWebImageOptionsを使って設定することで、どれから順番に取得することができるのかを設定できる - 遷移元の画像取得をキャンセルには、SDWebImageManagerを使う  画像もフォーマットをWebPに変更することで、3分の1に抑えることができた。SDWebImageはWebPに対応している。SDWebImage/WebPでpodするとインストールできる。  アプリ側は簡単、サーバー側が大変だった。WebPに変換する画像サーバを構成する[nginxでWebPに変換するdockerファイル](https://github.com/wantedly/nginx-image-server)を、githubに上げてある。  通信領域により、取得する画像サイズを変更する。通信開始と終了の経過時間で通信帯域を推測。最大サイズからキャッシュ画像をチェック。通信帯域が悪いのに、キャッシュには大きい画像しか無いときは、まずキャッシュを調べて、画像を取りに行く。  改善確認方法は、デベロッパ機能で通信の帯域を制限して確認した。  ボトルネックを潰す、でもそうしたら他がボトルネックになるので、PDCAをまわして、パフォーマンスを上げていくなどしないとダメ。 Q:通信中のものをキャンセルするときは、どうしたのか? A:キャンセルするメソッドが、話したように用意されている。 ###『効率的なアプリ開発のベストプラクティス』 - グリー株式会社 矢口裕也氏  IOS開発の醍醐味は、UI・UX最高ですっと言われること。一方でUXを提供しない仕事で、早い実装を求められることもあるツライこと。効率的に実装するにはどうしたらよいのか。 - 大原則、やることを減らす - UIを作る実装コスト - 通信の実装コスト **UIを作る実装コスト**  昔に比べて、今はだいぶ開発しやすくなっている。 - Auto Layout - Storyboard - Self Sizing Cell  Self Sizing Cellは最高、昔の苦しさは何だったのか。ios8を皆が使うべき。改善の余地として、React.jsみたいなアプローチがよい。なので、ReactNativeに期待。 **通信の実装コスト**  ほぼ仕様に依存する。仕様は大体の場合サーバー側が決める。実装コストを減らすには、大原則:やることを減らす。サーバー側に任せればいい。どちらでも行える処理であれば、サーバー側でやったほうが楽。iosは配列とかも扱いにくい。  APIは共通化、RESTにとらわれない。個々のクライアントの画面都合、ライブラリ都合に合わせたJSONを作るべき。 - ダウンロード可能なアセットを持たない - クライアントでキャッシュを持たない - ローカルストアも利用しない  なるべくサーバーに持たせよう!  サーバー側に持たせるときに、問題になるもの。 - きれいなRestfulサーバー - 汎用的なAPIであるのに、特定画面に特化させない - 原則主義だと厳しい - レガシーサーバー - 触るの怖い - リファクタリングしようとすると、デグレそう  説得するには、パフォーマンスのメリットを訴えること、サーバー側も自分で書く、強いマインドを持つこと。  それでもダメなら、中継サーバーを立てて取ってくる。クライアントに最高なJsonをPHPなどで書く。 - まとめ - UI回りは昔に比べて楽になった。 - 通信周りはプロトコルをどうするかが肝になる - サーバー側との連携が大事 Q:サーバー側にお願いする線引はあるのか? A:2つあって、ユーザ体験が挙がるのかと、それが重要なのか。ツイッター規模でみると投稿をサーバで持たせてもいいし、設定などの情報はローカルでもいい。 ###『WatchKit を実際にさわってみてわかったこと』 - フリーランス 堤修一氏  WatchKitが自分の中で熱くなったので発表。WatchKitがベータ公開したとき、クラスが15個しかなく、ドキュメント見ても、何も出来なかった。そのときは、そこで終了した。最近WatchKit案件で、分かってなかったことが沢山あることを知った。 WatchKitを実際に触ってみてわかったこと。 **アニメーション編** - staticなアニメーション  WatchKit AppのAsset Catalog内の連番画像は、アニメーションがめっちゃ早い。 - dynamicなアニメーション  setImageやsetImagDataを使うと、パフォーマンスへの影響があるかもしれない。どう実装するのか?NSTimerを使ってみる、明らかに遅い。キャッシュを使うことはダメ、フレームごとの画像をキャッシュするな!とドキュメントに書いてある。  正解は、Animated Imageを利用する。staticなアニメーションと同等の早さを実現。 **テキスト入力編**  Appleのデモには、アニメーションする3D絵文字がある。  WatchKitでAPIがあるのか?   ー> ある  presentTextInputControllerWithを使うだけで、smart Replies + 音声入力も簡単に実装できる。しかし、音声入力と絵文字は、シミュレーターではサポートされていない。 **UI編**  アップル公式の360度回す連番アニメーションは、1度ずつのpngファイルを用意している。カスタムフォントは、iosと同等の手順でできる。インターフェースのオーバーレイについては、オーバーレイは出来ないが、オーバーレイでやりたいことはできる。origin調整は、WKInterfaceGroupを活用する。  他にもUIは意外と色々なことができる。 Q:連番アニメーションのように、もっとよりよく360度回すものをいいものはないか。また、デザイナーに動画を作ってもらった方がいいのか? A:元のアニメーションをどこから持ってくるかによるが、よさ気なメソッドが用意されている。Flushでは、連番機能を吐き出すものがあったりしたので、そこからもらっていた。 ###『長生きするために心臓に悪いリリースはもうやめよう』 - クックパッド株式会社 所友太氏  リリース前の確認方法まとめ。  リリースボタン押すのは、怖い。会社の売上を数億円減るかも?と思うと、恐怖!社内でのテストはバッチリ!でも実際に公開されているアプリは大丈夫?  そこで、Internal Testersを使う。 - アップストアで公開されているものと違う - デバック - TestFlightで配信してテスト - アップストアで公開されているものと同じアプリ - プロモーションコードを使ってテスト(後) - Internal Testersを使ってテスト(審査始まる前) - アップルの審査が終わる前と後の違い - プロモーションコードを使ってテスト(審査後) - Internal Testersを使ってテスト(審査前)  しかし、いくらテストを厳密にやっても、アップストアにサブミットする段階で事故が起こることも0じゃない。  Internal Testersとは、アップルがTestFlightを買収して、Itunes Connectに加わった機能。Internal Testersはぜひ活用すべき、アップストアと公開されるものと同じアプリでテストできることと審査前であること、この2つの条件を満たす唯一の方法。 - Internal Testersの弱点 - ios8以降でしか使えない - 25人までしか使えない - 完全な自動化が出来ない  使い所は、テストフェーズが終わった最終確認で、数名で限られた端末で確認するとき。  Internal Testersを使えば、大きい会社でなければ、プロモーションコードを使ってのテストはなくしてもよい。  Internal Testers と CIは、両方使うといい。おすすめのCIは、travisCIを使う。  [岸川さんの方法](http://kishikawakatsumi.hatenablog.com/entry/20141022/1413963656)は、テスト用とサブミットで、ビルドしなおさない。テストしたのと署名を変えるだけでサブミットできる。サブミットされたアプリの正当性を担保できる。  CIすれば、Internal Testers使わなくでも9割は大丈夫だけど、最終確認はしてもよいと思う。  アップストアで公開されたアプリは、ちゃんとしたものがアップストアに公開されているのかを知るために、バージョン管理するといい。個人だったり、スタートアップにはこの管理は、必要ないかもしれない。 Q:アプリ内課金のテストもできるのか? A:実際に購入ができるわけではなく、買ったふりができるテストになっている。サンドボックスであるが、中でサンドボックス用に分けたりはしていないので、Internal Testersで9割大丈夫だと思う。 Q:バックアップから復元させたときのテストは試したりしたことあるのか? A:Internal Testersでやったことはない。通常のアプリと同じようなことはできるかもしれないが、試したことはない。 ###『エンジニア戦記 ~ 小さなチーム 大きな未来 ~』 - クラスメソッド株式会社 平井祐樹氏  ブログでテック系の記事を公開してかっこ良く見られているが、おっさんたちが頭悩まして開発している。  案件をやっていくうちで、問題が起きたとき悩むのは、WebAPI側とのやりとり。WebAPIの設計によって、アプリの作り方が大きく変わってくる。WebAPI担当者との付き合い方のお話。  よくアプリとWebAPIを同時に実装する事がある。そこで、起きること。  APIをHTTPステータスコードで表してくれない。フィールド名が重複している。エンドポイントがコンテンツごと用意されており、1画面表示するのに、何個も叩く必要がある。 **1screen, 1api coll !!**  Rest APIを徹底すると、ユーザ体験に合わないことがある。IOSエンジニアがWebAPIのことを分からずに、実装したら炎上する。なので、IOSエンジニアにもWebAPIの知識は必須。文句をいうのは簡単、改善案を提案する力を!  WebAPIを学ぶのにおすすめの本。

『まだiOSでリッチな演出に疲弊してるの?』

  • 面白法人カヤック 布田隆介氏

 仕事で、演出や機能ともに様々なものが求められる。リッチなデザインは疲弊する。貞子の映画を見ながら使うアプリは、完全なる疲弊した。それ以外にも、演出がどうしようもなく、動画を使ったことがある。

 実装方法には、CoreAnimation、Unity、cocos2dなどがあるが、SpriteKitを使うといいという話、これはナメられている。自分もcocos2dの廉価版とナメていた。
 SpriteKitは、ios7から追加された2dのフレームワーク。UIKitと同じように動く。SpriteKitをゲームではなく、UIKitベースのアプリで動くのかが問題だった。ちゃんと動くし、アニメーションなどが、簡単に作れる。タッチした場所をちゃんと表示したりするのも簡単にできる。

  • UIKitベースのアプリに入れるときに気をつけること

    • UIViewの上にSKViewをのせて、SKViewのタッチイベントを無効にする
    • UIViewとSKViewの座標が違う
  • SpriteKitを使ってみて

    • アップルの安心感
    • 既存コードを邪魔しない
    • デザイナーさんも使える

SpriteKitとUIKItを合わせるのはあり!

Q:cocos2dとの違いは?
A:カメラの機能のときはcocos2dも使える。UIkitベースに使いたいときは、SpriteKitでいい。
Q:パーティクルは重くない?
A:重いです。SKVIewの表示する範囲を狭くすると軽くなる。

ベストプレゼンテーター

 Wantedlyの杉上洋平さんの『通信のパフォーマンス改善』でした。

Comments