Furyu
[フリュー公式]

Tech Blog

フリュー株式会社の技術ブログです

2018年12月17日

adachi

Reactive Swift に Completable 的なものを導入した話

こんにちは。
ピクトリンク事業部の足立です。

ピクトリンクはプリントシール機で撮影した画像データを使ったコミュニケーションツールで、私はそのiOS版のアプリの開発を担当をしてます。

 

最近は、12/10に遅ればせながら、スマブラSPを買いました👋
一応ほぼ全作やっているので、使命感に駆られるように、大乱闘を繰り広げる毎日でちょっと寝不足気味です😪
アドベンチャーモード、ふつうレベルでも意外に難しく苦戦しています。楽しいです✨

 

では、本題に入りたいと思います。

 

この記事は フリュー Advent Calendar 2018 の 12/17(月) の記事になります。
今回はピクトリンクアプリの開発で導入している Reactive Swift をプロジェクト内でカスタマイズしたお話です。

 

きっかけ

ある日のPRレビューを実施していた時のことです。
 
足立
  「ここ SignalProducer<Void, HogeError> なんですけど、呼び出し元が observer.sendCompleted() しかしていないので then(_:) で繋げないと動かないと思いますよ」

メンバーM
  「え、そうなんですか? I/Fの定義だけだとわかりにくいし、なんとかならないんですかね」
 

的な会話が繰り広げられていました。

たしかに、SignalProducer<Void, HogeError> だけを見ると completed イベントしか通知されるとは思いませんよね。
実装をするたびに、関数の中を調べるなんて時間の無駄ですし、そんなわかりにくい設計は無くすべきです。

 

ということで Completable 的なものを導入する

「じゃあ、どんな感じにしようか?」
 

と、設計しているときに「完了のみの通知だし Completed? Completable? 的な感じですかねー」と進んでいき RxSwift 的には似たような機能はないのか?
と調べ始めました。
 

ありました。RxSwift / Completable

Completable についての詳しい説明はここではしませんが、 Completable そのものを返却できるような設計のようです。
Reactive Swift でそこまでのカスタマイズをするとなると、とてもじゃあないですが大変です💦
 

そこで、弊社iOSアプリ開発チームでは 専用のオブジェクトを通知することで Completable のような扱いにする としました。

 

やったこと

  • 通知に使う専用のオブジェクトを作成
  • Completable の時に使わないメソッドの非推奨化

 

通知に使う専用のオブジェクトを作成

こんな感じで Completable を定義しました。

`Completable` の時に使わないメソッドの非推奨化

通知されるイベントが completed のみになるので、間違った実装にならないために、 SignalProducerSignal などで定義されている幾つかのメソッドを利用させないようにします。
ReactiveSwift / UninhabitedTypeGuards.swift を参考にしました。
 

主に startWith***flatMap など value イベントの通知で使用するメソッド周りです。
以下は SignalProducer 周りの定義を抜粋しています。

 

使い方

基本的には通常の Reactive Swift の実装通りです。
Value の指定を Completable にするだけです。

 

まとめ

導入した結果としては、とても良かったと思います。
きっかけ でも触れましたが、PRレビューの際の
 

  • completed イベントのみしかこない実装ではないか?
  • value イベントが通知される前提の実装になっていないか?
     

などの、メソッドの定義をだけでなく実装の中身まで遡って見る必要がなくなったと思います。
   = PRレビューでの不要な指摘も減る(する側もされる側もハッピー😉)
 

実装するときも CompletableTypeGuards.swift の設定のおかげで間違った実装を防げるのも地味に良かったりします。
慣れていけば 使えない ことはわかっていきますが、プロジェクトにJOINしてきた人たちにとってはWarning表示という目に見えるカタチで知らせてくれるのも良い感じです。
 

と、ここまで良かった点を書いてきましたが、念のために。
Completable の使用にあたっては用法/用量をまもって欲しいと思います。
便利だからといって 「本当に Completable の通知で良いのか?」 という「その機能の責務」を考えずに実装を進めることは、その時は良くても数週間後、数ヶ月後にタイヘンなことになるかも・・・😇

 


