What Are the Options for Saving Data in iOS

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.

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

Saving data online for IOS

First you need to learn about restful web services. If you are familiar with server side scripting languages like php, then you can create web service for each operation. Here is a good tutorial for creating rest api.

Lets say you want to save chat data from iOS app to server. Here is what will happen.

Client Side (iOS app): Your app will make a request (hit a url ) e.g abc.com/savechat. With this request, your app will "POST" data along with request. e.g sender name, receiver name, message body and time etc. Then server can send response e.g. a success message back to client.

Server Side: Server will perform data operations like storing data and send a response back to client.

For processing web services (JSON) on app side either use libraries like Alamofire for Swift and AFNetworking for Objective C.

What are my options for storing data when using React Native? (iOS and Android)

Here's what I've learned as I determine the best way to move forward with a couple of my current app projects.

Async Storage (formerly "built-in" to React Native, now moved on its own)

I use AsyncStorage for an in-production app. Storage stays local to the device, is unencrypted (as mentioned in another answer), goes away if you delete the app, but should be saved as part of your device's backups and persists during upgrades (both native upgrades ala TestFlight and code upgrades via CodePush).

Conclusion: Local storage; you provide your own sync/backup solution.

SQLite

Other projects I have worked on have used sqlite3 for app storage. This gives you an SQL-like experience, with compressible databases that can also be transmitted to and from the device. I have not had any experience with syncing them to a back end, but I imagine various libraries exist. There are RN libraries for connecting to SQLite.

Data is stored in your traditional database format with databases, tables, keys, indices, etc. all saved to disk in a binary format. Direct access to the data is available via command line or apps that have SQLite drivers.

Conclusion: Local storage; you supply the sync and backup.

Firebase

Firebase offers, among other things, a real time noSQL database along with a JSON document store (like MongoDB) meant for keeping from 1 to n number of clients synchronized. The docs talk about offline persistence, but only for native code (Swift/Obj-C, Java). Google's own JavaScript option ("Web") which is used by React Native does not provide a cached storage option (see 2/18 update below). The library is written with the assumption that a web browser is going to be connecting, and so there will be a semi-persistent connection. You could probably write a local caching mechanism to supplement the Firebase storage calls, or you could write a bridge between the native libraries and React Native.

Update 2/2018
I have since found React Native Firebase which provides a compatible JavaScript interface to the native iOS and Android libraries (doing what Google probably could/should have done), giving you all the goodies of the native libraries with the bonus of React Native support. With Google's introduction of a JSON document store beside the real-time database, I'm giving Firebase a good second look for some real-time apps I plan to build.

The real-time database is stored as a JSON-like tree that you can edit on the website and import/export pretty simply.

Conclusion: With react-native-firebase, RN gets same benefits as Swift and Java. [/update] Scales well for network-connected devices. Low cost for low utilization. Combines nicely with other Google cloud offerings. Data readily visible and editable from their interface.

Realm

Update 4/2020
MongoDB has acquired Realm and is planning to combine it with MongoDB Stitch (discussed below). This looks very exciting.

Update 9/2020
Having used Realm vs. Stitch:
Stitch API's essentially allowed a JS app (React Native or web) to talk directly to the Mongo database instead of going through an API server you build yourself.

Realm was meant to synchronize portions of the database whenever changes were made.

The combination of the two gets a little confusing. The formerly-known-as-Stitch API's still work like your traditional Mongo query and update calls, whereas the newer Realm stuff attaches to objects in code and handles synchronization all by itself... mostly. I'm still working through the right way to do things in one project, which is using SwiftUI, so it's a bit off-topic. But promising and neat nonetheless.


Also a real time object store with automagic network synchronization. They tout themselves as "device first" and the demo video shows how the devices handle sporadic or lossy network connectivity.

They offer a free version of the object store that you host on your own servers or in a cloud solution like AWS or Azure. You can also create in-memory stores that do not persist with the device, device-only stores that do not sync up with the server, read-only server stores, and the full read-write option for synchronization across one or more devices. They have professional and enterprise options that cost more up front per month than Firebase.

Unlike Firebase, all Realm capabilities are supported in React Native and Xamarin, just as they are in Swift/ObjC/Java (native) apps.

Your data is tied to objects in your code. Because they are defined objects, you do have a schema, and version control is a must for code sanity. Direct access is available via GUI tools Realm provides. On-device data files are cross-platform compatible.

Conclusion: Device first, optional synchronization with free and paid plans. All features supported in React Native. Horizontal scaling more expensive than Firebase.

iCloud

I honestly haven't done a lot of playing with this one, but will be doing so in the near future.

If you have a native app that uses CloudKit, you can use CloudKit JS to connect to your app's containers from a web app (or, in our case, React Native). In this scenario, you would probably have a native iOS app and a React Native Android app.

Like Realm, this stores data locally and syncs it to iCloud when possible. There are public stores for your app and private stores for each customer. Customers can even chose to share some of their stores or objects with other users.

I do not know how easy it is to access the raw data; the schemas can be set up on Apple's site.

Conclusion: Great for Apple-targeted apps.

Couchbase

Big name, lots of big companies behind it. There's a Community Edition and Enterprise Edition with the standard support costs.

They've got a tutorial on their site for hooking things up to React Native. I also haven't spent much time on this one, but it looks to be a viable alternative to Realm in terms of functionality. I don't know how easy it is to get to your data outside of your app or any APIs you build.

[Edit: Found an older link that talks about Couchbase and CouchDB, and CouchDB may be yet another option to consider. The two are historically related but presently completely different products. See this comparison.]

Conclusion: Looks to have similar capabilities as Realm. Can be device-only or synced. I need to try it out.

MongoDB

Update 4/2020

Mongo acquired Realm and plans to combine MongoDB Stitch (discussed below) with Realm (discussed above).


