Storing variables during lifetime of the ios app - ios

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/

Related

Saving locked and unlocked game levels in spritekit

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

Ship iOS app with pre-populated Parse datastore

Given the recent addition of local datastore for iOS to Parse, it should be possible to rely exclusively on Parse to manage app's database, thus totally avoiding Core Data. Does this sound like a good idea? What would be the pros and cons of such an approach?
In particular, I am wondering whether it will be possible to pre-populate Parse local datastore with some data, and include this database as a part of the app when submitting to appstore.
UPDATE
From the comments that were posted, it seems that people misunderstood my intended use case. Sorry guys, I should have made my question more clear from the beginning. Let me clarify it now, anyway.
So, there is some amount of data in Parse database on the web, same for every user, e.g. a catalogue of books. It will be updated every now and then. What I want is to publish an app on App Store which is pre-populated with Parse data store, as it stands at the moment when the app is published. For that to happen, I'd like to pin all available data when building my app and ship that data store along with the app. The problem is that the pinned data will be stored on device's (or emulator's) file system, it won't be part of the project. That's why if I build the app and submit it to app store, the data won'd be included.
Any suggestions how to attach the local data store to the app?
The local data store is stored in the sandboxed part of the filesystem in iOS. When you package the store with the app, it'll live in the signed application folder, not in the location Parse expects it to be.
So, if you were looking to do this, you'd need to include your default local data store in the application on building/submission, and copy it into the location Parse expects it to be in (which is Library/Private Documents/Parse and the file is called ParseOfflineStore) when your application starts up. This must happen before you call enableLocalDatastore, or an empty one will be initialized.
It should be possible!
Read this in the docs. Parse has a highly resourceful and fully documented guide for their backend.
https://parse.com/docs/ios_guide#localdatastore
Per my comment above concerning didFinishLaunchingWithOptions; it has been a place for your to create objects on launch, I have been doing that for a long time. Especially with channels. However, by enabling the local data store you can access those objects you pinned or created with a simple query with no reachability per your concern. Either way they both are created on disk. Core Data has a lot more cons. Especially with NSFetchedResultsController and the flexibility it offers. It's all up to you what you want to do with your app. PFQueryTableViewController isn't bad but if your direction and vision for your app is to be exclusively Parse then why not. It's a great feature. However I didn't see anything in the docs about the local queries effecting your limit so I would suggest looking into that if you have a large audience performing numerous queries per second.
Take advantage of their docs. They do a great job at keeping us informed.

Lock file for editing in Dropbox

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.

CoreData and iCloud; how can I track which device last saved to the cloud?

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 actions are required when your app get an applicationWillResignActive call?

This question io3->ios4 upgrade said to support applicationWillResignActive. While implementing this call, I also implemented applicationDidEnterBackground and applicationWillEnterForeground. However, I found that my app would crash. After some debugging on the simulator I determined that I needed to reinitialize a key data structure in applicationWillEnterForeground. So my question is how would I have known that from reading the documentation? (In fact, I may be doing the wrong thing and just so happened to get it working again.) Is there an exact description of what to do when these methods are called?
Thanks.
The only things you should do when supporting multitasking, is saving the state of your app when it enters the background, and reload it when it becomes active. (If you generate a new template in Xcode, you'll see this.)
Saving state means writing any user preferences or data to disk. Reloading the state involves reading saved preferences and data, recreating any in memory data structures that might need it (like in your example you gave).
In most circumstances, there's little else you need to do. The only thing that would crash your app that is unique to multitasking would be trying to run code in the background for longer than the allotted amount of time, (which is 10 minutes.) Otherwise, it sounds like you have got other problems with your code.

Resources