iOS
...
Data Objects
การจัดการวัตถุด้วย ParseSwift SDK สำหรับ iOS
16 นาที
crud parse objects ใน ios บทนำ การจัดเก็บข้อมูลบน parse ถูกสร้างขึ้นรอบๆ parse object parse object คลาส แต่ละ parse object parse object ประกอบด้วยคู่คีย์ ค่า ของข้อมูลที่เข้ากันได้กับ json ข้อมูลนี้ไม่มีสคีมา ซึ่งหมายความว่าคุณไม่จำเป็นต้องระบุล่วงหน้าว่าคีย์ใดมีอยู่ในแต่ละ parse object parse object คุณสามารถตั้งค่าคู่คีย์ ค่า ใดๆ ที่คุณต้องการ และแบ็คเอนด์ของเราจะจัดเก็บมัน คุณยังสามารถระบุประเภทข้อมูลตามความต้องการของแอปพลิเคชันของคุณและจัดเก็บประเภทต่างๆ เช่น number number , boolean boolean , string string , datetime datetime , list list , geopointers geopointers , และ object object , โดยเข้ารหัสเป็น json ก่อนที่จะบันทึก parse ยังสนับสนุนการจัดเก็บและค้นหาข้อมูลเชิงสัมพันธ์โดยใช้ประเภท pointers pointers และ relations relations ในคู่มือนี้ คุณจะได้เรียนรู้วิธีการดำเนินการข้อมูลพื้นฐานผ่านแอปตัวอย่าง crud (แอป todo list) ซึ่งจะแสดงให้คุณเห็นวิธีการสร้าง อ่าน อัปเดต และลบข้อมูลจากฐานข้อมูลเซิร์ฟเวอร์ parse ของคุณโดยใช้ parseswift sdk parseswift sdk บทเรียนนี้ใช้แอปพื้นฐานที่สร้างขึ้นใน xcode 12 และ ios 14 ในทุกช่วงเวลา คุณสามารถเข้าถึงโครงการทั้งหมดได้ผ่านที่เก็บ github ของเรา ที่เก็บตัวอย่าง ios เป้าหมาย เรียนรู้วิธีการดำเนินการฐานข้อมูลพื้นฐานบน back4app โดยใช้แอป todo list เป็นตัวอย่าง ข้อกำหนดเบื้องต้น ในการทำให้การเริ่มต้นนี้เสร็จสมบูรณ์ คุณต้องมี xcode แอปที่สร้างขึ้นที่ back4app ติดตาม บทแนะนำการสร้างแอป parse ใหม่ เพื่อเรียนรู้วิธีการสร้างแอป parse ที่ back4app หมายเหตุ ติดตาม บทแนะนำการติดตั้ง parse sdk (swift) เพื่อสร้างโปรเจกต์ xcode ที่เชื่อมต่อกับ back4app การทำความเข้าใจแอป to do list ของเรา เพื่อให้เข้าใจ parseswift sdk parseswift sdk ได้ดียิ่งขึ้น คุณจะดำเนินการ crud บนแอป to do list ฐานข้อมูลของแอปพลิเคชันจะมีคลาสงานที่เรียบง่ายพร้อมชื่อและคำอธิบาย (ทั้งสองเป็น สตริง สตริง ) คุณสามารถอัปเดตชื่อและ/หรือคำอธิบายของแต่ละงานได้ การอ้างอิงอย่างรวดเร็วของคำสั่งที่เราจะใช้ เมื่อวัตถุเป็นไปตาม parseswift parseswift โปรโตคอล มันจะดำเนินการชุดของวิธีการที่อนุญาตให้คุณจัดการวัตถุและอัปเดตการเปลี่ยนแปลงใด ๆ บนฐานข้อมูล back4app ของคุณ วัตถุที่ให้คือ todolistitem todolistitem 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 list ในทุกเวลา คุณสามารถเข้าถึงโปรเจกต์ทั้งหมดได้ผ่านทาง github repositories ของเรา ios ตัวอย่าง repository ไปที่ xcode และค้นหา scenedelegate swift scenedelegate swift ไฟล์ เพื่อเพิ่ม navigation bar ด้านบนของแอป เราจึงตั้งค่า uinavigationcontroller uinavigationcontroller เป็น root view controller ในลักษณะดังต่อไปนี้ 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 } คลาส root view controller ( todolistcontroller todolistcontroller ) สำหรับ navigation controller เป็น subclass ของ uitableviewcontroller uitableviewcontroller , ซึ่งทำให้การจัดเรียงรายการของรายการเป็นเรื่องง่าย 2 ตั้งค่าอ็อบเจ็กต์ crud อ็อบเจ็กต์ที่คุณต้องการบันทึกในฐานข้อมูล back4app ของคุณต้องเป็นไปตาม parseobject parseobject โปรโตคอล ในแอป to do list ของเรา อ็อบเจ็กต์นี้คือ todolistitem todolistitem ดังนั้นคุณต้องสร้างอ็อบเจ็กต์นี้ก่อน 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 ของคุณ อินสแตนซ์ใหม่ของอ็อบเจ็กต์นี้จะถูกเก็บไว้ในฐานข้อมูลของคุณภายใต้ todolistitem todolistitem คลาส 3 ตั้งค่า todolistcontroller ใน todolistcontroller todolistcontroller เราควร implement การตั้งค่าที่จำเป็นทั้งหมดสำหรับ navigationbar navigationbar , และ tableview tableview คุณสมบัติ 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 } เพื่อสรุปขั้นตอนนี้ เราจะดำเนินการเซลล์มุมมองตารางที่กำหนดเอง todolistitemcell todolistitemcell 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 ทั้งหมดใน todolistcontroller todolistcontroller คลาส ไปที่ todolistcontroller swift todolistcontroller swift และเพิ่มวิธีการต่อไปนี้ใน todolistcontroller todolistcontroller คลาส 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 } \ สร้างวัตถุ ตอนนี้เราจะเริ่มการนำไปใช้ของ createobject(title\ description ) createobject(title\ description ) วิธีการ สร้างอินสแตนซ์ของ todolistitem todolistitem โดยใช้ init(title\ description ) init(title\ description ) ตัวสร้าง ในการบันทึกรายการใหม่นี้ในฐานข้อมูล back4app ของคุณ โปรโตคอล parseswift parseswift ให้บริการ save() save() วิธีการ วิธีการนี้สามารถเรียกใช้ได้ทั้งแบบซิงโครนัสหรือแบบอะซิงโครนัส เลือกหนึ่งในนั้นตามกรณีการใช้งานของคุณ การนำไปใช้แบบอะซิงโครนัสควรมีลักษณะดังนี้ 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 } ตอนนี้เราสามารถทำการเพิ่มสำหรับปุ่มเพิ่มที่อยู่ด้านขวาของแถบการนำทาง ไปที่ todolistcontroller todolistcontroller และเพิ่มสิ่งต่อไปนี้ 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 } \ อ่านวัตถุ เราย้ายไปที่ readobjects() readobjects() วิธีการ การดึง todolistitem todolistitem รายการจากฐานข้อมูล back4app ของคุณจะดำเนินการผ่าน query\<todolistitem> query\<todolistitem> วัตถุ การค้นหานี้ถูกสร้างขึ้นในลักษณะดังต่อไปนี้ 1 func readobjects() { 2 let query = todolistitem query() 3 4 } ในบทเรียนนี้เราจะใช้การค้นหาที่จะดึงรายการทั้งหมดของประเภท todolistitem todolistitem จากฐานข้อมูล back4app ของคุณ หากคุณต้องการดึงชุดของรายการเฉพาะ คุณสามารถระบุ queryconstraint queryconstraint ไปยัง todolistitem query(queryconstraint ) todolistitem query(queryconstraint ) ตัวอย่างเช่น เพื่อดึงรายการทั้งหมดที่ title == "some title" title == "some title" , การค้นหาจะมีรูปแบบ 1 let query = todolistitem query("title" == "some title") เมื่อคุณเตรียมคำค้นหาเสร็จแล้ว เราจะดำเนินการดึงรายการโดยการเรียก query find() query find() อีกครั้งหนึ่ง สิ่งนี้สามารถทำได้ทั้งแบบซิงโครนัสหรือแบบอะซิงโครนัส ในแอป 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 } เมื่อ readobjects() readobjects() เสร็จสิ้น เราสามารถดึงงานทั้งหมดที่เก็บไว้ในฐานข้อมูล back4app ของคุณและแสดงผลทันทีหลังจากที่แอปเข้าสู่พื้นหลัง กลับไปที่ todolistcontroller todolistcontroller และเขียนทับ viewdidappear() viewdidappear() เมธอด 1 class todolistcontroller uitableviewcontroller { 2 3 4 override func viewdidappear( animated bool) { 5 super viewdidappear(animated) 6 7 readobjects() 8 } 9 10 11 } \ อัปเดตวัตถุ เมื่อมี objectid objectid ของ todolistitem todolistitem วัตถุ การอัปเดตจะเป็นเรื่องง่าย เราเพียงแค่สร้างวัตถุ todolistitem todolistitem โดยใช้ init(objectid ) init(objectid ) ตัวสร้าง จากนั้นเราจะอัปเดตคุณสมบัติที่เราต้องการและเรียกใช้ save() save() เมธอด (ของ todolistitem todolistitem ) เพื่อบันทึกการเปลี่ยนแปลง 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 ของคุณมีความคล้ายคลึงกับการสร้างวัตถุ เราจะเริ่มต้นด้วยการสร้างอินสแตนซ์ของ todolistitem todolistitem โดยใช้ objectid ของรายการที่เราต้องการลบ จากนั้นเราจะเรียกใช้ (แบบซิงโครนัสหรือแบบอะซิงโครนัส) เมธอด delete() delete() ของวัตถุ หากการลบสำเร็จ เราจะอัปเดต 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 } ด้วย deleteobject(item ) deleteobject(item ) และ updateobject(objectid\ newtitle\ newdescription) updateobject(objectid\ newtitle\ newdescription) เสร็จสิ้นแล้ว เราจะดำเนินการเพิ่มการกระทำที่เกี่ยวข้องเพื่อเรียกใช้การดำเนินการเหล่านี้ กลับไปที่ todolistcontroller todolistcontroller และเพิ่ม 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 } ดังที่เราได้ชี้ให้เห็นก่อนหน้านี้ ปุ่มเสริมในแต่ละ todolistitemcell todolistitemcell จะเรียกแผ่นแก้ไขผ่าน tableview( accessorybuttontappedforrowwith ) tableview( accessorybuttontappedforrowwith ) เมธอดตัวแทน เสร็จเรียบร้อย! ในจุดนี้ คุณได้เรียนรู้วิธีการทำการดำเนินการ crud พื้นฐานกับ parse บน ios