iOSアプリを作るときのおすすめ構成
2017年末版
今からiOSアプリを作るとしたら、どんな構成がおすすめかについて、僕なりの見解(全体的にまあまあスタンダードなものかなと自覚しています)をつらつらと書いて行きます。
似たものとして、Youhei Sugigami さんが2015年8月に書かれた記事がありますが、当時2016年8月ということでSwift 2時代で、実質2世代前となっているので、今のタイミングで改めて僕なりに書いて見るのも良いかなと思いました。
iOSエンジニアのみなさん、こんにちは!WantedlyでiOSアプリ開発を担当してます、杉上です。 このブログでは新規でiOSのアプリ開発を開始するなら、どうなふうに作ろうかなと妄想してみました。なかなか仕事の現場では新規アプリ開発の…www.wantedly.com
また、人それぞれ見解が多少異なると思うので、同じタイミングであろうとも色々な方が書かれてみるのも面白い題材かなとも思っています( ´・‿・`)
それではiOSアプリ開発に必要な要素ごとにつらつらと書いていきます。それぞれ語りすぎるとボリュームが増えすぎるので、あえてなるべく浅めに書いていきます🐶
高性能なMacマシンを確保
まず、技術的なこと抜きに一定以上の性能のMacマシンを用意するのが良いです。取っ掛かりの勉強目的などならともかく、中規模以上のアプリを作る場合低スペックマシンでは著しく非効率です。
大体以下のようなイメージで、これ未満だと早めにマシン変えた方が幸せになれると思っています。
- 2–3年以内に買った20万円以上程度のMacBook Pro: 許容範囲
- iMac 5K: 良い感じ
- iMac Pro: 一般的なiOSアプリ開発ではオーバースペック気味でコスパは微妙かも🤔
会社で、交渉しても低スペック環境を強いられるのならば転職した方が良い気がしています🤔ちなみに転職ドラフトでSWHGという招待コードで登録するとお互いプロテインゲットできるので、気が向いたらお願いします( ´・‿・`)
Continuous Integration(CI)環境
次に、CI環境について触れます。CI環境構築は、ひと段落したところで整えることになりがちですが、早めに構築する意識が大事だと思っています。リポジトリ作って新規プロジェクト作ったら、即構築しても良いくらいに思います🤔
こちらの記事にも同じことが書かれていますね👀
今年でAdvent Calendarに参加するのは3年目。 今年は新規 アプリ開発 についてです。 仕事で何度か新規で iOS アプリを開発することがありました。チームやそのときの状況に応じて柔軟に対応するのがベストですが、その中でもや…nsblogger.hatenablog.com
iOSのCI環境構築は数年前まで難易度高めで工数もかかりがちでしたが、最近は以下の便利なサービス・ツールがあるので、比較的楽に組めるようになっています(とはいえ初めてだとけっこうつまずくとも思いますが)。
- 主なCIサービス: Bitrise・CircleCI・Travis CIなど
- CI支援ツール: fastlane
個人的なオススメは、Bitriseです。後発かつモバイルアプリ(iOS・Android・Xamarin・Ionic・Cordova・React Native)に特化しているためか、使いやすいです。Bitriseを使う場合、大きく次の2通りの方針があると思っていて、僕は最近は後者にしています。fastlaneとBitrise、どちらにロックインされるのを好むか次第かなと思います(ちなみにどちらもOSSです)。
- Bitriseのstepは最小限にして、主な処理はfastlane実行で行う
- Bitriseのstepメインに組む
後者の場合、一見Bitriseがダウンした時・サービスが終わった時など困りそうに思うかもしれませんが、Bitrise CLIでローカル実行もできるので、その点もあまり問題ないです。また今夏に約3.5億円の資金調達もするなど、順調そうなのでサービスが終わるなどの心配はしばらくは杞憂だと思っています🤔
また、Xcode 8からAutomatic Signingが導入されていますが、fastlaneはそれとの相性が微妙な一方、Bitriseはまあまあ相性良くさらに最近それがさらにやりやすく改善されたので、そういう面でもおすすめです。
(fastlaneでは仕組みは異なりますが match でこのあたり楽にできます。)
Yes, you read that right: iOS provisioning, automated. On Bitrise. 🎉blog.bitrise.io
一方、fastlaneもまだbetaながらRubyだけではなくSwiftでも書けるようになり、こちらも注目です👀 同じコンセプトの kdawgwilk/Autobahn というものもあったのですが、本家で対応されるともうお役御免な感じですかね🙏
そういえば最近どのCIサービス使っているかアンケート取ってみたので、参考にどうぞです:
アプリ配布
また、CI環境でなされる処理としてはアプリ配布がありますが、今は次の構成がスタンダードだと思います。どちらもとても簡単です。
- AdHoc版をFabric Betaで配信
- TestFlight版をiTunes Connectで配信
プロジェクト構成
次に、アプリな基本構成ですが、中規模以上のアプリはEmbedded Frameworkを使って適当にモジュールを分けることをおすすめします。次の記事は2年前のものですが、今もほぼそのまま通用する内容だと思っています。
iOS 8・Xcode 6から、 Embedded Frameworkが使えるようになりました 。 その導入法について書かれた記事などはよく見かけます("ios embedded framework" でググってください)が、実践的な説…qiita.com
モジュール分割粒度はなんとなく3–5つくらいが適度かなと思っています。設計的には本来もっと細かくしたくもなるところですが、モジュール数が増えすぎると起動時間が遅くなる問題があります。ただ、この問題が特に顕著なのは、端末再起動・アプリをしばらく使っていないなどでモジュールのキャッシュがクリアされてしまっている時の起動時間であり、常用しているアプリを再起動する時などは大抵モジュールのキャッシュが効いているためこの影響は少なく特に遅く感じません。そのため個人的には、起動時間問題はそこまで気にしすぎないようにしています(ユーザーとしても常用しているアプリが毎回起動時間長くてストレスに感じること無いので)。
設計的には本来もっと細かくしたくもなるところですが、モジュール数が増えすぎると起動時間が遅くなる問題があります。
ちょっと蛇足ですが、Swift Package Manager(SwiftPM)でCLIツール作ったりサーバーサイドSwiftの場合はこのあたり問題にならないので、モジュール分割粒度が細かくなる傾向があると思います。
サポートiOSバージョン
また、どの版までのiOSバージョンをサポートするかどうかもその後の開発効率に関わってくるので大事です。セオリーはAppleが推奨している直近2バージョンサポート(iOS 11が最新の今ではiOS 10以降サポート)だと思っています。直近2バージョンサポートすれば概ね95%くらいほユーザーはカバーできます。ただ、もっと低くても開発効率上げたいと思えれば最新バージョンのみのサポートでも良いですし、逆にその5%をカバーするメリットが大であれば開発コストが増大するのを許容してその判断するのも十分ありだと思っています。要はユーザーカバー率による損得勘定を冷静に判断するのが大事です。
ただ、現最新版であるiOS 11の事情考慮すると、iOS 10と11では特にUI周りでSafe Area筆頭に差があり、iOS 10を切るとけっこう楽になるので、特に今から作る新規アプリではiOS 11以上とする判断はけっこう良いのではと思っています(僕が今開発中の新規アプリもそうしています)。この判断はOSバージョン間によって差があって、例えばiOS 9と10では通知APIの差が気になる程度でそれ以外あまり9を切りたくなる動機無かったですが、iOS 6と7みたいにフラットUI化したタイミングでは両対応の手間がかなり大きく古い版を切りたいと強く感じました。
また、新規では直近2バージョンのサポートなどとしても、毎年秋のiOSメジャーアップデートのタイミングで潔く古いバージョンのサポートを切れずにズルズルサポート続けてしまい少しずつ開発負荷が高くなっていくこともありがちなので、古いバージョンを切れないか継続的に判断していくのも大事です。
まとめると、こんな感じですかね。
- セオリーは直近2バージョンのサポート
- 3バージョン以上のサポートも合理的な判断がなされていれば十分ありだと思う
- バージョン間の差が大きくてそれが工数増に繋がる場合、特に新規アプリでは最新バージョンのみのサポートもありだと思う
ライブラリの導入方法
ライブラリの導入方法としては、以下などがあって、Carthage・CocoaPodsを使うことが大半だと思います。
- Carthage
- CocoaPods
- Git Submodule(Subtree)
- 直接ソース追加
個人的には、CocoaPodsでプロジェクトファイルを弄られてしまうことに起因するトラブルが多くて、なるべくCarthageに統一したいところなものの、CocoaPods使わざるをえないメジャーなSDKがけっこうあったりして悩ましいです 🤔
また、CocoaPods・Carthageでインストールした成果物をバージョン管理に含めるかも色々流派があり、そのあたりは次の記事で書きましたので、ご参考に:
以下のTwitterアンケートを見かけたので、記事書いてみました。 結果は、母数が10人なので参考程度にするのが良いと思いますが、僕も多数派の「CocoaPodsもCarthageも含めている」を特に迷い無く選択しています。 【iOSア…qiita.com
UIの組み方
次にUIをどう組むのがオススメかについての僕の見解を書いていきます。
1 Storyboard — 1 ViewController
StoryboardはXcode 4.2から導入され、それまでのXib(Nib)に比べて画面遷移なども表現できることが主なメリットとして挙げられていますが、1 StorybaordにたくさんのViewControllerを詰め込んでいくと、次のようなデメリットが出てきます。
- 複数人開発でコンフリクトが多発
- 重くなる
- 一覧性が微妙
なので、最近は1 Storyboard — 1 ViewControllerにするのがスタンダードに感じていて、僕もけっこう前からそうしています(関連性の高い数画面を1 Storyboardに入れることもありますが)。
こうすると、StoryboardのSegueでサポートしている画面遷移をどうするのかということになりますが、次のいずれかをすれば良いだけで困りません。
- 普通にコードで書く
- Storybaord Reference (Xcode 7以降) を利用
僕はSegueのメリットが理解できないのでほぼ使わずに、画面遷移は基本的にコードで書いています。
また、ViewControllerはXibでも組めますが、StoryboardはXibの上位互換なのでStoryboardを使った方が良いです。
UIをStoryboard・Xibで組むかコードで組むか
UIをStoryboardで組むかコードで組むかは、度々話題になりますが、僕は以下がスタンダードだと思っていて、そうしています。
- Storyboardで書けるものはそちらで書く
- Storybaord上では不可能な計算が必要だったり動的に動かしたりするものはStoryboardで定義した
NSLayoutConstraint
をIBOutlet
として持ってきて値を書き換え - コードで定義しないと表現できない(あるいはとてもやりにくい)ものだけはコードで定義(この場合、Xibを複数作って条件によって出し分けというパターンも有効)
Storyboard上で色々設定する煩雑さなどはあるものの、設定した拘束群が結果どうなるかを、アプリ実行前にStoryboard上で視覚的に確認できたり警告が見えるというメリットは大きいです。特に Priority
を弄り出すと、コードで書く場合は実際にどうレイアウトされるのかをビルド前になかなか自信を持ってイメージできないです。
とはいえ、すべてコードで書く方がすべての定義が表に出て分かりやすいという感覚も理解できます。また、コードで書いてPlayground上で描画するとStoryboard上で書くのと同様なメリットが享受できるので、これもありかなとは思っています(僕は実際にこれで開発を進めたことはないですが) 🤔
また、Auto Layoutはこの本がオススメです。Xcode 7時代のものなので、Safe Areaなどカバーできてないところがありますが、Auto Layoutの肝となる部分は当時と変わらず今でも十分通用する本です。
Amazon配送商品ならよくわかるAuto Layout iOSレスポンシブデザインをマスターが通常配送無料。更にAmazonならポイント還元本が多数。川邉 雄介, 所 友太作品ほか、お急ぎ便対象商品は当日お届けも可能。www.amazon.co.jp
特に、UIStackView・サイズクラス・トレイトや、トルツメパターンなどについて少しでも不明点あれば一読オススメします。
とりあえずFirebase
そろそろおすすめライブラリなどの話に移っていきたいところですが、その前にFirebaseに触れます。
実はここ1・2年のアプリ開発で大きく情勢が変わったのは、Firebase周りでは無いでしょうか。ざっとここ3年ほどの流れをまとめてみました。
- 2014/10: GoogleがFirebase(リアルタイムデータ同期サービス)を買収
- 2015/05: Google I/O 2015にて、Firebase Realtime Databaseのオフラインサポート
- 2016/05: Google I/O 2016にて、FirebaseがmBaaSとして大進化(Authentication・Analytics・FCMなど対応)
- 2017/01: GoogleがFabricを買収
- 2017/03: Cloud Functions for Firebaseリリース(β)
- 2017/05: Google I/O 2017にて、Fabric統合など
- 2017/10: Cloud FirestoreというRealtime Database後継と言える、Googleのインフラが活用された強力なリアルタイムデータベースをリリース(β)
この間、2016年1月にFacebookの買収されたParseというmBaaSが1年後にサービスを閉じることがアナウンスされて、mBaaSの本命的なものが不在になりました。ところが、Firebaseのここ1・2年の怒涛の展開でParseをもずっと上回る圧倒的な完成度のmBaaSとして育ってくれて、アプリ開発者として、とてもありがたいです🙏
サーバーサイドとの兼ね合い次第ではありますが、特に新規で作る場合は次の要素はまずFirebaseで済まないか検討するのが良いと思います(そして、大変良くできているのでFirebaseで済むことが多いと思います)。
- 認証
- アナリティクス
- データベース(RDBとは違うので完全に頼れるかはサービス次第)
- ストレージ(画像アップロードなど)
- クラッシュレポート
- プッシュ通知
- パフォーマンス計測
- ABテスト
- Universal Links(サイトのコンテンツと1対1対応させたい場合には不向き)
- 広告
Fabricを買収したこともあり、アプリ配信もそのうちFirebaseでできるようになる気がしています 🤔
ちなみに、今開発中のアプリではサーバーサイドは今のところすべてFirebaseで済んでいます(後々、要件が増えてきたらGAEなどで拡張もあり得るかも?とも思いつつ)。
ライブラリ選定
次にライブラリ選定です。
前提として、最近はSwiftの言語機能・表現力も上がり、また標準ライブラリもちょくちょく良くなってきているので、以前と比べてライブラリの必要性は減ってきていると感じます。なので、下に挙げたものは使わずに自前で書くという選択肢もありです。ライブラリを使わないと自分で書くコード量は多少増えるものの、ブラックボックス部分が減って(もちろんOSSだとソースは確認できますが常に全行把握しているわけではないので)、むしろ書きやすくなることもあるかと思います。
各種リソースアクセスへの型付け
各種リソースへの型付けには Mathijs Kadijkさん作の R.swift がオススメです。
主に次のような流れで使いますが、共通的な処理はコードジェネレーション側で Rswift
フレームワークとして参照されるようになっているので、ライブラリとしてのインストールも必要です。
- プロジェクト内のリソース系ファイルを元にコードジェネレーション
R.
で各種リソースにアクセスして使用
僕はこういうコードジェネレーション系は利用に少し抵抗があったのですが、リリース後3年経って枯れてきていて(とはいえ開発もまだまだ活発)、評判も良いのでわりと最近使い始めて、使い勝手良くとてもオススメだと思っています。
Xcode 新機能への追従もとても早いです 👏
類似ライブラリとしては、 SwiftGen があります。
Lint
Lint系ツールは、SwiftLint一択ですね。未だに機能追加が活発で、アップデートすると新しい警告が増えていたりします( ´・‿・`)
デフォルトではたまに余計なお世話に感じる指摘もあるかもしれませんが、それは無効化すれば良いだけなので、必要な部分だけうまく活用すると良いのではと思います。
Homebrewでもインストールできますが、CocoaPods経由でインストールすると複数人開発でバージョンを合わせやすくなり、そちらがオススメです。
swiftlint autocorrect
を実行すると、可能なものについては自動修正してくれるので、特に初回導入時はまずこれを実行すると良いです。 Build Phases
での実行も autocorrect
オプション付きで良いかも?と思ったものの、ビルド中にコードを変更するとその変更と autocorrect
による変更が競合してどちらを優先するかのダイアログがちょくちょく出るので、現状ではおすすめしません。
ちなみに、XcodeのFix All Issues機能はXcode標準で検出される警告が対象なので、SwiftLintで発生した警告の一括解消目的( autocorrect
目的)には使えません🙅♀️
非同期処理
非同期処理の絡むメソッドはベタに書くと、結果通知はコールバック形式になり、それが連続するとそのネストが深くなって可読性・メンテナンス性が著しく落ちていくため、中規模以上のアプリではその解決は必須だと思っています。
その解決となるライブラリはいくつかありますが、 ReactiveX/RxSwift が最もポピュラーです。RxSwiftを導入して使いこなすと、上で書いた課題の解決以外にも様々な利点がありますが、個人的には特にMVVM支援系機能などは特に使っていません(iOSアプリ開発においてバインディング機構が公式にサポートされたものでは無くあまり使い勝手良く感じないなどの理由により)。
また、Rx(Reactive Extensions)は2009年にMicrosoft Researchが公開したのが初出で、2011年くらいには.NETでは普通に使われ始め、その後基本的な概念はそのままに各種プラットフォームでのライブラリも充実してきたという経緯もあり、とりあえずこれ覚えておけば汎用的な知識が身に付くという印象があります(僕自身2012年頃にC#で触れててこれは良いなと思ってたものがSwiftにも来て迷わず飛びついた感じでした)。
類似ライブラリとしては、 ReactiveCocoa/ReactiveSwift などあります。
ネットワークアクセス
ネットワークアクセスライブラリは、なんとなく世界的にはMoya( Alamofire に依存している)が定番な気がしています 🤔
個人的には、 APIKitを好んで使っています。以前はレスポンスのJSONデコード処理にHimotokiを組み合わせて使っていましたが、Swift 4で導入されたCodableによって大抵のケースでは不要になりました。
ただ、APIKitは最近かなり開発頻度が低下していて最低限の言語アップデート対応程度しか行われていない状態で、今後の機能改善などはあまり期待できないかもしれません 🤔 そのため、今から選ぶのにどれがオススメかと言われると、難しいです。
URLSessionが使いやすくなってきたので、すべて自分で書くのも十分ありかなとは思いつつ、結局APIKit相当のことを書くようなことになるので、その手間はなるべく少なくしたいところではあります 🤔 なので比較的シンプルにそのあたりを解決してくれるAPIKitはやはり良いものだなと思っています。
また、ネットワーク状態をチェックする時はashleymills/Reachability.swift も合わせて使っています。オフラインでAPIアクセスしてもオフライン系のエラーが帰ってくるので最低限それでもなんとかなりますが、ネットワーク状態を前もって把握することによってスムーズなハンドリングや最適なUI表示ができます。
画面遷移
ルーティングライブラリとしてはhyperoslo/Compassが定番だと思います。パスに対応するenumを switch-case
でハンドリングしてどの画面にどう遷移するかを補助するライブラリですね。
今月あがっていたこの記事の説明が良い感じです:
また、 AppDelegate
の window
の rootViewController
の取り扱いも大事で、これまた最近あがっていたこの記事の説明が良いです。
How to switch between the application parts and handle launch options.medium.com
y.imajoさんの次のスライドも併読すると理解しやすいかと思います。
個人的には、 まずrootViewController
の取り扱いが最重要で、さらに良い感じのルーティング処理も組み合わせてディープリンクハンドリングしやすくするとベター、みたいな感覚でいます。
Auto Layout
前述の通り、UIの実装はStoryboard・Xibをメインとするのがスタンダードだと思っています。それでも、コードで書く必要に迫られることはしばしばありますが、その際はNSLayoutAnchorの使えるiOS 9以降ではライブラリ使わずに普通に直書きするのが良いと思っています。以前、SnapKitを使って書いていたコードをNSLayoutAnchorで直書きするように書き換えましたが、コード量はほとんど増えず、またライブラリ不使用の方がAuto Layout概念と1対1対応するので自信を持って書ける感がありました。
『アプリ道場 Advent Calendar 2015』3日目は「三度の飯よりAuto Layoutが好き」(いや...そこまでは無理か...)な、ゆこびん(@yucovin)です。 そもそもイラストレイター兼デザイナーなので、アプリの…qiita.com
ただ、NSLayoutAnchorは以下の処理を忘れるミスをしがちなので、そこは十分気をつけるかあるいは薄いラップ関数を書くなどはした方がベターかもしれません。
- UIViewのtranslatesAutoresizingMaskIntoConstraintsをfalseにする
- NSLayoutConstraintのisActiveをtrueにする
僕は自作の mono0926/AutoLayoutExtension を使ってそのあたり解決しています。
画像URLの取り扱い
次に、UIImageViewなどで表示する画像のURLの取り扱いです。サーバーとのやりとりが発生するアプリでは、大抵は画像のURLを元に非同期でそのデータを取得してUIImage化してセットするという処理がなされていると思いますが、それを簡易に書けるライブラリを使うと便利です。
Objective-C時代はrs/SDWebImage一択な感覚でしたが、Swiftでは初期にそのSDWebImageをほぼベタにSwiftに書き換えたようなonevcat/Kingfisherが登場し、人気を博しました。僕も以前SDWebImageからKingfisherに乗り換えてみたのですが、単純な書き換えで済んだと思いきやそれまで動いていたものにバグが出たりしてその解決にかなり時間を要したり、またソースを見てもあまりSwiftぽい感じではなく微妙な印象でした。
そんな中、他に良いの無いかなと思っていたときに教えていただいた kean/Nuke が最高でした。
コードも綺麗でバグも特に気にならないです(あってもスマートにサクッと直してもらうか自らできそう)。kean/RxNukeなどの拡張もあって、それらとの組み合わせも良い感じです。
画像を非同期取得してセットするくらいならわざわざライブラリ使わずとも自分で書いて済ませて良いのでは?と思うかもしれませんが、キャッシュとか色々細かいところ考慮するとライブラリ使うのが得策だと思っています。キャッシュ周りの制御、ライブラリによって差がある気がしていますが、Nukeはデフォルトであるべき姿の実装になっていると感じています。
Caching is a great way to improve application performance and end-user experience. Some popular iOS libraries try to…kean.github.io
ローカルデータベース
主にWeb APIレスポンスをローカルで保存しつつ取り回すために、ローカルデータベースが用いられることがあります。かつては基本的にCore Data使うシーンでしたが、ここ数年はRealmが人気です。
新規アプリではRealmが選ばれることが多いかなと思っていますが、Core Dataもまあまあ良いと思っています。
2年前にこういう比較記事書きました。
(当時からそれぞれ進化ありますが、それには追従できていないので注意してください。)
今まで3年くらい Core Dataを使っていましたが、 JOIN USを引き継ぎ、バージョン3.0として作り直すタイミングで、初めて Realm を使ってみました。 色々思うところがあったので、それについて書きます。 特にRealmに…qiita.com
また、前述のFirebaseにFirestoreというドキュメント指向データベースが加わりましたが、それをリアルタイム同期可能なローカルデータベース感覚で使うというのもあり得ます。
2017年10月3日に、GoogleからFirebase Realtime Databaseの後継にあたるCloud Firestoreが発表されました。medium.com
僕は今新たに開発中のアプリではCore Data・Realmを使わずにFirestoreだけで済ませています。
(FirestoreあればCore Data・Realmが不要というわけではなくアプリ要件次第です。)
Keychain
Keychainは KeychainAccess一択ですね。
KeychainAccess - Simple Swift wrapper for Keychain that works on iOS, watchOS, tvOS and macOS.github.com
ただし、前述のFirebaseのAuthenticationを使う場合、Keychainを直接触れずに済むも多いです。なぜなら、Keychainは、主に access token
やアカウント情報というセキュアな情報を格納する際に使われますが、それらはFirebase Authenticationの内部でなされるからです。Firebase SDKを使うときはもちろん、別途自前のAPIを叩くときもそれがFirebase Authenticationのtokenを使う方式で組んであれば同様です。僕が今新たに開発中のプロジェクトではそういう構成になっているのでKeychainAccessなどは使っていません。
Firebase Authenticationについては、以前書いたこちらが参考になるかと思います💁
Firebase Authenticationを使いこなすと、かなり楽に高品質な認証プロセスを組めるので、紹介します。medium.com
UserDefaults
UserDefaultsの取り扱いは、Swiftでは以下のようにわりと簡潔に書けるので、ライブラリは使わなくとも良いかな感覚です。
// 値の保存
UserDefaults.standard.set(newValue, forKey: "some key")
// 値の取得(String型の場合)
UserDefaults.standard.string(forKey: "some key")
また、Swift 4でCodable準拠のオブジェクトはサクッとData型にシリアライズできるようになったので、そのシリアライズされたDataをUserDefaultsに入れるというのもありです。そのあたり大体似たような実装に行き着くと思いますが、 Nicholas Maccharoli さん作の Nirma/Default など利用するのもありだとも思っています。
ファイルアクセス
ローカルデータベース・NSUserDefaultsへの保存に適さないものは、アプリ領域内にファイルとして保存する必要があります。(キャッシュではなく)永続化したい画像などの大きなサイズのファイルを置くときに使われることが多いです。
ちなみに、ローカルデータベースの実体もこのようにDocumentsディレクトリ配下などに置かれていたりします。
どのディレクトリを使うかはお作法があり、このあたり参考になります。
はじめに アプリを作成していく上で追加データとかを保存する領域がアプリごとに振り当てられているのでそこにデータを保存してみる。 ディレクトリ構成 MyApp.app/ ┠ Document/ │ ┗ Inbox/ …qiita.com
細かいところまで知りたい場合は公式ドキュメント参照をおすすめします。
また、FileManagerは若干使いにくいので、それが気になる場合、 Saoud M. Rizwan さん作の saoudrizwan/Disk など使いやすくラップしてくれているライブラリを使うのをおすすめします。
Disk - Delightful framework for iOS to easily persist structs, images, and datagithub.com
また、保存されたファイルを確認したい場合、シミュレーターのアプリ領域を人力で探すのはけっこうきついのでこういったアプリを使うのをおすすめします。これは有料ですが無料のものもあるはずです。
Access all applications from your menu bar, Apps and Simulators, With FUSE for OS X. for OS X Yosemite or El Capitan…simpholders.com
ロガー
ライブラリとしては以下あたりが定番かなと思っています。
- DaveWoodCom/XCGLogger: シンプル
- SwiftyBeaver/SwiftyBeaver: リッチ
SwiftyBeaverはログライブラリにとどまらない「ログプラットフォーム」で、そういうものを求めている場合これ一択ですね。
SwiftyBeaver: the world's first logging platform for Swiftswiftybeaver.com
Objective-C時代はCocoaLumberjack/CocoaLumberjackが有名でしたが、Swiftで使うのは微妙な印象です。
個人的には、ロギングは以下のような形で良いかなと思っていて、要件満たす簡単なクラス・関数など定義して済ませています。
- 基本的なログはiOS 10以降ではOSLogによるロギングを利用してローカルに書き出すのみ
- エラー・クラッシュ系のログはCrashlytics(Firebaseに統合中)にも送る
- 重要なイベントはFirebase Analyticsに送る(BigQueryにも自動連携)
テスト
テストライブラリとしてはBDD(behavior-driven development)フレームワークであるQuickが有名ですが、以前書き心地微妙に感じてしまったため僕はXCTestを使ってベタに書いています。正直、アプリケーションコードについては自動テストのコスパあまり良くないなと思っていて、テストコードはあまり書いていないというのもQuickみたいなものを必要に思わない理由の1つです。 Quickのcontext
に相当する粒度でファイル分割する工夫程度でもテストコードの見通し良くなる気がしています。
最近リポジトリに上がってきた kishikawakatsumi/SwiftPowerAssert も注目ですが、まだ実利用できる段階にはなっていないようです。
SwiftPowerAssert - Power Assert in Swift. Provides descriptive assertion messages.github.com
ちなみに、 nextstepfm の最新回#16の50分くらいから取り上げられていて面白かったです( ´・‿・`)
ライセンス管理
導入したライブラリのライセンス管理ですが、僕の作った mono0926/LicensePlistをおすすめします。
LicensePlist - A license list generator of all your dependencies for iOS applicationsgithub.com
Carthage・CocoaPods・手動でソース追加、などどんなインストールを方法をされた場合でも良い感じに一まとめにしてiOS設定画面上で一覧表示できます。
イケてるライブラリの見つけ方
ちなみに、普段どうライブラリなど見つけているかというと、普通にググることもありますが、以下のような感じで何か良さげなものが無いか日々チェックしています(半分趣味です)。
- GitHub TrendingのSwift を週1でチェック
- 海外メルマガをチェック(週5本くらい、一通り読んでいます)
また、実際に使おうかなと思った際には、次の点など大丈夫かチェックしつつ導入を決めています。
- 本当にそのライブラリを導入することで開発効率が上がりそうか
- 作者チェック
- 設計やコードがしっくり来るか
- 今後メンテナンス期待できそうか
デザイン
デザイン系の知識も最近のアプリ開発エンジニアだとあるとベターだと思っていてちょくちょく勉強・キャッチアップなど続けています。アプリ開発は単なるコーディング能力などに限らない総合力だと思っています。
エンジニアがデザインスキルを少しでも持つと、デザイナーとの協業がスムーズになるはずです。
Sketch
デザインを組む際の今一番の定番ツールであるSketchですが、シンプルで使いやすいので適当に触っているだけでまあまあ扱えるようになりますが、さらに次の2冊読むとより使いこなせるようになると思います。
Amazonで吉竹 遼のUIデザイナーのための Sketch入門&実践ガイド。アマゾンならポイント還元本が多数。吉竹 遼作品ほか、お急ぎ便対象商品は当日お届けも可能。またUIデザイナーのための Sketch入門&実践ガイドもアマゾン配送…www.amazon.co.jp
Sketch(Sketch 3)の基本的な使い方を解説した電子書籍です。アプリケーションウィンドウの解説からインスペクタの使い方、各メニューの解説など日本語で解説しています。leanpub.com
最近はAdobe XDも良い感じで今後この2強になっていく気がしています🤔
Webサイトやモバイルアプリのデザインとプロトタイプの作成が、これ1つでできるAdobe XD CC、UI/UXデザイナー向け初めてのオールインワン製品です。www.adobe.com
画像リソースのエクスポート
SketchではiOSのエクスポート設定はデフォルトではPNGで@3xまでの3サイズ出力となっています。
Xcode 6からはPDF形式では1サイズのみで良くなって取り回しが良いので僕は基本こちらを使っています。また、PDF形式ではビルド時にPNG形式にラスタライズされます(Xcode 9でできるようになったベクター維持指定をしない場合)が、PNG形式では相性悪くサイズが大きくなってしまうものなどは同じくXcode 6から扱えるようになったJPG方式にしています。
エクスポート設定は、基本的にこの2択がおすすめだと思っています。
プロトタイピング
実装前に適宜プロトタイピングを経るのも実装の手戻り防止などに役立ちます。以下が有名どころですかね。
SketchのMarvelプラグイン使ってサクッと同期できるの便利です(InVision・Prottも同様のプラグインあるようです)。
Turn sketches and designs into interactive web, iPhone, iPad, Android and Apple Watch prototypes and mockups…marvelapp.com
その他触れられなかった点
MVVM・Redux・Flux・Clean Architecture・VIPER・Danger あたりもホットな話題かと思いますが、個人的にはそのあたりあまりキャッチアップできていないので特に触れません。
まとめ
テーマ的にこんな感じになりそうとは思っていましたが、まとまりの微妙な記事になってしまった感があります( ´・‿・`)でも色々一気に発散できて良かった気がしています( ´・‿・`)
本記事は、iOS Advent Calendar 2017の25日目でした🤗
iOS関連の記事を書いていきましょう( ´・‿・`) その2もできたようですよ[iOS2 Advent Calendar 2017 \- Qiita](https://qiita.com/advent-calendar/2017/ios2…qiita.com
ちなみに、こちらのiOS版ぽい感じにもなるかなと思いましたが、どうでしたかね( ´・?・`)