คำแนะนำ: อย่าทำรัง!
เรามีกรณีที่ต้องรอ API บางตัวให้เสร็จสิ้น จากนั้นจึงประมวลผลตรรกะเพิ่มเติมหรืออัปเดต UI ตามนั้น เราจะมาดูว่าฉัน (และคนอื่นๆ อีกหลายคน) เคยทำอะไรบ้าง จากนั้นจึงมาดูแนวทางการใช้งานกับ Swift ที่ดีที่สุด
ปัญหา
ดังที่คุณเห็นด้านล่าง เรากำลังเรียก API สองตัว จากนั้นเราต้องการอัปเดต UI เราจะใช้ Alamofire เพื่อให้ทุกอย่างง่ายขึ้นด้วยคำขอ API นอกจากนี้เรายังติดตามว่า API ทั้งสองใช้เวลานานแค่ไหนจึงจะเสร็จสมบูรณ์
หมายเหตุ: หากคุณกำลังลองใช้ด้วยตัวเอง อย่าลืมตั้งค่าการตั้งค่าความปลอดภัยของการขนส่งแอป ➡ อนุญาตให้โหลดโดยพลการไปที่ YES
ในไฟล์ Info.plist
ของคุณ
รหัส
คำอธิบายรหัส
- จุดสิ้นสุดคือโครงสร้างที่รวบรวม URL ไปยัง API ที่เราต้องการเรียกใช้ในภายหลัง
- จำเป็นต้องใช้
IBOutlet
เพื่อเข้าถึงออบเจ็กต์ UI เพื่ออัปเดตเมื่อสถานะการตอบสนองของ API เปลี่ยนแปลง startTimeInterval
เป็นการอ้างอิงถึงเมื่อเราเริ่มการเรียก API ครั้งแรกisWaiting
กำลังติดตามว่ามีคำขอ API ที่เรากำลังรอการตอบกลับหรือไม่ และเมื่อสถานะเปลี่ยนแปลง ระบบจะอัปเดต UI- ใน
viewDidLoad()
เรากำลังเรียก API สองตัวโดยใช้ Alamofire โปรดจำไว้ว่าเรากำลังทำรังพวกมันอยู่ ดังนั้นคำขอ API เหล่านั้นจะดำเนินการทีละรายการ ไม่ใช่พร้อมกัน updateUI()
เป็นเรื่องเกี่ยวกับการอัปเดตป้ายกำกับและactivityIndicatorView
ด้วยข้อความและภาพเคลื่อนไหวที่เหมาะสมตามลำดับ
สตอรี่บอร์ด
หากคุณสงสัยว่าสตอรี่บอร์ดของเรามีหน้าตาเป็นอย่างไร ก็ยังมีเหลือเพียงเล็กน้อยเท่านั้น มันเป็นเพียงป้ายกำกับและตัวบ่งชี้กิจกรรม
วิธีแก้ปัญหา: 'กลุ่มจัดส่ง'
ตอนนี้เข้าสู่ (ตั้งใจเล่น!) DispatchGroup
ออกแบบมาเป็นพิเศษสำหรับกรณีเช่นนี้ โดยจัดกลุ่มงานต่างๆ ไว้ด้วยกันและรอให้เสร็จ เมื่องานทั้งหมดเสร็จสิ้นก็สามารถแจ้งเตือนผ่านการปิด Swift เพื่อให้เราดำเนินการต่อไปได้
รหัส
คำอธิบายรหัส
- เราได้เพิ่มอินสแตนซ์
DispatchGroup
- เราใช้เมธอด
enter()
ในกลุ่ม นี่เป็นการบอกDispatchGroup
ว่าเรากำลังรออะไรบางอย่างอยู่ ลองนึกถึงDispatchGroup
เหมือนเป็นการนับจำนวนครั้งที่enter()
ถูกเรียก ดังนั้นตัวนับจะเพิ่มขึ้นหนึ่งทุกครั้งที่มีการเรียกenter()
- เราได้ลบการเรียก API ที่ซ้อนกันและวิธีที่เราเรียก API ทั้งสองพร้อมกัน โดยรวมแล้ว จะทำให้เวลารอของ API สั้นลง โปรดทราบว่าเรากำลังใช้เมธอด
leave()
เพื่อบอกDisaptchGroup
ว่างานเสร็จสมบูรณ์แล้ว ซึ่งหมายความว่าได้รับการตอบกลับจาก API แล้ว ด้วยการเรียกเมธอดleave()
เราจะลดตัวนับจินตภาพของเราลงหนึ่ง ทันทีที่ตัวนับจินตภาพของเราถึงศูนย์DispatchGroup
จะเรียกใช้เมธอดnotify()
หมายเหตุ:ทุกการโทร enter()
ควรมีการโทร leave()
ไปด้วย มิฉะนั้น วิธี notify()
จะไม่ถูกดำเนินการเลย
คุณอาจถูกล่อลวงให้โทร enter()
ก่อนการเรียก API เท่านั้น ดังตัวอย่างด้านล่าง:
แต่ฉันขอแนะนำให้คุณหลีกเลี่ยงสิ่งนั้น หากการตอบสนองของ API เร็วเกินไป กลุ่มจะถูกเข้าและออกเกือบจะในทันที และหากไม่มีงานอื่นที่กำหนดเวลาไว้ในกลุ่ม กลุ่มจะเรียก notify()
วิธีการและไม่รองานต่อไปของคุณ
ความเห็นส่วนตัวของผมคือเราควรจัดกลุ่มการโทร enter()
ไว้ด้วยกัน ถ้าเรารู้ว่าจะต้องเริ่มงานกี่งานก่อน
บทสรุป
ยอดเยี่ยม! วันนี้เราได้เรียนรู้วิธีใช้ DispatchGroup
เพื่อรอการดำเนินการแบบอะซิงโครนัส มีหลายวิธีในการใช้ DispatchGroup
แต่นั่นเป็นวันอื่น
ขอบคุณสำหรับการอ่าน.