openURL not work in Action Extension openURL not work in Action Extension ios ios

openURL not work in Action Extension


This is what I used to do:

UIWebView * webView = [[UIWebView alloc] initWithFrame:CGRectMake(0, 0, 0, 0)];NSString *urlString = @"https://itunes.apple.com/us/app/watuu/id304697459";NSString * content = [NSString stringWithFormat : @"<head><meta http-equiv='refresh' content='0; URL=%@'></head>", urlString];[webView loadHTMLString:content baseURL:nil];[self.view addSubview:webView];[webView performSelector:@selector(removeFromSuperview) withObject:nil afterDelay:2.0];

Please note that in this case I am instantiating this call from the UIInputViewController.

This method should also work using the URL scheme from the containing app

UPDATE 04/17/2015: This does not work with iOS 8.3. We are looking for a solution and we will update the answer soon

UPDATE 06/01/2015: We found a solution that works in iOS 8.3

var responder = self as UIResponder?while (responder != nil){    if responder!.respondsToSelector(Selector("openURL:")) == true{        responder!.callSelector(Selector("openURL:"), object: url, delay: 0)    }    responder = responder!.nextResponder()}

This will find a suitable responder to send the openURL to.

You need to add this extension that replaces the performSelector for swift and helps in the construction of the mechanism:

extension NSObject {    func callSelector(selector: Selector, object: AnyObject?, delay: NSTimeInterval) {        let delay = delay * Double(NSEC_PER_SEC)        let time = dispatch_time(DISPATCH_TIME_NOW, Int64(delay))        dispatch_after(time, dispatch_get_main_queue(), {            NSThread.detachNewThreadSelector(selector, toTarget:self, withObject: object)        })    }}

UPDATE 06/15/2015: Objective-C

Someone asked for the code in Objective-C so here it is. I am not going to run it as I don't have the time right now but it should be quite straightforward:

UIResponder *responder = self;while(responder){    if ([responder respondsToSelector: @selector(OpenURL:)]){        [responder performSelector: @selector(OpenURL:) withObject: [NSURL URLWithString:@"www.google.com" ]];    }    responder = [responder nextResponder];}

As mentioned, I have not run this Objective-C code, it is just a conversion from the Swift code. Please let me know if you encounter any issues and the solution and I will update it. Nowadays, I am just using swift and unfortunately my brain is deprecating Objective-C

UPDATE 05/02/2016: Deprecated functions

As pointed by @KyleKIM the Selector functions have been replaced in Swift 2.2 by #selector. Also, there is a function that is deprecated and will probably get removed in Swift 3.0 so I am doing some research to find an alternative.

UPDATE 09/16/2016: XCode 8, Swift 3.0 and iOS10The following code is still working on the mentioned versions. You will get some warnings:

let url = NSURL(string:urlString)let context = NSExtensionContext()context.open(url! as URL, completionHandler: nil)var responder = self as UIResponder?while (responder != nil){    if responder?.responds(to: Selector("openURL:")) == true{        responder?.perform(Selector("openURL:"), with: url)    }    responder = responder!.next}

UPDATE 6/15/2017: XCode 8.3.3

let url = NSURL(string: urlString)let selectorOpenURL = sel_registerName("openURL:")let context = NSExtensionContext()context.open(url! as URL, completionHandler: nil)var responder = self as UIResponder?while (responder != nil){    if responder?.responds(to: selectorOpenURL) == true{        responder?.perform(selectorOpenURL, with: url)    }    responder = responder!.next}


Try this code.

    UIResponder* responder = self;    while ((responder = [responder nextResponder]) != nil)    {        NSLog(@"responder = %@", responder);        if([responder respondsToSelector:@selector(openURL:)] == YES)        {            [responder performSelector:@selector(openURL:) withObject:[NSURL URLWithString:urlString]];        }    }


This is by design. We don't want Custom Actions to become app launchers.