Diverse developer blog

株式会社Diverse 開発者ブログです。

Swift の Mirror という API からみた、Swift の奇妙な挙動

Diverse で iOS アプリの開発をしている Kuniwak です。前に書いた記事では、単体テストで開発を2.5倍高速化した話を書きました。

さて、先日開催された iOSDC のリジェクトコンで、単体テストのテスト結果をわかりやすくするライブラリ「MirrorDiffKit」の開発秘話をお話ししてきました。この発表では、Swift を Mirror という API を通して見たときの奇妙な挙動を紹介しています。

発表の概要

5分ほどで読み終わるスライドになっています。Swift の奇妙な挙動をお楽しみください。

speakerdeck.com

宣伝

Diverse では Mirror というマイナー API とかも触ってみたい iOS エンジニアを募集しています!

あと、MirrorDiffKit をよろしくお願いします

github.com

DevFest Tokyo 2017でミクシィグループとKotlinについてお話してきました

id:kikuchy です。

先日開催された GDG DevFest Tokyo 2017 のセッション『Kotlin導入どうですか?』内で、ミクシィグループ内のKotlin導入状況についてお話させていただきました。


tokyo.gdgjapan.org


(2017/10/10時点ではスライドは未公開です)



セッションはサイバーエージェント 藤原さんがメインスピーカーとしてお話され、その中で各社の導入事例としてYahoo! Japan 森さん、DeNA 中川さん、ミクシィ 菊池からもお話をさせて頂きました。

会場はほとんど席が埋まるほどで、Androidエンジニアの方々のKotlin熱の高さをうかがい知る事ができました。

内容も各社の個性が表れており、面白かったです。
Yahoo! JapanさんのProGuardではなくDexGuardを使わなければいけない特殊な事情がKotlin導入を後押ししたエピソードとか、
DeNAさんの「若いエンジニアさんにとってはJavaは古代語である」という見解であるとか、
サイバーエージェントさんのプロジェクトによって導入の仕方が工夫されている事例であるとか、
社内を見回すだけではわからないような情報やノウハウを得ることができました。



また、界隈では「赤べこ本」と呼ばれる『Kotlinスタートブック』の著者の長澤太郎さんからも質問も鋭いものでした。


Kotlinは便利で強力な機能を持った言語ですが、それ故に気にしないといけないことがあるということですね。



(去年も参加させていただいていて、)今年のDevFestもたくさんのセッションが開かれていました。
GCPのお話や、VRのお話、IoTのお話やPWAのお話と、内容も多岐にわたっており、個人的にはやくスライドを読み直したいセッションもたくさんありました。

普段はクライアントのネイティブアプリを開発しておりますので、同じ界隈でも話したことのない方とお話したり、あまり関わらないコミュニティの方々とお話する機会を得たりと、とても楽しいイベントでした。


DevFestは世界各国で開催されていますし、日本でも来年も開催されるでしょう(そう期待しています!)。
せひ足を運んでみてはいかがでしょうか。
きっと何か得るものがあるのではないかと思います。


Diverseはこれからも、開発者コミュニティに貢献していきます\\ ٩( 'ω' )و //

俺コンで「iOS でテスト容易な設計を実現するためのデザインパターン」を発表してきました

はじめまして。Diverse で iOS アプリの開発をしている Kuniwak です。

先日開催された iOSDC の第三者によるリジェクトコンで、設計のデザインパターンについて発表してきました。
発表内容は、単体テストを簡単にするための設計のデザインパターンの紹介です。

発表の概要

speakerdeck.comこの発表では、単体テストでは必須となる、代替オブジェクト(Stub や Spyと呼ばれます)の作成方法から、UIKit への応用などの広範なベストプラクティスを紹介しています。また、特にアーキテクチャを限定していないため、MVVM や MVC、MVP などの設計にも応用できます。

このパターンを実践し続けた未来

なお、このパターンを使って単体テストを活用していくと、どのようになるかについてもお話ししましょう。

私の所属する iOS チームでは、この設計パターンを使って10万行ほどのSwiftのコードを開発しており、このうち14,000行ほどが単体テストのコードになっています。そして、単体テストをうまく活用できているプロジェクトでは、コンポーネントの多くが単責務で疎結合になることを強制されます。そのため、私たちのプロジェクトでは複数の責務が混在する FatViewController は1つもありませんし、Model にログ機能が混在することもありません。

もしかすると、FatViewController を防ぐための一番の方法は、単体テストを書き、その単体テストの声を聞くことなのかもしれませんね。

さて、この話を聞くと「そんなにテスト書いてたら開発速度落ちるでしょ」という声をいただくことを容易に想像できるのですが、実際は逆です。私たちのプロジェクトでは、単体テストを書きはじめてから行数ベースでおよそ3倍ほどの開発速度になりました*1。先ほど述べた通り、1/7は単体テストのコードですから、残りの本体コードを書く速度はおよそ2.5倍になったということです。

