Hatena::ブログ(Diary)

Over&Out その後 このページをアンテナに追加 RSSフィード Twitter

2016-08-22

iOSDCで発表しました『海外のiOSカンファレンスに登壇する - 完全版』 #iOSDC

先週の金・土に練馬で開催された600人規模のiOSカンファレンス「iOSDC 2016」にて、『海外のiOSカンファレンスに登壇する - 完全版』というタイトルで発表させていただきました。


f:id:shu223:20160822084525p:image:w298


応募時に書いたトーク概要はこちら

ベルリンの「UIKonf」、ロンドンの「iOSCon」、サンフランシスコの「AltConf」と、今年は3つの海外のiOSカンファレンスに登壇する機会に恵まれました。


とはいえ招待されたわけではなく、CFPに自ら応募して投票・審査の上で採択された結果です。


本発表では、海外カンファレンスに参加するメリット、CFPの探し方、発表の準備、実際の登壇でうまくいったことや失敗したこと等について話します。


海外のiOSカンファレンスに登壇するためのノウハウ集、というよりは、英語がそんなに得意でもない自分が、どう四苦八苦しつつも海外登壇までこぎつけたのか、その結果どうだったのかという失敗談多めの内容となっております。


動画がこちら *1。このトークでは埋め込みの音声や動画が重要な役割を担っているので、スライドよりも動画のほうが伝わるかなと思います。


発表スライドはこちら。


以下、裏話や当日の様子について書きたいと思います。


裏話その1: 実行委員長 長谷川さんの神対応

開催前にこういうツイートをしました。


そう、僕の出番はゲストスピーカーである岸川さんの裏にどーんとぶつかっていたわけです。


実は、スタッフの方のひとりと飲む機会があり、事前にこのタイムテーブルについて知ることができたのです*2が、「そんなの誰も来てくれるわけがない・・・」とFacebookで長谷川さんに突然の友達申請をし、長いDMを送り、何とかなりませんかと泣きつきました。


そんな突然かつ面倒なメッセージに対して、長谷川さんは「なぜこういうタイムテーブルになったか」という意図について大変詳細かつ丁寧なご説明を返信で書いてくれて、僕は深く納得し、誰も来ないかもしれないけど(草の根集客活動含め)がんばろう、と思うに至った、ということがありました。(さすがにDMをここに載せることはできないのですが、それにしても朝イチのお客さんの流れとか色々考えられていて感動を覚えるほどでした)*3


結果的には、想像以上に多くの方に来ていただけたし、あと個人的にも出番を朝イチで終えてカンファレンスを存分に楽しめたしで、これで本当に良かったなと。めちゃくちゃお忙しい中、めんどくさい登壇者の個別問い合わせに懇切丁寧に対応してくださった長谷川さん、ありがとうございました🙇🏻🙇🏻🙇🏻


裏話その2: 発表時間

前日夜の時点で15分の発表時間に対して30分以上もかかる、ということに気付きまして、


とりあえず寝て、朝起きたら何となく整理がつくだろうと思ったのですが、



全然整理がつかなかったのです。。


で、とりあえずスライドを削るのはあきらめて、「全部は説明せずに流れが分かる程度にだけ説明する」というページに印をつけておいて*4、その辺を飛ばしながら話すことで、Q&A用の時間もフルに使った19分30秒でなんとか話し切ることができたのでした。(ギリギリですいませんでした🙇🏻🙇🏻🙇🏻)


当日の様子

手元に写真がない *5 ので、会場に来られていた方々のツイートをお借りしつつ会場の様子をお伝えしたいと思います。












関連記事:


おわりに

iOSDC、登壇者としてもいち参加者としてもめちゃめちゃ楽しかったです。トークは勉強になるし面白かったし、アイコン入りの大きめサイズのネームプレートとか、懇親会のビールとか、いろんなところに愛とこだわりを感じるカンファレンスでした。あと参加した人達みんなが口を揃えて言っていたことですが、初回にしてこんなに滞りなくいい感じに進むのってすごいことだと思います。


こんな素晴らしいカンファレンスを主催された長谷川さん、超ハードに動かれていたスタッフのみなさまには本当に感謝です。



そしてチケット代がたったの4000円。僕はトークが採択される前にスポンサーチケット(8000円)を購入していたのですが、この内容でこの値段、お得すぎます。スポンサー企業のみなさまには足を向けて寝られません。チラシにしっかり目を通してサービスを積極的に利用させていただきます。


来年もあればぜひまた参加させていただきたいと思います。ありがとうございました!


関連記事


お知らせ

iOSDC Reject Conferenceにもday1、day2両方とも出させていただきます。


day1はこちらのテーマ。


day2の方は5分のLT枠で応募していて、落ちたのですが、15分枠が定員割れで空いていたので、そちらで出させていただくことになりました。


どちらもまだまだ勉強が必要な分野ですががんばって準備します。よろしくお願いします。

