Open menu with table of contents iOS Framework Basics 3
Logo of Stuttgart Media University for light theme Logo of Stuttgart Media University for dark theme
Mobile Application Development 2

iOS Framework Basics 3

Stuttgart Media University

1 Agenda

  • Framework Components - Storage Options
    • NSUser Defaults
    • Property List
    • Core Data

2 Storing Data on iOS devices locally

  • Data persistence is one of the most important functions in application development. Options to store data on iOS devices are (amonst others):
    • NSUser Defaults
    • Property List
    • Core Data
    • SQLite
    • Key Chain
  • We will focus here on the first three and most often used options to persist data on iOS

3 NSUser Defaults

  • Simple built in data dictionary for storing small amounts of data such as e.g. user settings
  • Example how to store simple data types:
let defaults = UserDefaults.standard
// String
defaults.set("Hans Mueller", forKey: "Name")
// Int
defaults.set(65, forKey: "Age")
// Date object
defaults.set(Date(), forKey: "AccessTime")
// Array
let array = ["Hello", "HdM"]
defaults.set(array, forKey: "StoredArray")
// Dictionary
let dict = ["Firstname": "Hans", "Lastname": "Mueller"]
defaults.set(dict, forKey: "StoredDict")

4 NSUser Defaults

  • Reading objects will never fail but return default values if the key does not exist:

    • integer(forKey:) returns an integer if the key existed, or 0 if not.
    • bool(forKey:) returns a boolean if the key existed, or false if not.
    • float(forKey:) returns a float if the key existed, or 0.0 if not.
    • double(forKey:) returns a double if the key existed, or 0.0 if not.
  • When retrieving objects, the result is optional. This means you can either accept the optionality, or typecast it to a non-optional type and use the nil coalescing operator to handle missing values. For example object(forKey:) returns AnyObject? so you need to conditionally typecast it to your data type:

let savedArray = defaults.object(forKey: "SavedArray") as? [String] ?? [String]()

5 Property Lists

  • Property lists are XML files that comply to Apple's PropertyList DTD
  • An example for a property list is the Info.plist file that resides in all app projects
  • To create your own .plist file go in the Xcode menu to File->New->File->Resource->Property List

center 50%

6 Property Lists

  • To access a property file within the app project use:
let path = Bundle.main.path(forResource: "myprop", ofType: "plist")
let dict = NSDictionary(contentsOfFile: path!)
  • Now you can read the contents like:
// reading a String item
let tableData = dict!.object(forKey: "testitem") as! String
// reading an Array of Strings
let devices = dict!.object(forKey: "devices") as! [String]

7 Property Lists

  • To write to a property file, it needs to be loaded into a mutable dictionary
// load the property file
let writableProp = NSMutableDictionary(contentsOfFile: path!)
// change a value
writableProp?.setValue("Ansgar Gerlicher", forKey: "Name")
// write the property file atomically
writableProp?.write(toFile: path!, atomically: true)

8 Core Data

  • Core Data is an ORM framework to persist objects in iOS
  • To activate it just check the CoreData box, when creating your app project

center 50%

  • This will add some extra code to your AppDelegate class allowing you to access the NSPersistentContainer instance to read and store data

9 Core Data

  • In order to read and store data using Core Data the following steps are necessary:
    • Create a Data Model using the integrated Data Model editor in XCode (here we create a Person entity):

center 50%

  • Inside your ViewController (or whereever you need to access your data model):
    • Import CoreData
    • Obtain an reference to the NSPersistentContainer instance and to the persistence context (viewContext) for this container:
let appDelegate = UIApplication.shared.delegate as! AppDelegate
let container = appDelegate.persistentContainer
let context = container.viewContext

10 Core Data

  • With Xcode version > 8.0 the classes for the entities that are defined in the model editor are automatically generated in the background.
  • Thus it is very easy to create a new instance of our Person class and set it's properties:
let person = Person(context: context)
person.name = "Ansgar R. S. Gerlicher"
person.age = 22

11 Core Data

  • In order to save the data persistently all you need to do is call save()on the context:
do {
    try context.save()
} catch {
    print("Failed saving context")
}

12 Core Data

  • To read stored data from the context, you need to use the NSFetchRequest class to define what objects you want to read
  • Then use the fetch()function to load the objects from the store
let request : NSFetchRequest<Person> = Person.fetchRequest()

do {
    let result = try context.fetch(request)
    for personObject in result {
        print(personObject)
    }
} catch {
    print("Loading Person failed")
}

13 Summary

  • In order to persist data on an iOS device you have many options:
  • Little information such as settings can be stored using the NSUser Defaults
  • App specific information and predefined data can be stored in Property list files
  • Images and binary data can be stored on the file systems
  • App specific data or user generated data can be stored in databases using Core Data ORM framework

14 Recab Questions

  • What kind of data would you store how?
  • When is the best time to persist data?
  • What is the best way to load data from a storage?