I have 4 database catalogues in my app, i will be switching the four catalogues.
When i start the app, i read the NSUserDefaults and try to load the default catalogue in the memory, but in the first time this doesnt happen. Instead i get null values returned first time just because the DB connection is not successful for some unknown reason, the debugger is unable to go there too.
But the app starts up the next time, the values are fetched successfully.
Please help
If your trying to fetch some necessary data from the user defaults, it might not be there the first time you run the app. You probably need to create a default set of defaults (heh) using:
-[NSUserDefaults registerDefaults:]
...before you query the user defaults for any value.
From User Defaults Programming Topics
The registration domain is a set of
application-provided defaults that are
used unless a user overrides them (the
“default defaults” or “factory
settings”). For example, the first
time you run Xcode, there isn’t an
IndexOnOpen value saved in your
defaults database. Consequently, Xcode
registers a default value for
IndexOnOpen in the
NSRegistrationDomain as a “catch all”
value. Xcode can thereafter assume
that an NSUserDefaults object always
has a value to return for the default,
simplifying the use of user defaults.
You set NSRegistrationDomain defaults
programmatically with the method
registerDefaults:.
Related
Conv.user.storage data is not persisting, when using an alpha tester account it resets every time. When using the simulator the data goes back to some snapshot it took at some point and has some values associated with a previous session.
I know this is vague but I was wondering if anyone ever had this problem.
I'm guessing the most reliable solution is to just use Google sign in if you are in anyway depending on that conv.user.storage data, is that right?
Let me add this snippet from Response section in the simulator, here you can user storage in the middle of the game, then I close and start again and all the values change completely going to a previous set of values from some point in the past, but this same set of values appears no matter how many times I reset, how can user storage find some previous snapsnot of values like this?
Before:
"userStorage": "{\"data\":{\"questionorder\":\"19,29,27,18,30,20,16,22,12,11,17,28,14,25,6,21,8,4,5,3,1,23,10,26,13,24,7,2,15\",\"thisquestionnum\":9,\"randmozier\":true,\"visited\":true,\"questioncode\":111,\"popularity\":50,\"population\":100,\"rounds\":1}}"
After:
"userStorage": "{\"data\":{\"questionorder\":\"5,20,13,18,6,19,12,9,1,21,11,10,22,25,24,8,14,3,16,17,7,26\" ,\"thisquestionnum\":4,\"randmozier\":true,\"visited\":true,\"questioncode\":111,\"popularity\":30,\"population\":100,\"rounds\":2}}"
What is weird about this is, no matter what user storage starts out at, it will return to the second "After" values if I restart the game -- nowhere in the code is this being set, it's a previous set of values from some point, how can this issue suddenly appear?
I have even reset the code back 1 month so it is not possible at all to choose up to 26 questions like is shown in "questionorder" above -- but still it returns to that second state of user storage which is impossible in the code as it is, this is some major error in actions-on-google library or something which has changed in the last few days, has anyone had this issue with conv.user.storage?
I want to set the language for one time once the user downloaded the app and started using it, for only first time. but not all the time he use the app. How can i do that?
like how we get select language options , while installing Microsoft products, etc
is this possible ?
you can control that when you application apears. Did you know about property lists?
You could use it. Or maybe you can create a file with Core data with name Configs. You need to check if field is blank and case yes, open a viewControllerChangeLanguange.After select save the data and start your application. Remember, everytime you start you will check your file. Case exists, set current language.Case not, invoke an interface to user select a language. All the controller could be made by just a file config.
I am creating a application UIPasteboard with my app's identifier as a name (e.g. com.example.app.pboard) as suggested in the docs.
All the copying and pasting works, but the damn thing never goes away. I set its persistent property explicitly to NO every time I access it to copy something onto it, and I even call UIPasteboard's +removePasteboardWithName: every time my app starts.
But every time I look at it, the most recent thing I copied onto it is always there, despite app restarts.
What gives?
No idea why what you are trying isn't working, here are two guesses and a possible solution:
Removing the paste board may be expected to be executed on exit from the app, so it doesn't execute until the app is terminated or backgrounded?
Calling remove and then asking for the items may be recreating it again in the same "place" so the items still remain.
You could perhaps solve this by setting the pasteboard's items to nil when leaving or entering the app.
You can set UIPasteboard to persistent. Accord to Apple's document,
setPersistent:
A Boolean value that indicates whether the pasteboard is persistent.
When a pasteboard is persistent, it continues to exist past app terminations and across system reboots. App pasteboards that are not persistent only last until the owning (creating) app quits. The system wide general pasteboard is persistent. Named, app-specific pasteboards are not persistent.
Update: For iOS 10, UIPasteboard set persistence automatically.
Note
Starting in iOS 10, the system sets pasteboard persistence automatically. If you try to set the setPersistent: property on a pasteboard, Xcode issues a deprecation warning.
Instead of named persistent pasteboards, use shared containers, as described in the Overview section of this document.
I am using the NSUserDefaults' api -registerDefaults api to register the factory defaults of my application. All is fine for the first version of the application. But when I provide an update for the iPhone application, I have 3 criteria to make sure:
The user preferences of older version app should be intact.
Addition to the factory defaults specific to the new version should be applied.
Providing flexibility in the design to the future version updates so that the user defaults modifies itself based on the new version.
The api -registerDefaults does not register factory defaults in new version updates because a plist file containing user preferences already exists in the /Library/Preferences of sandbox. And in case if we reset the preferences with new factory defaults, user preferences of previous version will be lost.
I think there should be a design pattern to handle such cases, so in general how do we cater with such situations? Doesnt Apple provide any inherent support for this? Or am I missing some links, I tried googling around without any success.
Thanks,
Raj
If this list of items you're talking about is an array registered under a single key, then yes, a larger array passed to -registerDefaults: will be ignored in favor of the smaller array stored in the persistent plist. NSUserDefaults tracks stuff on a per-key basis, and doesn't do any interpretation of the contents you store in there, so it's not going to try to automagically merge previous array values with new array values, or anything daft like that.
If you want new items to be added to this array by default when the user upgrades, I would recommend adding the items explicitly to the key yourself by fetching the existing array, adding the new items, and then saving the larger array back to the user defaults again. You can use a separate boolean flag to indicate that the upgrade has been done, to ensure that the addition doesn't get performed multiple times.
What is the problem? If the user never changes (or more exactly: sets) a preference, the factory default will be used. If an update of your app changes the factory defaults, those will be used instead. If the user has set his own preference, that will continue to be used.
A new factory default doesn't (and shouldn't) overwrite an user set preference. NSUserDefaults does exactly what you seem to be after.
I agree with Johan Kool. User defaults work as they should. If there's a preference that you want changed (for whatever reason) in an updated app version, just slightly rename the preference. For example, if someValue was a preference in version 1, then in version 2 name it someValue_v2 and your new factory default will take effect.
I have an iPhone app that stores some settings using NSUserDefault standardUserDefaults.
When I add new features to the app I need to add new default settings and so I have to migrate/upgrade the NSUserDefaults. For now, I just store the version number and check this when the app is launched. It has quickly become very messy as I have to add lots of if statements. I cannot assume that the user is just upgrading from the previous version but perhaps even a couple of versions before.
I like the way that CoreData seems to handle migrating table changes but I want to provide 2.2.1 SDK compatibility and of course CoreData is not the same thing as NSUserDefaults.
Any suggestions or best practices?
Hmm… I wouldn't "upgrade" the user defaults in this way, but instead query NSUserDefaults as usual, only if the default isn't set (objectForKey will return nil in that case), use a default value (which may then be written back to the user defaults to save time the next time). Since you'll have to do this every time a "new" default (i.e. one that didn't exist in 1.0) is read, I advise doing a wrapper class/file that does this, this way the code is written only once for each "new" default.
Also, while the question/problem is different, this answer works just as well in your case.