*1:公式チャンネルにはまだ個別の動画が上がっておらず、Bトラック全体の動画は埋め込みができない設定になっていたので、切り出してこちらにアップしました。公式のがアップされたら差し替えます

*2:発表前だったものの絶対に秘密というものではなかったそうです

*3:やるしかない、となった理由の決定打は、「そもそもA会場に全員が入れるわけじゃない」(→ 誰かが裏でやるしかない → 僕がそこを降りても別の誰かがそこに入ることになる → それはスタッフの誰かのトークになる)というところでした。

*4:アップした資料からはその印を削除してあります

*5:公式の写真がいずれシェアされるっぽいです!

2016-08-16

イスラエルとパレスチナでiOSとBLEについて講演してきた話

7月24日〜30日、「中東のシリコンバレー」と呼ばれスタートアップがめちゃめちゃ盛り上がっているイスラエルのテルアビブ、IT産業が伸びているというパレスチナのラマッラ、そしてあの聖地エルサレムにて、iOS×BLEについて話してきました。


f:id:shu223:20160816085014j:image:w300

(在イスラエル日本大使館作成のチラシ)


なにそれどういうこと?と思われた方もいらっしゃるかもしれませんが、これ、外務省の「日本ブランド発信事業」という事業の一環なのです。


こういうこともなかなかないだろうという貴重な経験をさせていただいたので、ブログに書いておこうと思います。


経緯

正式に決まったのは出発のちょうど1ヶ月前ですが、きっかけは半年以上前、昨年12月に開催された DemoDay.Tokyo #0 にまでさかのぼります。そこで「勉強しつつソースコードをオープンにしてたら海外からも仕事が来るようになった」という話をしたのですが、そこに外務省の方が来られていて、「こういうのあるんだけど興味ある?」「あります!」的なやり取りをさせていただいたのでした。


「iOSという米国産プラットフォーム上で活動してるだけの自分が日本ブランド発信なんて場違いだろう」という気持ちもありつつダメ元で応募書類を提出したところ、WHILLとかMoffとかBONXとか、日本発の魅力的なプロダクトに横断的に関わっているというところを評価されて見事採択されたのでした。


スケジュール

こんな感じのスケジュールでした。

  • 7/24 東京発
  • 7/25 テルアビブ着、エルサレムへ移動しアズリエリ工科大学にて講演
  • 7/26 テルアビブのGoogle Campusにて講演
  • 7/27 テルアビブのSigma Labsにて講演
  • 7/28 パレスチナのビルゼイト大学にて講演
  • 7/29 テルアビブ発
  • 7/30 東京着

毎日講演が入っていて、移動もあり、会食もあり、それ以外の時間は現地のスタートアップと会ったり資料の手直しをしたりしてたので、自分でどこかに観光に行くような余裕はありませんでした(後述しますが道中で名所に寄ってくれたりはしました)


位置関係

テルアビブとかエルサレムとか言っても多くの日本人にとってはなかなか位置関係をイメージしづらいんじゃないかと思うので、地図を載せておきます。


f:id:shu223:20160816084908p:image:w280


テルアビブ〜エルサレムまで車で片道1時間〜1時間半(渋滞状況による)ぐらいです。


歴史的背景とかは素人が下手に説明できない複雑さがあるのでぜひググッてみてください。。


各講演の様子

それぞれの規模はそんなに大きくはなくて、20〜40名ぐらい。しっかり細かい質問や意見を拾うことができてちょうど良い人数だったと思います。4講演とも基本的には同じテーマで話をした *1 のですが、それなりに場所も離れているので、参加者のかぶりはなかったようです。


初日:アズリエリ工科大学 / エルサレム

f:id:shu223:20160816085715j:image:w600


f:id:shu223:20160816085714j:image:w600


2日目: Google Campus / テルアビブ

f:id:shu223:20160816085753j:image:w600


f:id:shu223:20160816085750j:image:w600


3日目: Sigma Labs / テルアビブ

f:id:shu223:20160816085826j:image:w600


4日目: ビルゼイト大学 / パレスチナ

f:id:shu223:20160816090120j:image:w600


f:id:shu223:20160816090218j:image:w600



各講演やその他の活動についての報告はレポートに書いて既に外務省に提出したので、いずれサイトにて公開されるかと思います。


道中の観光

初日のエルサレムの会場への移動中に、大使館の方のはからいで旧市街に寄っていただきました。

