Метод 'application:openURL:options:' не вызывается

Я пытаюсь открыть свое приложение с веб-страницы, используя настраиваемые схемы. Приложение открывается, но не вызывается следующий метод:

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.

8 ответов

Решение

Осуществлять scene(_:openURLContexts:) в вашей сцене делегат.

Если URL-адрес запускает ваше приложение, вы получите scene(_:willConnectTo:options:) вместо этого, и это в options.

Вот метод в 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)
    }
}

С последней версией 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>) {
    ...
}

Решение, которое я могу подтвердить как работающее для приложений iOS 13, реализующих SceneDelegate:

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])        
}

iOS 14

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

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

    func handleURL(_ url: URL) {

    }
}

Благодаря @Matt вот как я решаю проблему.

на SceneDelegate.m

- (void) scene: (UIScene *)scene willConnectToSession:(UISceneSession *) параметры сеанса: (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);

}

У меня была такая же проблема, и ни один 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)
    }
}

Я столкнулся с проблемой, используя ярлык сафари для запуска приложения, несколько раз обратный вызов 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>>
)}

Обратитесь к этой документации Apple

Этот метод не вызывается, если ваши реализации возвращают NO из обоих методов application:willFinishLaunchingWithOptions: и application:didFinishLaunchingWithOptions:. (Если реализован только один из двух методов, его возвращаемое значение определяет, вызывается ли этот метод.) Если ваше приложение реализует метод applicationDidFinishLaunching: вместо application:didFinishLaunchingWithOptions:, этот метод вызывается для открытия указанного URL-адреса после того, как приложение был инициализирован. Если URL-адрес приходит, когда ваше приложение приостановлено или работает в фоновом режиме, система перемещает ваше приложение на передний план перед вызовом этого метода. Для этого метода делегирования нет эквивалентного уведомления.

Другие вопросы по тегам