คำแนะนำ: อย่าทำรัง!

เรามีกรณีที่ต้องรอ 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 แต่นั่นเป็นวันอื่น

ขอบคุณสำหรับการอ่าน.

ดาวน์โหลดรหัส



ทรัพยากร