Inter-app communication in iOS using URL scheme

I have two test apps: App1 & App2.

App1 takes String from the text field and triggers method:

  • Playing videos in WatchKit app
  • How to save the content in UIWebView for faster loading on next launch?
  • SWIFT: Why is “NSURL(string:” returning with Nil, even though it's a valid url in a browser?
  • Is it possible to register a http+domain-based URL Scheme for iPhone apps, like YouTube and Maps?
  • Load HTTPS url in a UIWebView
  • How to open iOS app from browser?
  • @IBAction func openApp(sender: AnyObject) { 
        let url1 = ("app2://com.application.started?displayText="+textToSend.text!)
        let url2 = url1.stringByAddingPercentEncodingWithAllowedCharacters(NSCharacterSet.URLQueryAllowedCharacterSet())
        UIApplication.sharedApplication().openURL(NSURL(string: url2!)!)
    }
    

    Which actually opens App2 which has only label which should change to the text sent through the url, code is within AppDelegate.swift:

    func application(app: UIApplication, openURL url: NSURL, options: [String : AnyObject]) -> Bool {
        let url = url.standardizedURL
        let query = url?.query
        ViewController().labelToDisplayResult.text = query
        return true;
    }
    

    Unfortunately the line where I am trying to pass result of the URL to the actual label is giving me this error:

    EXC_BAD_INSTRUCTION (CODE=EXC_I386_INVOP SUBCODE=0x0)
    

    However I have all the data in the App2 for sure as I can see their values in debugger:

    url NSURL   "app2://com.application.started?displayText=564315712437124375" 0x00007fa4e3426320
    query   String? "displayText=564315712437124375"
    

    Any idea why I am getting this error?

    Thanks…

    Solutions Collect From Internet About “Inter-app communication in iOS using URL scheme”

    Your error

    ViewController().labelToDisplayResult.text = query
    

    ViewController() Create a new instance of ViewController,not the one loaded from storyboard.I guess labelToDisplayResult is an outlet, so it is nil,so you get EXC_BAD_INSTRUCTION (CODE=EXC_I386_INVOP SUBCODE=0x0)

    This is what I usually do to handle openURL scheme,need to think about two states:

    1. Target App is launched before,so when open url happen,the target app is in background or inactive state
    2. Target App is not launched,so when open url happen,the target app is not running at all

    In Appdelegate

    class AppDelegate: UIResponder, UIApplicationDelegate {
    var openUrl:NSURL? //This is used when to save state when App is not running before the url trigered
    var window: UIWindow?
    
    
    func application(app: UIApplication, openURL url: NSURL, options: [String : AnyObject]) -> Bool {
        let url = url.standardizedURL
        NSNotificationCenter.defaultCenter().postNotificationName("HANDLEOPENURL", object:url!)
        self.openUrl = url
        return true;
    }
    
    func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
    
        return true
    }
    }
    

    Then in the ViewController handle openURL

    class ViewController: UIViewController {
    
    @IBOutlet weak var testLabel: UILabel!
    override func viewDidLoad() {
        super.viewDidLoad()
         NSNotificationCenter.defaultCenter().addObserver(self, selector: "handleOpenURL:", name:"HANDLEOPENURL", object: nil)
        let delegate = UIApplication.sharedApplication().delegate as? AppDelegate
        if let url = delegate?.openUrl{
           testLabel.text = url.description 
            delegate?.openUrl = nil 
        }
    }
    func handleOpenURL(notification:NSNotification){
        if let url = notification.object as? NSURL{
            testLabel.text = url.description
        }
    }
    deinit{
        NSNotificationCenter.defaultCenter().removeObserver(self, name: "HANDLEOPENURL", object:nil)
    }
    
    }