I\'m currently developing an App, that needs to open a browser to display a webpage.
To do that i use the [UIApplication sharedApplication] openURL
method with
Thanks for the advise from all the guys above, this is how I solved it in Xamarin.iOS (and Xamarin.Forms). The solution is inspired by what the guys have discussed above, and hope it helps others facing the same problem but using Xamarin.
[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));
});
});
}
}
After doing some very quick benchmarking I found @lidsinkers method to quite clearly be the fastest. Especially when I replaced the delay of 0.1
with 0.001
.
Thus I decided to convert it to Swift code:
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, Int64(0.001 * Double(NSEC_PER_SEC))), dispatch_get_main_queue()) {
UIApplication.sharedApplication().openURL(url)
}
Full method:
/// 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)
}
}
I noticed the same problem when calling -[UIApplication openUrl:] from the Application Delegate didReceiveRemoteNotification: or didFinishLaunchingWithOptions: since iOS 7.
I solved it by delaying the call a bit using GCD :
// objc
dispatch_async(dispatch_get_main_queue(), ^{
[[UIApplication sharedApplication] openURL:url];
});
It let iOS some time to finish application initialization and the call is then performed without any problem. Don't ask me why.
Does this works for you ?
As this answer is often seen, I added the swift version:
// swift
dispatch_async(dispatch_get_main_queue()) {
UIApplication.sharedApplication().openURL(url)
}
Had the exact same symptoms that you described: worked fine on iOS6, but ~10 second hang on iOS7. Turns out to be a threading issue.
We were issuing the [UIApplication sharedApplication] openURL
directly from the AppDelegate method applicationDidBecomeActive()
. Moving this to a background thread instantly solved the problem:
- (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]];
}
For ios 9
if([[UIApplication sharedApplication] canOpenURL:url]){
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[[UIApplication sharedApplication] openURL:url];
});
}
this seems to have worked for me