Swift - Möglichkeiten Daten zu speichern: Unterschied zwischen den Versionen
Steff (Diskussion | Beiträge) K |
Steff (Diskussion | Beiträge) K (→Einführung) |
||
| Zeile 11: | Zeile 11: | ||
# '''Cloud Service:''' Durch die Verwendung von Cloud-Service-Anbietern wie AWS, Firebase oder Firestore kann die Daten auf deren Servern gespeichert werden, anstatt auf dem lokalen Gerät. Dieser Ansatz eignet sich, wenn die Daten unter verschiedenen Benutzern geteilt werden oder auf mehreren Geräten zugänglich sein sollen. | # '''Cloud Service:''' Durch die Verwendung von Cloud-Service-Anbietern wie AWS, Firebase oder Firestore kann die Daten auf deren Servern gespeichert werden, anstatt auf dem lokalen Gerät. Dieser Ansatz eignet sich, wenn die Daten unter verschiedenen Benutzern geteilt werden oder auf mehreren Geräten zugänglich sein sollen. | ||
| − | [[Datei:Swift-ios-DatenSpeichern.jpg| | + | [[Datei:Swift-ios-DatenSpeichern.jpg|800px|zentriert]] |
| + | |||
| + | [[|800px|miniatur]] | ||
Letztlich hängt die Wahl der Methode zum Speichern von Daten von den spezifischen Anforderungen Ihrer App ab, einschließlich der Menge an zu speichernder Daten, der Komplexität des Datenmodells und den Anforderungen an die Datensynchronisierung und Sicherung. | Letztlich hängt die Wahl der Methode zum Speichern von Daten von den spezifischen Anforderungen Ihrer App ab, einschließlich der Menge an zu speichernder Daten, der Komplexität des Datenmodells und den Anforderungen an die Datensynchronisierung und Sicherung. | ||
Version vom 28. Januar 2023, 11:34 Uhr
Links
Swift (Programmiersprache)
Einführung
Es gibt mehrere Möglichkeiten, Benutzerdaten wie Notizen oder Einkaufslisten in einer iPhone-App, die in Swift geschrieben ist, zu speichern. Einige der populärsten Optionen sind:
- User Defaults: Dies ist eine einfache und einfach zu verwendende Methode zum Speichern von kleinen Mengen an Benutzerdaten. Es speichert Daten im Schlüssel-Wert-Paar-Format und die Daten werden automatisch gespeichert, wenn die App geschlossen wird oder im Hintergrund läuft.
- Core Data: Core Data ist ein Framework für objektrelationales Mapping (ORM), mit dem Entwickler auf das Datenmodell der App zugreifen können. Es ist eine leistungsstarke und flexible Lösung zum Speichern und Abrufen großer Datenmengen und bietet Funktionen wie Rückgängig- und Wiederholen-Funktionen, Änderungsverfolgung und Datenvalidierung.
- Realm: Realm ist ein von Dritten bereitgestelltes ORM, das Core Data ähnlich ist, aber im Allgemeinen als leichter und schneller gilt.
- File I/O: Dies ist die traditionelle Methode zum Speichern von Daten in iOS-Apps. Entwickler können Daten mithilfe des Foundation-Frameworks von und auf das lokale Dateisystem der App lesen und schreiben.
- Cloud Service: Durch die Verwendung von Cloud-Service-Anbietern wie AWS, Firebase oder Firestore kann die Daten auf deren Servern gespeichert werden, anstatt auf dem lokalen Gerät. Dieser Ansatz eignet sich, wenn die Daten unter verschiedenen Benutzern geteilt werden oder auf mehreren Geräten zugänglich sein sollen.
[[|800px|miniatur]]
Letztlich hängt die Wahl der Methode zum Speichern von Daten von den spezifischen Anforderungen Ihrer App ab, einschließlich der Menge an zu speichernder Daten, der Komplexität des Datenmodells und den Anforderungen an die Datensynchronisierung und Sicherung.
User Defaults
Swift - UserDefaults
In iOS ist UserDefaults eine bequeme Klasse zum Speichern von kleinen Mengen an benutzerspezifischen Daten. Es wird von einer plist-Datei unterstützt, die ein einfaches Schlüssel-Wert-Speicherformat ist.
Beispiele
Speichern von JSON Daten mit File I/O
Siehe auch
Swift JSONEncoder Swift & JSON
struct Setlist: Codable {
var title: String = "Default"
var songs = [Song]()
mutating func addSong(title: String, frequency: Float){
print("Setlist::addSong")
songs.append(Song(title:title, frequency: frequency))
}
}
struct Song: Codable {
let title: String
let frequency: Float
}
// convert Setlist to json Data
let setlist = Setlist()
setlist.addSong(title: "song1", frequency: 44.1)
let encoder = JSONEncoder()
guard let encoded = try? encoder.encode(setlist) else {
print("Encoding Failed")
return
}
// write json Data to file
let documentsURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
let fileURL = documentsURL.appendingPathComponent("setlist.json")
do {
try encoded.write(to: fileURL, options: .atomic)
} catch {
print("Error saving file: \(error)")
}
In diesem Beispiel wird die JSONEncoder Klasse verwendet, um eine Instanz des Structs Setlist in ein JSON-kodiertes Data-Objekt umzuwandeln. Das erzeugte JSON-kodierte Data wird in einer Datei gespeichert . In diesem Fall wird die Datei "setlist.json" im Dokumentenverzeichnis des Geräts gespeichert. Es ist zu beachten, dass es je nach Anwendungsfall sinnvoll sein kann, die Daten an einem anderen Ort oder in einem anderen Format zu speichern.
JSON Data Objekt als String ausgeben
if let jsonString = String(data: encoded, encoding: .utf8) {
print(jsonString)
} else {
print("Could not convert encoded Data to String")
}
Dieser Code verwendet encoded Data und wandelt es in einen String um, indem es es decodiert und UTF-8 als Encoding verwendet. Wenn die Konvertierung erfolgreich ist, wird der Inhalt des Strings auf der Konsole ausgegeben. Es ist zu beachten, dass der JSON String nicht immer lesbar ausfällt, da die Reihenfolge der Werte innerhalb des Objekts oder des Arrays unvorhersehbar ist.
Speichern von Daten mit CoreData
Das Speichern von Instanzen des Structs Setlist in Core Data erfordert einige zusätzliche Schritte im Vergleich zu User Defaults, da Core Data ein umfangreicheres Framework ist. Hier ist ein Beispiel dafür, wie dies mit Swift und Core Data erreicht werden kann:
import CoreData
struct Setlist {
var title: String = "Default"
var songs = [Song]()
var objectID: NSManagedObjectID?
mutating func addSong(title: String, frequency: Float){
print("Setlist::addSong")
songs.append(Song(title:title, frequency: frequency))
}
}
struct Song {
let title: String
let frequency: Float
}
// To Save
func saveSetlist(_ setlist: Setlist) {
guard let appDelegate = UIApplication.shared.delegate as? AppDelegate else { return }
let managedContext = appDelegate.persistentContainer.viewContext
let setlistEntity = NSEntityDescription.entity(forEntityName: "SetlistEntity", in: managedContext)!
let setlistMO = NSManagedObject(entity: setlistEntity, insertInto: managedContext)
setlistMO.setValue(setlist.title, forKey: "title")
var songMOs = [NSManagedObject]()
for song in setlist.songs {
let songEntity = NSEntityDescription.entity(forEntityName: "SongEntity", in: managedContext)!
let songMO = NSManagedObject(entity: songEntity, insertInto: managedContext)
songMO.setValue(song.title, forKey: "title")
songMO.setValue(song.frequency, forKey: "frequency")
songMOs.append(songMO)
}
setlistMO.setValue(NSOrderedSet(array: songMOs), forKey: "songs")
setlist.objectID = setlistMO.objectID
do {
try managedContext.save()
} catch let error as NSError {
print("Could not save. \(error), \(error.userInfo)")
}
}
// To Retrieve
func fetchSetlist(with objectID: NSManagedObjectID) -> Setlist? {
guard let appDelegate = UIApplication.shared.delegate as? AppDelegate else { return nil }
let managedContext = appDelegate.persistentContainer.viewContext
let fetchRequest = NSFetchRequest<NSManagedObject>(entityName: "SetlistEntity")
fetchRequest.predicate = NSPredicate(format: "self == %@", objectID as CVarArg)
do {
let setlistMO = try managedContext.fetch(fetchRequest).first
guard let title = setlistMO?.value(forKey: "title") as? String, let songsMO = setlistMO?.value(forKey: "songs") as? Set<NSManagedObject> else {
return nil
}
var songs = [Song]()
forsongMO in songsMO {
let title = songMO.value(forKey: "title") as? String, let frequency = songMO.value(forKey: "frequency") as? Float else {
continue
}
songs.append(Song(title: title, frequency: frequency))
}
var setlist = Setlist(title: title, songs: songs)
setlist.objectID = objectID
return setlist
} catch let error as NSError {
print("Could not fetch. (error), (error.userInfo)")
return nil
}
}
Dieses Beispiel verwendet Core Data, um Instanzen des Structs Setlist zu speichern und abzurufen. Es verwendet NSManagedObjects, um die Entitäten von Setlist und Song im Datenmodell darzustellen und die Beziehungen zwischen ihnen zu verwalten. Bitte beachten Sie, dass es hier nur um ein Beispiel geht und dass Core Data viele weitere Funktionen bietet, die je nach Anwendungsfall sinnvoll sein können.
Speichern mit SQLite und FMDB
Das Speichern von Instanzen des Structs Setlist in SQLite erfordert die Verwendung eines Wrapper-Libraries die eine einfachere Anbindung von SQLite Datenbanken in Swift ermöglicht, wie z.B FMDB. Hier ist ein Beispiel dafür, wie dies mit Swift und FMDB (OpenSoure Lib) erreicht werden kann:
import FMDB
struct Setlist {
var title: String = "Default"
var songs = [Song]()
var id: Int32?
mutating func addSong(title: String, frequency: Float){
print("Setlist::addSong")
songs.append(Song(title:title, frequency: frequency))
}
}
struct Song {
let title: String
let frequency: Float
}
let databaseQueue = FMDatabaseQueue(url: try! FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: true).appendingPathComponent("db.sqlite"))
func createTable() {
databaseQueue.inDatabase { db in
do {
try db.executeUpdate("CREATE TABLE Setlist (id INTEGER PRIMARY KEY, title TEXT);", values: nil)
try db.executeUpdate("CREATE TABLE Song (id INTEGER PRIMARY KEY, title TEXT, frequency REAL, setlist_id INTEGER, FOREIGN KEY(setlist_id) REFERENCES Setlist(id));", values: nil)
} catch {
print(error)
}
}
}
// To Save
func saveSetlist(_ setlist: Setlist) {
databaseQueue.inDatabase { db in
do {
try db.executeUpdate("INSERT INTO Setlist (title) VALUES (?);", values: [setlist.title])
setlist.id = db.lastInsertRowId
for song in setlist.songs {
try db.executeUpdate("INSERT INTO Song (title, frequency, setlist_id) VALUES (?, ?, ?);", values: [song.title, song.frequency,setlist.id])
}
} catch {
print(error)
}
}
}
// To Retrive
func fetchSetlist(with id: Int32) -> Setlist? {
var setlist: Setlist?
databaseQueue.inDatabase { db in
do {
let resultSetlist = try db.executeQuery("SELECT * FROM Setlist WHERE id = ?", values: [id])
if resultSetlist.next() {
setlist = Setlist(title: resultSetlist.string(forColumn: "title")!)
setlist!.id = id
let resultSongs = try db.executeQuery("SELECT * FROM Song WHERE setlist_id = ?", values: [id])
while resultSongs.next() {
let song = Song(title: resultSongs.string(forColumn: "title")!,frequency: resultSongs.double(forColumn: "frequency"))
setlist!.songs.append(song)
}
}
resultSetlist.close()
} catch {
print(error)
}
}
return setlist
}
Dieses Beispiel verwendet FMDB, um eine Verbindung zur SQLite-Datenbank herzustellen und Abfragen auszuführen, um Instanzen des Structs Setlist zu speichern und abzurufen. Beachten Sie, dass die Beispielstrukturen und die Datenbanktabellen beide eine ID-Eigenschaft haben, um die Beziehungen zwischen Setlist und Song zu verwalten. Es gibt auch andere Bibliotheken wie SQLite.swift die auch SQLite in Swift erleichtern. Ich empfehle Ihnen, sich mit den Best Practices für die Verwendung von SQLite in iOS-Apps vertraut zu machen, um sicherzustellen, dass Ihre Anwendung sicher und performant ist.