I add following code:
- (IBAction)done {
// Return any edited content to the host app.
// This template doesn't do anything, so we just echo the passed in items.
NSURL *url = [NSURL URLWithString:@"lister://today"];
[self.extensionContext openURL:url completionHandler:^(BOOL success) {
NSLog(@"fun=%s after completion. success=%d", __func__, success);
}];
[self.extensionContext completeRequestReturningItems:self.extensionContext.inputItems completionHandler:nil];
}
after I create the Action Extension target. But it can not work.
My purpose is that: when user view a photo in Photos.app (the iOS's default Photos.app or called gallery), and he click the share button to launch our extension view. We can transfer the image from Photos.app to my own app and deal or upload the image in my app.
I also try "CFBundleDocumentTypes" but it also can not work.
Any help will be appreciated.
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 iOS10 The 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
}