Saving function in swift - swift

I have made an app which has 15 levels, in which each level has 3 stages.
So overall I have 45 scenes/viewcontrollers.
I'm trying to figure out how I can create a saving function, so that if you close the app on the phone and you open it later, it will remember which level/stage you were at. I just started with swift and I am also wondering if this is way too ahead of my programming level to create this, but hopefully it might be more simple than I thought?

As long as the desired pieces are small, which simply saving level/stage text info would be, NSUserDefaults is the way to go.
Core Data is a great technology, but takes a bit of learning and is overkill for only saving a tiny bit of information. Been using NSUserDefaults myself a bunch lately, and it's working well.
//in Swift:
let defaults = NSUserDefaults.standardUserDefaults()
//send data to NSUserDefaults:
defaults.setObject(desiredValue, forKey: stringNameOfValue)
//retrieve data from NSUserDefaults:
desiredValue = defaults.objectForKey(stringNameOfValue)
for more info:
https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/NSUserDefaults_Class/

As already noted, NSUserDefaults is a great option for the scale of data storage you're looking at. But another good option is to use NSUbiquitousKeyValueStore. That class works similarly, but adds the ability to sync the small data items you're saving to iCloud.
There's a little bit more you have to think about when using iCloud KVS, but it's almost the same as using NSUserDefaults. And for that tiny bit of extra effort, your users get a huge win: when you close the app on your phone, you can open it later, on the same iPhone or on your iPad, Apple TV, Mac, iPod touch, other iPhone, etc, and still have it remember where you left off.

Related

NSUserDefaults Inconsistency or device inconsistency? - iPhone

I have developed a server based app for iPhone. But according to client requirements and to avoid overloading on server side, i am required to store data on local end. It is all text and typically 2-4 MB in size.
For this i'm using NSUserDefaults instead of sqlite or CoreData.
The app has been tested successfully for around 2-3 months during it's development as well as post development testing and never shown any type of inconsistency in data storage, updation or deletion on any sort of iphone device from iphone 3G - iphone 4S.
Now there is an incosistency issue in the live app, when user leave the app idle on a screen for around 15-20 minutes and doesn't press home button means app is not in the background.
In this case, data seems to be lost.
But as soon as refresh app, in that case data appears again & app starts functioning normal again.
Here lies the main problem that when i'm refreshing, i'm doing nothing but only fetching fresh data from the server it can be simply one to five records or nothing at all.
Then app is refreshed, all of the records are shown & it functions normally.
I have been trying to spot the issue for around 3 days, and it's not happening on my device (iPhone 4S). As far as i can think, it seems to be problem with the old devices.
Previously in testing, none of this happened on old or new devices.
My questions are -
a) Is this an incosistency in my coding?
b) Are NSUserDefaults not trustworthy for database management for live apps?
c) Is it a device version specific problem related to NSUserDefaults?
Anybody faced/facing the problem with NSUserDefaults??
Please suggest me something i can do for this or tell me i have to do all the database work again for the next version using sqlite or CoreData.
Anyhow this is critically important and needs to be fixed.
Any help is appreciated in advance.
As my suggestion for you please introduce the Sqlite database integration because of the when the short size of the data store and of cause it's good rather then the Sqlite but it's not working into large number of the data that time must use the Sqlite or coredata.
so i suggest to use the Sqlite data and coredata.

How to offer non-consumable content for in app purchase?

