iOS 開発者はコードを書くこと以外にも様々な業務を抱えています。
みなさんはこんな依頼を受けていませんか?
「Firebase App Distribution からインストールしたいのですが UDID を登録してくださいと言われます。どうしたらいいですか?」
「今開発中の Branch の最新版って触れますか?配信お願いします。」
「現在の審査状況どうなってましたっけ?」
「リリース用の Branch の merge 忘れてませんか?」
「dSYM アップロードしてませんよ。」
メールや GitHub を見に行ったり、手元でビルドし直して fastlane を実行したり…といろんなツールを切り替えるだけでも時間は過ぎてしまいます。
これらの作業、自動化してみませんか?
同僚のように頼もしい Bot を育ててみませんか?
本トークでは私が1人チームのころから iOS 開発に関わる業務のアレコレをコツコツ自動化してきたこと、それをベースに実際に会社で運用しているワークフローを余すことなくご紹介します。
共通したコードベースを基に、複数アプリをビルドしたいことがあります。
例えばCtoCのECサービスにおいて、同プロダクトの販売者向けアプリと購入者向けアプリを実現したいときなど。
このように、機能の出し分けはあるけれど、共通部分が多いのでソースコードを分けるほどではない、といった場面が起こり得ます。
こんな時に用いる手法として、Configurationを複数作成しそれぞれにおいてマクロを定義し、
機能出し分けを行いたい箇所で「#if」という記法を使って実装コードを出し分けていく、といったものがあります。
こういった開発においてよく発生してしまうのが、コードの至るところに「#if」が発生してしまい、可読性が落ちてしまうということです。
また本来であれば購入者のみが使用できる機能であっても、誤って販売者向けアプリにおいて表示してしまう、という不具合が起こる可能性も十分あります。
そういった課題を「型定義」の力を借りることで解決することができます。
本トークではこちらについてご紹介したいと思います。
iOS の UIKit は一見、文字入力のような基本的なことはとても簡単に行えるように思えます。
しかし、一度でも文字入力を扱ったことのある方は、その難しさと期待しない動作に頭を悩ましたことが一度はあると思います。
例えば、iOS のキーボードが文字入力に被ってしまう、キーボードの位置がずれる、変更したはずの文字が反映されない、日本語が入力できない...
実のところ、一般的に文字入力はとても複雑なユーザーインタラクションであり、さらに iOS はキーボードにも様々な種類があるため、一見すると正しそうな実装であっても、ドキュメントに記載のない様々な挙動により期待しない結果に終わってしまうことが多々あります。
このセッションでは、ほぼほとんどの方が経験する iOS の文字入力に関する些細な問題からとても大きな難題について、世界中で多くのユーザーが使う iOS アプリ開発や、iOS のキーボードフレームワーク「KeyboardGuide」などの開発など、これまで長い間蓄積してきた経験に基づいて、実際におこった問題を実例を踏まえて、その原因や対策を検証していきたいと思います。
対象とする方:
UITxtView
に昔年の思いがある方UIKeyboardWillChangeFrameNotification
などに昔年の思いがある方前提とする知識:
ユーザーにアプリを快適に使ってもらうためには、機能が動くだけでなくアプリのパフォーマンスも重要です。
端末が熱くて持てない、動作がカクカクするなど快適に動かないアプリは、ユーザー体験を著しくそこなってしまい、ユーザの離脱にもつながっていきます。
このような事態にならないためにも、アプリのパフォーマンスの計測を継続的におこない、
問題がある箇所を見つけて適切に対処すること重要です。
iOSアプリ開発ではInstrumentsなどを用いてパフォーマンスを計測することができますが、手動で計測しつづけるのは困難です。
今回は自分たちでCPU使用率と端末温度の計測を継続的に実施する仕組みをInstrumentsを用いて作成しました。
これらの仕組みを用意するために、CI/CDサービスをどうするか、どのように操作をし続けるかなど、様々な課題がありました。
また、運用していく中では、Instrumentsのデータの見づらさや想定外のクラッシュなどいくつもの問題が発生しました。
本トークでは、実際にiOSアプリケーションのCPU使用率と端末温度を継続的に計測する仕組みを作成し、運用している環境をどう実現したかに加えて「乗り越えた課題」、そして「残る課題と今後」についてより詳しく話をします。
プロダクトが成長するにつれて、アプリ品質向上とリリーススピードを高めることは難しくなっていきます。機能や画面が増えるにつれてマニュアルテストを続けるのは時間的なコストが上昇し、リリーススピードが落ちてしまいます。そこでE2EテストとしてUITestを導入し、テストを自動化する方法が考えられます。Apple標準UITestフレームワーク、XCUITestを検討する方も多いのではないでしょうか?
しかし、やみくもに大量の画面によるテストケースをコード化しても再利用性のないテストになることは明白です。また、XCUITestフレームワークの特性を理解し、適切にUIコンポーネントを操作するにはちょっとしたノウハウが必要です。
方法の一つとして、PageObjectデザインパターンを導入しテストコードと画面構成を切り分けましょう。実装方針をチームで話し合うのも重要です。一般に参照系のテストは実装が容易ですが、ユーザー状態を変更するUITestは実装が難しい場合があります。プロジェクトの性質によって適切な優先順位をつける必要があります。
このトークでは自社アプリにXCUITestによるUITestを導入した経験をもとにUITestの実装ノウハウを共有します。またUITest実装を進めるにあたってXCUITestのトリッキーな挙動もわかって来ました。
これらの問題の解決方法も合わせて共有できればと思います。
UITest導入と戦略と実践が学べ、UITest導入を検討している方にぴったりのトークです。
Swiftを用いたアプリ開発用にThe Composable Architecture(TCA)というのがあり、それがめっちゃ良いやん!と思うので紹介するトークです。
TCAは人間工学を考慮した一貫性のある方法でiOS(およびmacOS, tvOS, watchOS)アプリを構築するフレームワークです。
https://github.com/pointfreeco/swift-composable-architecture
TCAの良い点はRedux的にReducerを取り入れつつ、Reducerを画面ごとに用意し必要があればそれを別画面用に組み合わせることを前提としていることです。これによって巨大なグローバルなReducerを作ることはなく、Reducerを修正する場合に他の画面のコードを目にすることはありません。さらにロジックの繋ぎとしてうまくCombineフレームワークを使っているところも良い点でしょう。
Combineはリアクティブプログラミング(RP)フレームワークですが、他のRPフレームワークと同じオペレーターを使っても動作が異なることもあり、クローズドなフレームワークであることで不具合かどうか判断しづらいデメリットがあります。そのため、あくまで限定的にCombine利用するという点はTCAを使わなくても良い教材となるはずです。
SwiftUIを使ってどのような構成でアプリを作ろうかと考えている人にも参考になるトークとする予定です。
十分に発達した組織による開発では、本質的な機能間の疎結合化や逆コンウェイ戦略に則った組織構成への適応など、より高度な課題が様々出てきます。もちろんビルド・テスト時間の最適化といった個々の開発者の直接的な課題もその一つです。
どれだけアプリケーションアーキテクチャを洗練させ理解を進めても、これらの課題の解決は難しいでしょう。
そこでリードアーキテクトは、よりソフトウェア的なアーキテクチャを発展、また将来漸進的に進化できるように構成する必要があります。そのためには、構成要素を複数のモジュールに細分化し、組み換え容易にすることが重要です。
最近ではAndroidアプリ開発の流れか、2〜20ほどのモジュールからアプリを構築している所謂マルチモジュール化に挑戦しているチームも多くなりました。
これを更に発展させ、数百のモジュールからアプリを構築するためには通常の開発手法では無理が出てくるため、現担当プロジェクトではビルドツールにBazelを採用しています。
BazelはGoogleが開発し、iOSアプリ開発ではUberやLyft、Pinterestといったモバイルアプリに力を入れているテックカンパニーでも採用されている多言語向けのビルドツールです。
もちろんiOSアプリ開発への導入ハードルはかなり高いですが、効率的なモジュール定義や、CIマシンを含め開発者全員が同じキャッシュを共有するRemote Cacheなどの強力な機能も持っています。
このトークでは、モジュールを数百に細分化することでどのような利点があるのか、Bazelを採用することで何が可能になりどのような相乗作用があるのかをお話します。
クックパッドは「毎日の料理を楽しみにする」をミッションに、約20年前から料理のアイデアや工夫が流通する仕組みづくりに取り組んできました。現在も日本から世界中に広がる「プラットフォームをつくる」挑戦を続けています。
一方で、共働きの増加や核家族化、外食やデリバリーの普及など、毎日の料理を囲む環境は目まぐるしく変わってきています。
クックパッドはこれからの100年に向けて「レシピ」のその先にも取り組んでいます。
次の100年のスタンダードになる「食」の流通をつくるため、2018年に生鮮食品ECプラットフォーム「クックパッドマート」を開始しました。
「クックパッドマート」では今までにない仕組みで、毎日の献立づくり、買い物、調理すべてを変えることに挑んでおり、「新鮮で美味しい食材」を当たり前に安く買えるように、ゼロから食品流通プラットフォームの構築を進めています。
本セッションでは、クックパッドの新しい挑戦である「クックパッドマート」における開発や、既存の「レシピ」を組み合わせたまったく新しい買い物体験の実現、それらを支えるiOSアプリのアーキテクチャや SwiftUI の活用についてお話しします。
会計freeeについての紹介と、最近取り組んでいるiOS/Androidの横断的な課題を、Kotlin Multiplatformを使って解決しようとしている様子について、iOSの視点から紹介させていただきます。
・エンジニアから見たタウンワークアプリの特徴
・大規模サービスゆえの開発現場としての制限の話
・チャレンジ
デバッグモード(手動テストの効率化)
UIテストツール - レントゲン(UI自動テストの効率化)
クラッシュ率カイゼン(品質のモニタリングと対応)
100% Swift化(品質向上・開発コスト削減)
コンパイル速度カイゼン(開発コスト削減)
皆さんお馴染みUIColorは色データを記憶しているクラスですね。
色の名前やコンポーネント値を決定してUIViewに与えるだけの超単純なヤツ……
ではありません!UIColorがサブクラスを大量に持っているって知っていましたか?その数なんと18個(私調べ)!稀に見る大家族です。しかし我々がサブクラスを意識することはありません。UIColorのサブクラスは全てprivateで、表に出てくることはありません。
それにしても、18個もprivateなサブクラスを持つなんて、UIColorはどんな仕組みになっているのでしょうか?そもそもpublicなイニシャライザは10個だけ、メソッドも8個しかないのに何がどうなってるの??
本セッションでは、UIColorの構成を考察したり、ドキュメントにない細かい仕様を確認したりして、UIColorともっと仲良くなります。
【対象】
【トーク内容】
注:本プロポーザル中の数字はiOS13.5時点のものです。iOS14でイニシャライザが1つ増えそうだということは、つまり?
「ネイティブアプリで作ってよ」「それ、Webでよくない?」
ネイティブアプリ開発に触れることが多いエンジニアにとって「アプリを作ろう」という提案にはつい浮き足立ってしまうものですが、
一エンジニアとしては、Webとの比較を含めて適切な技術選定ができるようになっておきたいものです。
最近ではJavaScriptやブラウザの進化により、
Webページをアプリのように動作させることができたり、Apple PayなどのOS機能の一部をブラウザから動作させたり、
またiOS14ではアプリの一部をApp ClipsとしてWebから起動できるようになったりと、両者の関係はより複雑になってきました。
このトークでは非ゲームアプリを対象に、
従来ネイティブアプリでしか実現できなかった体験について現在のWebでの対応状況を整理するとともに、
App Clipsを含めたネイティブアプリとWebのそれぞれの使いどころや、組み合わせることで新たに生まれるユーザー体験について考えます。
予定しているトーク内容
アプリ開発における組織力学の話をします。
iOSアプリを構築する過程で、バックエンドAPIとの連携、デザインとの連携など様々なレイヤーとの相互作用が発生します。
そこには必ず人やチームが存在するため、必然的に「組織構造をどうするか」「どういう開発の流れを作っていくか」という組織構造の設計や、その中を流れる開発プロセスを同時に思考していく必要があります
アジャイル型の開発だとしても、各レイヤーの構築スピードが異なるため、結合のタイミングやMVPリリースのタイミングを計ったり、各レイヤー同士がどこまでレビューに介入するべきかなどを設計しないと、生産性のバランス崩れや意思決定の遅延、開発リードタイムにも大幅な影響を与えてしまいます。
ここを解決するためには、個々が対応するのではなく大規模な組織開発になればなるほど、根本的な組織構造から生まれる力学(バリューストリーム)を丁寧に作り上げる必要があります。
今回は、iOSアプリを開発する中で見えてきた、生産性のバランス可視化や意思決定プロセスの構築、開発体制の整備などあらゆる課題を解決するために行った取り組みについて事例を交えながらお話できればと思います。
皆さんはSwiftで書かれたソースコードを解析したことがありますか?
SwiftではSwfitLintが静的解析ツールとして有名です。
SwiftLintを導入しているプロジェクトも多いと思います。
しかし、決してSwiftLintだけが静的解析ツールではありません。
Java向けのIDEであるIntelliJはこの静的解析の技術をフルに活用しています。
IntelliJで開発をしたことがある人は、この技術がいかに我々の開発を効率化させるか実感したことだと思います。
様々な静的解析を用いたツールが提案されていますが、その恩恵の多くはJavaなど他の言語を対象にしているものが多く、Swiftを対象にした静的解析ツールはまだまだ少ないです。
この発表ではSwiftのソースコードを解析するSwiftSyntaxを用いて、実際に静的解析ツールを実装し、解説していきます。
静的解析の技術を身に付け、より発展的な静的解析に挑戦してみませんか?
SwiftUI、ワクワクしますね。
ところで残念ながらら、まだまだ UIKit で戦わなくてはいけないエンジニアもたくさんいるのだ。
そしてその中に、ビューの変形に CGAffineTransform を使わなくてはいけないエンジニアもまだまだたくさんいるはず。
CGAffineTransform は微妙に分かりにくいものだ。確かに scale や rotate などの比較的に分かりやすいイニシャライザがたくさん用意されているが、それが実際どう動いてるのかがわからない。組み合わせてみたら思ってるのと挙動違うし、プロパティーを確認してみてもよくわからない a b c d tx ty しか出てこないし。設定した scale や rotate は一体どこに消えてるの?
このトークは、そんなあなたのお悩みを解決する。大丈夫難しい話ではない。必要なのは四則演算の知識だけだ。
1年前ほど前に観たUberのエンジニアによる"Code Generation"(以後「自動生成」と記す)に関するセッションに影響を受け、みてねのiOS開発でも自動生成(Sourcery + Stencil)を取り入れました。
まずユニットテストを効率良く書けるようにするための「テストデータ」の自動生成というものを行いました。
これが思ったよりもチーム内で受け入れられて、今ではなくてはならないものになりました。
その後、チームの他のメンバーが「DI」まわりで自動生成を用いた素晴らしいアウトプットを出してくれました。
他にもまだまだ自動生成したいものがたくさんあります。
このようにみてねのiOS開発ではチームとして自動生成を絶賛活用中なので、その知見を以下のような項目で話せればと思っています。
実際の活用例(テスト、DI)
実装方法
1年ほど運用してみて(ハマったことや、チーム内における知見の共有など)
自動生成のpros/cons(例えば外部ライブラリを利用するという選択肢との比較)
みてね = 子供の写真や動画を家族内で共有するアプリ
人工知能技術の発展、および端末の性能向上の発展により、物体の判別や自然言語処理などiOSの様々な可能性が広がってきました。これらの技術の延長線として、我々が備えているものと同等の知能をいつかiOSアプリは宿すのでしょうか?
ヒトなどの動物が備える天然の知能にあって、現状のAIに欠けているものを2つ挙げるとすると「自律性」と「汎用性」が考えられます。
自律性についてですが、現状のAIは特定の問題をヒトが設定し解決するためのツールとしての使い方が主流です。それに対して、我々動物が持つ知能は環境から独立し、相互作用する自律性を備えています。
汎用性に関してですが、限られた状況においてのみ高い能力を発揮するのが、現状のAIです。砂漠から北極圏、都市での生活まで広く適応可能なヒトの知能には、まだまだ遠く及びません。例えばクジラの消化管にのみ適応した寄生虫のように環境を限定することで生き残った動物もいますが、高度に進化した動物の知能は、様々な環境に適応できる汎用性を備えています。
iOSアプリがこのような自律性と汎用性を兼ね備えるためには、何が必要なのでしょうか。1つ考えられるのは、「内部世界」です。我々の脳は常に情報が循環し複雑に流れる内部世界を持っています。iOSDC2019ではこのような複雑な流れを簡単にシミュレートするプログラムを公開しました。もう1つ考えられるのは、「感情」です。動物は、美味しい、美しい、心地よいなどのポジティブな感情を多く得られるように、痛い、醜い、苦しいなどのネガティブな感情を避けるように行動します。AIが自律性を備えるためには行動の指針が必要なのですが、この感情のような仕組みを模倣できればそのような指針になるでしょう。今回の発表では前回の「内部世界」のシミュレーションを踏まえ、アプリへ感情のようなもの?を導入しようとする試みについて話します。
WWDC2019でSwiftUIが発表されました。WWDC2020でもSwiftUIに関するセッションがいくつもあり、AppleがSwiftUIに注力していることが伺えます。SwiftUIはiOS 13以降で利用できるということもあり、既存アプリの運用保守では現段階ではまだ導入できないでしょう。
ですが、iOS 14から導入されるWidgetがSwiftUIのみで開発できるということもあり、今後、SwiftUIに触れる方も多いと思います。
そんな中、私が担当したアプリは新規アプリということもあり、SwiftUIとCombineを採用しました。実際にSwiftUIでアプリを開発してみると、機能が不足しており、SwiftUIだけでアプリを完結させるのは難しいといいうことがわかりました。
そのため、弊アプリではSwiftUI×UIKitという選択をして、SwiftUIはUIコンポーネントの実装に利用し、画面遷移はUIKitを利用するという設計にしました。
本トークでは弊アプリで選択した設計の説明と、この設計で解決した問題について説明します。
あなたは新しい新機能を開発しているとします。
プロダクトマネージャーから「新機能を含んだアプリがインストール済みだったら、アプリを起動して、未インストールだったら、ストアのインストールページ、または、 特定の Web サイトを開いてほしい」と言われたら、どうしますか?
iOS SDK に含まれる Universal Links や URL Scheme を利用して、アプリバージョンで分岐すれば良さそうと、まず、思いつきますよね。
でも、 Universal Links には同一ドメイン上の URL 遷移では起動しないという制限があったり、 URL Scheme はセキュリティ上の懸念があります。
この 2 点の問題を解決しつつ、当初の要件を満たすことが出来るのが Firebase Dynamic Links です。
本トークでは既存アプリへの Firebase Dynamic Links の導入経験から以下を話す予定です。
SwiftのWebAssembly対応を進めることを目的にした、SwiftWasmというプロジェクトがあります。このプロジェクトはこの1年で大きく前進し、現在では簡単なWebアプリケーションがSwiftで開発できるようになりました。
このトークでは私がSwiftWasmプロジェクトに参加してから実際に行なってきた、Swiftへのコントリビューションとその過程についてお話します。