2016年07月19日

morioka

Firebase Dynamic Linksでディープリンク

みなさんこんにちは、コンテンツ・メディア第1事業部の盛岡です。久々の投稿です。

今回のエントリは、関西モバイルアプリ研究会#15 で発表した内容を整理して掲載します。

今回は少し見難い画像もあるかもしれませんが、研究会で利用したものをそのまま利用してライブ感を持ってお届けします!

 

Firebase Dynamic Linksとは

公式ドキュメント

https://firebase.google.com/docs/dynamic-links/

 

概要

Firebase Dynamic Links(以下 FDL)とは、Android / iOSに対応したディープリンクを行うURLを生成するサービスです。

ディープリンクとは主にスマートフォン端末において、ネイティブアプリの特定のコンテンツへ直接リンクするようなものを指します。

さらにFDLの便利な機能として、「リンク時にアプリがインストールされてない場合、アプリインストール後に指定したリンク先へ戻すことが可能」という機能があります。強力な機能であり、是非活用したいですね。

 

スクリーンショット 2016-07-15 21.21.33

FDLの利用は無料であり、生成したURLを短くするいわゆる”短縮URL”としての機能もあります。

 

FDLの想定される用途

ドキュメントにも記載されてますが、用途としてはEメール/SNSなど検索エンジン外からのネイティブアプリへの誘導利用を想定されてます。
Firebaseではその他、検索エンジンからの誘導に「App Indexes」、ユーザー間での招待には「Invites」が用意されてます。

 

スクリーンショット 2016-07-11 13.39.38

 

各プラットフォームのディープリンク基礎知識

アプリケーションにFDLを対応させるために、以下のような技術について知識が必要です。

  • Android : App Links
  • iOS : URLScheme & Universal Links

 

以下で簡単に説明しますが、公式ドキュメントの一読をおすすめします。

 

App Links

公式ドキュメント

Handling App Links 

 

Androidにて、URLスキームに対応するのアプリケーションを起動するための仕組みです。

“AndroidManifest.xml”にURLとマッピングするActivityを指定します。

また、アプリケーションの証明書フィンガープリントを利用することで、起動スキームとアプリケーションを1対1で紐付けることも可能です。

 

Universal Links

公式ドキュメント

Support Universal Links

 

iOS9以降のiOSアプリケーションにて、http/https URLとアプリケーションをマッピングし、該当アプリケーションを起動するための仕組みです。

アプリケーション実装時に、”Associated Domains”を登録することで動作させます。(XCodeにて設定)

 

スクリーンショット 2016-07-15 21.26.01

 

また、マッピング対象のWebサイトルートに、”apple-app-site-association”ファイルを設置することでアプリケーションを起動するための認証を取ります。

