ios 使用 URL 启动应用程序,但未调用 OpenUrl
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/33034771/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Launch App using URL, but OpenUrl Not Called
提问by progammingBeignner
I have implemented a URL Scheme and use it to pass data to my app by calling method. The entire code is shown as below
我已经实现了一个 URL Scheme 并使用它通过调用方法将数据传递给我的应用程序。整个代码如下所示
- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url{
// Check the calling application Bundle ID
if ([[url scheme] isEqualToString:@"yuvitime"])
{
NSLog(@"URL scheme:%@", [url scheme]);
NSString * yuvitimeRequestValue = [url query];
NSDictionary * userInfor = [[NSDictionary alloc]initWithObjectsAndKeys:yuvitimeRequestValue, @"YuvitimeRequest", nil];
NSNotificationCenter * notificationCentre = [NSNotificationCenter defaultCenter];
[notificationCentre postNotificationName:@"URLSCHEMEACTIVATEDNOTIFICATION" object:self userInfo:userInfor];
return YES;
}
else
return NO;
}
If my app is in the background, everything works fine. When you click a URL, the app is brought back to Foreground and the URL is handled as coded in the above function.
如果我的应用程序在后台运行,则一切正常。当您单击 URL 时,应用程序会返回到前台,并且 URL 将按照上述函数中的编码进行处理。
However, if the app is terminated (app not launched yet), by clicking the URL, it only launches the app without calling the handling function that is shown above.
但是,如果应用程序终止(应用程序尚未启动),通过单击 URL,它只会启动应用程序,而不会调用上面显示的处理函数。
After searching through, the best result i manage to get is this
搜索后,我设法得到的最好结果是这个
application:WillFinishLaunchingWithOptions:When asked to open a URL, the return result from this method is combined with the return result from the application:didFinishLaunchingWithOptions:
method to determine if a URL should be handled. If either method returns NO, the system does not call the application:openURL:options
: method. If you do not implement one of the methods, only the return value of the implemented method is considered.
application:WillFinishLaunchingWithOptions:当要求打开一个 URL 时,该方法的返回结果与该方法的返回结果相结合,application:didFinishLaunchingWithOptions:
以确定是否应处理该 URL。如果任一方法返回 NO,则系统不会调用application:openURL:options
: 方法。如果不实现其中一种方法,则只考虑实现方法的返回值。
- application:didFinishLaunchingWithOptions:This method represents your last chance to process any keys in the launchOptions dictionary. If you did not evaluate the keys in your application:willFinishLaunchingWithOptions:
method, you should look at them in this method and provide an appropriate response.
Objects that are not the app delegate can access the same launchOptions dictionary values by observing the notification named UIApplicationDidFinishLaunchingNotification
and accessing the notification's userInfo dictionary. That notification is sent shortly after this method returns.
The return result from this method is combined with the return result from the application:willFinishLaunchingWithOptions:
method to determine if a URL should be handled. If either method returns NO, the URL is not handled. If you do not implement one of the methods, only the return value of the implemented method is considered.
- application:didFinishLaunchingWithOptions:此方法代表您处理launchOptions 字典中任何键的最后机会。如果您没有评估application:willFinishLaunchingWithOptions:
方法中的键,则应在此方法中查看它们并提供适当的响应。不是应用程序委托的对象可以通过观察命名的通知UIApplicationDidFinishLaunchingNotification
并访问通知的 userInfo 字典来访问相同的 launchOptions 字典值。该通知在此方法返回后不久发送。此方法的返回结果与该方法的返回结果相结合,application:willFinishLaunchingWithOptions:
以确定是否应处理 URL。如果任一方法返回 NO,则不处理 URL。如果不实现其中一种方法,则只考虑实现方法的返回值。
Despite the explanation, i still do not know how to do it and i couldn't find anything else concrete online.
尽管有解释,我仍然不知道该怎么做,而且我在网上找不到任何其他具体的东西。
Thanks
谢谢
Regards
问候
回答by vmeyer
I agree with Kaloyan, "handleOpenURL" is never called at application launch. So you have to check for URL in "launchOptions" in didFinishLaunchingWithOptions.
我同意 Kaloyan 的观点,在应用程序启动时从不调用“handleOpenURL”。因此,您必须在 didFinishLaunchingWithOptions 的“launchOptions”中检查 URL。
HOWEVER
然而
I adopted the same solution as Apple example codefor QuickActions (3D Touch). I keep the URL at launch in a variable, and I handle it in applicationDidBecomeActive:.
我采用了与QuickActions (3D Touch) 的Apple示例代码相同的解决方案。我将启动时的 URL 保存在一个变量中,并在applicationDidBecomeActive: 中处理它。
@interface MyAppDelegate ()
@property (nonatomic, strong) NSURL *launchedURL;
@end
@implementation MyAppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.launchedURL = [launchOptions objectForKey:UIApplicationLaunchOptionsURLKey];
...
}
- (void)applicationDidBecomeActive:(UIApplication *)application
{
if (self.launchedURL) {
[self openLink:self.launchedURL];
self.launchedURL = nil;
}
}
- (BOOL) application:(UIApplication *)application
openURL:(NSURL *)url
sourceApplication:(NSString *)sourceApplication
annotation:(id)annotation
{
NSURL *openUrl = url;
if (!openUrl)
{
return NO;
}
return [self openLink:openUrl];
}
- (BOOL)openLink:(NSURL *)urlLink
{
...
}
@end
回答by Ismail
I believe there is a better answer now as,
我相信现在有一个更好的答案,
application:handleOpenURL:
application:openURL:sourceApplication:annotation:
Both are deprecated in ios 9. Apple suggestion is:
application:handleOpenURL:
application:openURL:sourceApplication:annotation:
两者都在 ios 9 中被弃用。 Apple 的建议是:
Use
application:openURL:options:
instead.
使用
application:openURL:options:
来代替。
application:openURL:options:
has different behaviour than the old ones, as it will be executed in case the app was in background or will launch.
application:openURL:options:
具有与旧的不同的行为,因为如果应用程序在后台或将启动,它将被执行。
So, you need to handle the URL opening within it only. like below:
所以,你需要在它处理URL打开只。像下面这样:
- (BOOL)application:(UIApplication *)app
openURL:(NSURL *)url
options:(NSDictionary<NSString *,id> *)options {
// Check the calling application Bundle ID
if ([[url scheme] isEqualToString:@"yuvitime"])
{
NSLog(@"URL scheme:%@", [url scheme]);
NSString * yuvitimeRequestValue = [url query];
NSDictionary * userInfor = [[NSDictionary alloc]initWithObjectsAndKeys:yuvitimeRequestValue, @"YuvitimeRequest", nil];
NSNotificationCenter * notificationCentre = [NSNotificationCenter defaultCenter];
[notificationCentre postNotificationName:@"URLSCHEMEACTIVATEDNOTIFICATION" object:self userInfo:userInfor];
return YES;
}
else
return NO;
}
回答by Kaloyan Dobrev
Hi when the app is not launched before, the method "handleOpenURL" is never called. You have to check "launchOptions" in didFinishLaunchingWithOptions for object with key "UIApplicationLaunchOptionsURLKey"
嗨,当应用程序之前未启动时,永远不会调用方法“handleOpenURL”。您必须在 didFinishLaunchingWithOptions 中检查具有键“UIApplicationLaunchOptionsURLKey”的对象的“launchOptions”
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
NSURL *url = [launchOptions objectForKey:UIApplicationLaunchOptionsURLKey];
//call function to handle the url like in handleURL, but do not call handleURL directly
}
回答by ycwjjjj
For iOS 10, use
对于 iOS 10,请使用
func application(_ app: UIApplication,
open url: URL,
options: [UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool
回答by Jyotirmoy
I landed up with the same issue for an app on iOS 13. Even with the proper implementation of - (BOOL)application:(UIApplication *)app
openURL:(NSURL *)url
options:(NSDictionary<UIApplicationOpenURLOptionsKey, id> *)options
method, it never got invoked.
我在 iOS 13 上的应用程序中遇到了同样的问题。即使正确实现了- (BOOL)application:(UIApplication *)app
openURL:(NSURL *)url
options:(NSDictionary<UIApplicationOpenURLOptionsKey, id> *)options
方法,它也从未被调用。
From iOS13, the SceneDelegates get invoked instead of the AppDelegate method. Once I implemented the
从 iOS13 开始,调用的是 SceneDelegate 而不是 AppDelegate 方法。一旦我实施了
- (void)scene:(UIScene *)scene openURLContexts:(NSSet<UIOpenURLContext *> *)URLContexts
on the scene delegate, it would work if the app was already in memory. However, for a cold start, I had to implement the call back
在场景委托上,如果应用程序已经在内存中,它就会工作。然而,为了冷启动,我不得不实现回调
-(void)scene:(UIScene *)scene willConnectToSession:(UISceneSession *)session options:(UISceneConnectionOptions *)connectionOptions
as well.
While implementing
以及。
在实施的同时
-(void)scene:(UIScene *)scene willConnectToSession:(UISceneSession *)session options:(UISceneConnectionOptions *)connectionOptions
please remember to handle cases when the app is not launched from an URL.
请记住处理不是从 URL 启动应用程序的情况。
Here is an useful reference: https://forums.developer.apple.com/thread/124132
这是一个有用的参考:https: //forums.developer.apple.com/thread/124132
回答by Nikaaner
I had the same problem when application(_:open:options:)
wasn't called when the app was in background. The reason for this was the Firebase SDK which uses method swizzling.
application(_:open:options:)
当应用程序在后台时没有被调用时,我遇到了同样的问题。原因是 Firebase SDK 使用了方法 swizzling。
I solved this problem by setting FirebaseAppDelegateProxyEnabled = NO
in Info.plist
我通过设置解决了这个问题,FirebaseAppDelegateProxyEnabled = NO
在Info.plist
For more detailed information on how it works and what it affects you can read here https://firebase.google.com/docs/cloud-messaging/ios/client#method_swizzling_in
有关其工作原理及其影响的更多详细信息,您可以在此处阅读https://firebase.google.com/docs/cloud-messaging/ios/client#method_swizzling_in
回答by hstdt
For me, do not make application(_:open options:)
outsideAppDelegate {} scope
对我来说,不要application(_:open options:)
在AppDelegate {} 范围之外
回答by Dheeraj D
Swift 2.x
斯威夫特 2.x
func application(app: UIApplication, openURL url: NSURL, options: [String : AnyObject]) -> Bool {
if (url.scheme == "yuvitime") {
print("URL scheme:\(url.scheme)")
let yuvitimeRequestValue = url.query!
let userInfor = [
"YuvitimeRequest" : yuvitimeRequestValue
]
let notificationCentre = NSNotificationCenter.defaultCenter()
notificationCentre.postNotificationName("URLSCHEMEACTIVATEDNOTIFICATION", object: self, userInfo: userInfor)
return true
}
else {
return false
}
}