如何在AppDelegate和ViewController之间共享属性,并在终止应用程序之前保存

时间:2019-05-12 03:29:36

标签: swift xcode

我有一个类,其属性在viewController中更新。当应用程序进入后台或使用AppDelegate退出时,我想保存属性。我使用了以下代码,但似乎没有将属性传递给AppDelegate。此外,applicationWillTerminate代码似乎没有执行。

// testClass is defined and the properties are updated in viewController, e.g
testClass.status = true  // default is false

// I want to save testClass.status when the app goes into background or being terminated using the following:

 @UIApplicationMain

 class AppDelegate: UIResponder, UIApplicationDelegate {

 var vc = ViewController()     


 func applicationDidEnterBackground(_ application: UIApplication) { 

    print(vc.testClass.status)  //  prints false

    //codes to save
 }

    // save before App is terminated
 func applicationWillTerminate(_ application: UIApplication) {

     print(vc.testClass.status) // this code did not get executed?

   //codes to save
 }
}

2 个答案:

答案 0 :(得分:2)

ionViewDidLoad ionViewWillEnter ionViewDidEnter ionViewWillLeave ionViewDidLeave ionViewWillUnload 仅在用户终止应用程序而不将其切换到后台模式时才被调用。

该应用程序处于活动状态时,请双击“主页”按钮并终止该应用程序。

但是,如果将应用切换到后台,然后尝试终止该应用,则不会调用applicationWillTerminate

您正在applicationWillTerminate中创建ViewController的实例

AppDelegate

如果您在另一个var vc = ViewController()类实例中更改testClass属性,则此处将不会获得该值。因此,像这样创建一个ViewController

singleton

现在从单例类更新任何视图控制器中的值

class TestClass: NSObject {

    static let shared = TestClass()
    private override init() {
        super.init()
    }
    var status = false
}

class ViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() TestClass.shared.status = true } } 中保存并从AppDelegate中获取值

UserDefaults

或创建一个计算属性,以在每次更改时将其保存在UserDefaults中。

class AppDelegate: UIResponder, UIApplicationDelegate {
    var window: UIWindow?
    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        TestClass.shared.status = UserDefaults.standard.bool(forKey: "Status")        
        return true
    }
    func applicationDidEnterBackground(_ application: UIApplication) {
        UserDefaults.standard.set(TestClass.shared.status, forKey: "Status")
    }
    func applicationWillTerminate(_ application: UIApplication) {
        UserDefaults.standard.set(TestClass.shared.status, forKey: "Status")
    }
}

答案 1 :(得分:1)

正如其他人已经提到的,您可以忽略applicationWillTerminate

要在应用程序进入后台时获得通知,只需在视图控制器中添加观察者即可。

但是,我建议您观察didEnterBackground而不是willResignActive

一次在viewDidLoad中添加观察者

override func viewDidLoad() {
    super.viewDidLoad()
    NotificationCenter.default.addObserver(forName: UIApplication.willResignActiveNotification, object: nil, queue: nil) { notification in
        // save the properties
    }
}

或者,如果您使用多个视图控制器,则可以在viewWillAppear中添加观察者,并在viewDidDisappear中将其删除

旁注:

如果使用情节提要,请不要使用默认的初始化程序ViewController()创建视图控制器。您将获得一个全新的实例,该实例不是故事板实例。