旧市街はユダヤ教・イスラム教・キリスト教の聖地であり、嘆きの壁や聖墳墓教会、岩のドームといった各宗教縁の施設を訪れる人々が絶えない。旧市街は城壁に囲まれ、東西南北に宗派ごとで四分割されている。北東はムスリム地区、北西はキリスト教徒地区、南西はアルメニア正教徒地区、南東はユダヤ人地区となっている。現在の城壁はオスマン・トルコのスレイマン1世によって建設されたものである。城壁には北側中央にあるダマスクス門から時計回りに、ヘロデ門、獅子門、黄金門、糞門、シオン門、ヤッフォ門、新門の八つの門があり、ここからしか出入りができない。19世紀に作られた新門以外はスレイマン時代より存在する門である。(エルサレム - Wikipedia

こういうすごいところなのです。


f:id:shu223:20160725162845j:image:w600


f:id:shu223:20160725163126j:image:w600

(石造りの街並)


f:id:shu223:20160725162641j:image:w400

(嘆きの壁で講演の成功を祈る。かぶっている帽子はキッパというそうです)


観光ではありませんが、パレスチナはこういう機会でもないとなかなか入っていけない(個人の旅行でも入れるみたいですが)ので、すべてが新鮮でした。


f:id:shu223:20160728143114j:image:w600

(パレスチナのとあるレストランから見た風景)


あと、パレスチナからの帰り、かの有名な死海にも寄っていただいたのですが、ビーチに出られるゲートが既に閉まっていて、遠くの方から眺めることしかできませんでした。


大使との会食

なんと、イスラエル大使公邸にてイスラエル大使とお食事をご一緒させていただく機会にも恵まれました。


f:id:shu223:20160726210756j:image:w500


安倍総理やオバマ大統領との写真が飾られている中、恐縮しすぎてちゃんと話せるのかと心配もありましたが、非常に気さくに話していただき、ご飯も和洋イスラエル料理の折衷で非常に美味しく、至福の時間を過ごさせていただきました。


f:id:shu223:20160816093042j:image:w600


途中ポケモンGOの話題になり、帰り際にズバット(コウモリみたいなやつ)を見つけて大使とのツーショットを撮影したところ非常に喜んでいただけました。(写真は 在イスラエル日本大使館のページに掲載されています。)


治安

よく聞かれるのですが、今回の滞在中、治安について不安に感じることは一切ありませんでした。そもそも「海外危険情報」を出しているのが外務省であり、移動も行き先もその外務省や現地大使館の方々が全面的にアレンジしてくださったので、大船に乗った気持ちだったというのもあります。


が、最近ではテルアビブの平均年収が東京のそれを超えたという話もあり、普通に生活水準も高く、警備もしっかりしていることもあって、基本的にかなり平和なようです。


f:id:shu223:20160727122358j:image:w600

(とあるオフィスから見たテルアビブ市街)


旅行なり仕事なりで、またぜひ行きたいと思っています。


おわりに

行く前はワクワク感よりも「自分でいいのだろうか」という不安の方が大きかったのですが、それなりに事業の趣旨に沿った貢献もできたと思うし、僕としては大変貴重な経験を多くさせていただけたので、とにかく行ってよかったです。


本事業の実現にご尽力いただいた外務省の皆様、各講演のアレンジから滞在中の移動や食事等全てにおいてお世話になった在イスラエル日本国大使館の皆様、パレスチナ講演にご協力いただいた対パレスチナ暫定自治政府日本国政府代表事務所の皆様、どうもありがとうございました!


お知らせ

iOSDC

いよいよ今週末に差し迫った iOSDC 2016 にて、『海外のiOSカンファレンスに登壇する - 完全版』というタイトルで発表させていただきます。


ベルリンの「UIKonf」、ロンドンの「iOSCon」、サンフランシスコの「AltConf」と、今年は3つの海外のiOSカンファレンスに登壇する機会に恵まれました。


とはいえ招待されたわけではなく、CFPに自ら応募して投票・審査の上で採択された結果です。


本発表では、海外カンファレンスに参加するメリット、CFPの探し方、発表の準備、実際の登壇でうまくいったことや失敗したこと等について話します。


出番は朝イチの10:20、しかもゲストスピーカーである岸川さんの裏ということで誰も来てくれないんじゃ・・・と恐々としております。来ていただけると嬉しいです。


iOSDC Reject Conference

iOSDC Reject Conferenceにもday1、day2両方とも出させていただきます。


day1はこちらのテーマ。


day2の方は5分のLT枠で応募していて、落ちたのですが、15分枠が定員割れで空いていたので、そちらで出させていただくことになりました。


どちらもまだまだ勉強が必要な分野ですががんばって準備します。よろしくお願いします。


*1:イベントの告知内容や現地主催者の要望に応じてソースコードレベルの話までするかどうかというようなちょっとした調整はした

2016-07-20

TensorFlowをiOSで動かしてみる

TensorFlow に iOS サポートが追加された というニュースを見かけたので、ビルドして、iOSで動作させてみました。


f:id:shu223:20160720074930j:image:w240

たまたま目の前にあった扇風機もバッチリ認識してくれました)


本記事では最終的にうまくいった手順を書いています。この手順をなぞってみるにあたってTensorFlowや機械学習・ディープラーニングについての専門知識は不要ですのでぜひお試しください!


