iOS에서 ParseSwift로 CRUD 데이터베이스 작업하기
16 분
ios에서 crud parse 객체 소개 parse에 데이터를 저장하는 것은 \<font color="#2166ae">parse object\</font> 클래스 주위에 구축되어 있습니다 각 \<font color="#2166ae">parse object\</font> 는 json 호환 데이터의 키 값 쌍을 포함합니다 이 데이터는 스키마가 없으므로 각 \<font color="#2166ae">parse object\</font> 에 어떤 키가 존재하는지 미리 지정할 필요가 없습니다 원하는 키 값 쌍을 설정하면, 우리의 백엔드가 이를 저장합니다 응용 프로그램의 필요에 따라 데이터 유형을 지정하고 \<font color="#2166ae">number\</font> , \<font color="#2166ae">boolean\</font> , \<font color="#2166ae">string\</font> , \<font color="#2166ae">datetime\</font> , \<font color="#2166ae">list\</font> , \<font color="#2166ae">geopointers\</font> , 및 \<font color="#2166ae">object\</font> , 저장하기 전에 json으로 인코딩합니다 parse는 또한 \<font color="#2166ae">pointers\</font> 및 \<font color="#2166ae">relations\</font> 를 사용하여 관계형 데이터를 저장하고 쿼리하는 것을 지원합니다 이 가이드에서는 crud 예제 앱(할 일 목록 앱)을 통해 기본 데이터 작업을 수행하는 방법을 배우게 되며, \<font color="#2166ae">parseswift sdk\</font> 를 사용하여 parse 서버 데이터베이스에서 데이터를 생성, 읽기, 업데이트 및 삭제하는 방법을 보여줍니다 이 튜토리얼은 xcode 12에서 생성된 기본 앱과 ios 14 을 사용합니다 언제든지 github 리포지토리를 통해 전체 프로젝트에 접근할 수 있습니다 ios 예제 리포지토리 https //github com/templates back4app/ios crud to do list 목표 to learn how to perform basic database operations on back4app using a todo list app as an example 필수 조건 to complete this quickstart, you need xcode back4app에서 생성된 앱 다음의 new parse app 튜토리얼 https //www back4app com/docs/get started/new parse app 을 따라 back4app에서 parse 앱을 만드는 방법을 배우세요 참고 다음의 parse sdk (swift) 설치 튜토리얼 https //www back4app com/docs/ios/parse swift sdk 을 따라 back4app에 연결된 xcode 프로젝트를 만드세요 우리의 할 일 목록 앱 이해하기 to better understand the \<font color="#2166ae">parseswift sdk\</font> you will perform crud operations on a to do list app the application database will have a simple task class with a title and a description (both \<font color="#2166ae">문자열\</font> ) you can update each task’s title and/or description 우리가 사용할 명령어의 빠른 참조 once an object conforms the \<font color="#2166ae">parseswift\</font> protocol, it automatically implements a set of methods that will allow you to manage the object and update any changes on your back4app database given the object \<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> 프로토콜을 준수해야 합니다 우리의 할 일 목록 앱에서 이 객체는 \<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 } 이 튜토리얼에서는 back4app 데이터베이스에서 \<font color="#2166ae">todolistitem\</font> 유형의 모든 항목을 검색하는 쿼리를 사용합니다 특정 항목 집합을 검색하려는 경우 \<font color="#2166ae">queryconstraint\</font> 요소를 \<font color="#2166ae">todolistitem query(queryconstraint )\</font> 에 제공할 수 있습니다 예를 들어, \<font color="#2166ae">title == "some title"\</font> ,인 경우 쿼리는 다음과 같은 형태를 취합니다 1 let query = todolistitem query("title" == "some title") 쿼리가 준비되면, 우리는 \<font color="#2166ae">query find()\</font> 를 호출하여 항목을 검색합니다 다시 말해, 이는 동기적으로 또는 비동기적으로 수행할 수 있습니다 우리의 할 일 목록 앱에서는 비동기적으로 구현합니다 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 데이터베이스에서 객체를 삭제하는 것은 객체를 생성하는 것과 매우 유사합니다 우리는 삭제하려는 항목의 objectid로 \<font color="#2166ae">todolistitem\</font> 의 인스턴스를 생성하는 것으로 시작합니다 다음으로, 우리는 단순히 객체의 \<font color="#2166ae">delete()\</font> 메서드를 호출합니다(동기 또는 비동기) 삭제가 성공하면 ui를 업데이트하고, 그렇지 않으면 오류를 보고합니다 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> 대리자 메서드를 통해 편집 시트를 호출합니다 완료되었습니다! 이 시점에서, ios에서 parse를 사용하여 기본 crud 작업을 수행하는 방법을 배웠습니다