🍁

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

に公開

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 {
            application.open(url)
            break
        }
        responder = responder?.next
    }
}

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

key value
Identifier $(PRODUCT_BUNDLE_IDENTIFIER)
URL Schemes container-app(任意の文字列)
Role Editor
performが必要だった頃の話

application.open(url)の行はもともと、application.perform(sel_registerName("openURL:"), with: url)と書いてありました。Xcode 16.4で久しぶりにこの実装でビルドすると動きませんでした。

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

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

参考

Discussion