How to Save Data in iOS

How to save local data in a Swift app?

The simplest solution for storing a few strings or common types is UserDefaults.

The UserDefaults class provides convenience methods for accessing common types such as floats, doubles, integers, Boolean values, and URLs.

UserDefaults lets us store objects against a key of our choice, It's a good idea to store these keys somewhere accessible so we can reuse them.

Keys

struct DefaultsKeys {
static let keyOne = "firstStringKey"
static let keyTwo = "secondStringKey"
}

Setting

let defaults = UserDefaults.standard
defaults.set("Some String Value", forKey: DefaultsKeys.keyOne)
defaults.set("Another String Value", forKey: DefaultsKeys.keyTwo)

Getting

let defaults = UserDefaults.standard
if let stringOne = defaults.string(forKey: DefaultsKeys.keyOne) {
print(stringOne) // Some String Value
}
if let stringTwo = defaults.string(forKey: DefaultsKeys.keyTwo) {
print(stringTwo) // Another String Value
}


Swift 2.0

In Swift 2.0 UserDefaults was called NSUserDefaults and the setters and getters were named slightly differently:

Setting

let defaults = NSUserDefaults.standardUserDefaults()
defaults.setObject("Some String Value", forKey: DefaultsKeys.keyOne)
defaults.setObject("Another String Value", forKey: DefaultsKeys.keyTwo)

Getting

let defaults = NSUserDefaults.standardUserDefaults()
if let stringOne = defaults.stringForKey(DefaultsKeys.keyOne) {
print(stringOne) // Some String Value
}
if let stringTwo = defaults.stringForKey(DefaultsKeys.keyTwo) {
print(stringTwo) // Another String Value
}

For anything more serious than minor config you should consider using a more robust persistent store:

  • CoreData
  • Realm
  • SQLite

How to save data in iOS

Let's say you want to save score and level, which are both properties of an object called dataHolder.

DataHolder can be created as a singleton, so you don't have to worry too much about from where you access it (its sharedInstance actually):

It's code would look a bit like this:

DataHolder.h

#import <Foundation/Foundation.h>

@interface DataHolder : NSObject

+ (DataHolder *)sharedInstance;

@property (assign) int level;
@property (assign) int score;

-(void) saveData;
-(void) loadData;

@end

DataHolder.m

NSString * const kLevel = @"kLevel";
NSString * const kScore = @"kScore";

@implementation DataHolder

- (id) init
{
self = [super init];
if (self)
{
_level = 0;
_score = 0;
}
return self;
}

+ (DataHolder *)sharedInstance
{
static MDataHolder *_sharedInstance = nil;
static dispatch_once_t onceSecurePredicate;
dispatch_once(&onceSecurePredicate,^
{
_sharedInstance = [[self alloc] init];
});

return _sharedInstance;
}

//in this example you are saving data to NSUserDefault's
//you could save it also to a file or to some more complex
//data structure: depends on what you need, really

-(void)saveData
{
[[NSUserDefaults standardUserDefaults]
setObject:[NSNumber numberWithInt:self.score] forKey:kScore];

[[NSUserDefaults standardUserDefaults]
setObject:[NSNumber numberWithInt:self.level] forKey:kLevel];

[[NSUserDefaults standardUserDefaults] synchronize];
}

-(void)loadData
{
if ([[NSUserDefaults standardUserDefaults] objectForKey:kScore])
{
self.score = [(NSNumber *)[[NSUserDefaults standardUserDefaults]
objectForKey:kScore] intValue];

self.level = [(NSNumber *)[[NSUserDefaults standardUserDefaults]
objectForKey:kLevel] intValue];
}
else
{
self.level = 0;
self.score = 0;
}
}

@end

Don't forget to #import "DataHolder.h" where you need it, or simply put it in ...-Prefix.pch.

You could perform actual loading and saving in appDelegate methods:

- (void)applicationDidEnterBackground:(UIApplication *)application
{
[[DataHolder sharedInstance] saveData];
}

- (void)applicationWillEnterForeground:(UIApplication *)application
{
[[DataHolder sharedInstance] loadData];
}

You can access your score and level data from anywhere with [DataHolder sharedInstance].score and [DataHolder sharedInstance].level.

This might seem like an overkill for a simple task but it sure helps to keep things tidy and it can help you to avoid keeping all the data in appDelegate (which is usually the quick & dirty path to solution).

Best method to store data for an iOS app?

