Ios 应用程序启动时无法从didFinishLaunchingWithOptions访问viewcontroller

Ios 应用程序启动时无法从didFinishLaunchingWithOptions访问viewcontroller,ios,swift,uiviewcontroller,appdelegate,Ios,Swift,Uiviewcontroller,Appdelegate,我遇到一个问题,当我在didfishlaunchingwithoptions中从一个被杀死的应用程序中午餐时,我无法访问viewcontroller.swft文件中的函数 我正在尝试使用AppDelegate的viewController?.loadRequestnotificationwaiting(for:url as!String)访问函数,我将数据传递到viewController,在那里我可以做一些事情。但是当我在viewcontrollerloadRequestnotificatio

我遇到一个问题,当我在
didfishlaunchingwithoptions
中从一个被杀死的应用程序中午餐时,我无法访问viewcontroller.swft文件中的函数

我正在尝试使用AppDelegate的
viewController?.loadRequestnotificationwaiting(for:url as!String)
访问函数,我将数据传递到viewController,在那里我可以做一些事情。但是当我在viewcontroller
loadRequestnotificationwaiting
的函数中放置警报时。未传递数据

现在,我在其他区域使用相同的方法从appdelegate将数据传递到viewcontroller,它们工作正常。在
didfishlaunchingwithoptions

当试图从
didfishlaunchwithoptions
访问viewcontroller时,viewcontroller是否还不可用

AppDelegate.swift

class AppDelegate : UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate {
    weak var viewController : ViewController?

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        UNUserNotificationCenter.current().delegate = self
        ConnectionManager.sharedInstance.observeReachability()
        // Override point for customization after application launch.
        FirebaseApp.configure()
        registerForPushNotifications()

        // opened from a push notification when the app is closed
        if let userInfo = launchOptions?[.remoteNotification] as? [String : AnyObject] {
            if let object = userInfo["aps"] {
                let url = object["url"]

                viewController?.loadRequestnotificationwaiting(for: url as! String)
            }
        }
        return true
    }

}
class ViewController: UIViewController, WKNavigationDelegate {
    func loadRequestnotificationwaiting(for notification_url_wait : String) {
        notification_url_final_wait = notification_url_wait

        let url = URL(string: notification_url_final_wait!)
        let URLrequest = URLRequest(url: url!)
        self.webView.load(URLrequest)
    }
}
ViewController.swift

class AppDelegate : UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate {
    weak var viewController : ViewController?

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        UNUserNotificationCenter.current().delegate = self
        ConnectionManager.sharedInstance.observeReachability()
        // Override point for customization after application launch.
        FirebaseApp.configure()
        registerForPushNotifications()

        // opened from a push notification when the app is closed
        if let userInfo = launchOptions?[.remoteNotification] as? [String : AnyObject] {
            if let object = userInfo["aps"] {
                let url = object["url"]

                viewController?.loadRequestnotificationwaiting(for: url as! String)
            }
        }
        return true
    }

}
class ViewController: UIViewController, WKNavigationDelegate {
    func loadRequestnotificationwaiting(for notification_url_wait : String) {
        notification_url_final_wait = notification_url_wait

        let url = URL(string: notification_url_final_wait!)
        let URLrequest = URLRequest(url: url!)
        self.webView.load(URLrequest)
    }
}

您依赖于
AppDelegate
viewController
属性,但您正在视图控制器的
viewDidLoad
方法中设置此属性;当您的应用程序已在运行时收到通知时,这是正常的,因为已设置了
viewController
属性

当通知导致启动应用程序时,不会设置
viewController
属性,也不会调用该函数

假设您需要的视图控制器是故事板中的初始视图控制器,您可以从应用程序代理的
窗口
属性中获取根视图控制器

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
    UNUserNotificationCenter.current().delegate = self
    ConnectionManager.sharedInstance.observeReachability()
    // Override point for customization after application launch.
    FirebaseApp.configure()
    registerForPushNotifications()

    // opened from a push notification when the app is closed
    if let userInfo = launchOptions?[.remoteNotification] as? [String : AnyObject] {
        if let object = userInfo["aps"],
            let url = object["url"] as? String,
            let viewController = self.window?.rootViewController as? ViewController {
                viewController.loadRequestnotificationwaiting(for: url)
        }
    }
    return true
}
  • 如果视图控制器是root,则可以通过调用
    UIApplication.shared.keyWindow!来调用它!。rootViewController或用
    视图控制器覆盖它
  • 您可以使用
    -[NotificationCenter postNotificationName:object:userInfo:][/code>发出通知,并在视图控制器中观察此通知名称

  • viewController
    设置在哪里?您应该在声明它的代码
    弱变量viewController:viewController?
    的顶部看到它,但它没有给它赋值,因此它将是
    nil
    。您可能需要应用程序的
    窗口中的
    rootViewController
    属性。我在
    didRegisterForRemotionTificationsWithDeviceToken
    didReceivereMotonification
    中使用相同的方法,并且它与这些属性一起工作,因此您的代码将值分配给应用程序委托
    viewController
    属性在某个地方,但这发生在
    didFinishLaunching
    之后。当通知从应用程序的关闭状态传入时,应用程序崩溃
    线程1:致命错误:在展开可选值时意外发现nil
    您需要确保不强制展开可能为
    nil
    的内容。在视图控制器中处理通知可能不是最好的方法;当应用程序收到通知且视图控制器不在前台时,可能无法加载该视图控制器。如果您确实使用视图控制器,请准备好将插座设置为
    nil
    。我不一定在视图控制器中处理通知。我在FirebaseMessagingService中这样做。我只是将有效负载中的url发送到viewcontroller,以便我可以将该url加载到我的WebView中。您对通过intent和LocalBroadcastManager发送url有何看法?