在 Swift 中从 AppDelegate 调用自定义委托
Calling custom delegate from AppDelegate in Swift
我在 AppDelegate.swift 中有这个委托,它会在另一个应用程序使用 url 方案打开我的应用程序时触发。
AppDelegate.swift
func application(application: UIApplication, openURL url: NSURL, sourceApplication: String?, annotation: AnyObject) -> Bool {
return true
}
当另一个应用程序使用 url 方案打开我的应用程序时它会很好地触发,但是当此函数触发时,我想通知某个 ViewController。我想我可以用一个定制的委托来做到这一点,让 AppDelegate 通知谁实现了我的委托有人打开了应用程序。
MyDelegate.swift
protocol MyDelegate {
func opened(hasBeenOpened: Bool!)
}
然后我的ViewController实现这个委托
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)
}
}
到目前为止一切顺利,但让我们 return 到 AppDelegate.swift 中的 openURL() 函数并尝试调用 MyDelegate.opened()。这是我完全迷路的地方。
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
}
控制台打印 "openUrl delegate running",所以它是 运行,但我的委托变量变成了 nil
。我缺少一些初始化吗?
我似乎无法弄清楚如何从 AppDelegate 调用我自己的自定义委托。有没有其他方法可以通知 ViewControllers 这已经发生了?或者这总体上是个坏主意,还有其他更好的方法吗?
提前谢谢大家,非常感谢您的帮助。
如果这是一个好主意或坏主意,无需详细说明,问题是您的 delegate
属性 in AppDelegate
从未初始化。在 UIViewController
的初始化方法中,您需要访问 AppDelegate 并将委托 属性 设置为 self
.
您正在尝试初始化一个不可能的协议 (var delegate = MyDelegate?()
)。
您使用委托的方式是在 class 上注册一致性,您在 LoginViewController
中正在这样做,并直接在该 [=22] 的实例上调用协议中定义的方法=].
例如:
var loginViewController = // get an instance of LoginViewController
loginViewController.opened(true)
在这种情况下,您无权访问实例,在 App Delegate 中保留对视图控制器的引用也不是好的做法。所以我认为您正在寻找的范例是通知。查看 NSNotificationCenter or the NSHipster article on notifications.
的文档
试试 NSNotification,我不认为在 AppDelegate 中持有特定的视图控制器是个好主意。
我在 AppDelegate.swift 中有这个委托,它会在另一个应用程序使用 url 方案打开我的应用程序时触发。
AppDelegate.swift
func application(application: UIApplication, openURL url: NSURL, sourceApplication: String?, annotation: AnyObject) -> Bool {
return true
}
当另一个应用程序使用 url 方案打开我的应用程序时它会很好地触发,但是当此函数触发时,我想通知某个 ViewController。我想我可以用一个定制的委托来做到这一点,让 AppDelegate 通知谁实现了我的委托有人打开了应用程序。
MyDelegate.swift
protocol MyDelegate {
func opened(hasBeenOpened: Bool!)
}
然后我的ViewController实现这个委托
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)
}
}
到目前为止一切顺利,但让我们 return 到 AppDelegate.swift 中的 openURL() 函数并尝试调用 MyDelegate.opened()。这是我完全迷路的地方。
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
}
控制台打印 "openUrl delegate running",所以它是 运行,但我的委托变量变成了 nil
。我缺少一些初始化吗?
我似乎无法弄清楚如何从 AppDelegate 调用我自己的自定义委托。有没有其他方法可以通知 ViewControllers 这已经发生了?或者这总体上是个坏主意,还有其他更好的方法吗?
提前谢谢大家,非常感谢您的帮助。
如果这是一个好主意或坏主意,无需详细说明,问题是您的 delegate
属性 in AppDelegate
从未初始化。在 UIViewController
的初始化方法中,您需要访问 AppDelegate 并将委托 属性 设置为 self
.
您正在尝试初始化一个不可能的协议 (var delegate = MyDelegate?()
)。
您使用委托的方式是在 class 上注册一致性,您在 LoginViewController
中正在这样做,并直接在该 [=22] 的实例上调用协议中定义的方法=].
例如:
var loginViewController = // get an instance of LoginViewController
loginViewController.opened(true)
在这种情况下,您无权访问实例,在 App Delegate 中保留对视图控制器的引用也不是好的做法。所以我认为您正在寻找的范例是通知。查看 NSNotificationCenter or the NSHipster article on notifications.
的文档试试 NSNotification,我不认为在 AppDelegate 中持有特定的视图控制器是个好主意。