Passing data from Scene Delegate to ViewController when opening app with URL

1.3k views Asked by At

I need to Show a View on my initial controller and set a UILabel when the app launches through URL Dynamic Link during Firebase Email Verification.

Problem I'm having is the label is not initialised so app crashes during the process. I have tried many approaches but can't get it to show my view and set the label when opening a Dynamic Link, even when the App is already open.

Scene Delegate

func scene(_ scene: UIScene, continue userActivity: NSUserActivity) {

    if let link = userActivity.webpageURL?.absoluteString
    {
     
        if Auth.auth().isSignIn(withEmailLink: link) {

            Config().verifyEmail(link: link)
        }
    }
}

AppDelegate

@main
class AppDelegate: UIResponder, UIApplicationDelegate {

var errorText: String?
var errorType: Bool?

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
    
    FirebaseApp.configure()
    
    return true
}

ViewController

func loadErrorInfo()
{
    let appDelegate = UIApplication.shared.delegate as! AppDelegate

    if let eText = appDelegate.errorText, let eType = appDelegate.errorType {
        errorCall(message: eText, error: eType)
    } else {
        errorBox.isHidden = true
    }
}
func errorCall(message: String, error: Bool)
{
    if error {
        self.errorLabel.textColor = UIColor.yellow
        self.errorLabel.text = message
        self.errorBox.isHidden = false
        self.errorBox.shake()
    } else {
        self.errorLabel.textColor = UIColor.white
        self.errorLabel.text = message
        self.errorBox.isHidden = false
        self.errorBox.shakeL()
    }
}

Custom Config NSObject Class

import UIKit
import FirebaseAuth

open class Config: NSObject {

public func verifyEmail(link: String)
{
    var email = ""; var password = ""
    if let x = UserDefaults.standard.object(forKey: "Email") as? String { email = x }
    if let y = UserDefaults.standard.object(forKey: "Password-\(email)") as? String { password = y }
    
    if password != "" && email != ""
    {
        Auth.auth().signIn(withEmail: email, link: link) { (user, error) in
        if let use = user, error == nil
        {
            Auth.auth().currentUser?.updatePassword(to: password) { (error) in
                  if let error = error
                  {
                        print(error)
                    let appDelegate = UIApplication.shared.delegate as! AppDelegate
                    appDelegate.errorText = error.localizedDescription
                        appDelegate.errorType = true
                    ViewController().loadErrorInfo()
                  }
                  else
                  {
                    print(use, "Logged In")
                    let appDelegate = UIApplication.shared.delegate as! AppDelegate
                    appDelegate.errorText = "\(use) Logged In"
                    appDelegate.errorType = false
                    ViewController().loadErrorInfo()
       
                  }
               }
            }
        }
    }
}

}

Not sure what other method will work. To summarise, after clicking a Dynamic Link in an Email, I want to Change my UILabel on main ViewController which is an initial controller. At the moment every approach causes it to crash as the UILabel is not Set, even if the controller is already initialised.

1

There are 1 answers

0
Paul On BEST ANSWER

Managed to fix it by initialising the controller again and updating the root controller.

// SceneDelegate

func changeRootViewController(_ vc: UIViewController, animated: Bool = true)
{
    guard let window = self.window else {
        return
    }
    window.rootViewController = vc
}

//Reinitialise

let storyboard = UIStoryboard(name: "Main", bundle: nil)
let destinationNavigationController = storyboard.instantiateViewController(withIdentifier: "ViewController2")
(UIApplication.shared.connectedScenes.first?.delegate as? SceneDelegate)?.changeRootViewController(destinationNavigationController)