OpenUrl冻结了10秒以上的应用程序

我目前正在开发一个应用程序,需要打开一个浏览器来显示一个网页。 要做到这一点,我使用[UIApplication sharedApplication] openURL方法与URL。

在iOS 6中,这是完美的,但是在iOS 7中,它冻结了10多秒的应用程序,然后打开浏览器,一切都很好。

这发生在使用临时供应。 互联网上有人评论说,这是一个已知的问题,但是,有一个评论是我能find关于这个问题。

从应用程序委托didReceiveRemoteNotification:或didFinishLaunchingWithOptions:从iOS 7调用[UIApplication openUrl:]时,我注意到同样的问题。

我用GCD延迟了一下电话,解决了这个问题:

 // objc dispatch_async(dispatch_get_main_queue(), ^{ [[UIApplication sharedApplication] openURL:url]; }); 

它让iOS有一段时间来完成应用程序的初始化,然后调用没有任何问题。 不要问我为什么。

这对你有用吗?

由于经常看到这个答案,我添加了迅捷版本:

 // swift dispatch_async(dispatch_get_main_queue()) { UIApplication.sharedApplication().openURL(url) } 

我在iOS 7中看到了同样的问题。我的解决scheme与已经提出的解决scheme稍有不同。 通过使用performSelector只需0.1秒的延迟,应用程序立即打开URL。

 [self performSelector:@selector(methodToRedirectToURL:) withObject:url afterDelay:0.1]; 

有你所描述的完全相同的症状:在iOS6上工作正常,但在iOS7上约10秒钟。 原来是一个线程问题。

我们直接从AppDelegate方法applicationDidBecomeActive()发布[UIApplication sharedApplication] openURL 。 移动到后台线程立即解决了这个问题:

 - (void)applicationDidBecomeActive:(UIApplication *)application { ... // hangs for 10 seconds // [[UIApplication sharedApplication] openURL:[NSURL URLWithString: url]]; // Fix: use threads! [NSThread detachNewThreadSelector:@selector(openbrowser_in_background:) toTarget:self withObject:url]; ... } - (void)openbrowser_in_background:(NSString *)url { [[UIApplication sharedApplication] openURL:[NSURL URLWithString: url]]; } 

感谢上面所有人的build议,这是我解决它在Xamarin.iOS(和Xamarin.Forms)。 这个解决scheme受到了上面讨论过的东西的启发,希望它能帮助其他人面对同样的问题,但是使用Xamarin。

 [Register("AppDelegate")] public class AppDelegate { .... 

[Register("AppDelegate")] public class AppDelegate { ....

  public override bool OpenUrl(UIApplication application, NSUrl url, string sourceApplication, NSObject annotation) { // We do some logic to respond to launching app, and return to that app. Task.Delay(500).ContinueWith(_ => { this.InvokeOnMainThread( () => { UIApplication.SharedApplication.OpenUrl(NSUrl.FromString(openUri)); }); }); } 

}

在做了一些非常快速的基准testing后,我发现@lidsinkers方法显然是最快的。 特别是当我用0.001代替0.1的延迟。

因此我决定把它转换成Swift代码:

 dispatch_after(dispatch_time(DISPATCH_TIME_NOW, Int64(0.001 * Double(NSEC_PER_SEC))), dispatch_get_main_queue()) { UIApplication.sharedApplication().openURL(url) } 

完整的方法:

 /// An attempt at solving 'openUrl()' freeze problem func lidsinkerOpenURL(url: NSURL) { dispatch_after(dispatch_time(DISPATCH_TIME_NOW, Int64(0.001 * Double(NSEC_PER_SEC))), dispatch_get_main_queue()) { UIApplication.sharedApplication().openURL(url) } } 

对于ios 9

 if([[UIApplication sharedApplication] canOpenURL:url]){ dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ [[UIApplication sharedApplication] openURL:url]; }); } 

这似乎为我工作

如果在viewDidLoad方法中放置“openURL”操作,那么它肯定会执行缓慢。 你可以把它放在viewDidAppear方法中。 或者,您可以在viewDidLoad方法中使用GCD,如下所示:

 dispatch_async(dispatch_get_main_queue(), ^{ [[UIApplication sharedApplication] openURL:url]; }); 

这是Swift 3.0中的答案,检查是否可以打开URL。

 guard let url = URL(string: myURLString) else { return } if UIApplication.shared.canOpenURL(url) { DispatchQueue.main.async { UIApplication.shared.openURL(url) } } 

我发现在iOS 10中使用它会更好。

 dispatch_async(dispatch_get_main_queue(), ^{ if ([[[[UIDevice currentDevice] systemVersion] componentsSeparatedByString:@"."].firstObject integerValue] < 10) { [[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"tel:..."]]; } else { [[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"tel:..."] options:@{} completionHandler:^(BOOL success) { }]; } });