ビルド手順

iOSサポートバージョンであるv0.9.0をチェックアウトして、以下の手順でビルドしていきます。手順はこの通りになぞるだけですし、ほぼスクリプトを実行するだけで非常に簡単です(が、実行時間がかなりかかります)。


  • スクリプトを実行して Eigen や Protobuf 等の依存ライブラリをダウンロード
cd tensorflow
tensorflow/contrib/makefile/download_dependencies.sh

  • protobuf をビルド&インストール
cd tensorflow/contrib/makefile/downloads/protobuf/
./autogen.sh
./configure
make
sudo make install

ここで、僕の環境では `./autogen.sh` 実行時に

Can't exec "aclocal": No such file or directory at /usr/local/Cellar/autoconf/2.69/share/autoconf/Autom4te/FileUtils.pm line 326.
autoreconf: failed to run aclocal: No such file or directory
shuichi-MacBook-Pro-Retina-15inch:protobuf shuichi$ ./configure
-bash: ./configure: No such file or directory

というエラーが出ました。”aclocal”というのは、”automake”パッケージに含まれているらしいので、automakeをインストール。

brew instal automake

で、改めて

./autogen.sh
./configure
make
sudo make install

  • iOS native版のprotobufをビルド
cd ../../../../..
tensorflow/contrib/makefile/compile_ios_protobuf.sh

  • iOSアーキテクチャ向けにTensorFlowをビルド
tensorflow/contrib/makefile/compile_ios_tensorflow.sh

サンプルをビルドする

`tensorflow/tensorflow/contrib/ios_example` に2種類のサンプルがあります。


simple と名付けられたサンプルアプリは、今回ビルドした static library をアプリ内に組み込む際の最小実装としての参考にはなりそうですが、デモとして見て楽しい機能があるわけではないので、本記事ではもう一方の camera の方を紹介します。


まず、このファイルをダウンロードして、解凍すると入っている、

  • imagenet_comp_graph_label_strings.txt
  • tensorflow_inception_graph.pb

の2つのファイルを、`tensorflow/contrib/ios_examples/camera/data` に置きます。*1


この Inception というのはGoogleが提供する画像認識用の学習済みモデルのようです。


cameraサンプル実行例

cameraサンプルを実行すると、すぐにカメラが起動します。身近のものを色々と映してみました。(リアルタイムカメラ入力に対する認識結果を表示してくれます)


MacBook

f:id:shu223:20160720080028j:image:w240


"Notebook" "Laptop" どっちでも正解!


扇風機

f:id:shu223:20160720074930j:image:w240


"Electric Fan" 正解!


椅子

f:id:shu223:20160720080106j:image:w240


"Folding Chair"(折りたたみ椅子) 惜しい。。ですが、そもそも `imagenet_comp_graph_label_strings.txt` には chair が3種類しかなくて、その中では一番近いと言ってもいいかもしれません。


iPhone

f:id:shu223:20160720080129j:image:w240


"iPod"・・・惜しい!iPhoneなのでほぼ正解と言ってもいいかもしれません。


パフォーマンス

今回cameraサンプルを試したデバイスはiPhone 6だったのですが、認識はまだまだリアルタイムとは言い難く、数秒単位の遅延がある感じでした。まだiOS向けにビルドできるようになったというだけでiOSにおける GPU Accelerated はされてないですし、パフォーマンスの最適化はまだまだこれからのようです。


ちなみに iOS 10 で Accelerate.framework に追加された BNNS (Basic neural network subroutines) を使用した最適化もissueに挙がっています。


ビルド手順の情報ソース

iOSサポートバージョンである0.9.0トップ階層にあるREADMEを見ても、iOSについては書かれていません


上述したビルド手順は`contrib/makefile` 配下のREADMEに書かれています。

関連情報を以下にまとめておきます。


サンプルのソースコードを読んでみる

サンプルは全編Objective-C++で書かれています。読んでもわからないだろうと思いつつ、せっかくなので読んでみます。


tensorflow_utils

モデルとラベルデータを読み込むメソッドと、認識結果を返すメソッドを持つユーティリティクラスのようです。

tensorflow::Status LoadModel(NSString* file_name, NSString* file_type,
                             std::unique_ptr<tensorflow::Session>* session);
tensorflow::Status LoadLabels(NSString* file_name, NSString* file_type,
                              std::vector<std::string>* label_strings);
void GetTopN(const Eigen::TensorMap<Eigen::Tensor<float, 1, Eigen::RowMajor>,
             Eigen::Aligned>& prediction, const int num_results,
             const float threshold,
             std::vector<std::pair<float, int> >* top_results);

汎用的に使えそう。


ios_image_load

画像ファイルを読み込むクラス。

std::vector<tensorflow::uint8> LoadImageFromFile(const char* file_name,
             int* out_width,
             int* out_height,
             int* out_channels);