(例:https://pictlink.comとアプリを連携させる場合、https://pictlink.com/apple-app-site-association を設置する)

 

iOS9ではアプリケーションがインストールされてない場合にAppStoreへの遷移を促す場合には、Universal Linksを利用するくらいしか手がないためにFDLでも利用しています。

 

Firebase Dynamic Linksコンソールにおけるドメインの払い出し

ここからは、Firebase側での処理を確認して行きます。

FDLを利用し始めるとドメインが払い出されます。

ここでは黒塗りしますが、  abcde.app.goo.gl  のような(abcdeはサンプル)ドメインが各Firebaseプロジェクト毎に出来上がります。

 

スクリーンショット 2016-07-11 11.11.34

 

上記の払い出された “app.goo.gl”は何に利用されるのでしょうか?

これは、FDLのリンクのドメイン部分として記述され、リダイレクタとして利用するイメージです。

 

また、Universal Linksの設定において、登録するドメインにもなります。

(app.goo.glとサービス側のドメインの2つをAssociated Domainsに登録する必要があります)

 

では、Universal Linksで利用するapple-app-site-associationは、”app.goo.gl”ではどうしているのでしょうか?

実際にiOSアプリケーションをFirebaseに登録後、app.goo.glを掘ってみました。

 

スクリーンショット 2016-07-11 11.18.26

app.goo.glにて動的に生成されてますね。

動的に生成されるapple-app-site-associationには、Firebaseプロジェクトに複数のiOSアプリケーションがあっても、全て含めてくれます。

 

アプリケーションへの組み込みについての補足

仕組みの解説は一旦終わり、実際の組み込みについてです。

Firebase自体の利用方法から、アプリケーションの登録、自社アプリへの組み込みまで公式ドキュメントの実装どおりに行えば問題無いと思います。

ただし、何点か補足があるので説明します。

 

補足1:Firebaseに登録したアプリケーションの項目設定

Firebaseに登録しているネイティブアプリケーションの設定項目を埋めるという作業がありますので忘れずにやっておきましょう。

以下の項目が、オプショナル扱いのものです。

アプリ種別 設定項目
Android 証明書フィンガープリント(SHA-1)
iOS App Store ID
iOS  チームID

 

App LinksやUniversal Linksにちゃんと対応するために必要です。

 

補足2:Universal Linksのデバッグ

iOS9対応のためにネイティブアプリケーション側でUniversal Linksの設定も必須となりますが、Universal Linksの設定はデバッグが難しいため注意が必要です。

そのため、私は以下のようなツールを活用していました。

 

App Search API Validation Tool – Apple Developer

34 iOS 9 Apps That Support Universal Links (updated 11-19) — Jack’s Place

 

あとは、Webサーバのアクセスログを確認などして地道に動作確認を実施していきました。

 

補足3:Androidの実装

Androidにおいて、アプリケーションインストール後のリンクを再取得する処理で注意が必要です。

以下にアプリケーション内で記述するサンプルソースを示します。DeepLinkを取得した後、処理をresultCallBack内に記載(下記9行目)しないとダメであり、ブロック外には制御は戻ってきません。

 

 

動作確認

実際のリンクサンプルと、動作確認を行った結果を示していきます。

 

パラメータ内容 値(サンプル)
FDL配布ドメイン abcde.app.goo.gl
コンテンツURL https://pictlink.com/myPage
Androidパッケージ名 jp.furyu.pictlink.android
iOSバンドルID jp.furyu.pictlink.ios
アプリScheme pictlink
AppStore ID 000000001

 

リンク

https://abcde.app.goo.gl/?link=https://pictlink.com/myPage&apn=jp.furyu.pictlink.android

&ibi=jp.furyu.pictlink.ios&ius=pictlink&isi=00000001

 

利用するパラメータを元に、公式ドキュメントに従ってリンクを組み立てましょう。

このようなリンク一つで、Android / iOSのアプリケーションの起動を制御出来るはずです。

(さらに、コンテンツURLに対応するWebサイトがれば、PCブラウザからはWebサイトへ遷移させることも可能です!)

 

動作確認結果

上記のパラメータを用いて動作確認を行った結果、以下の機能が対象OSにて動作しました。

 

 動作 Android iOS8 iOS9
アプリインストール時:リンククリック後アプリ起動
アプリ未インストール時:リンククリック後、アプリストアへ遷移
アプリインストール後:初回起動時にリンクアドレス再取得

 

まとめ

Firebase Dynamic Linksを利用することで、サービス運営者からネイティブアプリケーションへの誘導がうまく出来るようになります。

これまではリダイレクタを自作したり、複雑なjsを用意したり、”あまり触れたくない”ノウハウの塊のような箇所をFirebase側でソリューションとして提供してもらっているイメージです。

 

利用にあたり、アプリケーションの入り口となるコンテンツやページの設計には注意が必要です。アプリケーションとマッピングするサイトURLを丁寧に設計すれば「サイト→ネイティブアプリ」のシームレスな連携が可能になるでしょう。

 

また、導入方法自体はそれほど困難ではないのですが、FDLの動作とアプリケーションの動作を理解していないと、想定した動きにならないことが多いので時間が取られることもあるかもしれません。

個人的には、ディープリンクと言えばFirebase Dynamic Linksの利用が第一候補になっていくのでは、と考えます。本当に便利なものなので、みなさんも是非ご活用下さい。