![](/img/trans.png)
[英]viewDidLoad of my RootViewController gets called by application:didFinishLaunchingWithOptions: and applicationDidBecomeActive:
[英]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.