こんにちは、絶賛iOSの修行中の福成です。
今回はLINEアプリとの連携をやってみました。
Swift2.xまでの情報はネットに沢山はあるのですが、Swift3になって色々と書き方が変わっているらしく、
いざ実装しようとしたらハマりまくったのでこちらで共有することにしました。
URL Schemeとは
ざっくり言うとiOSアプリに対してこのURLSchemeを独自に設定することで、
別のアプリからURLSchemeが呼ばれたときにそのアプリを開くことができるというものです。
例えばGoogle Maps アプリの場合ですと、
comgooglemaps:// のようなスキームを使うことで
Google Maps アプリを開くことができます。
実際にブラウザアプリのURL入力欄に
comgooglemaps://を入力すると、
ブラウザアプリからGoogle Maps アプリにタスクが切り替わることがみてとれるかと思います。
LINEのような公式のSNSアプリにも
line://のようなスキームが設定されていて、
このスキームの後に色々付け足すことでLINEアプリを開いた後にどのような操作を行いたいか指定することができます。
今回はその中からテキストや画像をLINEに投稿したりタイムラインに共有するスキームを用いて実装を行いたいと思います。
実装
開発環境
Xcode 8.1
Swift 3.0.1
実装を行う前に
iOS9以降だと、使いたいURL schemeをinfo.plistで指定する必要があります。
Arrayタイプの「LSApplicationQueriesSchemes」を作成してitem「line」を追加します。
こちらを参考にしてください
テキストを投稿
/** メッセージを投稿 - parameter text: 送りたいメッセージ内容 */ static func sendMessage(_ text: String) { let lineSchemeMessage: String! = "line://msg/text/" var scheme: String! = lineSchemeMessage + text scheme = scheme.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) let messageURL: URL! = URL(string: scheme) self.openURL(messageURL) } /** URLを開く - parameter url: URL */ static private func openURL(_ url: URL) { if UIApplication.shared.canOpenURL(url) { UIApplication.shared.open(url, options: [:], completionHandler: nil) } else { // 本来であれば、指定したURLで開けないときの実装を別途行う必要がある print("failed to open..") } } |
最初の2行では、 line://msg/text/の後に送りたいテキストの文字列をくっつけています。
let lineSchemeMessage: String! = "line://msg/text/" var scheme: String! = lineSchemeMessage + text |
テキストに日本語を含む場合はaddingPercentEncodingでエンコーディングをきちんと行わないと、アプリが落ちます。
scheme = scheme.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) let messageURL: URL! = URL(string: scheme) |
UIApplication.shared.canOpenURLで引数のURLが有効なURLであるかどうかをチェックして
UIApplication.shared.openでURLを開きます。
このあたりのメソッドなどがSwift2系から若干変わっているようです。
if UIApplication.shared.canOpenURL(messageURL) { UIApplication.shared.open(messageURL, options: [:], completionHandler: nil) } else { // 本来であれば、指定したURLで開けないときの実装を別途行う必要がある print("failed to open..") } |
上記のif文が通らないこととしてよくあるのが、ターゲットとなるアプリを持っていないというのが挙げられます。
そのためLINEアプリを持ってない場合、アラートを表示したりAppleStoreを起動してLINEアプリのインストールを促したりといった実装が本来必要になってきます。
実際に動かすと、LINEが起動し、送り先を指定する画面になります。
ここで例えばタイムラインに投稿を選択すると、写真のように作ったアプリ側で指定した文字列がすでに入力されて
すぐ送信できるような状態になっていることがわかります。
画像を投稿
/** 画像を投稿 - parameter image: 送りたい画像 */ static func sendImage(_ image: UIImage) { let pasteBoard = UIPasteboard.general pasteBoard.image = image let lineSchemeImage: String = "line://msg/image/%@" let scheme = String(format: lineSchemeImage, pasteBoard.name as CVarArg) let messageURL: URL! = URL(string: scheme) self.openURL(messageURL) } |
画像を送るには、UIPasteBoardというものを用います。
let pasteBoard = UIPasteboard.general pasteBoard.image = image |
そしてURLを組み立てるところですが、サイトにあるようなNSStringを使う方法だとアプリが落ちてしまいました。
Stringのみを使う方法を調べ、結果的にうまくいったのですがこのCVarArgというのが未だによくわからない・・・
let lineSchemeImage: String = "line://msg/image/%@" let scheme = String(format: lineSchemeImage, pasteBoard.name as CVarArg) let messageURL: URL! = URL(string: scheme) |
あとはテキストと同様の方法でURLを開くだけです。openURLも同じものです。
実際に動かすと、先程と同じようにLINEが起動し、送り先を指定する画面になります。
送り先を指定すると、ViewContorollerと同じディレクトリに置いてある画像が指定された状態になっています。
感想
振り返ってみると、画像はやたらとハマった気がします。
何よりもそもそものSwiftやObjective-Cに関する知識不足を実感しました。どんどん書いて精進したいと思います。
LINEだけでもスキームはいっぱいあるみたいですね。こちらも折にふれて試していけたらと思います。
この記事を書いた人
- 2年目のiOSエンジニアです!
最近書いた記事
- 2017.12.02re:Invent 3日目 keynote(day1)に参加してきました!
- 2017.11.30re:Invent 2017 2日目 11/28
- 2017.11.28【セッション参加レポート】Media Intelligence for the Cloud with Amazon AI【MAE402】
- 2017.08.24【Alamofire】通信のリトライを行う