Edited at

【Swift, Firebase】究極の瞑想アプリを作った話

More than 1 year has passed since last update.

マツコの知らない世界で有名になった 「瞑想」 ですが、

今回、ヨガ教室をやっている yoggy inc. さんの新規事業ということで、

瞑想スタジオと合わせた瞑想アプリを製作し公開しました。

また、先日クリエイティブの専門誌である 「ブレーン」 にもこのアプリが取り上げられました。


主要機能


  • 瞑想のガイダンスを流す

  • 瞑想を続けるための進捗管理やカレンダー機能、心測定機能など

  • アプリのサブスクリプション


    • 無料期間あり

    • 月々または年額



  • HealthKitとの連携


動作


環境


  • XCode 9.2~

  • Swift 4.0.3~

  • Carthage 0.27.0 ~

  • Cocoapods 1.4.0 ~


開発期間


  • 3/12 ~4/23 開発

  • 4/23 ~ 4/27 テスト

  • 4/27 ~ バグ修正、チケット対応


開発体制


  • iOSメイン: おかむー + 実装サポート数名

  • サーバー: おかむー


進捗管理


  • Google Docsのスプレッドシート

  • github issue


プロトタイプ


  • prott


ソースコード管理


  • github


作戦


  • サーバーサイドとアプリの開発が両方必要だったため、スピードとコスパ重視のFirebaseを使いました


    • ライブラリにもたくさんお世話になりました



  • あとあとややこしくなりそうなのは極力使わない


    • UIWindowはつかわない

    • UserDefaultも極力使わない、もし使うのであればkeyChainを利用するが、極力使わない




主な技術や構成、使用したライブラリ


  • MVVMを採用


    • DataSourceを分離しテストしやすい構造にする



  • Firebase


    • 本番環境とstg環境を用意



  • Lottie(旧BodyMovin)


    • コアなアニメーションはAfter Effectsで書き出してもらう





Gemfileで管理するもの


- cocoapods
- fastlane



podfileで管理するもの


- swiftDate
- firebase
- fbloginkit
- fabric



cartfile(なるべくcarthageに寄せた)で管理するもの


- json
- github “SwiftyJSON/SwiftyJSON”
- reactive
- github “SwiftBond/Bond”
- setting
- github “nickoneill/PermissionScope” ~> 1.0
- ui
- github “ninjaprox/NVActivityIndicatorView”
- github “SVProgressHUD/SVProgressHUD”
- github “airbnb/lottie-ios”
- github “xmartlabs/Eureka” ~> 4.0
- github “danielgindi/Charts” ~> 3.0.5
- github “kaandedeoglu/KDCircularProgress”
- github “ChiliLabs/CHIPageControl” ~> 0.1.3
- cache
- github “rs/SDWebImage”
- DB
- github “realm/realm-cocoa”
- scrollView
- github “dzenbot/DZNEmptyDataSet”
- github “eggswift/pull-to-refresh”
- network
- github “ashleymills/Reachability.swift” ~> 3.0
- github “Alamofire/Alamofire”
- storekit
- github “bizz84/SwiftyStoreKit”
- calendar
- github “WenchaoD/FSCalendar”
- secret
- github “evgenyneu/keychain-swift” ~> 10.0


管理画面やデータ更新


  • Firebaseを使用するので、管理画面は開発せずGoogle Sheetを管理画面としました


瞑想コンテンツの更新


  • GoogleSheetはjson形式でexportできるので、それをFirebase Storageに置いてもらうオペレーションをしてもらう

  • 音声や画像ファイルなどは、あらかじめFirebase Storageにuploadしておき、downloadURLをGoogle Sheetの管理画面へ記入してもらう


push通知


  • FCMは使わず、Cloud Messagingを利用して手動でpushします


ユーザーのDataの管理


  • Realmは、encryptionKeyで暗号化して使用する

  • ログインはFirebaseAuthenticationにまかせる


    • Email

    • Facebook

    • 匿名



  • 個人情報でないその他の情報は、Realtime Databaseにputして、Cloud Storage バケットへ定期的にバックアップする


品質管理・規約


  • お互いにプルリクを送り合う

  • 今回SwiftLintは使わなかった

  • finalとprivate修飾子の徹底


    • 三項演算子と??アンラップは今回は、使用を許可



  • interfaceはextensionにつける

  • 強制アンラップは禁止

  • Windowはつかわない

  • UserDefaultも極力使わない、もし使うのであればkeyChainを利用するが、極力使わない

などなど、まあSwifterにとっては当たりまえなことは多い


アニメーション


瞑想画面


  • 瞑想中の映像は、AfterEffectで動画として書き出して再生させる

  • 波形部分は、UIViewで毎秒drawする

  • 瞑想開始待ちローディングは、AfterEffectでSVGで書き出してもらい、Lottieで実装する


ホーム画面


  • 瞑想進捗 CABasicAnimationで実装

  • 画面遷移 CustomTransitionで実装


ツール画面


  • 呼吸カウント AfterEffectでSVGで書き出してもらい、Lottieで実装する

  • タイマー KDCircularProgressを使用して実装

  • 心測定 AfterEffectでSVGで書き出してもらい、Lottieで実装する


テストコード


  • XCTest

  • XCUITest


構造について


  • Clean Architectureを採用したかったが、開発期間的に慣れているMVVMにしました


めんどくさかったところ


  • 外部と提携したSDKが、x86_64に対応していなかった


    • targetをdev,stg,prodを作成し、devのみコンパイルフラグを使って、排除することでローカルでの開発できるようにした(ふつうではある)




難しかったところ



  • このアプリは、背景が有機的に動いている演出があるため、全ての画面が透明背景で、いろいろ問題があった


    • デフォルトのトランジションを使うと、背面とかぶるのでカスタムトランジションやアニメーションを工夫して書く必要があった



  • 設定画面などはEurekaを使用していたが、透明がゆえに、Eurekaも限界がきて最後は、ほとんど自前に書き換えた



大変だったところ


  • 開発期間が短く、いろいろ犠牲になった


    • 食事、自分のコミット、技術の切り売りなど

    • 将来のためにも、しっかりと時間のある案件をやりたい or 5倍のスピードで実装できるようになりたい




感想


  • まずは周りの人に感謝です。ありがとうございました。

  • 業務や趣味でもFirebaseは結構使っていたのでハマる事なく実装できた

  • アンドロイド対応などもあればチャレンジしたい

  • サブスクリプションの設定で、明らかにAppleの翻訳ミスを見つけてしまった(今後記事にする)


さいごに

などを書いています。

過去の作品などはこちら

https://www.okamu.ro/