I'm using this server side for a piece of the app that uses AsyncStorage locally. I like that everything is stored as JSON objects, making transmission to the client devices very straightforward. In my use case, it's used as a cache between an upstream provider of TV guide data and my client devices.

There is no hard structure to the data, like a schema, so every object is stored as a "document" that is easily searchable, filterable, etc. Similar JSON objects could have additional (but different) attributes or child objects, allowing for a lot of flexibility in how you structure your objects/data.

I have not tried any client to server synchronization features, nor have I used it embedded. React Native code for MongoDB does exist.

Conclusion: Local only NoSQL solution, no obvious sync option like Realm or Firebase.

Update 2/2019

MongoDB has a "product" (or service) called Stitch. Since clients (in the sense of web browsers and phones) shouldn't be talking to MongoDB directly (that's done by code on your server), they created a serverless front-end that your apps can interface with, should you choose to use their hosted solution (Atlas). Their documentation makes it appear that there is a possible sync option.

This writeup from Dec 2018 discusses using React Native, Stitch, and MongoDB in a sample app, with other samples linked in the document (https://www.mongodb.com/blog/post/building-ios-and-android-apps-with-the-mongodb-stitch-react-native-sdk).

Twilio Sync

Another NoSQL option for synchronization is Twilio's Sync. From their site:
"Sync lets you manage state across any number of devices in real time at scale without having to handle any backend infrastructure."

I looked at this as an alternative to Firebase for one of the aforementioned projects, especially after talking to both teams. I also like their other communications tools, and have used them for texting updates from a simple web app.


[Edit] I've spent some time with Realm since I originally wrote this. I like how I don't have to write an API to sync the data between the app and the server, similar to Firebase. Serverless functions also look to be really helpful with these two, limiting the amount of backend code I have to write.

I love the flexibility of the MongoDB data store, so that is becoming my choice for the server side of web-based and other connection-required apps.

I found RESTHeart, which creates a very simple, scalable RESTful API to MongoDB. It shouldn't be too hard to build a React (Native) component that reads and writes JSON objects to RESTHeart, which in turn passes them to/from MongoDB.


[Edit] I added info about how the data is stored. Sometimes it's important to know how much work you might be in for during development and testing if you've got to tweak and test the data.


Edits 2/2019 I experimented with several of these options when designing a high-concurrency project this past year (2018). Some of them mention hard and soft concurrency limits in their documentation (Firebase had a hard one at 10,000 connections, I believe, while Twilio's was a soft limit that could be bumped, according to discussions with both teams at AltConf).

If you are designing an app for tens to hundreds of thousands of users, be prepared to scale the data backend accordingly.

What is the best way to store / load local data in iOS?

I know that your structure is more complicated, but I wanted to tackle the multiple arrays question. Consider something like:

let teachers = ["Larry Fine", "Curly Howard", "Moe Howard"]
let classNames = ["Calculus 101", "Religious Studies 102", "Teaching with Technology in Film and Media Studies 201"]

Rather than having multiple arrays, you might have a single structure, e.g.:

struct Course: Codable {
let teacher: String
let className: String
}

You could then represent that in a single JSON structure in a text file, say courses.json, like so:


[
{
"teacher" : "Larry Fine",
"className" : "Calculus 101"
},
{
"teacher" : "Curly Howard",
"className" : "Religious Studies 102"
},
{
"teacher" : "Moe Howard",
"className" : "Teaching with Technology in Film and Media Studies 201"
}
]

In Swift 4, you'd do something like:

var courses: [Course]?

And then to load a JSON file from your bundle and populate courses:

let fileURL = Bundle.main.url(forResource: "courses", withExtension: "json")!
let data = try! Data(contentsOf: fileURL)
courses = try! JSONDecoder().decode([Course].self, from: data)

You then end up with a single array of courses which has advantages over the separate teachers and courseNames arrays. For example, if you want to sort the courses by course name, it makes sure that the course name and teacher name are sorted together.

Now, I know your structure is more complicated than this, so your JSON is likely to get more complicated, too, but I just wanted to illustrate the idea of (a) custom objects; and (b) using Swift 4's new Codable protocol and JSONDecoder to parse that JSON.

Data Storage options for iOS


NSUserDefaults

  • NSUserDefaults is really meant for storing small pieces of data such as settings, preferences, and individual values.
  • NSUserDefaults offers a trivial learning curve and thread safe implementation.

CoreData

  • Learning curve may be a bit steep
  • CoreData and related classes provide easy ways to get your entities into UITableViews, like NSFetchedResultsController.
  • CoreData abstracts away a lot of the messy things you'd otherwise have to deal with yourself, such as lists of objects, one-to-many or many-to-many relationships, or constraints on object attributes, into a single nice clean object-oriented interface
  • CoreData manages save and undo functionality for you. It has a persistent store, which tracks changes, and can be flushed to the disk automatically at any number of times

However, if you're new to Cocoa I would avoid CoreData, to give yourself a chance to learn the basics first.

If I had to choose I would dive directly into CoreData. It makes sense also for small projects. NSUserDefaults is not meant to be used as a database (all the operations are ran on the main thread).

storing data locally on the iphone

For simple data you should use NSUserDefaults. CoreData is very cool but mainly to store DB structures, and introduces complexity (but i love it:)). If you just need to store String, Array and so on (basically prefs), you can go with NSUserDefaults:

For example:

NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];  //load NSUserDefaults
NSArray *fakeFavs = [[ NSArray alloc] initWithObjects:@"2",@"4", @"100", nil]; //declare array to be stored in NSUserDefaults
[prefs setObject:fakeFavs forKey:@"favourites"]; //set the prev Array for key value "favourites"


Related Topics



Leave a reply



Submit