Запустить приложение, используя URL-адрес, но OpenUrl не вызывается
Я реализовал схему 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-адрес, приложение возвращается к Foreground, и URL-адрес обрабатывается как закодированный в вышеуказанной функции.
Однако, если приложение прекращено (приложение еще не запущено), щелкнув URL-адрес, он запускает приложение только без вызова функции обработки, показанной выше.
После поиска лучший результат, который мне удалось получить, - это
приложения: WillFinishLaunchingWithOptions:
Когда его попросят открыть URL-адрес, результат возврата этого метода комбинируется с результатом возврата из метода application:didFinishLaunchingWithOptions:
, чтобы определить, следует ли обрабатывать URL-адрес. Если любой из методов возвращает NO, система не вызывает метод application:openURL:options
:. Если вы не применяете один из методов, учитывается только возвращаемое значение реализованного метода.
- приложение: didFinishLaunchingWithOptions:
Этот метод представляет ваш последний шанс обработать любые ключи в словаре launchOptions. Если вы не оценили ключи в методе application:willFinishLaunchingWithOptions:
, вы должны посмотреть на них в этом методе и предоставить соответствующий ответ.
Объекты, не являющиеся делегатом приложения, могут получить доступ к тем же значениям словаря launchOptions, наблюдая уведомление с именем UIApplicationDidFinishLaunchingNotification
и обращаясь к словарю userInfo уведомлений. Это уведомление отправляется вскоре после возвращения этого метода.
Результат возврата этого метода объединяется с результатом возврата метода application:willFinishLaunchingWithOptions:
, чтобы определить, следует ли обрабатывать URL. Если какой-либо метод возвращает NO, URL-адрес не обрабатывается. Если вы не реализуете один из методов, учитывается только возвращаемое значение реализованного метода.
Несмотря на объяснение, я до сих пор не знаю, как это сделать, и я не мог найти ничего конкретного в Интернете.
Спасибо
Привет
Ответы
Ответ 1
Я согласен с Kaloyan, "handleOpenURL" никогда не вызывается при запуске приложения. Поэтому вам нужно проверить URL-адрес в "launchOptions" в файле didFinishLaunchingWithOptions.
ОДНАКО
Я принял такое же решение, как Apple пример кода для QuickActions (3D Touch). Я сохраняю 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
Ответ 2
Привет, когда приложение не запускается раньше, метод "handleOpenURL" никогда не вызывается. Вы должны проверить "launchOptions" в файле didFinishLaunchingWithOptions для объекта с ключом "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
Я считаю, что теперь есть лучший ответ, как
-
application:handleOpenURL:
-
application:openURL:sourceApplication:annotation:
Оба устарели в ios 9. Предложение Apple:
Используйте application:openURL:options:
вместо этого.
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;
}
Ответ 4
Для iOS 10 используйте
func application(_ app: UIApplication,
open url: URL,
options: [UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool
Ответ 5
Для меня не создавайте application(_:open options:)
вне 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
}
}