iOS
...
Data Objects
使用ParseSwift SDK进行数据查询:基础教程
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 } 以下方法将允许我们保存和查询 contact contact 对象 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 类中,我们实现了一个基本表单来添加一个 contact contact 。要保存一个 contact contact 对象的实例,我们使用 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 类! 使用导航栏中的 + + 按钮,添加几个联系人并测试不同的查询。