kumamotone’s blog

iOS/Android アプリエンジニアです https://twitter.com/kumamo_tone

potatotips #48 に参加しました (iOS, Androidブログまとめ)

potatotips #48iOSブログまとめ枠で参加させていただきましたのブログです。

Rettyさんの会場。広いし綺麗

f:id:kumamotone:20180222214744j:plain

今回は5分発表+1分質疑応答スタイルでした。最近はそこそこずっと参加しているのですがはじめて見た。

以下発表内容です。iOSブログまとめ枠でしたが今回はAndroidの発表内容に関してもまとめてみました。間違いや気になるところなどあればご指摘ください。埋まっていない資料は公開されたのを見つけ次第反映します。

テスト実行時に不要な初期化コードを実行しないようにする / kNagadou さん

speakerdeck.com

アプリ起動時に初期データを構築することがある。固有の環境変数や外部SDKのセットアップなど‥

初期化処理はAppテスト時はAppDelegateの処理を実行しないようにしたい。ほかにも問題あって、Viewのインスタンスは不要だが、デフォルトだと、Unitテスト時もUIがロードされる。また、テスト用の初期化処理は別のところに分けたい。

これらを解決するにはまずmain関数的なところでテストかどうかを判定する、その後テストならTestAppDelegateとかを実行して、Main Interfaceのロードはプロダクション用のAppdelegateで処理するようにすればよさそう。

main関数的なところでという部分に関しては、実はmain.swiftが暗黙的に呼ばれていて、main.swiftをプロジェクトに追加すれば上書きできて初期化処理書ける。

Android Instant Apps対応した話 / take_e10 さん

www.slideshare.net

Instant Apps対応した。Instant Appsには制限ある。今現状だと使えない機能、そもそも非サポートな機能。Module<4MB必須とか‥

特に4MB制限がキツイ。Instant Apps対応はほぼほぼこの作業となる。Module分割で4MBを目指す。APK Analyzerでサイズ見れるが、4MB超えるとアップロードした時点でエラーになる。

やったことの中で効いたのはやはり画像。WebPにしたりVectorDrawableにしたり。

ちなみにic_launcher.png (ドロイドくん)のアイコン、いつのまにか入っていて消せなかった 18KBもあってつらい‥

Q. 同じ名前のめちゃくちゃ小さいファイルで置き換えるというのはいかがか?

  1. やったと思うのだがなんか無理だった

Androidチームにコンバートされてから半年、いかにしてAndroidエンジニアになったか / niba1122 さん

Android開発を学ぶためにやったこと。最初1ヶ月はUdacityのeラーニングと、赤べこ本やった。

UdacityはAndroid Basics: UserInterfaceというのと、Developing Android Appsというコースをやった。面白かったのは Android Visualizer というのがあって、ブラウザでXML書ける。

Udacityは独学で網羅的に学べて良いが、英語なのでちょっと大変。その後は実践で学ぶ形式となったが、学ぶことが多くてよかった。Udacityと赤べこ本おすすめ。

Q. Udacityいくら?

  1. 無料です

Q.サンプルのバージョンとかは?

  1. 古いこともあるが大きな問題はなかった 言語はJava

初めてのXcode Behavior / TachibanaKaoru さん

speakerdeck.com

Xcode Source Code ExtensionはWWDC2016で紹介された。

公式だぜ!という感じで盛り上がっていたが、蓋を開けてみれば配布、作成、デバッグが大変、動作にかなり制限がある…過去の非公式プラグインでできていたことが出来ない…

一方、Xcode Behaviorというのがある、Xcodeのmenuから使える。太古の昔からある機能。Xcodeから独立していて、スクリプト走らせれる。

Source Code Extensionとの比較。

Source Code Extension Xcode Behavior
Xcodeで今開いているファイルの中身のみを変更できる。 スクリプトでできることはなんでもできる。
Xcodeで開いているファイルの中身のみ取得できる。 起動するときに環境変数が渡せるので、今Xcodeで開いているファイルがわかる。
作成、配布、変更つらい 配布、自分で書いたスクリプトを自己責任で使うスキームで、作成も配布も変更も楽。
GUI表示できない GUI表示できる。AppKitも可。
Xcodeコンパイル言語のみ スクリプトならなんでもOK。もちろんSwiftも可。

実例。

Apple公式のサンプルコード、たとえば以下のページのxcodeprojを開くと、

developer.apple.com

f:id:kumamotone:20180223000529p:plain

マークダウンが表示されている。

f:id:kumamotone:20180223000547p:plain

