CRUD операции Parse в iOS с помощью ParseSwift SDK
17 мин
crud parse объекты в ios введение хранение данных в parse основано на классе \<font color="#2166ae">parse object\</font> каждый \<font color="#2166ae">parse object\</font> содержит пары ключ значение совместимых с json данных эти данные не имеют схемы, что означает, что вам не нужно заранее указывать, какие ключи существуют в каждом \<font color="#2166ae">parse object\</font> вы можете просто установить любые пары ключ значение, которые хотите, и наш бэкенд сохранит их вы также можете указывать типы данных в соответствии с потребностями вашего приложения и сохранять такие типы, как \<font color="#2166ae">число\</font> , \<font color="#2166ae">логическое значение\</font> , \<font color="#2166ae">строка\</font> , \<font color="#2166ae">дата и время\</font> , \<font color="#2166ae">список\</font> , \<font color="#2166ae">geopointers\</font> , и \<font color="#2166ae">объект\</font> , кодируя их в json перед сохранением parse также поддерживает хранение и запрос реляционных данных, используя типы \<font color="#2166ae">указатели\</font> и \<font color="#2166ae">связи\</font> в этом руководстве вы узнаете, как выполнять основные операции с данными через пример приложения crud (приложение списка дел), которое покажет вам, как создавать, читать, обновлять и удалять данные из вашей базы данных сервера parse с использованием \<font color="#2166ae">parseswift sdk\</font> этот учебник использует базовое приложение, созданное в xcode 12 и ios 14 в любое время вы можете получить доступ к полному проекту через наши репозитории на github репозиторий примера ios https //github com/templates back4app/ios crud to do list цель чтобы узнать, как выполнять основные операции с базой данных на back4app, используя приложение todo в качестве примера предварительные требования чтобы завершить этот быстрый старт, вам нужно xcode приложение, созданное на back4app следуйте учебнику по созданию нового приложения parse https //www back4app com/docs/get started/new parse app чтобы узнать, как создать приложение parse на back4app примечание следуйте учебнику по установке parse sdk (swift) https //www back4app com/docs/ios/parse swift sdk чтобы создать проект xcode, подключенный к back4app понимание нашего приложения to do list чтобы лучше понять \<font color="#2166ae">parseswift sdk\</font> вы будете выполнять операции crud в приложении to do list база данных приложения будет иметь простой класс задачи с заголовком и описанием (оба \<font color="#2166ae">строки\</font> ) вы можете обновить заголовок и/или описание каждой задачи быстрая справка по командам, которые мы собираемся использовать как только объект соответствует \<font color="#2166ae">parseswift\</font> протоколу, он автоматически реализует набор методов, которые позволят вам управлять объектом и обновлять любые изменения в вашей базе данных back4app учитывая объект \<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 } эти методы перечислены ниже 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 создать шаблон приложения для списка дел в любое время вы можете получить доступ к полному проекту через наши репозитории на github репозиторий примера для ios https //github com/templates back4app/ios crud to do list перейдите в xcode и найдите файл \<font color="#2166ae">scenedelegate swift\</font> чтобы добавить панель навигации в верхней части приложения, мы настраиваем \<font color="#2166ae">uinavigationcontroller\</font> в качестве корневого контроллера представления следующим образом 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 } класс корневого контроллера представления ( \<font color="#2166ae">todolistcontroller\</font> ) для контроллера навигации является подклассом \<font color="#2166ae">uitableviewcontroller\</font> , это упрощает компоновку списка элементов 2 настройка объекта crud объекты, которые вы хотите сохранить в вашей базе данных back4app, должны соответствовать \<font color="#2166ae">parseobject\</font> протоколу в нашем приложении to do list этот объект называется \<font color="#2166ae">todolistitem\</font> поэтому вам сначала нужно создать этот объект 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 } этот объект определяет класс в вашей базе данных back4app любой новый экземпляр этого объекта затем сохраняется в вашей базе данных под классом \<font color="#2166ae">todolistitem\</font> 3 настройка todolistcontroller в \<font color="#2166ae">todolistcontroller\</font> мы должны реализовать всю необходимую конфигурацию для \<font color="#2166ae">navigationbar\</font> , и \<font color="#2166ae">tableview\</font> свойств 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 } чтобы завершить этот шаг, мы реализуем пользовательскую ячейку таблицы \<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 мы реализуем всю логику crud в классе \<font color="#2166ae">todolistcontroller\</font> перейдите к \<font color="#2166ae">todolistcontroller swift\</font> и добавьте следующие методы в класс \<font color="#2166ae">todolistcontroller\</font> 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 } \ создать объект теперь мы начинаем реализовывать метод \<font color="#2166ae">createobject(title\ description )\</font> создайте экземпляр \<font color="#2166ae">todolistitem\</font> с помощью инициализатора \<font color="#2166ae">init(title\ description )\</font> чтобы сохранить этот новый элемент в вашей базе данных back4app, протокол \<font color="#2166ae">parseswift\</font> предоставляет метод \<font color="#2166ae">save()\</font> этот метод может быть вызван синхронно или асинхронно, выберите один из них в зависимости от вашего случая использования асинхронная реализация должна выглядеть так 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 } теперь мы можем завершить действие для кнопки добавления, расположенной с правой стороны навигационной панели перейдите к \<font color="#2166ae">todolistcontroller\</font> и добавьте следующее 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 } \ чтение объекта мы переходим к \<font color="#2166ae">readobjects()\</font> методу получение \<font color="#2166ae">todolistitem\</font> элементов из вашей базы данных back4app выполняется через \<font color="#2166ae">query\<todolistitem\>\</font> объект этот запрос создается следующим образом 1 func readobjects() { 2 let query = todolistitem query() 3 4 } в этом уроке мы используем запрос, который извлечет все элементы типа \<font color="#2166ae">todolistitem\</font> из вашей базы данных back4app если вы хотите извлечь набор конкретных элементов, вы можете предоставить \<font color="#2166ae">queryconstraint\</font> элементы для \<font color="#2166ae">todolistitem query(queryconstraint )\</font> например, чтобы получить все элементы, где \<font color="#2166ae">title == "некоторый заголовок"\</font> , запрос принимает следующую форму 1 let query = todolistitem query("title" == "some title") как только у вас будет готов запрос, мы продолжаем извлекать элементы, вызывая \<font color="#2166ae">query find()\</font> это можно сделать синхронно или асинхронно в нашем приложении to do list мы реализуем это асинхронно 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 } с \<font color="#2166ae">readobjects()\</font> завершено, мы теперь можем получить все задачи, хранящиеся в вашей базе данных back4app, и показать их сразу после того, как приложение выйдет на передний план вернитесь к \<font color="#2166ae">todolistcontroller\</font> и переопределите метод \<font color="#2166ae">viewdidappear()\</font> 1 class todolistcontroller uitableviewcontroller { 2 3 4 override func viewdidappear( animated bool) { 5 super viewdidappear(animated) 6 7 readobjects() 8 } 9 10 11 } \ обновить объект учитывая \<font color="#2166ae">objectid\</font> объекта \<font color="#2166ae">todolistitem\</font> , обновление выполняется просто мы просто создаем экземпляр объекта \<font color="#2166ae">todolistitem\</font> с помощью инициализатора \<font color="#2166ae">init(objectid )\</font> затем мы обновляем необходимые свойства и вызываем метод \<font color="#2166ae">save()\</font> (объекта \<font color="#2166ae">todolistitem\</font> ) для сохранения изменений 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 } \ удалить объект удаление объектов в вашей базе данных back4app очень похоже на создание объектов мы начинаем с создания экземпляра \<font color="#2166ae">todolistitem\</font> с objectid элемента, который мы хотим удалить затем мы просто вызываем (синхронно или асинхронно) метод \<font color="#2166ae">delete()\</font> объекта если удаление прошло успешно, мы обновляем пользовательский интерфейс, в противном случае мы сообщаем об ошибке 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 } с \<font color="#2166ae">deleteobject(item )\</font> и \<font color="#2166ae">updateobject(objectid\ newtitle\ newdescription)\</font> завершено, мы продолжаем добавлять соответствующие действия для вызова этих операций вернитесь к \<font color="#2166ae">todolistcontroller\</font> и добавьте 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 } как мы уже упоминали ранее, кнопка аксессуара в каждом \<font color="#2166ae">todolistitemcell\</font> вызывает лист редактирования через \<font color="#2166ae">tableview( accessorybuttontappedforrowwith )\</font> метод делегата сделано! на этом этапе вы узнали, как выполнять основные операции crud с parse на ios