Roggie
Roggie

Reputation: 1217

My UserDefaults values are always one-behind (Concurrency/Parallelism) in Swift

In order to ensure that the latest app config settings values are used through-out my app, I need to ensure that the latest values are written to the UserDefaults first.

Inside my didFinishLaunchingWithOptions I am calling the following function

DataService.run.fetchLatestAppConfigSettings()

My fetchLatestAppConfigSettings() function is:

func fetchLatestAppConfigSettings(){

    REF_APPCONFIGSETTINGS.observeSingleEvent(of: .value, with: { (snapshot) in

        let venueRadius = snapshot.childSnapshot(forPath: "venueRadius").value as! Double
        self.defaults.set(venueRadius, forKey: VENUE_RADIUS)

        let discoverRadius = snapshot.childSnapshot(forPath: "discoverRadius").value as! Double
        self.defaults.set(discoverRadius, forKey: DISCOVER_RADIUS)


    }) { (error) in
        print("error \(error.localizedDescription)")
    }


}//end func

The following VC uses the values from UserDefaults but because the latest value hasn't been written by the time the following code is executed the value is alway one behind.

func fetchVenues(forLocation: CLLocation, handler: @escaping (_ venuesLoaded: Bool) -> ()){

            //radius value passed is not the latest
            DataService.run.getAllVenues(deviceLocation: forLocation, radius: DataService.run.venueRadius) { (venues) in

                self.venueArray = venues 
                self.filteredVenueArray = venues
                self.tableView.reloadData() 


                handler(true)

                if self.filteredVenueArray.count == 0{
                    self.emptyStateLabel.isHidden = false
                } else {
                    self.emptyStateLabel.isHidden = true
                }


    }//end func

Upvotes: 0

Views: 236

Answers (1)

Josh Homann
Josh Homann

Reputation: 16327

Your firebase call is asynchronous, so you need to tell everyone who is interested that your defaults have changed once the firebase call completes. The easiest way to do that is to just post a custom notification. Everyone who is interested in the change should listen for the notification.

//Make your custom notification
extension Notification.Name {
    static let userDefaultsUpdated = Notification.Name("userDefaultsUpdated")
}

//Post the notification when you update defaults
NotificationCenter.default.post(Notification(name: .userDefaultsUpdated))

//Subscribe everywhere that needs to be interested in UserDefaults changes
let token = NotificationCenter.default.addObserver(forName: .userDefaultsUpdated, object: nil, queue: .main) { notification in
  //Do stuff with new defaults here
}

Upvotes: 1

Related Questions