はじめまして。
R&Dチーム所属、20新卒の葉山といいます。
入社して4ヶ月ほどはTensorRTによるMultiple Object Trackingの高速化を行っていたのですが、最近は心機一転iOSアプリの開発をやらせていただいています。
今回は、iOSアプリの開発経験が全くのゼロだった私が、この2ヶ月で実際のタスクをこなしながら学んできたことをピックアップしてまとめていきたいと思います。
ライフサイクル
まずはiOSアプリケーションの全貌(?)を掴みたかったので、アプリケーションのライフサイクルについて確認しました。
アプリケーションのライフサイクル(Apple公式ドキュメント)
また、各々の画面を構成するViewControllerのライフサイクルも確認しました。
上記の資料を参照しつつ、既に実装済みのアプリのプロジェクトと照らし合わせることで、大まかな構成を理解することができました。
Swift関連
Optional
Swiftに関してまず最初に勉強したのが、Optionalについてです。 Optionalに関しては日本語で解説されている記事が沢山ありますので、それらを参考にさせていただきました(以下はその一つ)。
最初は適切なOptionalの使い方がわからず苦戦しましたが、慣れるにつれて非常に強力な言語機能であるということがわかってきました。
PromiseKit
非同期処理を行うPromiseパターンは、SwiftではPromiseKitにより利用することができます。 PromiseKitに関しては公式のドキュメントの例を参考にするのが一番良いかと思いますが、折角なので自分がまとめた内容から基本事項+αを以下に紹介させていただきます。
PromiseKitの基本的な使い方
非同期処理を行う場合、その戻り値をPromiseでラップして次の処理に渡します。複数の非同期処理をクロージャを用いてチェインさせることができます。
これにより、「前の処理が完了した後に次の処理を行う」というふうに複数の非同期処理を順番に実行することが可能です。
以下が典型的な例です。
hoge().then { foo in
// fooを使う
return fuga()
}.done { bar in
// barを使う
}.catch {
// エラーは全てここにたどり着く
}
hoge()やfuga()はPromiseを返します。
PromiseとGuarantee
PromiseKit 6ではfailを起こさないPromiseとしてGuaranteeが用意されており、使い分けることができます。
例として、after()は指定秒のwaitを実行しますが、failすることがないのでGuaranteeを返します。
firstly {
after(seconds: 0.1)
}.done {
// failしないのでcatchはできない。Guaranteeが返ってくる。
}
then, done, map
Promiseパターンのチェインを構成する基本的な要素に、then、done、mapがあります。
これらの使い分けは以下のようなイメージです。
then:Promiseを受け取って、Promiseを返すとき
done:Promiseを受け取って、何も返す必要のないとき
map:Promiseを受け取って、Promiseを外した中身のobjectを返すとき
他にも、tap、get、最初の例で出てきたcatchなどがあります。
複数のPromiseを処理する
whenを使うと、複数のPromiseが完了した際の処理を実現できます。
firstly {
when(fulfilled: operation1(), operation2())
}.done { result1, result2 in
//…
}
ただ、恐らく並列に処理されるので、逐次的に処理したい場合はwhenでは難しいかと思います。
cauterize
これはTipsですが、「catchが可能だがする必要がない」ことがわかっているとき、最後にcauterize()をすればwarningを消せます。
(ドキュメントのQ&Aで目立たず書かれているので、ここで紹介しておきます。)
hoge().tap { result in
// エラーハンドリング済み
}.cauterize()
PromiseKitも最初こそ学習コストがありますが、一度慣れてしまえば非同期処理を書くための非常に強力なパートナーになりますね。
SwiftではPromiseKitの他にも、非同期処理に便利なフレームワークとしてRxSwift(OSS)やCombine(iOS13以降で導入、Apple公式)などがあります。
これらの特徴や使い分けについても今後勉強していきたいです。
Sentry
Sentryはアプリケーションのイベントログを収集するツールです。
Sentryに関しては、同じくR&Dチームの中村が当ブログで解説記事を書いているので、是非ご覧ください。
Sentryは導入&利用が比較的簡単でありがたいですね。
fastlane
fastlaneは、主にリリース作業の自動化を助けてくれるCUIツールです。 ビルドのアップロード、証明書の管理、スクリーンショット生成、Slackへの通知などなど...、自動化に必要な様々な処理が実行できます。
Sentryとの連携
私が開発を行っているプロジェクトでも初期からfastlaneを利用していました。開発チームにjoin後、私が追加した部分としては上述のSentryとの連携です。その内容を以下に紹介します。
まずは次のプラグインをgemで追加します。
gem 'fastlane-plugin-sentry'
Sentryでは、クラッシュログのシンボル化(Symbolicate)のためにデバッグシンボル(dSYM)をアップロードすることが必要です。
以下のように、download_dsymsアクションとsentry_upload_dsymアクションが利用できます。
download_dsyms(version: {バージョン番号}, build_number: {ビルド番号}, wait_for_dsym_processing: true)
sentry_upload_dsym(auth_token: {認証トークン}, org_slug: {Sentryの組織名}, project_slug: {Sentryのプロジェクト名})
wait_for_dsym_processingは、dSYMの生成を待つためにtrueにしておいたほうが安全かと思われます。
また、以下のアクションによりSentryにReleaseを作ることができます。
sentry_create_release(
auth_token: {認証トークン},
org_slug: {Sentryの組織名},
project_slug: {Sentryのプロジェクト名},
version: {バージョン番号},
app_identifier: {バンドルID}
)
おまけ
スクラム開発
iOSアプリの開発とは離れますが、スクラムも今の開発チームにjoinして初めて経験していることの一つです。
スクラムについては、Optimal Bizチームの伊藤が当ブログで記事を書いているので、是非そちらもご覧ください。
(プランニングポーカーおもしろい)
終わりに
iOSアプリ開発を2ヶ月経験してみた所感として、開発環境の変化が多いんだなということを感じました。
というのも、iOSアプリ開発に関する情報を探している際に、既に古くなった情報に出会う機会が多かったからです。
これはやはり、言語仕様や開発様式、はたまたAppleの審査内容などが、WWDCを機に1年ごとにアップデートされているからなのだと思います。
私も、今後も知識の更新を心掛けていきたいと思います。
今回は、私がこの2ヶ月でiOSアプリ開発について学んだことからピックアップしてご紹介しました。
一つでも参考になる情報をお届けできていれば幸いです。
OPTiMではクライアントアプリの開発に興味があるエンジニアも募集しています。
よろしければ、こちらの採用情報もご覧ください。