Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

iOS

UserDefaults changes problem, settings are uploaded to server

Hey boys and girls, i need some help.

My app uses Userdefaults to store settings, I have created the settings for my app in the IOS settings menu, added the observer for UserDefaults.didChangeNotification in viewDidLoad to get notified on a setting change, so i can upload the new settings to the server.

my problem is that Userdefaults contains many other key-value pairs which are irrelevant for my app but it fires the change notification on every single change which is a real pain. So if i load the app, it doesnt matter if i didn't change my settings, some values have changed and i upload the settings again and again to the server.

I have searched the internet for some solution for days now but still can't find a way to solve the problem. All i need is to store my preferences and nothing more...Is there a place to store my stuff and nothing more?

Any help will be appreciated!

all this stuff is in the UserDefaults on top of my other 6-7 key, and these are changing...these are the problem... i need a private place to store my stuff :-(

AddingEmojiKeybordHandled = 1 ApplePasscodeKeyboards = ( "hu_HU@hw=Automatic;sw=QWERTZ", "emoji@sw=Emoji" ) AKLastCheckInAttemptDate = 2019-05-21 11:12:42 +0000 AKLastCheckInSuccessDate = 2019-05-21 11:12:43 +0000 NSInterfaceStyle = macintosh METAL_ERROR_MODE = 6 com.apple.content-rating.TVShowRating = 1000 AKDeviceUnlockState = 1 com.apple.content-rating.AppRating = 1000 com.apple.content-rating.MovieRating = 1000 AppleLanguages = ( "hu-HU" ) METAL_DEBUG_ERROR_MODE = 4 com.apple.content-rating.ExplicitBooksAllowed = 1 INNextHearbeatDate = 579766372.0214601 com.apple.content-rating.ExplicitMusicPodcastsAllowed = 0 AppleLanguagesDidMigrate = 16F156 METAL_DEVICE_WRAPPER_TYPE = 0 INNextFreshmintRefreshDateKey = 579683653.361061 NSAllowsDefaultLineBreakStrategy = 1 AKLastIDMSEnvironment = 0 METAL_WARNING_MODE = 4 AKLastEmailListRequestDateKey = 2019-05-18 09:11:56 +0000 PKKeychainVersionKey = 4 AppleLocale = hu_HU NSLanguages = ( "hu-HU", en ) METAL_ERROR_CHECK_EXTENDED_MODE = 4

Caleb Kleveter
Caleb Kleveter
Treehouse Moderator 37,862 Points

Why do you need to save the user defaults to a server? The idea behind UserDefaults is that you can store device specific configurations for your app across launches. If you have to store user settings across devices and are storing them on a server, I would forgo using UserDefaults completely.

2 Answers

in the meantime i have found a workaround. i have removed the observer for UserDefaults.didChangeNotification and instead i have added observers for each value i'm interested in. now, i'm checking in the method observeValue for my keys, and if any of them changed i will upload the changes to the server...

so in code

override func viewDidLoad() {
.....
UserDefaults.standard.addObserver(self, forKeyPath: "one_of_the_key_im_interested", options: .new, context: nil)
UserDefaults.standard.addObserver(self, forKeyPath: "another_important_key", options: .new, context: nil)
...
}

override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
        if keyPath == "one_of_the_key_im_interested" || keyPath == "another_important_key" {
            sendUserPreferencesToServer()
        }
    }

deinit {
        UserDefaults.standard.removeObserver(self, forKeyPath: "one_of_the_key_im_interested")
        UserDefaults.standard.removeObserver(self, forKeyPath: "another_important_key")
}

Hey Caleb.

the problem is the following. I have a service where the user can see storm warning station levels on a map. If he wants, he can select some stations, so he can receive notification updates about these selected stations. So if he doesn't want to know levels of C and E stations, only A-B-D he selects it, i store this in the user defaults, and also upload this setting to the server. He will only receive notifications about A-B-D, and none about C-E. This is why it's important to store on the server.