プロジェクトには追加されているけど使われてないっぽい。


CameraExampleViewController

サンプル本体。肝っぽいところだけを拾っていくと、


`std::unique_ptr<tensorflow::Session>` なメンバ変数を定義して、

std::unique_ptr<tensorflow::Session> tf_session;

viewDidLoadのタイミングでモデルを〜.pbファイルからロード

tensorflow::Status load_status =
  LoadModel(@"tensorflow_inception_graph", @"pb", &tf_session);

で、カメラからのリアルタイム入力が得られるたびに呼ばれるデリゲートメソッドを見てみると、

- (void)captureOutput:(AVCaptureOutput *)captureOutput
didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer
       fromConnection:(AVCaptureConnection *)connection {
  CVPixelBufferRef pixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer);
  [self runCNNOnFrame:pixelBuffer];
}

CMSampleBufferRef から CVPixelBufferRef を取得して `runCNNOnFrame:` を呼んでいるだけのようです。


`runCNNOnFrame:` はコードが若干長いですが、このへんと、

tensorflow::Tensor image_tensor(
    tensorflow::DT_FLOAT,
    tensorflow::TensorShape(
        {1, wanted_height, wanted_width, wanted_channels}));
auto image_tensor_mapped = image_tensor.tensor<float, 4>();
tensorflow::uint8 *in = sourceStartAddr;
float *out = image_tensor_mapped.data();

このへんが肝っぽいです。

if (tf_session.get()) {
  std::string input_layer = "input";
  std::string output_layer = "output";
  std::vector<tensorflow::Tensor> outputs;
  tensorflow::Status run_status = tf_session->Run(
      {{input_layer, image_tensor}}, {output_layer}, {}, &outputs);
  if (!run_status.ok()) {
    LOG(ERROR) << "Running model failed:" << run_status;
  } else {
    tensorflow::Tensor *output = &outputs[0];
    auto predictions = output->flat<float>();

    // ラベル取得
  }
}

が、すみません、それぞれ何をやっているのかを解説するにはTensorFlowの処理をちゃんと理解する必要がありそうです。。(勉強します)


自分のアプリに組み込む

試せていませんが、こちら に手順が示されていました。

  • ユニバーサルなstatic library(libtensorflow-core.a)をビルドしてプロジェクトに追加する
    • [Library Search Paths] にも追加。

