あいも変わらずモバイル情報です。
成果物はこちら。
事の発端
よく見ますよね、モバイルサイトの至る所にある「Twitterでシェア」、「Facebookでシェア」ってボタン。
よく見るんですけど・・・押しますか?アレ。
TwitterもFacebookも、もちろんアプリを使ってますよね。
ブラウザでなんて、誰もログインしてないですよね。
てことは誰も押さないですよね?!!
ネイティブアプリ全盛期にブラウザWebでシェアしてね!ったって、
わざわざログインしてまでやってくれる人が、果たしてどれくらいいるでしょうか。
うー、Webつらい!アプリ強い!
せめてこのボタンを押すとアプリが起動し・・たら素敵ではありませんか?!
どうにかなるのか
別に目新しい技術ではないのですが、実は"URIScheme"っていうものがあります。
URLスキーマって言われたりスキームって言われたり、色々呼ばれてます。
Androidだとインテントって呼んでたりもするらしい。
"http://" だとブラウザが起動するのと同じように、特定のアプリを呼び出すやつです。
Twitterなら"twitter://"とかです。
これらはアプリ側で定義されてある必要があります。
それならそうと
<a href="twitter://timeline">TwitterAppのタイムラインを表示!</a>
ってすりゃいいわけです。
楽勝です。
と言いたいところですが・・・。
- アプリがインストールされてなかったら?
- Androidでも動くのか?
とか気になってきますよね?
確かに動くし良いっちゃ良いのですが、そこは気にしないといけません。
app-opner.js
てなわけで作りました。
iOS5以上、Android4以上で動くと思います。
厳密に色んな端末で検証したわけではないですが、手元のいくつかの端末では動いてました。
var isAndroid = navigator.userAgent.toLowerCase().indexOf('android') !== -1; var shareText = encodeURIComponent('Webからアプリが開いたよ!! @leader22++ https://github.com/leader22/app-opener') + ' '; var schemeStr = (isAndroid) ? 'intent://post?message=' + shareText + '#Intent;scheme=twitter;package=com.twitter.android;end;' : 'twitter://post?message=' + shareText; new AppOpener({ schemeStr: schemeStr, fallbackUrl: 'http://lealog.net' });
って定義されたページでも用意しておけば、リンク踏むだけでおっけーです。
schemeStrさえ用意すれば、後はなんとかしてくれるライブラリです。
OS別の挙動について
iOS
有効なスキームだった場合は、思った通り動作します。
iOS Chromeでも、アプリ内WebViewでも問題なかったです。
ログインしてない場合などは、アプリは開きますがもちろんログイン画面に行きます。
普通のaタグだったりで直接コレを開こうとすると、
アプリがインストールされてない場合などに、無効なリンクとして処理されるっぽく、処理できない旨のalertが表示されます。
この味気ないalertではなく、それなりにハンドリングしたい・・ってあなた!
iframeを使えばなんとかなります!
冒頭のリポジトリからコードを見てみてくださいまし。
URIスキーム自体を探すのにはココが便利です。
Android
またもこいつに手を焼かれるのかとおもいきや、割とすんなりです。
ただAndroidのプロセス管理?の挙動がちょっとiOS民からすると特殊で、そこだけ注意します。
Androidの場合はインテントなる仕組みを使って実現します。
iOSと同じスキームでも動くっぽいのですが、どのアプリを使うかをユーザーに判断させるようなフローになるっぽい。
URL開く時に、「ブラウザで開く?それともChromeで開く?」って出るアレ。
アレもまぁある種親切なのですが・・・、
これを回避したい場合には、このインテントを使ってアプリを直接指定する他ないようです。
たとえばTwitterなら、
iOS: 'twitter://post?message={{TEXT}}' ANDROID: 'intent://post?message={{TEXT}}#Intent;scheme=twitter;package=com.twitter.android;end;'
って感じです。
棚ぼた的な感じですが、この指定の仕方をしていると、該当するアプリがインストールされていない場合、
GooglePlayを開いてくれるという謎のフォールバック機能が!
どうやらAndroid Chromeではiframeから呼べないっぽいので、どちらでも動く愚直に開く方式にしました。
あ、一つ言い忘れました。
S Browser、お前だけは許さねぇ!
これで晴れてアプリでシェアできる
できます。が。
実はいちばんやりたかったFacebookアプリの起動がどうにもこうにもできませんで・・。
正確には、起動まではいけるが、「1タップで即シェアな状態」までもっていくスキームが見つけられず・・。
Google先生に聞いてありとあらゆるパターンを試しましたがダメでした。
せっかく作ったのに勿体無いなーと思いつつ、
TwitterやLINE、その他のアプリはスキームさえあればコレで動くので、成果としてはまあ満足してはいるんですけどねー。
Facebookでシェアするスキーム!WANTED!
ほんとは
iOSとAndroidのschemeStrの差まで吸収して、各SNSにシェアするメソッドまで定義しようと思ってました。
ただ、Facebookさまが使えないとなるともはや・・なので、自由に渡すカタチにしました。
iOSの場合のインストールされてなかったフックくらいは提供しても良かったのですが、特に使い道がないのでそっとしておきました。
ちなみに
Facebookさま曰く、
Don't prefill captions, comments, messages, or the user message parameter of posts with content a person didn’t create, even if the person can edit or remove the content before sharing.
つまり、できたところでポリシー違反にはなるので、それはそれでアレなんですが・・。
やっぱりWebはWebらしく謙虚にいきましょうと思った春のひとときでした。