注意: beta 5時点での情報です
iOS8で追加される待望のApp Extensionですが,あくまでExtensionなのでContaining appを呼び出したくなることがあると思います. App Extension Programming Guideにもあるように,App ExtensionとContaining appとの連携にはShared resourcesのほかにOpen URLを利用します. Open URLというと従来より形式化された手法ですので,とくにはまりどころは無いと思っていたのですが,はまりどころがあったので紹介させていただきます.
App ExtensionにはUIApplicationが無い
Open URLといえばご存知のようにUIApplicationを取得すればお気楽に実装できるのですが,App ExtensionにはUIApplicationのopenURL:メソッドが存在しません.
// UIApplication.h より抜粋 - (BOOL)openURL:(NSURL*)url NS_EXTENSION_UNAVAILABLE_IOS("");
見事に隠されてますね. したがって,Open URLを実装したければ,別の方法を取る必要があります.
App ExtensionではNSExtensionContextを使う
ここで登場するのがNSExtensionContextのopenURL:completionHander:です.
Share Extensionの場合,エンドポイントとなるSLComposeServiceViewControllerがNSExtensionContextを持っていますので,以下のように実装することが考えられます.
// `NSExtensionContext`を使ってopenURLする NSURL *URL = [NSURL URLWithString:@"myapp://login"]; [self.extensionContext openURL:URL completionHandler:^(BOOL success) { // successが`YES`なら成功 }];
これで安心と思いきや,そうは問屋がおろしません.
なんだそれは!と思われるかもしれませんが,openURL:completionHandler:はToday Extension以外で動作しません.
動作を確認してみたとき,successにNOが得られて,てっきりContaining appを呼び出すCustom URL Schemeを間違っているのかと思いましたが,どうやらそうではないようです.
それでも絶対Open URLしたい!
我々にはUIWebViewがあります.
Zero RectのUIWebViewを作成し,開きたいURLをloadRequest:すると当然のように動作します.
もちろんロードが完了するまでUIWebViewを保持する必要がありますのでSLComposeServiceViewControllerに貼り付けておきましょう.
余談ですが,SLComposeServiceViewControllerは特別な存在なのかなあと思ったら,わりと普通にUIViewControllerのサブクラスです.
// Share Extensionでの真のOpen URL UIWebView *webView = UIWebView.new; [self.view addSubview:webView]; // ロード完了まで保持しておきたいので適当に貼り付けておく NSURL *URL = [NSURL URLWithString:@"myapp://login"]; [webView loadRequest:[NSURLRequest requestWithURL:URL]];
まとめ
UIWebViewこそ人類に残された最後の希望.