簡體   English   中英

應用程序 openURL 在 didFinishLaunchingWithOptions 幾秒鍾后被調用

[英]Application openURL gets called a few seconds after didFinishLaunchingWithOptions

我的應用程序中有一個深層鏈接功能,可以在一個案例旁邊正常工作。 根據打開應用程序的網址,我有 3 個不同的入職頁面。 因此,當應用程序啟動時,我需要知道哪個鏈接(如果有)打開了應用程序,然后顯示正確的入門頁面。 問題是我需要知道在方法中顯示什么屏幕:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 

但我只能知道深層鏈接是否打開了應用程序

- (BOOL)application:(UIApplication *)application
            openURL:(NSURL *)url
  sourceApplication:(NSString *)sourceApplication
         annotation:(id)annotation 

didFinishLaunchingWithOptions被調用后 5 秒被調用(我計算了秒數)。 所以我有 5 秒鍾的時間看到一個錯誤的入職頁面,直到調用openURL (如果它將被調用)。

所以我的問題是:有沒有辦法知道應用程序是在didFinishLaunchingWithOptions之前還是期間從 url 啟動的?

順便說launchOptions ,當應用程序從深層鏈接打開時, didFinishLaunchingWithOptions launchOptions為零

您正在尋找的啟動選項鍵是UIApplicationLaunchOptionsURLKey (Objective-C) / UIApplicationLaunchOptionsKey.url (Swift)。
如果您的目標是 iOS 9 及更高版本,則只需攔截來自

  • application:didFinishLaunchingWithOptions:如果應用程序不在內存中)
  • application:openURL:options:如果應用程序已經在后台)。

這是UIApplicationDelegate的一個簡約實現,它應該涵蓋這兩種情況——請注意,為了清楚起見,省略了許多不相關的邏輯:

目標-C:

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

    NSURL *url = launchOptions[UIApplicationLaunchOptionsURLKey];
    if (url) {
        // TODO: handle URL from here
    }

    return YES;
}

- (BOOL)application:(UIApplication *)app
            openURL:(NSURL *)url
            options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options {

    // TODO: handle URL from here

    return YES;
}

@end

斯威夫特 5:

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {

        if let url = launchOptions?[.url] as? URL {
            // TODO: handle URL from here
        }

        return true
    }

    func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey: Any] = [:]) -> Bool {

        // TODO: handle URL from here

        return true
    }
}

我剛剛在 iOS 13 中遇到了類似的問題,但在 iOS 13 中情況發生了變化,因為UIWindowSceneDelegate已經被引入並且現在可以完成之前由UIApplicationDelegate完成的一些工作(取決於您的應用程序設置)。

@Olivier 在這個線程中的回答對我來說仍然非常有用,因為它指出了處理 URL 方案的兩種情況; 即當應用程序不在內存中時,它調用application:didFinishLaunchingWithOptions: ,當應用程序已經加載並在后台時,第二種情況調用application:openURL:options:

因此,正如我上面提到的,如果您使用的是由 XCode 11 生成的默認應用程序模板,那么自 iOS 13 以來的情況會有所不同。我不會在這里詳細介紹,所以這里有一個關於該主題的信息豐富的教程: 理解iOS 13 場景委托

但是,如果您在場景中使用新方法,需要修改的關鍵方法是scene(_:willConnectTo:options:)此處為文檔)和scene(_:openURLContexts:)此處為文檔)。 前者是在應用程序尚未加載時對 URL 方案進行操作的位置(因此它有點替代application:didFinishLaunchingWithOptions: ),后者是當應用程序已在后台時獲取 URL 時的 URL 方案被調用(所以這個替換了application:openURL:options: )。

使用scene(_:willConnectTo:options:) ,您可以查找 URL 方案(如果有)的 URL,執行如下操作:

if let url = connectionOptions.urlContexts.first?.url {
    // handle
}

對於scene(_:openURLContexts:) ,您可以查看URLContexts集的內部。

我希望這有幫助!

以前的好主意。 我做了一些測試..

我確認了 iOS 13 的可能性和錯誤。

序言:我在 plist 上啟用了所有標志:(來自https://forums.developer.apple.com/thread/118932

... UIFileSharingEnabled LSSupportsOpeningDocumentsInPlace UISupportsDocumentBrowser .. 並在 plist 中添加了所有類型:

<key>CFBundleDocumentTypes</key>
<array>
    <dict>
        <key>CFBundleTypeIconFiles</key>
        <array/>
        <key>CFBundleTypeName</key>
        <string>abc File</string>
        <key>CFBundleTypeRole</key>
        <string>Editor</string>
        <key>LSHandlerRank</key>
        <string>Owner</string>
        <key>LSItemContentTypes</key>
        <array>
            <string>org.example.app.document.abc</string>
        </array>
    </dict>
</array>


<key>UTExportedTypeDeclarations</key>
    <array>
        <dict>
            <key>UTTypeConformsTo</key>
            <array>
                <string>public.data</string>
            </array>
            <key>UTTypeDescription</key>
            <string>abc File</string>
            <key>UTTypeIconFiles</key>
            <array/>
            <key>UTTypeIdentifier</key>
            <string>org.example.app.document.abc</string>
            <key>UTTypeTagSpecification</key>
            <dict>
                <key>public.filename-extension</key>
                <array>
                    <string>abc</string>
                </array>
            </dict>
        </dict>
    </array>

我在這里登錄:

1)

  func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        // Override point for customization after application launch.

        print(documentsDir())

        if let url = launchOptions?[.url] as? URL {
            // TODO: handle URL from here
            openWriteAndCloseLog(msg: "1 " + url.absoluteString, withTimestamp: true)
        }
        return true
    }

2)

func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey: Any] = [:]) -> Bool {
    // TODO: handle URL from here
    openWriteAndCloseLog(msg: "2 " + url.absoluteString, withTimestamp: true)
    return true
}

3)

func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { 
    if let url = connectionOptions.urlContexts.first?.url {
        // handle
        openWriteAndCloseLog(msg: "3 " + url.absoluteString, withTimestamp: true)            
    }
    guard let _ = (scene as? UIWindowScene) else { return }
}

似乎我們只通過了 3(根據我的調試日志,我可以看到內部文檔,因為我通過 iTunes 共享)

我做了一個小的演示應用程序來測試它。

https://github.com/ingconti/DocumentBroswerSampleApp

您可以從(例如,mal..)打開附件,您將看到:

在此處輸入圖片說明

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM