27

我正在尝试使用自定义方案从网页打开我的应用程序。应用程序已打开,但未调用以下方法:

func application(_ app: UIApplication, open url: URL, options [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
    // This is not called
}

我的info.plist样子如下:

    <key>CFBundleURLTypes</key>
    <array>
        <dict>
            <key>CFBundleURLSchemes</key>
            <array>
                <string>MyApp</string>
            </array>
            <key>CFBundleURLName</key>
            <string>url here</string>
        </dict>
    </array>

该项目是使用 Xcode 11.1 创建的,我正在 iOS 13 上进行测试。

4

7 回答 7

66

scene(_:openURLContexts:)在您的场景委托中实现。

如果 URL 启动您的应用程序,您将获得scene(_:willConnectTo:options:)相反的信息,并且它位于options.

于 2019-10-30T12:30:23.117 回答
24

这是 SceneDelegate.swift 中的方法。Swift版适用于iOS13

@available(iOS 13.0, *)
func scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>) {
    if let url = URLContexts.first?.url {
        // Handle URL
        WXApi.handleOpen(url, delegate: AppDelegate.shared)
    }
}
于 2019-11-16T13:25:48.920 回答
19

使用最新的 SDK,如果您不使用 SceneDelegate,这确实可以正常工作。

如果您使用的是 sceneDelegate,则不会调用以下 AppDelegate 方法,因此无法处理登录。

func application(_ application: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
    let handled = ApplicationDelegate.shared.application(
        application,
        open: url,
        sourceApplication: options[UIApplication.OpenURLOptionsKey.sourceApplication] as? String,
        annotation: options[UIApplication.OpenURLOptionsKey.annotation])
    return handled
}

这是因为,此方法(可以理解)被推迟到 SceneDelegate 中的以下方法:

func scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>) {
    ...
}

我可以确认适用于实现 SceneDelegate 的 iOS 13 应用程序的解决方案是:

func scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>) {
    guard let url = URLContexts.first?.url else {
        return
    }
    let _ = ApplicationDelegate.shared.application(
        UIApplication.shared,
        open: url,
        sourceApplication: nil,
        annotation: [UIApplication.OpenURLOptionsKey.annotation])        
}
于 2019-11-29T01:35:33.507 回答
3

感谢@Matt,这就是我解决问题的方法。

在 SceneDelegate.m 上

- (void)scene:(UIScene *)scene willConnectToSession:(UISceneSession *)session options:(UISceneConnectionOptions *)connectionOptions {

    NSURL *url = connectionOptions.URLContexts.allObjects.firstObject.URL;
    NSLog(@"当应用不在内存时 ::::: %@",url);

}

​​​
- (void)scene:(UIScene *)scene openURLContexts:(NSSet *)URLContexts {

    NSURL *url = URLContexts.allObjects.firstObject.URL;    
    NSLog(@"当应用在内存中时 ::::: %@",url);

}
于 2019-10-31T07:52:55.347 回答
1

我有同样的问题,也scene(_ scene:, continue userActivity:)没有scene(_ scene:, openURLContexts URLContexts:)被调用。

当我检查connectionOptions传递给方法scene(_ scene:, willConnectTo session, options connectionOptions:)时,它有一个带有预期 URL 的用户活动。所以,我最终手动调用了该方法:

func scene(_ scene: UIScene,
           willConnectTo session: UISceneSession,
           options connectionOptions: UIScene.ConnectionOptions) {

    if let userActivity = connectionOptions.userActivities.first {
        self.scene(scene, continue: userActivity)
    }
}
于 2019-12-17T09:13:42.380 回答
0

iOS 14

MyApp: App {
    @UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate

    var body: some Scene {
        WindowGroup {
            RootView()
                .onOpenURL(perform: handleURL)
        }
    }

    func handleURL(_ url: URL) {

    }
}
于 2020-11-14T19:51:40.897 回答
0

遇到一个问题,使用safari快捷方式启动应用,openURLContexts回调多次。

2019-12-09 18:33:41.257088+0800 OCTEST[5019:1468254] openURLContextsopenURLContexts {(
    <UIOpenURLContext: 0x2805a71c0; URL: appoctest://action=123123123; options: <UISceneOpenURLOptions: 0x280bd4750; sourceApp: (null); annotation: (null); openInPlace: NO>>
)}
2019-12-09 18:33:42.022132+0800 OCTEST[5019:1468254] openURLContextsopenURLContexts {(
    <UIOpenURLContext: 0x2805a6d40; URL: appoctest://action=123123123; options: <UISceneOpenURLOptions: 0x280bd6f70; sourceApp: (null); annotation: (null); openInPlace: NO>>
)}
于 2019-12-09T11:26:23.860 回答