I am developing an app for learning piano and I would like to offer lessons as non-consumable in app purchases. All of the files that are required for the lesson will be bundled with the app (as they don't take up a ton or space; two PDFs, a .mid, and a .png). Currently, for testing purposes, I have just been hard coding the lessons into my app and they get loaded on viewDidLoad.
My question is how can I store a library of lessons that I can modify when a purchase is made to show that it had been purchased? Essentially, all I want to do is when a completed transaction is received, the value of purchaseStatus will change from 0 to 1.
The stored data consists of a number of strings, NSNumbers, and an array of NSNumbers.
I have seen a few options such as plists and NSUserDefaults but I'd really appreciate some advice on the best way to go about it.
Thanks in advance :)
I would say storing the purchase status of each purchasable module in an NSDictionary that you store in NSUserDefaults would probably be the most straightforward/simplest option. Every time you launch the app, query this dictionary to determine what has been purchased and accordingly reveal those purchased entities to the user (in the form of an entry in a table view, an icon, a no longer hidden button, etc.).
Plists are fair game as well, but it would require a bit more maintenance (where to store the plist so that it may be backed up by iCloud, etc.) whereas NSUserDefaults has that all taken care of for you (it's backed up by iCloud).

iPhone OS: implementing your own achievements, how do I do it?

I'm working on a game where really the only game part is (at least right now) that the user can unlock achievements as she does various things throughout the game. I have a database that can keep track of certain user actions and record how many times a user does something but I'm having trouble figuring out the best way to architect the app so that I have to do the least amount of work. Kind of suck with the timing because gamecenter is not ready and it seems like openfeint is changing gears, but maybe I'm wrong. I'd prefer to do everything "in house" if it is not too ridiculous. looking for suggestions.
One of the parts I'm having the most trouble figuring out is how to manage the state of all the achievements. NSuserdefaults vs. core data vs. a flat data file.
Also is there anyway to send a notification if a core data field reaches a certain amount?
Thanks,
Nick
Are you keeping the achievements on the device only, or also on the server? On the device, there is no reason not to use Core Data.
Using Core Data, you could use KVO on your model properties to monitor when certain values reach a new achievements.

Do NSUserDefaults persist through an Update to an app in the Appstore?

Is this the case? Do NSUserDefaults get reset when you submit an update to an app on the App Store, or are they reset?
My app is crashing when updated but not crashing when downloaded fully - so I'm trying to determine what could possibly be different in the updated session to the freshly downloaded session.
Cheers,
Nick.
They are usually not reset unless the user deletes the app. For basic data, NSUserDefaults is the best way to save data such as preferences, dates, strings etc. If you are looking to save images and files, the file system is a better bet.
I beleive the answer is YES, it will persist. This also fully documented under the Application Directory chapter in the Apple iPhone OS Programming Guide.
Direct answer to the posted question: YES.
Your problem:
Your app gets crashed due to logic issues. Suppose you store an object in defaults and the app checks it's value on launch (or elsewhere). In you update you could change the way it is checked or used, e.g. you expect a value, but the object is nil, or vice versa. This may cause a SIGABRT or EXC_BAD_ACCESS.
If you had CoreData model and you changed something in your model and update, without managing migration, thats probably reason why your app crashes on update...
I have a similar experience. Our app stores a version number in Settings.Bundle/Root.Plist. This gets displayed through the iPhone Settings app. What we find is that on an Install the version number gets loaded from the app bundle - therefore the version number is correct. On an update however the version number doesn't change. This gives the impression the user is running a previous version of the app. We don't have any logic linked to the version number, it's just for display (it could be used by contact centre staff when diagnosing faults).
Our experience is NSUserDefaults doesn't get cleared when a user updates our app, but the Settings display doesn't get updated either.
Be aware of this case, when your app is running in background and you cannot access your stored values in NSUserDefaults:
Eric:
There have been many threads and bugs about this, but it's happening to me again in ios 9. I have an app that launches in the background in response to NSURLSession tasks and content-available pushes. Reproducibly, if I reboot my phone and wait for a background launch of my app to happen, then when I open the app I find that [[NSUserDefaults standardUserDefaults] dictionaryRepresentation] contains all the system values, e.g. AppleITunesStoreItemKinds, etc. but does not contain any of the values I have set. If I force-quit and relaunch the app all of my values come back. Is there any way to avoid it caching the "empty" standardUserDefaults from before the phone is unlocked, or at least to determine when they are messed up and fix them without having to force-quit the app?
Eskimo (eskimo1#apple.com):
The problem here is that NSUserDefaults is ultimately backed by a file in your app’s container and your app’s container is subject to data protection. If you do nothing special then, on iOS 7 and later, your container uses NSFileProtectionCompleteUntilFirstUserAuthentication, a value that’s inherited by the NSUserDefaults backing store, and so you can’t access it prior to first unlock.
IMO the best way around this is to avoid NSUserDefaults for stuff that you rely on in code paths that can execute in the background. Instead store those settings in your own preferences file, one whose data protection you can explicitly manage (in this case that means ‘set to NSFileProtectionNone’).
There are two problems with NSUserDefaults in a data protection context:
Its a fully abstract API: the presence and location of its backing store is not considered part of that API, so you can’t explicitly manage its data protection.
Note On recent versions of OS X NSUserDefaults is managed by a daemon and folks who try to manipulate its backing store directly have run into problems. It’s easy to imagine the same sort of thing coming to iOS at some point.
Even if changing the data protection were possible, NSUserDefaults has no mechanism to classify data based on the context in which you’re using it; it’s an ‘all or nothing’ API. In your case you don’t want to remove protection from all of your user defaults, just those that you need to access in the background before first unlock.
Finally, if any of this data is truly sensitive, you should put it in the keychain. Notably, the keychain does have the ability to set data protection on an item-by-item basis.
Source:
https://webcache.googleusercontent.com/search?q=cache:sR9eZNHpZtwJ:https://forums.developer.apple.com/thread/15685

iPhone: is it possible to alter data in an application's Documents folder?

I am building an iPhone game where I store the player's game data in the Documents folder of the application. The game data is serialized to disk using encodeWithCoder. Using this approach, am I at risk of malicious players altering the game data by hand?
I know jail broken phones give you ssh access to your phone. So in theory, a player can ssh into his phone, find the game data, and edit it using vi to tweak their data?
I have a jail broken phone for testing and I'm trying it now, but each attempt at editing it seems to corrupt the file and make it impossible to be read by the game.
I'm also trying to scp the data file to my dev machine, open it up using xcode, tweaking the values, and sending it back to the app. But I'm not having any success on seeing the new values appear in the game.
So am I safe from this type of exploit?
Thanks.
If you are really worried about it, encrypt it.
I say if since the # of people who are going to jailbreak their phone to hack your app is so miniscule it is not worth worrying about. If and when it is worth worrying about, you can change it.
This smells like a premature optimization to me.
No, on a jailbroken iPhone the user can do whatever he likes to do, even change your file. The only save place is the internet on a by you controlled server.
Agreed, this sounds like a minor problem. Why would a user want to go through the trouble of hex editing their score on a jailbroken device? The last time I even thought of doing something similar was with Neuromancer on the Apple II+.
If you do have a case where trusted local data is required as part of some online competition, you could try storing it on the device using the Keychain API, although even that might be accessible to the local user.