If the data you want to store is very little and not sensitive, you can use UserDefaults
For example, user's name, their age etc.

For Large amounts of data you should use Core Data, its a good and an easy way to manage your objects. For example, you have 1000 items, each with a property, you can basically use core data for that. It is pretty straightforward as how to create Managed Objects, store them and how to later retrieve them using queries.

Basically when you configure your project with core data, project creates an sqlite file attached to your project.

There are many tutorials on how to get started with Core Data, if you have an average experience with iOS, it will be a piece of cake for ya.

Here's a nice tutorial that will help you setup core data in your project:

https://www.raywenderlich.com/173972/getting-started-with-core-data-tutorial-2

Saving data locally (IOS)

You have a number of options to save your app's data.

Which storage option you choose, depends on a number of factors, such as a the volume of data plan to store, performance expectations, how complex your data structure is, Do you plan to sync the data across devices (For eg: Same user installs app on an iPhone & iPad), Security considerations etc.

Bear in mind it's impossible to give an exhaustive list. Here are a few basic options.

Storage Option 1 :
Data that is stored locally on the device.

  • Use Userdefaults - quick and easy, but not recommended.
  • Store data in a file on the device. - Check out iOS Documents on serialisation.
  • Core Data - Use this, If you expect to have a large amount of data, with complex data structure.
  • Other databases, like SQLite. Check out FMDB.

Storage Option 2 :
If you plan to access the data from other locations, (another device, web app etc).

  • iCloud - Apple's cloud storage solution.
  • Firebase
  • Tons of other third party storage as a service options.

Best Way to save data locally on the device in iOS app

It sounds as though the text field (with the 1000-2000 words) is static text that is bundled with the app and can not be changed by the user of the app. If that's the case, then you can store that data in the app bundle with plist files, or JSON files and load it on demand (assuming you don't need to search though it).

Then, if each of those records has only a single boolean value that is changeable by the user, those could be stored in NSUserDefaults very easily (since you've stated you're only dealing with 35-40 records). You'd use the id to link the boolean to the data file.

You could use Core Data or Realm to store the data, but it may be overkill if you don't need a search feature and the user can't change the text. But if you do go with a database option, be aware that you can not store static data (the text), in a location that is backed up by iCloud, or Apple will reject your app. Regardless of whether you use iCloud in the app or not. So if you were to create a Core Data persistent store and save it to the users Documents folder, then load in all the static data, you will be rejected. You would want to save that data store in the users Cache folder so that iCloud doesn't back it up. The issue you'll hit after that though is that you want the user's choices that are your boolean values backed up. This means they need to be stored in a different place. Core Data does have a feature that lets you create Configurations where it will separate the user changeable data from the non-changeable data, but again, that's overkill for your case.

I'd recommend starting with Realm over 'Core Data` for such a small dataset. It's much easier to get up and running.

How to save data permanently untill uninstallation of app in simulator or iphone in swift 3?

The best way to store data is in UserDefaults

You can store and retrieve data from userDefault like

For Save data in UserDefaults

UserDefaults.standard.setValue(token, forKey: "user_token")

For retrieve data in UserDefaults

print("\(UserDefaults.standard.value(forKey: "user_token"))")

As per @vadian's suggestion,

UserDefaults have many methods. To save and retrieve data here, we used value:forKey, similarly if the value is a string then string:forKey and Etc. that are deprecated.

But, here is the best way set(_: forKey:) read @vadian's comment.

How to save data into CoreData in one view controller, and then have a tableview displaying the data in another view controller?

I suspect that what you did was a copy/paste in InterfaceBuilder to create your SecondViewController.

The original code you were using had a variable named tableView which is still referenced in InterfaceBuilder. To fix this, open InterfaceBuilder and find your SecondViewController. If not already expanded, expand your scene objects and select your SecondViewController then using the Inspector on the right, show the "Connections Inspector". You will likely find a tableView outlet with an exclamation mark and another outlet named historyTable. Simply remove the tableView reference and make sure your historyTable is propertly linked.

In regards to the "Unresolved identifier cell", its because you misplaced the closing bracket of your viewDidLoad function. Since your function is not closed, all other functions thereafter are created as local functions of viewDidLoad instead of functions of your SecondViewController. To fix your source, simply remove the bracket that is just above return cell and add it just self.historyTable.dataSource = self (Yes, currently you have it as self.tableView.dataSource but your variable is named historyTable).



Related Topics



Leave a reply



Submit