简体   繁体   中英

Calling custom delegate from AppDelegate in Swift

I have this delegate in AppDelegate.swift that fires once another app opens my app with a url scheme.

AppDelegate.swift

 func application(application: UIApplication, openURL url: NSURL, sourceApplication: String?, annotation: AnyObject) -> Bool {
        return true
 }

It fires just fine when another app opens my app with the url scheme, but when this function fires, I want to notify a certain ViewController. I thought I could do this with a custom made delegate, and let the AppDelegate notify who ever implements my delegate that someone has opened the app.

MyDelegate.swift

protocol MyDelegate {
    func opened(hasBeenOpened: Bool!)
}

Then my ViewController implements this Delegate

LoginViewController.swift

import UIKit

/* Obviously this class has more code and other functions, 
but for the illustration of the problem, I removed all the other unrelated things.*/

class LoginViewController: UIViewController, MyDelegate {
    func opened(hasBeenOpened: Bool!) {
        print(hasBeenOpened)
    }
}

So far so good, but let's return to the openURL() function in AppDelegate.swift and try to call the MyDelegate.opened(). This is where I am completely lost.

AppDelegate.swift

func application(application: UIApplication, openURL url: NSURL, sourceApplication: String?, annotation: AnyObject) -> Bool {

        print("openURL delegate running")

        if var delegate = MyDelegate?() {
            delegate.opened(true)
        }

        return true
    }

The console prints "openUrl delegate running", so it's running, but my delegate variable becomes nil . Is there some initialization I'm missing?

I can't seem to figure out how I call my own custom Delegate from the AppDelegate. Is there another way to notify ViewControllers that this has happened? Or is this a bad idea overall, is there another way that's considered better?

Thank you all in advance, I really appreciate the help.

Without going into details if this is a good or bad idea, the problem is your delegate property in AppDelegate is never initialized. In the initializer method of your UIViewController you need to get access to the AppDelegate and set the delegate property to self .

You are trying to initialise a protocol ( var delegate = MyDelegate?() ) which is not possible.

The way you use delegates is by registering conformance on a class, which you are doing in LoginViewController , and calling a method defined in the protocol directly on an instance of that class.

For example:

var loginViewController = // get an instance of LoginViewController
loginViewController.opened(true)

In this case you don't have access to an instance, nor would it be considered good practice to keep a reference to a view controller in the App Delegate. So I think the paradigm you are looking for is notifications. Have a look at the documentation for NSNotificationCenter or the NSHipster article on notifications .

试试NSNotification,我认为在AppDelegate中保存特定的视图控制器不是一个好主意。

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM