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) { }]; } });
- UIImagePickerController摄像头视图在iOS 8上奇怪的旋转(图片)
- 如何从UIImagePickerController中select多个图像
- 添加空格/填充到UILabel
- 从NSString NSJSONSerialization
- 如何在没有Storyboard的情况下在Xcode 6中创build一个空应用程序
- 企业应用程序部署不安装在iOS 8.1.3上
- 如何检查一个string是否包含Objective-C中的另一个string?
- 在Swift中用UIActivityViewController共享文本或图像的基本示例
- 像使用NSSortDescriptor的NSInteger一样对NSString值进行sorting