しかもView in Sourceって書いてあるリンクを踏むとソースファイルに飛べる。どうやらXcodeのソースコメントに- Tag:を入れると、マークダウンファイルなどからソースコードへのリンクが簡単に作れるらしい。

これを自前のプロジェクトでやってみようとすると…

f:id:kumamotone:20180223000801p:plain

f:id:kumamotone:20180223000815p:plain

f:id:kumamotone:20180223000843p:plain

んん…

さっき見たのと違う…となる

ふつうにやると、Xcodeではそもそもマークダウンはレンダリングされず、生のマークダウンがエディタで表示されてしまうもよう。

調べてみるとどうやら、プロジェクトファイルのなかに特定のplistファイルが置かれていればマークダウンをレンダリングしてくれるようになるもよう。

www.toyship.org

でこれを自前で毎回置くのはめんどくさいので、以下のようなスクリプトを書いて Xcode Behavior でやってしまえば便利。

gist.github.com

Xcode Behavior便利。太古の昔から使える技だが、今こそ見直されるべき。

リリースを自動化した話 / TakuSemba さん

speakerdeck.com

リリース、Sembaさんのチームはapkをアルファとして公開、apkをproductionに上げる、githubでrelease noteを書く、というフローにしてる。

apkをアルファとして公開する部分とリリースノートを書く部分を自動化した。

apkをアルファとして公開する部分。gradle-play-publisherというのを使った。gradleにメールアドレスとか書けば使えるようになって、色々設定もできる。

./gradlew tasks --all するとリストが見れる。bootstrapReleasePlayResourcesは現在公開しているapkの情報をとってこれる。これを編集してpublishListingReleaseする。whatnewを編集してpublishApkReleaseする。

リリースノートを書く部分。GithubAPI叩いてCIに組み込めば良い。リリースのタグがプッシュされると、CIが走るようになっている。

Heckelの差分アルゴリズムについて / YuyaHorita さん

a,b c,d e と a,c,e,f を定義 すると差分は直感的に b,d,f となる。これを噛み砕くと、いくつかのコマンドの塊とみなせて、差分アルゴリズムはこれを実装したものといえる。

差分検知、iOSならDiffer, Dwifft, Androidなら DiffUtil などのライブラリがある。 アルゴリズムとしては Myers, Heckel などがあるが、今日はHeckelについて説明。

アルゴリズムの説明。シンボルテーブルを一つ用意して、新しい配列OからNの配列の差分を取ることを考える。配列O,Nの各要素をKeyとして辞書型のシンボルテーブルに登録。Valueには配列O, N内での数、O内でのindexを保存しておく。

次に自分の分身を自分自身以外を参照させて生成。配列O,Nの各要素を1対1対応した配列ON, NAを用意し、1対1対応している要素への参照を保持し、参照先はSymbolTable もしくは もう一方の配列。

これを配列Nにもやってく。相手側の配列に要素があるならindexを変えるMoveでOK、シンボルテーブルしか参照できないなら古い配列ならDelete、新しい配列ならInsertとなる。

これを使うとO(N)で計算が可能。Myers, Wuに関してもGithubに上げるつもりなのでよろしく。

Contact AppっぽいSticky Headerをつくる / e10dokup さん

speakerdeck.com

Contact AppやDroid Kaigiとかで見る名前一覧のアレつくる。

RecyclerView.ItemDecoration。RecyclerViewのアイテムに対して装飾するabstract class。getItemOffsets, onDraw, onDrawOverの 3つのメソッドをoverrideしてつくる。描画はcanvas.drawText()でやる。

サンプルはこちらから。

github.com

Metal Acceleratedかどうかを調べる方法 / shu223 さん

speakerdeck.com

WWDC2017で出た図で、UIKitやCore Animationも低レイヤでMetalを使っている(Metal Acceleratedされている)ことが明らかになった。

OpenGLiOSでは今はMetalの上に実装されているとAppleの人がWWDCのラボで言ってたけど公式情報はない、が裏が取れない。

裏が取りたい‥なんで取りたいかというと、最適化されていることがわかるし、自分の最適化手法が適切かどうかの判断材料になるし、低レイヤに踏み込んで自前実装するかどうかの判断材料にもなる。

試したこと。まずはGPU Reportだが、Metalを明示的に使用していないと、XcodeGPU Reportは出てこない。そこでInstruments。Metal System Traceというのを使うと、明示的に使ってなくてもわかる。ざっくりした見方としては、上から順に実行されていて、ディスプレイに描画されるまでの流れがわかる。

APIのデータのマッピングを約18倍速くした話 / magiepooh さん

画面遷移遅いなーとなって調べたら、SO-04Gとか古い端末とOSだと最悪20秒ぐらい掛かることが分かった…

