How to launch a parent iOS App from its App Extension

后端 未结 7 1379
借酒劲吻你
借酒劲吻你 2021-02-07 07:22

Does any one know how to launch the parent app from the app extension\'s view controller?

I just want to launch the main app from its app extension.

相关标签:
7条回答
  • 2021-02-07 07:33

    Working solution in Swift 3.1 (tested in iOS10):

    You need to create your own URL Scheme for your host app, then add this function to your ViewController and call it with openURL("myScheme://myIdentifier")

    //  Function must be named exactly like this so a selector can be found by the compiler!
    //  Anyway - it's another selector in another instance that would be "performed" instead.
    func openURL(_ url: URL) -> Bool {
        var responder: UIResponder? = self
        while responder != nil {
            if let application = responder as? UIApplication {
                return application.perform(#selector(openURL(_:)), with: url) != nil
            }
            responder = responder?.next
        }
        return false
    }
    
    0 讨论(0)
  • 2021-02-07 07:39

    In the WWDC session Creating Extensions for iOS and OS X, Part 1 around the 22 minute mark the say to use the openURL:completionHandler: method from the UIViewController's extensionContext to open a custom URL scheme

    [self.extensionContext openURL:[NSURL URLWithString:@"your-app-custom-url-scheme://your-internal-url"]
                 completionHandler:nil];
    
    0 讨论(0)
  • 2021-02-07 07:45

    The documentation is pretty clear on saying that you can use extensionContext openURL within a Today extension. By implication, openURL can only be used in a Today exception and our experiences are proving this to be true--I also can't get it working from within a Share extension.

    I would be interested to see if any of these work arounds are accepted by Apple's review process. I doubt it. If Apple wanted it to work, it would have been easy enough for them to allow it.

    Apple allows any Today widget to use the openURL:completionHandler: method to open the widget’s own containing app.

    If you employ this method to open other apps from your Today widget, your App Store submission might entail additional review to ensure compliance with the intent of Today widgets.

    I'm certain this second paragraph was added after Launcher was accepted, rejected, and then later approved for sale.

    0 讨论(0)
  • 2021-02-07 07:48

    Here is working solution (tested on iOS 9.2) at least for Keyboard Extension. This category adds special method for access to hidden sharedApplication object and then call openURL: on it. (Of course then you have to use openURL: method with your app scheme.)

    extension UIInputViewController {
    
        func openURL(url: NSURL) -> Bool {
            do {
                let application = try self.sharedApplication()
                return application.performSelector("openURL:", withObject: url) != nil
            }
            catch {
                return false
            }
        }
    
        func sharedApplication() throws -> UIApplication {
            var responder: UIResponder? = self
            while responder != nil {
                if let application = responder as? UIApplication {
                    return application
                }
    
                responder = responder?.nextResponder()
            }
    
            throw NSError(domain: "UIInputViewController+sharedApplication.swift", code: 1, userInfo: nil)
        }
    
    }
    
    0 讨论(0)
  • 2021-02-07 07:49

    it is working in my current working app using action extension

    1- in parent app plist add custom URL like

    2- add both functions in your extension view controller

    func openURL(url: NSURL) -> Bool {
        do {
            let application = try self.sharedApplication()
            return application.performSelector(inBackground: "openURL:", with: url) != nil
        }
        catch {
            return false
        }
    }
    
    func sharedApplication() throws -> UIApplication {
        var responder: UIResponder? = self
        while responder != nil {
            if let application = responder as? UIApplication {
                return application
            }
    
            responder = responder?.next
        }
    
        throw NSError(domain: "UIInputViewController+sharedApplication.swift", code: 1, userInfo: nil)
    }
    

    3- call this function in your button action or somewhere you want to do

    self.openURL(url: NSURL(string:"openPdf://HomeVC")!)
    

    here homevc is the class name of your View controller which should be presented

    4- in your app delegate implement the method like

      func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
        let urlPath : String = url.absoluteString
        print(urlPath)
        if urlPath.contains("HomeVC"){
            //here go to firstViewController view controller
            self.window = UIWindow(frame: UIScreen.main.bounds)
    
            let storyboard = UIStoryboard(name: "Main", bundle: nil)
    
            let initialViewController = storyboard.instantiateViewController(withIdentifier: "homeVC")
    
            self.window?.rootViewController = initialViewController
            self.window?.makeKeyAndVisible()
        }
    }
    

    I hope will work fine, can also share data between extension app and parent app

    0 讨论(0)
  • 2021-02-07 07:50

    Here is another way to do it:

    1. Step 1 from here
    2. Select extension target and go to its Build Settings. Set Require Only App-Extension Safe API to NO.
    3. Use UIApplication.shared.openURL(URL(string:"openPdf://")!) as you normally would do it outside extension to open urls.

    Note, that you'll get 'openURL' was deprecated in iOS 10.0 warning. So this looks like it is not guaranteed to work in future.

    Consider using local Notifications to wake up host app instead of this.

    0 讨论(0)
提交回复
热议问题