この理由は、おそらく単体テストによりデバッグにかかる時間が大幅に短縮されたことでしょう。最終的に、私たちのプロジェクトで手戻りの原因のほとんどが仕様の誤解や見た目の修正のみになりました。つまり、単体テストで防ぐべき手戻りをほとんど防げているということです。さらに、これは嬉しい副作用なのですが、今のところクラッシュフリーを達成できています。

皆さんも、単体テストで開発を爆速化していきましょう。

宣伝

Diverse では開発を爆速化させたい iOS エンジニアを募集しています!

あと、MirrorDiffKit をよろしくお願いします!!!!  

github.com

 

*1:この時期に開発人数が2人から3人になっているので、単体テストだけが要因というわけではありません

Android Test Night #1 でお話させていただきました

id:kikuchy です。

先日開催されたイベント Android Test Night #1 - connpass にて、JUnit5とAndroidのテストについてお話させていただきました。


testnight.connpass.com



つい10日ほど前にリリースされたばかりのJUnit5はAndroidで使えるのか、
どんな機能が便利に使えるのか、というお話です。


はじめは
「Junit5のユーザーガイド通りにセットアップしても動かない」
という旨をお話させていただいたのですが、発表後にAndroid対応版があるということを教えていただきました。

Javaだけでなく、工夫すればKotlinのテストも実行できるようです。
(Javaのテストを実行できることは手元で確認しました)

JUnit5では、以前からある便利な機能が使いやすく改良されている印象です。
使える機会があれば、ぜひお手元のプロジェクトでお使いになってください。

会の様子

OpenSTFや各種クラウドサービスを駆使した メルカリさんの事例 をはじめ、 DangerTDD など話題は多岐にわたり、非常に勉強になる会でした。


当日の発表をまとめてくださっている記事がありますので、こちらも御覧ください。

qiita.com



懇親会では、QAチームの有無や普段のデバッグのフローなど、主に品質保証の話が飛び交っていたようでした。
良いテストエンジニアの在不在が、実装エンジニアの負担とアプリケーションの品質を左右するのだなぁ、と感じます。



DeNAさんで開催されているTest Nightシリーズ。iOS Test Night には弊社から3人ものエンジニアが登壇させていただいております。

iOSの場合と同様、日本ではAndroidアプリケーションに特化した継続的な勉強会があまり見当たりません。
こうした情報共有の場と機会を提供してくださることは非常にありがたいと考えております。
この場を借りてお礼申し上げます。

これからもDiverseはテストに関する知見も発表していきます。\\ ٩( 'ω' )و //

夏のKotlin LT祭 でLTしてきました

id:kikuchy です。

先日開催された夏のKotlin LT祭にてKotlinJSについてお話させていただきました。

kotlin.connpass.com




GoogleがAndroidの公式開発言語にする、Springが対応を表明する、Kotlin/Nativeが発表されるなどして、Kotlin界隈もますます盛り上がってきております。
しかし、Kotlinのファーストリリース時からある機能なのにいまいちパッとしない機能があります。

Kotlin -> JavaScriptのトランスパイル機能です。

当日も会場の方々に挙手をお願いしたところ、予想通り使っている方はほとんどいらっしゃいませんでした。

どうしてパッとしないのか、実は隠れた使い勝手の良さがあるのでは、もしかしたらすぐにでも業務に投入できたりするのでは…
と思って、実際に使ってみた感じを報告するスライドになっております。


結論はスライドに書いたとおりです。

LTを聞いてKotlinについておもうこと

Androidに限定しないKotlinについての勉強会だったため、サーバーサイドの話題も多く、JVM言語としてはかなり主要な位置を占めてきはじめている言語だなと改めて感じました。

JVMで動くプログラムを作るなら、まず第一の選択肢にKotlinが上がる時代がもうすぐに来るでしょう。

私個人は自分用のコマンドラインツールやGUIのアプリなどもKotlinで書いています。
Stream関連の拡張関数も充実していますし、Delegated Propertiesを使ってPropertiesの項目をクラスメンバに割り当てると扱いが楽だったりと、便利に使えています。
趣味プロにもKotlinをぜひお使いください!

Kotlin/Nativeも盛り上がって欲しいですね。
iOSをKotlinで書く未来がくると夢見て…


DiverseではAndroid開発にKotlinを使用しています!
Kotlinを使った開発をしたい方はぜひ一度お越しください!↓

diverse-inc.co.jp

Shibuya.apk #17に登壇してきました