ちなみにJSONが1MBあって、Kotlin+Moshiでパースしてた。

やっていき。まず対策その1、Moshi はリフレクションを用いているため、コストが高い。Kotshiを使うと20sec->12secになった。

対策その2、オブジェクト生成が多すぎるのではとなった {"obj":{123, 456.2...}} みたいなlongとdoubleの入り混じった感じの感じのオブジェクト。これはStringの配列にした。12sec->8.4secにした

最後によくよくデータ見直してみると重複した配列データを4つ受け取っていた。てへ なおして 8.4sec->2.9sec。

というわけでかなり速くなった。ちなみにShared Element Transitionがあると2.9秒でも意外と遅く感じない。その後大量の配列の取得は別APIに切り出した。これで1.2秒(18倍)。ちなみにiOSはそんなに時間かからないの謎…端末のスペックなのだろうか…

アプリの翻訳管理を楽にする / kosako さん

Rettyアプリは端末内の言語設定ではなく、アプリ内で言語切り替えするようなアプリ。

一般的にはstringファイル作ってNSLocalizedString("key", comment:"")みたいな感じでやってく?が、これはめんどくさい‥特にKeyの名前を名前を決めるのが面倒くさい typoするかもしれないし

Google SpreadSheetを使ってみた。Google Google Apps Scriptでspreadsheetからアプリ用のリソースファイルとswiftファイルを生成する。Googleのバックアップと同期を使ってローカルに自動DL。

同期はなんか拡張子が変になったり?するようなのでfswatchというのを使うといい。

kosakoさんのプロジェクトではNSLocalizedStringは使ってなくて Stringにlocalizedというextensionを生やして対応していた( "keyname".localized() )。まだtypoの危機があるのでenumを使うようにした。Localize.keyname.localized()みたいな。こうするとサジェストされて雰囲気で書けるようになるので良い。

Q. スクリプトは公開しないのか?

  1. Qiita にあるよ

qiita.com

Alexa、APKを配布して / horie1024 さん

speakerdeck.com

APKの配布方法、手動とかGradleとかCIとかあるが、音声でできたら便利では?と思った

流れ。alexa→LambdaでBitriseをトリガー、BitriseでDeploygate叩く。

スキル作るには呼び出し名が必ず必要で、今回は「Alexa,ビットライズでAPKを配布して」の形で使うのだが、呼び出し名がビットライズ、インテントが「APKを配布して」となる。トリガーにはBuild Triger APIをつかう。deploy workflowにScript Stepを追加して、ビルド完了後APKをアップロード。DeployGateでAPKを配布。アップロードされた。

これで音声コマンドでAPK配布までできるようになった。

Alexa、APKを配布してのような普通の人が使わないような言葉も認識してくれて良い。

iOSフレームワークViperのススメ / hirothings さん

speakerdeck.com

MVCのつらさ、工夫しないとルーティングがない、Viewのロジックとデータに関するロジックが交じる。

かっちりしたフレームワークが欲しいがスピードも犠牲にできない、そこでViper。

Viperは単一責任の原則に基づいて作られたフレームワークで、iOSの現場で生まれたフレームワーク

Viperの説明(省略)。

チームに持っていくときは、簡単なTwitterクライアントのサンプルを持っていって見てもらった

github.com

結果好感触だったので自信をもって進められた。

テスタブルになったのでStubとSpyを使ったユニットテストを採用した。

Presenter以外のレイヤーの実装に悩まされずに済んだ。

ボイラープレート増える問題に関しては、Kuriとかコードジェネレータを使うと良い。

RuntimePermissionChecker というライブラリを作った / taptappun さん

Runtime Permisson。コーディングしてたら Permission 書くの忘れてた、となって時間無駄にすること多い。

Permissionのこと考えたくない‥AndroidManifest.xmlにPermission記述したら自動的によろしくやって欲しい。

なので作った。細かい話や導入はQiitaにのっけているのですが、みんな使ってくれ!

qiita.com

感想とか

iOSAndroidも面白くて聞き逃せない!

f:id:kumamotone:20180222214817j:plain

懇親会もアーキテクチャの話とか質問とかフリーランスの話とかできて楽しかったです。

TachibanaKaoru さんの Xcode Behavior ですが、帰ってから gistにアップロードされていたスクリプトを実際にXcode Behaviorで実行してみました。

f:id:kumamotone:20180223002530p:plain

設定からスクリプトを指定して

f:id:kumamotone:20180223002554p:plain

実行

f:id:kumamotone:20180223002625p:plain

ウィンドウ開き直す

f:id:kumamotone:20180223002721p:plain

おぉ〜

お疲れ様でした