iOS
...
Data Objects
ParseSwift SDK로 Back4App 데이터베이스 쿼리 수행하기
14 분
기본 쿼리 소개 대부분의 사용 사례에서, 우리는 특정 조건을 가진 데이터베이스에서 데이터를 가져와야 합니다 이러한 조건에는 복잡한 비교 및 정렬 요구 사항이 포함될 수 있습니다 따라서 모든 애플리케이션에서 효율적인 쿼리를 구성하는 것이 기본적이며, 동시에 데이터베이스는 가능한 한 빠르게 이를 실행할 수 있어야 합니다 이 parseswift sdk parseswift sdk 는 애플리케이션 요구 사항에 따라 쿼리를 구성하는 데 필요한 도구를 제공합니다 이 튜토리얼에서는 이러한 도구를 탐색하고 실제 애플리케이션에서 사용하는 방법을 알아봅니다 이 튜토리얼은 xcode 12에서 생성된 기본 앱과 ios 14 을 사용합니다 언제든지, 우리의 github 리포지토리를 통해 전체 프로젝트에 접근할 수 있습니다 ios 예제 리포지토리 목표 back4app 데이터베이스에서 데이터를 검색하기 위한 기본 쿼리를 만드는 방법을 이해합니다 전제 조건 이 빠른 시작을 완료하려면 다음이 필요합니다 xcode back4app에서 생성된 앱 새 parse 앱 튜토리얼 을 따라 back4app에서 parse 앱을 만드는 방법을 배웁니다 참고 parse sdk (swift) 설치 튜토리얼 을 따라 back4app에 연결된 xcode 프로젝트를 만듭니다 우리의 연락처 앱 이해하기 프로젝트 템플릿은 사용자가 연락처 정보를 추가하여 back4app 데이터베이스에 저장하는 연락처 앱입니다 앱의 홈 화면에서 다양한 유형의 쿼리를 위한 버튼 세트를 찾을 수 있습니다 + + 버튼은 내비게이션 바의 오른쪽 상단에 위치해 있으며, 필요한 만큼 연락처 연락처 를 추가할 수 있습니다 우리가 사용할 명령어의 빠른 참조 이 예제에서는 연락처 연락처 객체를 사용합니다 1 import foundation 2 import parseswift 3 4 struct contact parseobject { 5 // required properties from parseobject protocol 6 var originaldata data? 7 var objectid string? 8 var createdat date? 9 var updatedat date? 10 var acl parseacl? 11 12 // custom fields for the contact's information 13 var name string? 14 var birthday date? 15 var numberoffriends int? 16 var favoritefoods \[string]? 17 18 19 } 다음 방법을 사용하면 저장하고 쿼리할 수 있습니다 연락처 연락처 객체 create contact //when creating and saving a new instance of contact we can use 1 var newcontact contact = contact(name "john doe", birthday date(), numberoffriends 5, favoritefoods \["bread", "pizza"]) 2 3 // saves newcontact on your back4app database synchronously and returns the new saved item it throws and error if something went wrong 4 let savedcontact = try? newcontact save() 5 6 // saves newcontact on your back4app database asynchronously, and passes a result\<contact, parseerror> object to the completion block to handle the save process 7 newcontact save { result in 8 // handle the result to check wether the save process was successfull or not 9 } query all //for retrieving all the contact items saved on a back4app database, we construct a query\<contact> object and call the find() method on it 1 let contactsquery = contact query() // a query to fetch all contact items on your back4app database 2 3 // fetches the items synchronously or throws an error if found 4 let fetchedcontacts = try? query find() 5 6 // fetches the items asynchronously and calls a completion block passing a result object containing the result of the operation 7 query find { result in 8 // handle the result 9 } query by name //in order to create a query with a specific condition, we use the static method query( ) provided by the parseobject protocol we pass a queryconstraint object to the method as a parameter this queryconstraint object represents the type of constraint we are imposing on the query for queries involving comparison constraints, the parseswift sdk provides the following methods to create them 1 import parseswift 2 3 // a constraint to retreive all contact items that have exactly the string 'jhon doe' in their 'name' field 4 let constraint1 = try? equalto(key "name", value "john doe") 5 6 // an operator like implementation for the equalto(key\ value ) method 7 let constraint2 queryconstraint = "name" == "jhon doe" 8 9 // a constraint to retrieve all contact items that have the string 'john' in their 'name' field (only workd with string type fields) 10 let constraint3 queryconstraint = containsstring(key "name", substring "jhon") 11 12 let query = contact query(constrint1) // depending on your use case, you can send any of the above constraints as parameter 13 14 // executes the query synchronously it throws an error if something happened 15 let fetchedcontacts = try? query find() 16 17 // executes que query asynchronously and returns a result<\[contact], parseerror> object with the result 18 query find() { result in 19 // handle the result 20 } query by friend count //when we want to query contacts which have a certain amount of friends or more, we do it in the following way 1 import parseswift 2 3 // a constraint to retrieve all contact items that have 30 or more number of friends 4 let constraint1 queryconstraint = "numberoffriends" >= 30 5 6 // a constraint to retrieve all contact items that have more than 30 number of friends 7 let constraint2 queryconstraint = "numberoffriends" > 30 8 9 let query = contact query(constraint1) // depending on your use case, you can send any of the above constraints as parameter 10 11 // executes the query synchronously it throws an error if something happened 12 let fetchedcontacts = try? query find() 13 14 // executes que query asynchronously and returns a result<\[contact], parseerror> object with the result 15 query find() { result in 16 // handle the result 17 } query with ordering //adding an ordering option to queries is straightforward any query\<contact> object has the order( ) method to do so a simple query using the birthday as descending order can be implemented in the folowing way 1 import parseswift 2 3 // a query without order to retrieve all the contact items 4 let unorderedquery = contact query() 5 6 // sorts the result by the brithday field the parameter in the enumeration is the key of the field used to order the results 7 let descendingorder = query\<contact> order descending("birthday") 8 9 let orderedquery = unorderedquery order(\[descendingorder]) // returns a new query with the requested (descending) ordering option 10 11 // executes the query synchronously it throws an error if something happened 12 let orderedcontacts = try? orderedquery find() 13 14 // executes que query asynchronously and returns a result<\[contact], parseerror> object with the result 15 orderedcontacts find() { result in 16 // handle the result 17 } 1 연락처 앱 템플릿 다운로드 이 xcode xcode 프로젝트는 다음과 같은 구조를 가지고 있습니다 언제든지 github 리포지토리를 통해 전체 프로젝트에 접근할 수 있습니다 ios 예제 리포지토리 이 가이드의 주요 목표에 집중하기 위해, 우리는 쿼리와 관련된 섹션만 자세히 설명할 것입니다 parseswift sdk 에 대해 2 추가 crud 흐름 쿼리를 시작하기 전에, back4app 데이터베이스에 이미 저장된 연락처가 몇 개 있어야 합니다 newcontactcontroller newcontactcontroller 클래스에서, 우리는 연락처 연락처 를 추가하기 위한 기본 양식을 구현합니다 연락처 연락처 객체의 인스턴스를 저장하기 위해, 우리는 handleaddcontact() handleaddcontact() 메서드를 사용합니다 이 메서드는 newcontactcontroller newcontactcontroller 클래스에 구현되어 있습니다 1 // newcontactcontroller swift file 2 3 4 extension newcontactcontroller { 5 /// retrieves the info the user entered for a new contact and stores it on your back4app database 6 @objc fileprivate func handleaddcontact() { 7 view\ endediting(true) 8 9 // collect the contact's information from the form 10 guard let name = nametextfield text, 11 let numberoffriendsstring = numberoffriendstextfield text, 12 let numberoffriends = int(numberoffriendsstring), 13 let favoritefoods = favoritefoodstextfield text? split(separator ",") else { 14 return showalert(title "error", message "the data you entered is con valid ") 15 } 16 17 // once the contact's information is collected, instantiate a contact object to save it on your back4app database 18 let contact = contact( 19 name name, 20 birthday birthdaydatepicker date, 21 numberoffriends numberoffriends, 22 favoritefoods favoritefoods compactmap { string($0) trimmingcharacters(in whitespaces) } 23 ) 24 25 // save the new contact 26 contact save { \[weak self] result in 27 switch result { 28 case success( ) 29 self? showalert(title "success", message "contact saved ") { 30 self? dismiss(animated true, completion nil) 31 } 32 case failure(let error) 33 self? showalert(title "error", message "failed to save contact \\(error message)") 34 } 35 } 36 } 37 } 이 단계에 대한 자세한 내용은 기본 작업 가이드 를 참조하세요 3 기본 쿼리 수행하기 \ 이름으로 우리가 살펴볼 첫 번째 예는 특정 하위 문자열이 포함된 연락처를 검색할 수 있는 쿼리입니다 이를 위해 먼저 이름 이름 필드에 대한 queryconstraint queryconstraint 객체를 생성합니다 이 객체는 우리가 원하는 제약 조건을 포함할 것입니다 parseswift sdk parseswift sdk 는 (간접적으로) queryconstraint queryconstraint 를 생성하기 위한 다음 메서드를 제공합니다 1 // queryconstraint swift file 2 3 / 4 add a constraint for finding string values that contain a provided substring 5 warning this will be slow for large datasets 6 parameter key the key that the string to match is stored in 7 parameter substring the substring that the value must contain 8 parameter modifiers any of the following supported pcre modifiers (defaults to nil) 9 `i` case insensitive search 10 `m` search across multiple lines of input 11 returns the resulting `queryconstraint` 12 / 13 public func containsstring(key string, substring string, modifiers string? = nil) > queryconstraint 14 15 / 16 add a constraint that requires that a key is equal to a value 17 parameter key the key that the value is stored in 18 parameter value the value to compare 19 returns the same instance of `queryconstraint` as the receiver 20 warning see `equalto` for more information 21 behavior changes based on `parseswift configuration isusingequalqueryconstraint` 22 where isusingequalqueryconstraint == true is known not to work for livequery on 23 parse servers <= 5 0 0 24 / 25 public func == \<t>(key string, value t) > queryconstraint where t encodable 예를 들어, 연락처 연락처 의 john 이 포함된 이름 이름 필드를 가진 모든 항목을 검색할 수 있는 쿼리를 생성할 수 있습니다 1 // create the query sending the constraint as parameter 2 let constraint queryconstraint = containsstring(key "name", substring "john") // the first parameter (key) referres to the name of the field 3 let query = contact query(constrain) 4 5 // retrieve the contacts asynchronously (or sinchronously if needed) 6 query find() { result in 7 // handle the result and do the corresponding ui update 8 } 제약 조건이 이름 이름 필드가 주어진 문자열과 정확히 일치해야 하는 경우, 우리는 사용할 수 있습니다 1 // create the query sending the constraint as parameter 2 let value = "john" 3 let constraint queryconstraint = "name" == value 4 let query = contact query(constrain) \ 친구 수에 따라 숫자 비교와 관련된 제약 조건이 있는 쿼리는 다음을 생성하여 구성할 수 있습니다 queryconstraint queryconstraint 와 함께 1 / 2 add a constraint that requires that a key is greater than a value 3 parameter key the key that the value is stored in 4 parameter value the value to compare 5 returns the same instance of `queryconstraint` as the receiver 6 / 7 public func > \<t>(key string, value t) > queryconstraint where t encodable 8 9 / 10 add a constraint that requires that a key is greater than or equal to a value 11 parameter key the key that the value is stored in 12 parameter value the value to compare 13 returns the same instance of `queryconstraint` as the receiver 14 / 15 public func >= \<t>(key string, value t) > queryconstraint where t encodable 16 17 / 18 add a constraint that requires that a key is less than a value 19 parameter key the key that the value is stored in 20 parameter value the value to compare 21 returns the same instance of `queryconstraint` as the receiver 22 / 23 public func < \<t>(key string, value t) > queryconstraint where t encodable 24 25 / 26 add a constraint that requires that a key is less than or equal to a value 27 parameter key the key that the value is stored in 28 parameter value the value to compare 29 returns the same instance of `queryconstraint` as the receiver 30 / 31 public func <= \<t>(key string, value t) > queryconstraint where t encodable 30명 이상의 친구가 있는 모든 연락처를 쿼리하기 위해 우리는 사용합니다 1 let query = contacts query("numberoffriends" >= 30) 2 3 // retrieve the contacts asynchronously (or sinchronously if needed) 4 query find() { result in 5 // handle the result and do the corresponding ui update 6 } \ 쿼리 결과 정렬 쿼리의 결과를 정렬하기 위해 query\<contacts> query\<contacts> 객체는 order( ) order( ) 메서드를 제공합니다 이 메서드는 요청된 정렬 옵션을 고려하여 새로운 query\<contact> query\<contact> 객체를 반환합니다 매개변수로는 우리가 원하는 정렬을 나타내기 위해 열거형( query\<contact> order query\<contact> order )을 전달합니다 다음 코드 조각은 birthday birthday 필드를 기준으로 내림차순 정렬을 적용합니다 1 // a query without order to retrieve all the contact items 2 let unorderedquery = contact query() 3 4 // sorts the contacts based on their brithday the parameter in the enumeration is the key of the field used to order the results 5 let descendingorder = query\<contact> order descending("birthday") 6 7 let orderedquery = unorderedquery order(\[descendingorder]) // returns a new query with the requested (descending) ordering option 8 9 // executes que query asynchronously and returns a result<\[contact], parseerror> object with the result 10 orderedcontacts find() { result in 11 // handle the result 12 } 위의 프로젝트 예제 https //github com/templates back4app/ios basic queries example , 우리는 위에서 언급한 쿼리를 구현했습니다 contactscontroller contactscontroller 클래스에는 fetchcontacts() fetchcontacts() 메서드가 있으며, 여기에서 다음 코드 조각을 찾을 수 있습니다 1 2 3 class contactscontroller { 4 let querytype querytype 5 6 7 8 private func fetchcontacts() { 9 // we create a query\<contact> according to the querytype enumeration 10 let query query\<contact> = { 11 switch querytype { 12 case byname(let value) 13 return contact query(containsstring(key "name", substring value)) 14 case bynumberoffriends(let quantity) 15 return contact query("numberoffriends" >= quantity) 16 case byordering(let order) 17 let query = contact query() 18 switch order { 19 case ascending return query order(\[ ascending("birthday")]) 20 case descending return query order(\[ descending("birthday")]) 21 } 22 case all 23 return contact query() 24 } 25 }() 26 27 // execute the query 28 query find { \[weak self] result in 29 switch result { 30 case success(let contacts) 31 self? contacts = contacts 32 33 // update the ui 34 dispatchqueue main async { self? tableview\ reloaddata() } 35 case failure(let error) 36 // notify the user about the error that happened during the fetching process 37 self? showalert(title "error", message "failed to retrieve contacts \\(error message)") 38 return 39 } 40 } 41 } 42 } 4 앱 실행하기! 실행 버튼을 누르기 전에 xcode xcode , back4app back4app 애플리케이션을 appdelegate appdelegate 클래스에서 구성하는 것을 잊지 마세요! 내비게이션 바의 + + 버튼을 사용하여 몇 개의 연락처를 추가하고 다양한 쿼리를 테스트하세요