Xcode 11.4 with iOS 13.4 and Swift 5.2 is here! Data Storage Mobile Applica,on Development in iOS School of EECS Washington State University Instructor: Larry Holder Mobile Applica,on Development in iOS 1
Data Storage • Already seen: UserDefaults • File I/O: Read, Write, Codable • Database support: CoreData • Data in the cloud: Firebase Mobile Application Development in iOS 2
File I/O • FileManager – .default: singleton shared file manager for app – Numerous methods for manipulaAng files • FileManagerDelegate – Constraint checking and error handling Mobile Application Development in iOS 3
File I/O Process • Get URL to directory • Append file name to URL • Convert data to String • Use String.write(to: URL, atomically: Bool, encoding: .uA8) to write – Atomically: write to auxiliary file first • Use String(contentsOf: URL , encoding: .uA8) to read • Both throw errors Mobile Application Development in iOS 4
File I/O: Write func writeData(_ str: String, to fileName: String) -> Bool { if let directoryURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first { let fileURL = directoryURL.appendingPathComponent(fileName) do { try str.write(to: fileURL, atomically: true, encoding: .utf8) return true } catch { print("\(error)") } } else { print("Error accessing document directory.") } return false } Mobile Applica,on Development in iOS 5
File I/O: Read func readData(from fileName: String) -> String? { if let directoryURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first { let fileURL = directoryURL.appendingPathComponent(fileName) do { let str = try String(contentsOf: fileURL, encoding: .utf8) return str } catch { print("\(error)") } } else { print("Error accessing document directory.") } return nil } Mobile Applica,on Development in iOS 6
File I/O: Codable • Problem: Convert everything to a String ☹ • Solu5on: Codable types – Can be encoded/decoded to common formats, e.g., JSON – JSON data easily converted to/from String • All basic types and containers are Codable • Classes consis5ng of Codable proper5es are Codable Mobile Application Development in iOS 7
File I/O: Codable class Player: Codable { var name: String var health: Int var inventory: [String] init(name: String, health: Int) { self.name = name self.health = health self.inventory = [] } func printPlayer() { print("Player: name = \(name), health = \(health), inventory = \(inventory)") } } Mobile Applica,on Development in iOS 8
File I/O: Codable func writePlayers(_ players: [Player], to fileName: String) -> Bool { let jsonEncoder = JSONEncoder() do { let jsonData = try jsonEncoder.encode(players) if let jsonStr = String(data: jsonData, encoding: .utf8) { if writeData(jsonStr, to: fileName) { return true } } } catch { print("\(error)") } return false } Mobile Applica,on Development in iOS 9
File I/O: Codable func readPlayers(from fileName: String) -> [Player] { if let str = readData(from: fileName) { if let jsonData = str.data(using: .utf8) { let jsonDecoder = JSONDecoder() do { let players = try jsonDecoder.decode([Player].self, from: jsonData) return players } catch { print("\(error)") } } } return [] } Mobile Applica,on Development in iOS 10
Database Support Core Data • – iOS-specific object store SQLite (www.sqlite.org) • – Cross-pla3orm table store (already available in iOS) Third-party opBons ($) • – Realm (realm.io) • Cross-pla)orm object store – Firebase (firebase.google.com) • Real2me Database: Cross-pla)orm JSON document store • Cloud Firestore: Cross-pla)orm document store Mobile Application Development in iOS 11
Core Data • Check “Use Core Data” for New Project – Includes empty data model – Includes boilerplate code to create database • Or, add Core Data model to exis5ng project Mobile Application Development in iOS 12
Core Data Stack: Model • Create Managed Object Model (Schema) • Schema consists of enAAes, their aJributes, and relaAonships Mobile Application Development in iOS 13
Core Data Stack: Persistent Container and Context • Persistent container (NSPersistentContainer) – Data store (the "database") – Defined in AppDelegate.swiF – Obtained from UIApplicaHon.shared.delegate • Managed object context (NSManagedObjectContext) – Tracks changes to data store unHl saved – Obtained from NSPersistentContainer.viewContext Mobile Application Development in iOS 14
Core Data Stack: Access import CoreData class TableViewController: UITableViewController { var managedObjectContext: NSManagedObjectContext! var appDelegate: AppDelegate! override func viewDidLoad() { super.viewDidLoad() appDelegate = UIApplication.shared.delegate as? AppDelegate managedObjectContext = appDelegate.persistentContainer.viewContext } } Mobile Applica,on Development in iOS 15
Core Data: Insert • Methods – NSEnHtyDescripHon.insertNewObject(forEnHtyName: String, into: NSManagedObjectContext) -> NSManagedObject – NSManagedObject.setValue(value: Any?, forKey: String) – NSManagedObjectContext.save() Mobile Application Development in iOS 16
Core Data: Insert func addPlayer(name: String, health: Int) { let player = NSEntityDescription.insertNewObject(forEntityName: "Player", into: self.managedObjectContext) player.setValue(name, forKey: "name") player.setValue(health, forKey: "health") appDelegate.saveContext() // In AppDelegate.swift } Mobile Applica,on Development in iOS 17
Core Data: Fetch • Methods – NSFetchRequest<NSManagedObject>(en7tyName: String) -> NSFetchRequest<NSManagedObject> – NSFetchRequest<NSManagedObject>.predicate = NSPredicate(format: String, args...) – NSManagedObjectContext.fetch(request: NSFetchRequest<NSManagedObject>) throws Mobile Application Development in iOS 18
Core Data: Fetch func getPlayers() -> [NSManagedObject] { let fetchRequest = NSFetchRequest<NSManagedObject>(entityName: "Player") var players: [NSManagedObject] = [] do { players = try self.managedObjectContext.fetch(fetchRequest) } catch { print("getPlayers error: \(error)") } return players } func printPlayer(_ player: NSManagedObject) { let name = player.value(forKey: "name") as? String let health = player.value(forKey: "health") as? Int print("Player: name = \(name!), health = \(health!)") } Mobile Applica,on Development in iOS 19
Core Data: Delete • Methods – NSManagedObjectContext.delete(object: NSManagedObject) – NSManagedObjectContext.save() Mobile Application Development in iOS 20
Core Data: Delete func removePlayersByName(_ name: String) { let fetchRequest = NSFetchRequest<NSManagedObject>(entityName: "Player") fetchRequest.predicate = NSPredicate(format: "name == %@", name) var players: [NSManagedObject]! do { players = try self.managedObjectContext.fetch(fetchRequest) } catch { print("removePlayersByName error: \(error)") } for player in players { managedObjectContext.delete(player) } appDelegate.saveContext() // In AppDelegate.swift } func removePlayer(_ player: NSManagedObject) { managedObjectContext.delete(player) appDelegate.saveContext() } Mobile Applica,on Development in iOS 21
Firebase • firebase.google.com • Authentication • Realtime Database – Cross-platform JSON document store (NoSQL) • Cloud Firestore – Cross-platform document store (NoSQL) – Stores Collections of Documents – Documents contain key/value pairs Mobile Applica,on Development in iOS 22
Firebase Setup • Create Google account • Goto firebase.google.com • "GO TO CONSOLE" and sign in • Add project Mobile Applica,on Development in iOS 23
Firebase Setup • Add Firebase to app – Register app – Download config property list file and add to app – Add Firebase SDK to app • Cocoapods: pod 'Firebase/AnalyHcs' – Add iniAalizaAon code Mobile Application Development in iOS 24
Firebase Setup // AppDelegate.swift import UIKit import Firebase @UIApplicationMain class AppDelegate: UIResponder, UIApplicationDelegate { func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { // Override point for customization after application launch. FirebaseApp.configure() return true } // ... } Mobile Applica,on Development in iOS 25
Firebase Authentication • Pod 'Firebase/Auth' • Enable authenHcaHon methods Mobile Application Development in iOS 26
Firebase Authentication Firebase Authen@ca@on import FirebaseAuth // Create user Auth.auth().createUser(withEmail: email, password: password) { authResult, error in // ... } // Sign in (existing user) Auth.auth().signIn(withEmail: email, password: password) { authResult, error in // ... } // Current user let user = Auth.auth().currentUser // Sign out current user try? Auth.auth().signOut() Mobile Applica,on Development in iOS 27
Cloud Firestore: Create Database Mobile Application Development in iOS 28
Recommend
More recommend