My game uses cocos2d-x and will be published on iOS platform first, later on Android. I save a lot of things with CCUserDefault (scores, which level was completed, number of coins taken, etc...). But now i have a big doubt.
What will happen when the game will receive its first update?
CCUserDefault uses an xml file stored somewhere in the app storage space. This file is created and retained until one uninstall the app. I am wondering what happens when the app is updated. Will the old xml file mantained?
Because if not, how should i handle app updates (updates in the sense that 2,3 or more new level packages will be added, but the informations about the old ones, like scores, which level was finished and which not, number of coins etc..., need absolutely not to be lost)?
Thanks.
As much I know normally they not reset on update, you need to delete the app. What I think what you need at your first/previous update that you make some setting which signify/tell about version and if it not equal to recent one than update your NSUserDefualt with some basic setting or say reset your setting.
Ok, i found the answer. CCUserDefault stores the xml file under:
application_home/library/caches
The iOS App Programming Guide states that all the data under
application_home/document
application_home/library
will be preserved. That is, after the update, your userdefault.xml file will be still there.
Related
In my spritekit app, I have Chapters which contain 30 levels. All of the levels are initially locked. Once a level is won, the next level is unlocked. NSUserDefaults does not seem like an ideal choice. I tried to save my data in a plist file in the "application support" folder by having an array for each level pack and a value (1 or 0 depending on the level's status) that corresponds to each level. This also did not seem ideal because it could be edited and would be reset with an update.
My goal is to have this data persist through an app Update and not be easily edited by a user. Are there any good solutions for this?
NSUserDefaults is a actually a very good way to store data like this. You are after all only talking about storing BOOL values. NSUserDefaults is not reset or deleted during an app update unless the user deletes the app. This is stated in the iPhone iOS Programming Guide, Files Saved During Update (page 114):
When a user downloads an app update, iTunes installs the update in a new app directory. It then moves the user’s data files from the old installation over to the new app directory before deleting the old installation.
As Whirlwind already commented, there are many ways to store data. Here is a link to a previous question dealing with various storage methods.
You can serialize your property list and store it as data into the NSUserDefaults. You can also encrypt it before storing, to ensure nobody can modify it in any way.
Apple Docs for plist serialization
https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/PropertyLists/SerializePlist/SerializePlist.html
I am building app in iOS that saves data in Dropbox. Multiple device can use the same data. While doing this, sometime two device may overwrite same file. To avoid this situation is there any like lock file for writing.
Any alternative workaround solutions are also welcome.
While I don't know the Dropbox API, I would always be careful with a locking mechanism. I know from some systems, that the locks lead to a problem, if for example the app crashes or quits and the lock does not get released.
A very simple approach though would be to store the modification date when you have read the file. Then, before saving changes, compare your stored value with the most current one. If they are different, the file was modified. Next ask your users how to proceed and either commit the changes, cancel or create a new file with the same name and some appendix. That is how some sync clients I use are dealing with this problem.
I have a CoreData app (using https://github.com/lhunath/UbiquityStoreManager), backed by iCloud. In one use case a user with a local store enables iCloud (where data already exists). I want to prompt the user to make a decision of whether to migrate the local data to iCloud or just use the iCloud version. As part of this, I'd like to display the device name and last sync date of the version in iCloud.
I've been tinkering around with my NSPersistentStore's metadata, but that doesn't appear to get synced to iCloud.
Any suggestions?
You could use iCloud's key-value store to store the device name & date of the last sync.
My no doubt unpopular suggestion is "don't". Trying to determine what is in iCloud at any given time puts you on pretty shaky ground. You may be able to get it to work most of the time, but there will always be circumstances where it breaks down.
If you really must import some data when first enabling iCloud, I suggest just always importing the data, and then deduping later as the iCloud data comes in. As ugly as it sounds, that's the only approach really guaranteed to work with Apple's approach.
It is worth taking a look at other Core Data sync frameworks like TICDS and Ensembles. They take a more sane approach to data identity, which means you can avoid the whole deduping step. (Disclosure: I develop Ensembles)
do a metadata query on the iCloud files and check the most recent transaction log file in iCloud. See the link below for a sample app that uses this approach to check whether the app is properly synchronised with iCloud.
http://ossh.com.au/design-and-technology/software-development/sample-library-style-ios-core-data-app-with-icloud-integration/
EDIT:
I just realised I don't get the actual device name, but once you have found the most recent log file then use this to get the device. Just be aware this call may be expensive.
NSFileVersion *openedVersion = [NSFileVersion currentVersionOfItemAtURL:fileURL];
return openedVersion.localizedNameOfSavingComputer;
What happens to the app when it is killed/terminated from the multitasking tray (i.e double click the home button and delete it from there)? And i relaunch the app again by clicking on it? Consider this scenario. I save some variables (global variables) and i save some values to them. I killed/deleted the app from multitasking tray and relaunched it. I no longer have variable values. How can i store them through the entire process of app life cycle and they can be changed when someone changes within the app life cycle. If you need more information please ask. I have been saving the values to a plist file.I created a settings bundle and saving values to them as global variables..is it the way to go?
To save data even after the app is killed/terminated, you have to use persistent storage. There are a number of different ways to do this. A few of these ways are using NSUserDefaults, plists, or CoreData.
See these links, and try to find out what's best for what you're trying to do.
iOS persistent storage strategy
Use SQLite, plist, or something else?
You should also check out the iOS development lectures, there's two parts and the first part covers persistent storage in great detail. It's called Effective iPhone App Development. I recommend watching both, but the first part of the first one would answer your questions.
https://developer.apple.com/videos/ios/
I've been having trouble getting an app submitted to the App Store. This is due to the fact that that database, which is updatable, is too large for the iCloud backup limitations. Most of the data in the db is static, but one table records the user's schedule for reviewing words (this is a vocabulary quiz).
As far as I can tell, I have two or three realistic options. The first is to put the whole database into the Library/Cache directory. This should be accepted, because it's not backed up to iCloud. However, there's no guarantee that it will be maintained during app updates, per this entry in "Make App Backups More Efficient" at this url:
http://developer.apple.com/library/IOs/#documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/PerformanceTuning/PerformanceTuning.html
Files Saved During App Updates
When a user downloads an app update, iTunes installs the update in a new app directory. It then moves the user’s data files from the old installation over to the new app directory before deleting the old installation. Files in the following directories are guaranteed to be preserved during the update process:
<Application_Home>/Documents
<Application_Home>/Library
Although files in other user directories may also be moved over, you should not rely on them being present after an update.
The second option is to put the data into the NSDocuments or NSLibrary directory, as mark it with the skipBackupFlag. However, one problem is this flag doesn't work for iOS 5.0 and previous per this entry in "How do I prevent files from being backed up to iCloud and iTunes?" at
https://developer.apple.com/library/ios/#qa/qa1719/_index.html
Important The new "do not back up" attribute will only be used by iOS 5.0.1 or later. On iOS 5.0 and earlier, applications will need to store their data in <Application_Home>/Library/Caches to avoid having it backed up. Since this attribute is ignored on older systems, you will need to insure your app complies with the iOS Data Storage Guidelines on all versions of iOS that your application supports
This means that even if I use the "skipBackupFlag", I'll still have the problem that the database is getting backed up to the cloud, I think.
So, the third option, which is pretty much of an ugly hack, is to split the database into two. Put the updatable part into the NSLibrary or NSDocuments directory, and leave the rest in application resources. This would have the small, updatable part stored on the cloud, and leave the rest in the app resources directory. The problem is that this splits the db for no good reason, and introduces possible performance issues with having two databases open at once.
So, my question is, is my interpretation of the rules correct? Am I going to have to go with option 3?
p.s. I noticed in my last post cited urls were edited to links without the url showing. How do I do this?
Have you considered using external file references as described in https://developer.apple.com/library/IOS/#releasenotes/DataManagement/RN-CoreData/_index.html . Specifically, refer to "setAllowsExternalBinaryDataStorage:" https://developer.apple.com/library/IOS/documentation/Cocoa/Reference/CoreDataFramework/Classes/NSAttributeDescription_Class/reference.html#//apple_ref/occ/instm/NSAttributeDescription/setAllowsExternalBinaryDataStorage: . Pushing out large data into a separate file can help reduce database size .