iOSでのParse CRUD 操作: Swift開発者向けガイド
15 分
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">数値\</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の例アプリ(todoリストアプリ)を通じて基本的なデータ操作を行う方法を学びます。これにより、 \<font color="#2166ae">parseswift sdk\</font> を使用して、parseサーバーデータベースからデータを作成、読み取り、更新、削除する方法を示します。 このチュートリアルでは、xcode 12で作成された基本的なアプリと ios 14 を使用します。 いつでも、私たちのgithubリポジトリを通じて完全なプロジェクトにアクセスできます。 ios例リポジトリ https //github com/templates back4app/ios crud to do list 目標 back4appでtodoリストアプリを例に基本的なデータベース操作を行う方法を学ぶために 前提条件 このクイックスタートを完了するには、次のものが必要です: xcode back4appで作成されたアプリ。 次の new parse app チュートリアル https //www back4app com/docs/get started/new parse app を参照して、back4appでparseアプリを作成する方法を学んでください。 注意: 次の install parse sdk (swift) チュートリアル https //www back4app com/docs/ios/parse swift sdk を参照して、back4appに接続されたxcodeプロジェクトを作成してください。 私たちのto doリストアプリの理解 より良く理解するために、 \<font color="#2166ae">parseswift sdk\</font> に対してto doリストアプリでcrud操作を行います。アプリケーションのデータベースには、タイトルと説明を持つシンプルなタスククラスが含まれます(両方とも \<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 to doリストアプリテンプレートの作成 いつでも、私たちの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リストアプリでは、このオブジェクトは \<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のセットアップ 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> メソッドに移ります。あなたの back4app データベースから \<font color="#2166ae">todolistitem\</font> アイテムを取得するのは、次のような \<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> を呼び出してアイテムを取得します。これも同期的または非同期的に行うことができます。私たちのto doリストアプリでは、非同期的に実装しています。 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操作を行う方法を学びました。