🍁

Swift: Share Extensionから本体アプリを開く

2022/02/18に公開

Today Extension の場合は extensionContext.open(URL)でカスタムスキームを叩けば本体アプリが開けますが、Share Extension の場合はそれは使えません。Apple公式からAPIが用意されていないため、黒魔術を使いましょう。

func openContainerApp() {
    let url = URL(string: "container-app://") // カスタムスキームを作って指定する
    var responder: UIResponder? = self
    while responder != nil {
        if let application = responder as? UIApplication {
	    let selector = sel_registerName("openURL:")
            application.perform(selector, with: url)
            break
        }
        responder = responder?.next
    }
}

カスタムスキームは TARGETS -> Info -> URL Type で追加できます。

key value
Identifier $(PRODUCT_BUNDLE_IDENTIFIER)
URL Schemes container-app(任意の文字列)
Role Editor

perform() に渡す Selector について、UIApplication.openURL()が objc func ではないので #selector(UIApplication.openURL(_:)) とすることができないことから sel_registerName() を使っています。どうしても #selector を使いたいならダミーの関数を定義すればいけます。

@objc func openURL(_ url: URL) {}
let selector = #selector(openURL(_:))

参考

Discussion