问题
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
- (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.
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.
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: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.
Despite the explanation, i still do not know how to do it and i couldn't find anything else concrete online.
Thanks
Regards
回答1:
I agree with Kaloyan, "handleOpenURL" is never called at application launch. So you have to check for URL in "launchOptions" in didFinishLaunchingWithOptions.
HOWEVER
I adopted the same solution as 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
回答2:
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"
- (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
}
回答3:
I believe there is a better answer now as,
application:handleOpenURL:
application:openURL:sourceApplication:annotation:
Both are deprecated in ios 9. Apple suggestion is:
Use
application:openURL:options:
instead.
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.
So, you need to handle the URL opening within it only. like below:
- (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;
}
回答4:
For iOS 10, use
func application(_ app: UIApplication,
open url: URL,
options: [UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool
回答5:
For me, do not make application(_:open options:)
outside AppDelegate {} scope🤣
回答6:
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
}
}
来源:https://stackoverflow.com/questions/33034771/launch-app-using-url-but-openurl-not-called