使用 URL 启动应用程序,但未调用 OpenUrl
Launch App using URL, but OpenUrl Not Called
我已经实现了一个 URL 方案,并使用它通过调用方法将数据传递到我的应用程序。整个代码如下所示
- (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;
}
如果我的应用程序在后台运行,一切正常。当您单击 URL 时,应用程序将返回到前台,并且 URL 将按照上述函数中的编码进行处理。
但是,如果应用程序被终止(应用程序尚未启动),通过单击 URL,它只会启动应用程序而不会调用上面显示的处理函数。
经过搜索,我得到的最好的结果是这个
应用程序:WillFinishLaunchingWithOptions:
当要求打开 URL 时,此方法的 return 结果与 application:didFinishLaunchingWithOptions:
方法的 return 结果相结合,以确定 URL 应该被处理。如果任一方法 return 为 NO,则系统不会调用 application:openURL:options
: 方法。如果您不实现其中一种方法,则仅考虑已实现方法的 return 值。
- application:didFinishLaunchingWithOptions:
此方法是您处理 launchOptions 字典中任何键的最后机会。如果您没有评估 application:willFinishLaunchingWithOptions:
方法中的键,您应该在此方法中查看它们并提供适当的响应。
不是应用程序委托的对象可以通过观察名为 UIApplicationDidFinishLaunchingNotification
的通知并访问通知的 userInfo 字典来访问相同的 launchOptions 字典值。该通知在该方法 return 之后不久发送。
此方法的 return 结果与 application:willFinishLaunchingWithOptions:
方法的 return 结果相结合,以确定是否应处理 URL。如果任一方法 return 为 NO,则不处理 URL。如果您不实现其中一种方法,则只考虑已实现方法的 return 值。
尽管有解释,我仍然不知道该怎么做,而且我在网上也找不到其他具体的内容。
谢谢
此致
您好,之前未启动应用程序时,从未调用方法 "handleOpenURL"。您必须在 didFinishLaunchingWithOptions 中检查 "launchOptions" 以查找具有键 "UIApplicationLaunchOptionsURLKey"
的对象
- (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
}
我同意 Kaloyan 的观点,"handleOpenURL" 在应用程序启动时从未被调用。所以你必须在 didFinishLaunchingWithOptions.
的 "launchOptions" 中检查 URL
然而
我采用了与Apple相同的解决方案example code for QuickActions (3D Touch). I keep the URL at launch in a variable, and I handle it in 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
我相信现在有更好的答案,
application:handleOpenURL:
application:openURL:sourceApplication:annotation:
两者都在 ios 9 中被弃用。苹果的建议是:
Use application:openURL:options:
instead.
application:openURL:options:
与旧的行为不同,因为它会在应用程序处于后台或 将启动时执行 。
因此,您只需要处理其中的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;
}
Swift 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
}
}
对于iOS 10,使用
func application(_ app: UIApplication,
open url: URL,
options: [UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool
对我来说,不要在application(_:open options:)
外部 AppDelegate {}范围
当应用程序处于后台时未调用 application(_:open:options:)
时,我遇到了同样的问题。原因是 Firebase SDK 使用 method swizzling。
我通过在 Info.plist
中设置 FirebaseAppDelegateProxyEnabled = NO
解决了这个问题
有关其工作原理和影响的更多详细信息,您可以在此处阅读 https://firebase.google.com/docs/cloud-messaging/ios/client#method_swizzling_in
我在 iOS 13 上的一个应用程序遇到了同样的问题。即使正确实施了 - (BOOL)application:(UIApplication *)app
openURL:(NSURL *)url
options:(NSDictionary<UIApplicationOpenURLOptionsKey, id> *)options
方法,它也从未被调用。
从 iOS13 开始,将调用 SceneDelegates 而不是 AppDelegate 方法。一旦我实施了
- (void)scene:(UIScene *)scene openURLContexts:(NSSet<UIOpenURLContext *> *)URLContexts
在场景委托上,如果应用程序已经在内存中,它就会工作。但是,为了冷启动,我不得不实现回调
-(void)scene:(UIScene *)scene willConnectToSession:(UISceneSession *)session options:(UISceneConnectionOptions *)connectionOptions
还有。
实施时
-(void)scene:(UIScene *)scene willConnectToSession:(UISceneSession *)session options:(UISceneConnectionOptions *)connectionOptions
请记住处理未从 URL 启动应用程序的情况。
我post通知太早了,我通过添加延迟解决了我的问题。
`- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options{
NSString *urlStr = url.absoluteString;
BOOL ret = [urlStr hasPrefix:@"dxylink://joinCourse"];
if(ret){
NSLog(@"url query:%@",[url query]);
NSArray *paramsArray = [[url query] componentsSeparatedByString:@"&"];
NSMutableDictionary *params = [[NSMutableDictionary alloc] init];
for(NSString *param in paramsArray){
NSArray *curParams = [param componentsSeparatedByString:@"="];
[params setValue:[curParams lastObject] forKey:[curParams firstObject]];
}
NSArray *arr = [NSArray arrayWithArray:params.allValues];
self.codeStr = arr.firstObject;
[self performSelector:@selector(postNoti) withObject:nil afterDelay:1];
NSLog(@"url scheme params:%@",params);
}
return YES;
}
- (void)postNoti {
[[NSNotificationCenter defaultCenter] postNotificationName:@"LinkNoti" object:nil userInfo:@{@"str":self.codeStr}];
}`
我已经实现了一个 URL 方案,并使用它通过调用方法将数据传递到我的应用程序。整个代码如下所示
- (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;
}
如果我的应用程序在后台运行,一切正常。当您单击 URL 时,应用程序将返回到前台,并且 URL 将按照上述函数中的编码进行处理。
但是,如果应用程序被终止(应用程序尚未启动),通过单击 URL,它只会启动应用程序而不会调用上面显示的处理函数。
经过搜索,我得到的最好的结果是这个
应用程序:WillFinishLaunchingWithOptions:
当要求打开 URL 时,此方法的 return 结果与 application:didFinishLaunchingWithOptions:
方法的 return 结果相结合,以确定 URL 应该被处理。如果任一方法 return 为 NO,则系统不会调用 application:openURL:options
: 方法。如果您不实现其中一种方法,则仅考虑已实现方法的 return 值。
- application:didFinishLaunchingWithOptions:
此方法是您处理 launchOptions 字典中任何键的最后机会。如果您没有评估 application:willFinishLaunchingWithOptions:
方法中的键,您应该在此方法中查看它们并提供适当的响应。
不是应用程序委托的对象可以通过观察名为 UIApplicationDidFinishLaunchingNotification
的通知并访问通知的 userInfo 字典来访问相同的 launchOptions 字典值。该通知在该方法 return 之后不久发送。
此方法的 return 结果与 application:willFinishLaunchingWithOptions:
方法的 return 结果相结合,以确定是否应处理 URL。如果任一方法 return 为 NO,则不处理 URL。如果您不实现其中一种方法,则只考虑已实现方法的 return 值。
尽管有解释,我仍然不知道该怎么做,而且我在网上也找不到其他具体的内容。
谢谢
此致
您好,之前未启动应用程序时,从未调用方法 "handleOpenURL"。您必须在 didFinishLaunchingWithOptions 中检查 "launchOptions" 以查找具有键 "UIApplicationLaunchOptionsURLKey"
的对象- (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
}
我同意 Kaloyan 的观点,"handleOpenURL" 在应用程序启动时从未被调用。所以你必须在 didFinishLaunchingWithOptions.
的 "launchOptions" 中检查 URL然而
我采用了与Apple相同的解决方案example code for QuickActions (3D Touch). I keep the URL at launch in a variable, and I handle it in 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
我相信现在有更好的答案,
application:handleOpenURL:
application:openURL:sourceApplication:annotation:
两者都在 ios 9 中被弃用。苹果的建议是:
Use
application:openURL:options:
instead.
application:openURL:options:
与旧的行为不同,因为它会在应用程序处于后台或 将启动时执行 。
因此,您只需要处理其中的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;
}
Swift 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
}
}
对于iOS 10,使用
func application(_ app: UIApplication,
open url: URL,
options: [UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool
对我来说,不要在application(_:open options:)
外部 AppDelegate {}范围
当应用程序处于后台时未调用 application(_:open:options:)
时,我遇到了同样的问题。原因是 Firebase SDK 使用 method swizzling。
我通过在 Info.plist
FirebaseAppDelegateProxyEnabled = NO
解决了这个问题
有关其工作原理和影响的更多详细信息,您可以在此处阅读 https://firebase.google.com/docs/cloud-messaging/ios/client#method_swizzling_in
我在 iOS 13 上的一个应用程序遇到了同样的问题。即使正确实施了 - (BOOL)application:(UIApplication *)app
openURL:(NSURL *)url
options:(NSDictionary<UIApplicationOpenURLOptionsKey, id> *)options
方法,它也从未被调用。
从 iOS13 开始,将调用 SceneDelegates 而不是 AppDelegate 方法。一旦我实施了
- (void)scene:(UIScene *)scene openURLContexts:(NSSet<UIOpenURLContext *> *)URLContexts
在场景委托上,如果应用程序已经在内存中,它就会工作。但是,为了冷启动,我不得不实现回调
-(void)scene:(UIScene *)scene willConnectToSession:(UISceneSession *)session options:(UISceneConnectionOptions *)connectionOptions
还有。
实施时
-(void)scene:(UIScene *)scene willConnectToSession:(UISceneSession *)session options:(UISceneConnectionOptions *)connectionOptions
请记住处理未从 URL 启动应用程序的情况。
我post通知太早了,我通过添加延迟解决了我的问题。
`- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options{
NSString *urlStr = url.absoluteString;
BOOL ret = [urlStr hasPrefix:@"dxylink://joinCourse"];
if(ret){
NSLog(@"url query:%@",[url query]);
NSArray *paramsArray = [[url query] componentsSeparatedByString:@"&"];
NSMutableDictionary *params = [[NSMutableDictionary alloc] init];
for(NSString *param in paramsArray){
NSArray *curParams = [param componentsSeparatedByString:@"="];
[params setValue:[curParams lastObject] forKey:[curParams firstObject]];
}
NSArray *arr = [NSArray arrayWithArray:params.allValues];
self.codeStr = arr.firstObject;
[self performSelector:@selector(postNoti) withObject:nil afterDelay:1];
NSLog(@"url scheme params:%@",params);
}
return YES;
}
- (void)postNoti {
[[NSNotificationCenter defaultCenter] postNotificationName:@"LinkNoti" object:nil userInfo:@{@"str":self.codeStr}];
}`