简体   繁体   中英

How to run a function when an app first loads

I'm trying to write a simple to-do list in Swift that will store the list as an array of Strings and then call it back from memory when the app loads.

I've got the following code:

var itemList = [String]()

func loadData() -> [String] {
    var arr = [String]()

    if NSUserDefaults.standardUserDefaults().objectForKey("storedData") != nil {
        arr = NSUserDefaults.standardUserDefaults().objectForKey("storedData")! as! [String]
    }
    else {
        arr = ["Nothing to do..."]
    }

    return arr
}

func saveData(arr: [String]) {
    NSUserDefaults.standardUserDefaults().setObject(arr, forKey: "storedData")
}

Where I'm getting stuck is in where to place the call to loadData(). This is an app that has two view controllers (one for the list, one for an add item setup), so if I place the loadData() call in viewDidLoad() for the main view controller, the array is called back in from memory (and over-written) every time I switch back to the main view controller.

Where is the best place to call this so that it will load once only, upon the app starting up?

the array is called back in from memory (and over-written) every time I switch back to the main view controller.

No. viewDidLoad only loads once, when the app starts. Only viewWillApprear and viewDidAppear get called everytime the viewcontroller changes.

Also you could make your code a bit more compact by using if let :

  if let storedData = NSUserDefaults.standardUserDefaults().objectForKey("storedData") as! [String]{
     arr = storedData
  }

But if you want to make sure to load this only once, you can put it in your AppDelegate file in your applicationDidFinishWithOptions method.

But you'd have to make a variable in your AppDelegate file which you can access from your viewController.

viewDidLoad() only happens when the View Controller is first instantiated. If it is your root view controller you can have it in viewDidLoad().

The other goes, viewDidLoad > viewWillAppear > viewDidAppear. After the view is first loaded only the latter 2 methods are called whenever you navigate.

you can also always register for a NSApplicationDidFinishLaunchingNotification notification at the notification center

check it out here: https://developer.apple.com/library/mac/documentation/Cocoa/Reference/ApplicationKit/Classes/NSApplication_Class/index.html#//apple_ref/c/data/NSApplicationDidFinishLaunchingNotification

Use or overwrite respectively

application(_:didFinishLaunchingWithOptions:)

of your application delegate. That is called only once upon application launch. See https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIApplicationDelegate_Protocol/#//apple_ref/occ/intfm/UIApplicationDelegate/application:didFinishLaunchingWithOptions :

viewDidLoad is called after the view for a single controller is first loaded. It shouldn't be called more than once for the life-cycle of a single viewController. Maybe it is possible that, if you are not calling "super.viewDidLoad()" in your own viewDidLoad method, then it may be called again? While you can generally assume that the rootViewController for an application is only created once, I think it's theoretically possible that it might be cleared out of memory by the app if required and then recreated again - so I would never assume it's only called once.

One thing you could do is just set a boolean (default false) to true whenever you load the data and then not call it again if the flag is already set to true.

Alternatively, it's a good idea to separate the data management from your viewControllers. A relatively simple solution would be to have a class called "AppData" say, which might be a singleton (so you can only ever have one instance of it) or a member of your AppDelegate. Then, in your app delegate's "applicationDidFinishLaunchingWithOptions method, you could create the one instance of the AppData class and call the loadData method on it. This class would then live independently of whichever view is currently showing, and the current view could call methods on this object to load/save/update data as required.

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