iOS Parse SDK: CRUD-Operationen für Datenobjekte in Swift
17 min
crud parse objekte in ios einführung die speicherung von daten auf parse basiert auf der \<font color="#2166ae">parse object\</font> klasse jedes \<font color="#2166ae">parse object\</font> enthält schlüssel wert paare von json kompatiblen daten diese daten sind schemalos, was bedeutet, dass sie im voraus nicht angeben müssen, welche schlüssel in jedem \<font color="#2166ae">parse object\</font> sie können einfach beliebige schlüssel wert paare festlegen, und unser backend wird sie speichern sie können auch die datentypen entsprechend den anforderungen ihrer anwendung angeben und typen wie \<font color="#2166ae">zahl\</font> , \<font color="#2166ae">boolean\</font> , \<font color="#2166ae">string\</font> , \<font color="#2166ae">datetime\</font> , \<font color="#2166ae">liste\</font> , \<font color="#2166ae">geopointers\</font> , und \<font color="#2166ae">objekt\</font> , die vor dem speichern in json kodiert werden parse unterstützt auch die speicherung und abfrage relationaler daten durch die verwendung der typen \<font color="#2166ae">zeiger\</font> und \<font color="#2166ae">beziehungen\</font> in diesem leitfaden lernen sie, wie sie grundlegende datenoperationen durch eine crud beispielanwendung (todo listen app) durchführen, die ihnen zeigt, wie sie daten von ihrer parse server datenbank erstellen, lesen, aktualisieren und löschen können, indem sie das \<font color="#2166ae">parseswift sdk\</font> dieses tutorial verwendet eine grundlegende app, die in xcode 12 und ios 14 erstellt wurde zu jeder zeit können sie auf das vollständige projekt über unsere github repositories zugreifen ios beispiel repository https //github com/templates back4app/ios crud to do list ziel um zu lernen, wie man grundlegende datenbankoperationen auf back4app mit einer todo listen app als beispiel durchführt voraussetzungen um dieses schnellstart tutorial abzuschließen, benötigen sie xcode eine app, die bei back4app erstellt wurde befolgen sie das tutorial für neue parse apps https //www back4app com/docs/get started/new parse app , um zu lernen, wie man eine parse app bei back4app erstellt hinweis befolgen sie das tutorial zur installation des parse sdk (swift) https //www back4app com/docs/ios/parse swift sdk , um ein xcode projekt zu erstellen, das mit back4app verbunden ist verstehen unserer to do listen app um das \<font color="#2166ae">parseswift sdk\</font> besser zu verstehen, werden sie crud operationen an einer to do listen app durchführen die anwendungsdatenbank wird eine einfache aufgabenklasse mit einem titel und einer beschreibung haben (beides \<font color="#2166ae">strings\</font> ) sie können den titel und/oder die beschreibung jeder aufgabe aktualisieren schnellreferenz der befehle, die wir verwenden werden sobald ein objekt dem \<font color="#2166ae">parseswift\</font> protokoll entspricht, implementiert es automatisch eine reihe von methoden, die es ihnen ermöglichen, das objekt zu verwalten und änderungen in ihrer back4app datenbank zu aktualisieren angenommen, das objekt \<font color="#2166ae">todolistitem\</font> 1 struct todolistitem parseobject { 2 3 4 /// title for the todo item 5 var title string? 6 7 /// description for the todo item 8 var description string? 9 } diese methoden sind unten aufgeführt create //once created an instance of todolistitem object and set its custom properties, you can save it on your back4app database by calling any of the following methods 1 var newitem todoilisttem 2 // newitem's properties 3 4 // saves newitem on your back4app database synchronously and returns the new saved item it throws and error if something went wrong 5 let saveditem = try? newitem save() 6 7 // saves newitem on your back4app database asynchronously, and passes a result\<todolistitem, parseerror> object to the completion block to handle the save proccess 8 newitem save { result in 9 // handle the result to check the save was successfull or not 10 } 11 read //for reading objects stored on your back4app database, todolistitem now provides the query() static method which returns a query\<todolistitem> this query object can be constructed using on or more queryconstraint objects int he following way 1 let query = todolistitem query() // a query to fetch all todolistitem items on your back4app database 2 let query = todolistitem query("title" == "some title") // a query to fetch all todolistitem items with title "some title" on your back4app database 3 let query = todolistitem query(\["title" == "some title", "description" = "ok"]) // a query to fetch all todolistitem items with title = "some title" and description = "ok" 4 5 // fetchs the items synchronously or throws an error if found 6 let fetcheditems = try? query find() 7 8 // fetchs the items asynchronously and calls a completion block passing a result object containing the result of the operation 9 query find { result in 10 // handle the result 11 } update //given the objectid of an object stored on you back4app database, you can update it in the following way 1 let itemtoupdate = todolistitem(objectid "oobject id") 2 // update the properites of itemtoupdate 3 4 // save changes synchronousty 5 itemtoupdate save() 6 7 // or save changes asynchronously 8 itemtoupdate save { result in 9 // handle the result 10 } delete //the deletion process is performed by calling the method delete() on the object to be deleted 1 var itemtodelete todolistitem 2 3 // delete itemtodelete synchronously 4 try? itemtodelete delete() 5 6 // delte itemtodelete asynchronously 7 itemtodelete delete { result in 8 // handleresult 9 } 1 to do liste app vorlage erstellen zu jeder zeit können sie auf das vollständige projekt über unsere github repositories zugreifen ios beispiel repository https //github com/templates back4app/ios crud to do list gehen sie zu xcode und finden sie die \<font color="#2166ae">scenedelegate swift\</font> datei um eine navigationsleiste oben in der app hinzuzufügen, richten wir einen \<font color="#2166ae">uinavigationcontroller\</font> als root view controller auf folgende weise ein 1 class scenedelegate uiresponder, uiwindowscenedelegate { 2 3 var window uiwindow? 4 5 func scene( scene uiscene, willconnectto session uiscenesession, options connectionoptions uiscene connectionoptions) { 6 guard let scene = (scene as? uiwindowscene) else { return } 7 8 window = init(windowscene scene) 9 window? rootviewcontroller = uinavigationcontroller(rootviewcontroller todolistcontroller()) 10 window? makekeyandvisible() 11 12 // additional logic 13 } 14 15 16 } die root view controller klasse ( \<font color="#2166ae">todolistcontroller\</font> ) für den navigationscontroller ist eine unterklasse von \<font color="#2166ae">uitableviewcontroller\</font> , das erleichtert das layout einer liste von elementen 2 einrichten des crud objekts objekte, die sie in ihrer back4app datenbank speichern möchten, müssen dem \<font color="#2166ae">parseobject\</font> protokoll entsprechen in unserer to do liste app ist dieses objekt \<font color="#2166ae">todolistitem\</font> daher müssen sie dieses objekt zuerst erstellen 1 import foundation 2 import parseswift 3 4 struct todolistitem parseobject { 5 // required properties from parseobject protocol 6 var objectid string? 7 var createdat date? 8 var updatedat date? 9 var acl parseacl? 10 11 /// title for the todo item 12 var title string? 13 14 /// description for the todo item 15 var description string? 16 } dieses objekt definiert eine klasse in ihrer back4app datenbank jede neue instanz dieses objekts wird dann in ihrer datenbank unter der \<font color="#2166ae">todolistitem\</font> klasse gespeichert 3 einrichten des todolistcontrollers in \<font color="#2166ae">todolistcontroller\</font> sollten wir alle notwendigen konfigurationen für die \<font color="#2166ae">navigationbar\</font> , und \<font color="#2166ae">tableview\</font> eigenschaften implementieren 1 class todolistcontroller uitableviewcontroller { 2 var items \[todolistitem] = \[] 3 4 override func viewdidload() { 5 super viewdidload() 6 7 setuptableview() 8 setupnavigationbar() 9 } 10 11 private func setupnavigationbar() { 12 navigationitem title = "to do list" uppercased() 13 navigationitem rightbarbuttonitem = uibarbuttonitem(barbuttonsystemitem add, target self, action #selector(handlenewitem)) 14 } 15 16 private func setuptableview() { 17 tableview\ register(todolistitemcell self, forcellreuseidentifier todolistitemcell identifier) 18 } 19 20 override func tableview( tableview uitableview, numberofrowsinsection section int) > int { 21 items count 22 } 23 24 override func tableview( tableview uitableview, cellforrowat indexpath indexpath) > uitableviewcell { 25 let cell = tableview\ dequeuereusablecell(withidentifier todolistitemcell identifier, for indexpath) as! todolistitemcell 26 cell item = items\[indexpath row] 27 return cell 28 } 29 30 /// this method is called when the user wants to add a new item to the to do list 31 @objc private func handlenewitem() { 32 33 } 34 35 36 } um diesen schritt abzuschließen, implementieren wir die benutzerdefinierte tabellenansichtszelle \<font color="#2166ae">todolistitemcell\</font> 1 // content of todolistitemcell swift file 2 class todolistitemcell uitableviewcell { 3 class var identifier string { "\\(nsstringfromclass(self self)) identifier" } // cell's identifier 4 5 /// when set, it updates the title and detail texts of the cell 6 var item todolistitem? { 7 didset { 8 textlabel? text = item? title 9 detailtextlabel? text = item? description 10 } 11 } 12 13 override init(style uitableviewcell cellstyle, reuseidentifier string?) { 14 super init(style subtitle, reuseidentifier reuseidentifier) 15 16 accessorytype = detailbutton // this accessory button will be used to present edit options for the item 17 } 18 19 required init?(coder nscoder) { 20 super init(coder coder) 21 22 accessorytype = detailbutton // this accessory button will be used to present edit options for the item 23 } 24 } 4 crud fluss wir implementieren die gesamte crud logik in der \<font color="#2166ae">todolistcontroller\</font> klasse gehe zu \<font color="#2166ae">todolistcontroller swift\</font> und füge die folgenden methoden zur \<font color="#2166ae">todolistcontroller\</font> klasse hinzu 1 // mark crud flow 2 extension todolistcontroller { 3 /// creates a todolistitem and stores it on your back4app database 4 /// parameters 5 /// title the title for the to do task 6 /// description an optional description for the to to task 7 func createobject(title string, description string?) { 8 9 } 10 11 /// retrieves all the todolistitem objects from your back4app database 12 func readobjects() { 13 14 } 15 16 /// updates a todolistitem object on your back4app database 17 /// parameters 18 /// objectid the object id of the todolistitem to update 19 /// newtitle new title for the to to task 20 /// newdescription new description for the to do task 21 func updateobject(objectid string, newtitle string, newdescription string?) { 22 23 } 24 25 /// deletes a todolistitem on your back4app database 26 /// parameter item the item to be deleted on your back4app database 27 func deleteobject(item todolistitem) { 28 29 } 30 } \ objekt erstellen jetzt beginnen wir mit der implementierung der \<font color="#2166ae">createobject(title\ description )\</font> methode erstellen sie eine instanz von \<font color="#2166ae">todolistitem\</font> mit dem \<font color="#2166ae">init(title\ description )\</font> initialisierer um dieses neue element in ihrer back4app datenbank zu speichern, bietet das \<font color="#2166ae">parseswift\</font> protokoll eine \<font color="#2166ae">save()\</font> methode diese methode kann synchron oder asynchron aufgerufen werden, wählen sie eine davon entsprechend ihrem anwendungsfall eine asynchrone implementierung sollte so aussehen 1 func createobject(title string, description string?) { 2 let item = todolistitem(title title, description description) 3 4 item save { \[weak self] result in 5 guard let self = self else { return } 6 switch result { 7 case success(let saveditem) 8 self items append(saveditem) 9 dispatchqueue main async { 10 self tableview\ insertrows(at \[indexpath(row self items count 1, section 0)], with right) 11 } 12 case failure(let error) 13 dispatchqueue main async { 14 self showalert(title "error", message "failed to save item \\(error message)") 15 } 16 } 17 } 18 } jetzt können wir die aktion für die schaltfläche „hinzufügen“ abschließen, die sich auf der rechten seite der navigationsleiste befindet gehe zu \<font color="#2166ae">todolistcontroller\</font> und füge das folgende hinzu 1 class todolistcontroller uitableviewcontroller { 2 enum itemdescription int { case title = 0, description = 1 } 3 4 5 6 /// this method is called when the user wants to add a new item to the to do list 7 @objc private func handlenewitem() { 8 showeditcontroller(item nil) 9 } 10 11 /// presents an alert where the user enters a to do task for either create a new one (item parameter is nil) or edit an existing one 12 private func showeditcontroller(item todolistitem?) { 13 let controllertitle string = item == nil ? "new item" "update item" 14 15 let edititemalertcontroller = uialertcontroller(title controllertitle, message nil, preferredstyle alert) 16 17 edititemalertcontroller addtextfield { textfield in 18 textfield tag = itemdescription title rawvalue 19 textfield placeholder = "title" 20 textfield text = item? title 21 } 22 23 edititemalertcontroller addtextfield { textfield in 24 textfield tag = itemdescription description rawvalue 25 textfield placeholder = "description" 26 textfield text = item? description 27 } 28 29 let mainactiontitle string = item == nil ? "add" "update" 30 31 let mainaction uialertaction = uialertaction(title mainactiontitle, style default) { \[weak self] in 32 guard let title = edititemalertcontroller textfields? first(where { $0 tag == itemdescription title rawvalue })? text else { 33 return edititemalertcontroller dismiss(animated true, completion nil) 34 } 35 36 let description = edititemalertcontroller textfields? first(where { $0 tag == itemdescription description rawvalue })? text 37 38 edititemalertcontroller dismiss(animated true) { 39 if let objectid = item? objectid { // if the item passed as parameter is not nil, the alert will update it 40 self? updateobject(objectid objectid, newtitle title, newdescription description) 41 } else { 42 self? createobject(title title, description description) 43 } 44 } 45 } 46 47 let cancelaction = uialertaction(title "cancel", style cancel, handler nil) 48 49 edititemalertcontroller addaction(mainaction) 50 edititemalertcontroller addaction(cancelaction) 51 52 present(edititemalertcontroller, animated true, completion nil) 53 } 54 } \ objekt lesen wir wechseln zur \<font color="#2166ae">readobjects()\</font> methode das abrufen von \<font color="#2166ae">todolistitem\</font> elementen aus ihrer back4app datenbank erfolgt über ein \<font color="#2166ae">query\<todolistitem\>\</font> objekt diese abfrage wird folgendermaßen instanziiert 1 func readobjects() { 2 let query = todolistitem query() 3 4 } in diesem tutorial verwenden wir eine abfrage, die alle elemente vom typ \<font color="#2166ae">todolistitem\</font> aus ihrer back4app datenbank abruft falls sie eine menge spezifischer elemente abrufen möchten, können sie \<font color="#2166ae">queryconstraint\</font> elemente zu \<font color="#2166ae">todolistitem query(queryconstraint )\</font> zum beispiel, um alle elemente abzurufen, bei denen \<font color="#2166ae">title == "some title"\</font> , hat die abfrage die form 1 let query = todolistitem query("title" == "some title") sobald sie die abfrage bereit haben, fahren wir fort, die elemente abzurufen, indem wir \<font color="#2166ae">query find()\</font> auch dies kann synchron oder asynchron erfolgen in unserer to do liste app implementieren wir es asynchron 1 func readobjects() { 2 let query = todolistitem query() 3 4 query find { \[weak self] result in 5 guard let self = self else { return } 6 switch result { 7 case success(let items) 8 self items = items 9 dispatchqueue main async { 10 self tableview\ reloadsections(\[0], with top) 11 } 12 case failure(let error) 13 dispatchqueue main async { 14 self showalert(title "error", message "failed to save item \\(error message)") 15 } 16 } 17 } 18 } mit \<font color="#2166ae">readobjects()\</font> abgeschlossen, können wir nun alle aufgaben abrufen, die in ihrer back4app datenbank gespeichert sind, und sie direkt anzeigen, nachdem die app in den vordergrund tritt gehen sie zurück zu \<font color="#2166ae">todolistcontroller\</font> und überschreiben sie die \<font color="#2166ae">viewdidappear()\</font> methode 1 class todolistcontroller uitableviewcontroller { 2 3 4 override func viewdidappear( animated bool) { 5 super viewdidappear(animated) 6 7 readobjects() 8 } 9 10 11 } \ objekt aktualisieren gegeben ist die \<font color="#2166ae">objectid\</font> eines \<font color="#2166ae">todolistitem\</font> , ist es einfach, ein update durchzuführen wir instanziieren einfach ein \<font color="#2166ae">todolistitem\</font> objekt mit dem \<font color="#2166ae">init(objectid )\</font> initializer als nächstes aktualisieren wir die benötigten eigenschaften und rufen die \<font color="#2166ae">save()\</font> methode (von \<font color="#2166ae">todolistitem\</font> ) auf, um die änderungen zu speichern 1 func updateobject(objectid string, newtitle string, newdescription string?) { 2 var item = todolistitem(objectid objectid) 3 item title = newtitle 4 item description = newdescription 5 6 item save { \[weak self] result in 7 switch result { 8 case success 9 if let row = self? items firstindex(where { $0 objectid == item objectid }) { 10 self? items\[row] = item 11 dispatchqueue main async { 12 self? tableview\ reloadrows(at \[indexpath(row row, section 0)], with fade) 13 } 14 } 15 case failure(let error) 16 dispatchqueue main async { 17 self? showalert(title "error", message "failed to save item \\(error message)") 18 } 19 } 20 } 21 } \ objekt löschen das löschen von objekten in ihrer back4app datenbank ist sehr ähnlich wie das erstellen von objekten wir beginnen damit, eine instanz von \<font color="#2166ae">todolistitem\</font> mit der objectid des elements zu erstellen, das wir löschen möchten als nächstes rufen wir einfach die (synchron oder asynchron) \<font color="#2166ae">delete()\</font> methode des objekts auf wenn das löschen erfolgreich war, aktualisieren wir die benutzeroberfläche, andernfalls melden wir den fehler 1 func deleteobject(item todolistitem) { 2 item delete { \[weak self] result in 3 switch result { 4 case success 5 if let row = self? items firstindex(where { $0 objectid == item objectid }) { 6 self? items remove(at row) 7 dispatchqueue main async { 8 self? tableview\ deleterows(at \[indexpath(row row, section 0)], with left) 9 } 10 } 11 case failure(let error) 12 dispatchqueue main async { 13 self? showalert(title "error", message "failed to save item \\(error message)") 14 } 15 } 16 } 17 } mit \<font color="#2166ae">deleteobject(item )\</font> und \<font color="#2166ae">updateobject(objectid\ newtitle\ newdescription)\</font> abgeschlossen, fahren wir fort, die entsprechenden aktionen hinzuzufügen, um diese operationen aufzurufen gehen sie zurück zu \<font color="#2166ae">todolistcontroller\</font> und fügen sie hinzu 1 // mark uitableviewdatasource delegate 2 extension todolistcontroller { 3 // when the user taps on the accessory button of a cell, we present the edit options for the to do list task 4 override func tableview( tableview uitableview, accessorybuttontappedforrowwith indexpath indexpath) { 5 guard !items isempty else { return } 6 7 showeditoptions(item items\[indexpath row]) 8 } 9 10 /// presents a sheet where the user can select an action for the to do list item 11 private func showeditoptions(item todolistitem) { 12 let alertcontroller = uialertcontroller(title title, message nil, preferredstyle actionsheet) 13 14 let editaction = uialertaction(title "edit", style default) { \[weak self] in 15 self? showeditcontroller(item item) 16 } 17 18 let deleteaction = uialertaction(title "delete", style destructive) { \[weak self] in 19 alertcontroller dismiss(animated true) { 20 self? deleteobject(item item) 21 } 22 } 23 24 let cancelaction = uialertaction(title "cancel", style cancel) { in 25 alertcontroller dismiss(animated true, completion nil) 26 } 27 28 alertcontroller addaction(editaction) 29 alertcontroller addaction(deleteaction) 30 alertcontroller addaction(cancelaction) 31 32 present(alertcontroller, animated true, completion nil) 33 } 34 } wie wir bereits früher erwähnt haben, löst die zubehörtaste in jedem \<font color="#2166ae">todolistitemcell\</font> ein bearbeitungsblatt über die \<font color="#2166ae">tableview( accessorybuttontappedforrowwith )\</font> delegatenmethode aus es ist erledigt! an diesem punkt haben sie gelernt, wie man die grundlegenden crud operationen mit parse auf ios durchführt