The `compile_ios_tensorflow.sh' script builds a universal static library in tensorflow/contrib/makefile/gen/lib/libtensorflow-core.a. You'll need to add this to your linking build stage, and in Search Paths add tensorflow/contrib/makefile/gen/lib to the Library Search Paths setting.

  • libprotobuf.a と libprotobuf-lite.a をプロジェクトに追加する。
    • [Library Search Paths]にも追加

You'll also need to add libprotobuf.a and libprotobuf-lite.a from tensorflow/contrib/makefile/gen/protobuf_ios/lib to your Build Stages and Library Search Paths.

  • [Header Search paths] を追加

The Header Search paths needs to contain the root folder of tensorflow, tensorflow/contrib/makefile/downloads/protobuf/src, tensorflow/contrib/makefile/downloads, tensorflow/contrib/makefile/downloads/eigen-eigen-, and tensorflow/contrib/makefile/gen/proto.

  • [Other Linker Flags] に `-force_load` を追加

In the Linking section, you need to add -force_load followed by the path to the TensorFlow static library in the Other Linker Flags section. This ensures that the global C++ objects that are used to register important classes inside the library are not stripped out. To the linker, they can appear unused because no other code references the variables, but in fact their constructors have the important side effect of registering the class.

  • bitcodeを無効にする

The library doesn't currently support bitcode, so you'll need to disable that in your project settings.


まとめ

TensorFlowをiOS向けにビルドし、付属のサンプルを動かしてみました。パフォーマンスの最適化等、まだまだこれから感はありますが、扇風機や椅子、ノートパソコンやiPhone等、大きさも形も全然違うものを認識してくれて未来を感じます。


試してみるだけなら機械学習やTensorFlowについての専門知識を必要としませんし、ぜひお手元で動かしてみてください!


次のステップとしては、下記記事で紹介されているテンソルの計算部分に特化してSwiftで書かれたライブラリと比較したりしつつ、ちゃんとTensorFlowでやっていることを理解したいと思います。


また、本記事同様に「とりあえず動かしてみる」シリーズとして、こちらもよろしければどうぞ:


*1:ちなみにこのとき、 https://github.com/miyosuda/TensorFlowAndroidDemo/find/master にある同名ファイルを使っても、ちゃんと動きません。参考

2016-07-17

【書評】初学者はもちろん、中級者にもオススメのAuto Layout解説書

著者の川邉さん(@jeffsuke)および出版社のリックテレコム様より『よくわかるAuto Layout - iOSレスポンシブデザインをマスター』をご献本いただきました。


f:id:shu223:20160717140912j:image:h600


タイトルの通りAuto Layoutの解説書で、豊富な図やスクリーンショットを用いて、非常にわかりやすく書かれています。前書きによると、本書の対象読者は

過去一度はXcodeを用いてiOSアプリをつくったことがあるが、Auto Layoutとサイズクラスを用いたAdaptive Layoutと言われると尻込みしてしまう開発者

とのこと。


なんかもうベストセラーになったりしてるらしく、


AutoLayoutの必要性は今更僕が説くことでもないですし、監修は名著『UIKit詳解リファレンス』の著者 所さん


ということで、これはもう

  • iOSアプリ開発に携わっている(携わろうとしている)
  • AutoLayoutがよくわかってない

という方はもう買うしかないでしょう。買いましょう!



よくわかるAuto Layout  iOSレスポンシブデザインをマスター
川邉 雄介
リックテレコム
売り上げランキング: 14,747

(Kindle版もありますが、固定レイアウトのようです。)



・・・と、Auto Layoutに自信のない初学者の方には当然のようにオススメなのですが、AutoLayoutがそれなりにわかっている(と自分では思っていた)僕が読んでも、勉強になったポイントがいくつもありました。以下で紹介していきます。


Content Hugging Priority と Content Compression Resistance Priority と Instrinsic Content Size

250とか750とかのデフォルト値が振られてるアレです。


f:id:shu223:20160718095410j:image:w250


Auto Layoutはわかっているつもりでも、このへんの理解が曖昧なままwarningが出たときになんとなく優先度をいじってみたりしている、みたいな人は実は多いのではないでしょうか。私がまさにそうでしたが、本書では詳細かつ明解に解説されていて、曖昧に理解していたところがスッキリしました。以下メモ。

  • それぞれ Instrinsic Content Size についての「大きくなりにくさ」「小さくなりにくさ」を意味している*1
  • NSLayoutConstraintの優先度の値が同値の場合は、NSLayoutConstraintによる制約が優先される

レイアウトのライフサイクル(p35〜)

1. 制約の更新、2. フレームの更新、3. レンダリングというiOSにおけるレイアウトの3つのステップについて詳細に解説されています。


恥ずかしながら `updateConstraintsIfNeeded`, `layoutIfNeeded`, `layoutSubviews`, `setNeedsDsplay` といったメソッドでそれぞれ何が行われるのか、または何が行われないのか、といったことの理解が曖昧だったのですが、順序立ててわかりやすく解説されていて非常に勉強になりました。

  1. 制約の更新
    • `updateConstraints` が呼ばれる
    • ボトムアップ(子ビューから親ビュー)に制約の計算が実行される
    • 制約の有効/無効化、優先度変更、追加/削除などをトリガに実施される
    • この制約の更新を明示的に実行したい場合には `updateConstraintsIfNeeded` もしくは `setNeedsUpdateConstraints` を呼ぶ
  2. フレームの更新
    • `layoutSubviews` が呼ばれる
    • `layoutSubviews` が呼ばれると `updateConstraintsIfNeeded` も呼ばれ、必要に応じて制約の更新も行われる
    • トップダウン(親ビューから子ビュー)に実施される
    • ビューのフレームの変更・サブビューの追加・削除等をトリガに実施される
    • 明示的に実行したい場合には `layoutIfNeeded` もしくは `setNeedsLayout` を呼ぶ
    • `layoutSubview` をオーバーライドすると、`super.layoutSubviews()` の時点で既に制約の更新が完了しているので、そのレイアウト情報を用いて何らかの処理を実行したい場合に有効(+この方法で無限スクロールを実現する例)
  3. レンダリング
    • `drawRect:` が呼ばれる
    • 明示的に実行したい場合には `setNeedsDisplay` または `setNeedsDisplayInRect:` を呼ぶ

また `viewWillLayoutSubviews` と `viewDidLayoutSubviews` についても、それぞれの段階では(レイアウトサイクルの)どのステップは完了していて何は完了していないのか、というところの理解がスッキリしました。

  • viewWillLayoutSubviews
    • この時点では、サブリューのレイアウトは決定されていないが、画面の向きは決定している
    • この後、「制約の更新」と「フレームの更新」が実施される
  • viewDidLayoutSubviews
    • layoutSubviews による「フレームの更新」が完了すると呼ばれる
    • この後にレンダリングが行われるので、viewDidAppearはこれより後に呼ばれる

UIWindowの話

直接Auto Layoutとは関係ないですが、iOSでUIを実装するにあたってUIWindowに関して知っておいた方がいいことが簡潔に解説されています。`windowLevel` による重なり順の話とか、画面サイズを取得する場合に

UIScreen.mainScreen().bounds

UIScreen.sharedAppliation().keyWindow?.bounds

はどう違うか、とか。


UIStackView

iOS 9で追加された UIStackView についても、10ページを使ってしっかり解説されています。


ちなみに

Start with Stack View, use constraints as needed

まずはStack Viewを使って、必要に応じてconstraintsを使おう


WWDCのセッションでも言われていたとか。


コードで制約を設定する & NSLayoutAnchor

僕は基本的にはIB/Storyboardで制約を貼るのですが、仕事柄多くのプロジェクトに関わるので、「IB/Storyboard使わない派」な方々のコードに触れる機会も度々ありまして、コードで制約を設定することもたまにあります。


本書では、NSLayoutConstraint のイニシャライザを使う方法、VFL (Visual Format Language)を使う方法、iOS 9 で追加されたNSLayoutAnchorを使う方法等、まるまる一章を使ってその方法が解説されています。


ちなみにそろそろiOS 9の機能を使ってもいい(iOS 8を切ってもいい)空気になってきたと個人的には感じていますが、NSLayoutAnchor を使うと超シンプルかつ直感的にレイアウト制約をコードから設定できるようになります。


(before)

NSLayoutConstraint(item: subview,
                   attribute: .Leading,
                   relatedBy: .Equal,
                   toItem: view,
                   attribute: .LeadingMargin,
                   multiplier: 1.0,
                   constant: 0.0).active = true

(after)

let margins = view.layoutMarginsGuide
subview.leadingAnchor.constraintEqualToAnchor(margins.leadingAnchor).active = true

本章末尾のコラムではAuto Layoutを簡潔に書くためのオープンソースライブラリもいくつか紹介されています。


その他、細かい話

Auto Layout のアルゴリズム

この線型方程式系を解くアルゴリズムは、Greg J. Badros と Alan Borning、Peter J. Stuckey によって2001年に発表された、制約充足問題を説く Cassowary というツールキットで用いられたアルゴリズムを使用しています。(p.15)

明日から開発に活かせる、という話ではないのですが、こんなこともサラッと書かれていて、しっかり調べて執筆されている書籍なんだなということが伺えます。


外接矩形(alignment rects)をデバッグ時に確認する

[Edit Scheme] > [Run] > [Arguments] の [Arguments Passed On Launch] に `-UIViewShowAlignmentRects` を追加してチェックを入れると、実行時に外接矩形が表示される、というTips。


NSLayoutAttributeのLeft/RightとLeading/Trailingの違い

基本的にLeading/Trailingを使ってたので意識したことなかったですが、アラビア語とかヘブライ語のように右から左へ書く言語ではLeading/TrailingがそれぞれRight/Leftと同値となるそうです。


制約の矛盾が実行時に起きたときのエラーメッセージの見方

実行時にぶわーっと出てくるエラーメッセージ、ありますよね。僕は最近だとAutoLayoutを使ったアニメーションをやろうとして何かが間違っててこれが出てきました。で、メッセージ読んでもどの制約が悪いのかわかりづらい、と思ってたんですが、制約にちゃんとidentifierふればいいみたいです。(p86)


Xcode 7 の Storyboard Reference

Xcode 7 で追加された [Refactor to Storyboard...] メニューからの Storyboard の分割方法もしっかり書かれています。


Auto LayoutのデバッグTips

UIView に `exerciseAmbiguityInLayout()` なるメソッドがあり、これを用いると曖昧な制約を持つビューオブジェクトのフレームを、制約を満たす範囲でランダムに変更してくれるそうです。


他にもオブジェクトが持つインスタンス変数名と値を吐いてくれる `_ivarDescription` メソッド*2とか、ビューデバッガーの [Show Constraints] 機能とか、知らなかったことが色々と書いてありました。


まとめ

書籍『よくわかるAuto Layout』を紹介させていただきました。Auto Layoutがよくわかってない人を対象として書かれた書籍ですが、中級者にも勉強になる部分は多いと感じました。


本をまるっと一冊通読してAuto Layoutを勉強するというのはなかなか難しい、と感じる方もいらっしゃるかもしれません。が、目次を見れば分かる通り、Auto Layoutについてかなり網羅的かつ本質的に解説されてますので、リファレンス的に手元に置いておくのもいいのでは、と思います。


気になった方はぜひ!


よくわかるAuto Layout  iOSレスポンシブデザインをマスター
川邉 雄介
リックテレコム
売り上げランキング: 14,747


*1:この訳はAppleのドキュメントにあったのか著者のオリジナルかわかりませんが、簡潔で秀逸だなと思いました

*2:※Privateです

2016-07-16

【書評】モバイルエンジニア向けのAWS解説書

著者・監修の佐々木 拓郎さん、 高柳さん、および SB Creative さまより『Amazon Web Services クラウドネイティブ・アプリケーション開発技法 一番大切な知識と技術が身につく』をご献本いただきました。


f:id:shu223:20160506083601j:image:w600


昨今のモバイルアプリケーションには大抵の場合バックエンドも必要になりますが、たとえば僕はiOSアプリしかつくれません。そういう場合に、他のサーバーサイドエンジニアやインフラエンジニアと組む以外に、ちょっと前であれば Parse.com を利用してサクッと済ませてしまう、という選択肢もありましたが、来年にはサービス終了してしまうという悲しい事態になってしまった今、やはりモバイルアプリケーションのバックエンドのインフラとして真っ先に候補に挙がるのは AWS(Amazon Web Services)です。


ただそのAWS、LambdaとかMobile HubとかIoTとか色々ありすぎて、手を付け始める前からハードルを感じてしまう部分があることも否めません。例えば外部デバイスからアプリで吸い上げたデータを置いておきたい場合にはどれがいいんだろう、とか。お手軽さとか値段とかそのデータをどう利用したいか等にもよるのだと思いますが、どう検討・比較したらいいのか素人目には難しく思えてしまいます。


前置きが長くなりましたが、そんなAWSの各種サービスについてモバイルエンジニアを対象読者として(※)解説されている本がこちらです。


(Kindle版もありますが、固定レイアウトのようです。)


600ページ強の大作です。以下、個人的にいいなと思ったポイントを紹介していきます。


※ちなみに実際には『対象とする読者は、モバイルやJavaScript等でフロントエンドアプリを開発するアプリケーションエンジニア』とあるのでモバイルエンジニアだけではないのですが、僕がモバイルエンジニアなのでその視点で書かせていただきます。


AWS各サービスの詳細かつ丁寧な解説

Chapter 3 には、各サービスの特徴や使いどころ、機能・導入方法・料金・制限事項など、かゆいところに手が届く情報がまとめられています。

  • 3-1 Amazon S3
  • 3-2 Amazon API Gateway
  • 3-3 Amazon Simple Notification Service
  • 3-4 Amazon DynamoDB
  • 3-5 AWS Lambda
  • 3-6 Amazon Cognito
  • 3-7 Amazon Machine Learning
  • 3-8 Amazon Kinesis
  • 3-9 Amazon Simple Queue Service
  • 3-10 AWS IoT
  • 3-11 AWS Mobile Hub

全項目に利用方法と基本的な使い方が書かれていて、それぞれ10〜20ページにわたって豊富なスクリーンショット付きで丁寧に解説されているので、迷うことなく試してみることができそうです。


f:id:shu223:20160716164206j:image:w600


すぐに使う予定があるわけではなくても、これを見ながら一通り触ってみるのも良さそうです。一度でも触っておけば、どんなことができるのかとか、どれぐらい簡単なのかとかの感触がつかめるので。(個人的には、Lambda、Machine Learning、IoT、Mobile Hub あたりを本書を見つつ触ってみたいと思っています)


興味深いサンプル群

Chapter4からは具体的なアプリケーションを実装してみるチュートリアルとなっており、モバイルエンジニアにとっても魅力的なサンプルが並んでいます。


以下にそのリストを列挙してみます。(個人的に特に気になったものを太字にしてみました)

  • 4-1 Cognitoによる認証を利用したスマートフォン向け写真共有アプリケーション(iOS/Android)
  • 4-2 API GatewayとLambdaによるサーバ連携するモバイルアプリケーション(Android)
  • 4-3 API GatewayとCognito、Lambdaを連携した認証・認可サービス
  • 4-4 API Gatewayを使ったモバイルのスタブAPI
  • 4-5 DynamoDBとApple Watchによる健康情報の収集(iOS/watchOS)
  • 4-6 iBeaconと連動する勤怠管理アプリケーション(iOS/Android)
  • 4-7 Device Farmを利用したモバイルの多端末自動テストの実施(Android)
  • 4-8 S3とLambdaによるキーワードキュレーションサービス
  • 4-9 KinesisによるTwitter情報の収集
  • 4-10 Machine Learningを用いたWeb閲覧履歴保存&キュレーションサービス
  • 4-11 Cognito Syncを使った簡易メモアプリケーション(iOS/Android)

カッコ()内はiOSもしくはAndroidのどちらのサンプルが付いているかを示しています


いかがでしょうか。太字をつけたものの、私はいずれのサンプルも実際に仕事で必要になりそうなシーンが浮かんで、自分で手を動かして試してみたい、と思いました。


ちなみにiOSのサンプルはSwiftで書かれています。


まとめ

アプリケーションエンジニア向けに書かれたAWS解説本、『Amazon Web Services クラウドネイティブ・アプリケーション開発技法』を紹介しました。普段あまりサーバーサイドの開発に携わることのない私のようなクライアントサイドのエンジニアにもわかりやすく、興味深い技術書だと思います。バックエンドやAWSまわりに興味がある・知識をつけたい方はぜひ一度書店などで検討されてはいかがでしょうか。(僕も勉強します!)



2009 | 08 |
2011 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2012 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2013 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2014 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2015 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 12 |
2016 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 |