id:kikuchy です。
ここ半年ほどはiOSの開発をしていて、そこで一緒に仕事をしている id:devorgachem から良いアーキテクチャを教えてもらったので、それをAndroid開発に適用する方法をお話させていただきました。
とは言え、難しいことではありません。

スライド中でお見せしたサンプルのリポジトリはこちら。

github.com

要は

Activity/Fragmentにフラグを書くのをやめて、画面がとり得る状態をちゃんと列挙して管理しましょう、というお話です。

もっと言うと

状態を専用クラス(モデル)で管理し、Activity/Fragmentから切り離すととても便利です。
とり得る状態と状態遷移の仕方がわかっているので、

  1. 所定の操作をした時に、所望の状態になっているか
  2. 所定の操作をした時に、意図しない状態に陥っていないか

だけ確認できればテストは最低限のテストはできますし(Viewとかは別問題ですからね!)、一部のモデルを再利用することも可能です。


特に、APIで得られたデータを加工して表示するのが主な責務になっているアプリですと、通信状態 ≒ 画面の状態になりがちなので、通信状況を管理できるとコードの見通しが良くなります。


頂いた質問など

発表後にいくつかご質問をいただいだきましたので、共有させていただきます。

Kotlinのsealed classを使用しているのはなぜ?(enumは使わないの?)

一言で言えば、SwiftのAssociated Values付きenumと同じことをしたかったから、です。

Kotlinには特定スコープ内でのみ継承が可能になるsealed classというクラスがあります。

kotlinlang.org

アプリケーションの状態にはデータを付随させたいことが多々あります。
(例えば、「通信完了」状態には、通信の結果得られたレスポンスor失敗の原因が付随するはずです。)

やりたいことは状態を列挙して宣言しておくことなので、たしかにenumでも事足りそうな気がします。
が、JavaやKotlinにおけるenumはプログラム起動時にすべてのインスタンスが生成されてしまう(シングルトンになっている)ので、状態ごとに違う型のデータを付随させることが難しいのです。
(値をNullableで取り扱うことを許容すれば実現可能だと思います)

sealed classとdata class、それに加えてwhen式を使えば、Swiftのenumと同じことを実現できます。
data classを使えばequals()も自動的に用意されるので、テスト時の比較も簡単でSwiftよりも便利です!

LiveDataを使っている理由は?(もしくは、RxLifecycleの使用を勧めている理由は?)

モデルの生存期間がActivity/Fragmentよりも長くなりえることを想定しているためです。
(必ずしも、長くする必要があるわけではありません)

状態を抱えているモデルの生存期間は、Activity/Fragmentのライフサイクルとは独立しています。
特にDIツール(Dagger2など)を使ってシングルトンとして生成されたモデルのインスタンスなどは、Activity/Fragmentより長く生きることになります。

するとよく言われている通り、onNextのタイミングでViewが居なくなっていてNPEを引き起こしたり、Subscriberがリークする原因となるので、適宜、モデルからの通知を止めてやる必要があります。

そのために用意されているのがLiveDataなりRxLifecycleなので、それの使用をおすすめしているという訳です。


ちなみに

モデル部は通常のJava Libraryとして作れるのでJVM上でテスト可能です。(サンプルではそうしています)
テストが速攻で終わって便利です。



Diverseはこれからも新しい提案や試みを発表してゆきます°˖✧◝(⁰▿⁰)◜✧˖°

iOS Test Night #4 でLTしてきました

id:kikuchy です。
Androidをやっていたはずですが、最近はiOSをガッツリやっています。

先日開催されたiOS Test Night #4に登壇してLTをさせていただきました。


testnight.connpass.com


今回は、テストコードをアプリケーションコードと同じ(Groupの)階層に置きなおすツールを作った話をしました。

紹介しているツールはこちらになります。
github.com





きっかけは、前回 iOS Test Night #3 であった以下のツイートを見てのことでした。

ちょうどその頃、fastlaneのオプションを追いかけたりしてコードを読み、Xcodeprojというgemを知ったばかりだったのです。

github.com

このgemは、Xcodeのプロジェクト設定や含まれるファイルなどを管理する project.pbxproj を抽象化して取り扱うものです。
ビルドターゲットに含まれているファイルを取得することもできますし、ターゲットからファイルを削除したり追加することも可能。

とても便利なgemですので、Xcodeプロジェクトを操作するようなツールを作りたいと思っている方は、ぜひ一度チェックしてみてください。




発表の後に主催の方からこのようなツイートをいただきました。

勉強会で得られるものは、問題の解決方法だけではありません。
問題がある、ということ自体を教えてもらうことができます。
問題があれば、解決するチャンスです!

Diverseのエンジニアは、これからも問題も解決方法も発信してゆきます。\\ ٩( 'ω' )و //