30/09/2018, 23:27

Completion Handlers trong Swift 3 - IOS

Nguồn: [http://niviki.com/2016/08/completion-handlers-trong-swift-3-ios/] (http://niviki.com/2016/08/completion-handlers-trong-swift-3-ios/) có thể xem được code màu mè hơn
Kiến thức yêu cầu:

  1. Function
  2. Closures
  3. JSON
 

Khi nào cần dùng Completion Handlers ?

Thông thường, khi chúng ta download dữ liệu như JSON, hình ảnh sẽ cần sử dụng Completion Handlers để thông báo kết quả của việc download này như thế nào.

Demo

Khai bào hàm có dùng Completion Handlers

Để dễ hiểu mình sẽ lấy ví dụ 1 hàm tượng trưng cho việc download JSON từ trang niviki.com/toppost/json. Chỉ là giả định thôi nha, link này không có dữ liệu gì đâu

 

Completion Handler

Nhìn vào tham số của hàm:

loadData( url : String, completion : (String) -> () )

Để dễ hiểu, bạn cứ đọc câu thần chú là: Khi hoàn thành thì completion của tui sẽ gắn với 1 String và không trả về gì hết

Cách viết khác:

loadData( url : String, completion : (result : String) -> Void )

Nếu viết theo kiểu dài dòng này thì trong hàm khi gán giá trị cho completion, bạn phải dùng: Completion Hanlder 2Bên trong hàm loadData bạn xử lý logic như tải dữ liệu chẳng hạn, tải xong thì bạn gán dữ liệu vào completion . Đương nhiên để cho dễ hiểu mình cho completionString thôi, bạn có thể trả về bất kỳ kiểu gì bạn thích. Chẳng hạn mình đang viết một app download bảng xếp hạng TOP Music Video thì mình sẽ dùng:

func loadData(url : String, completion : ([MusicVideo]) -> Void )

[MusicVideo] là một mảng class của mình.

Gọi hàm có completion handler như thế nào

Với hàm tượng trưng ban đầu, để gọi (sử dụng) hàm này, ta dùng:

Completion Handler 3

Với 2 đối số là urlcompletion. (Thực chất completion là hàm, bạn có thể xem thêm về closure tại đây. )

url thì dễ hiểu rồi, với completion thì chúng ta điền gì vào?

Có 2 cách:

  • Bạn tạo một function riêng cho dễ nhìn
  • Viết trực tiếp luôn, dân gian còn gọi là trailing closures (trail và đuôi đó, tức là viết sau cái hàm luôn)

Tạo function riêng

func didLoadData(number : String) -> (){

print(number)

}

Mình đặt tên hàm là didLoadData, bạn có thể đặt tên hoa mỹ hơn như daTaiXongDuLieuRoiNe cũng được.

Bạn chú ý tham số của hàm didLoadData(number : String) và kiểu trả về là -> ()

Bạn thấy quen không? Tức là cái completion bạn khai báo sao thì hàm didLoadData bạn khai báo giống như vậy. Đại ý của Apple là 2 cái khớp thì mới ráp vô hàm loadData được đó. Khi sử dụng bạn chỉ cần

loadData(url: "khoa.com", completion: didLoadData)

Lúc này, kết quả sẽ ra:

Khong thay data dau het a, hihhih

Trailing Closures

Cái này thì nhìn ảo diệu và ngắn ngọn hơn.

loadData(url:"niviki.com/toppost/json"){

result in

print(result)

}

Bây giờ có 2 nhân vật mới là resultin xuất hiện.

result đại diện cho tham số được khai báo tại completion - tức là một chuỗi String trong ví dụ trên. Tại sao lại đặt result, tui muốn đặt tên khác được không? Được chứ!

loadData(url: "niviki.com/toppost/json"){

ketquane in

print(ketquane)

}

Lúc này, kết quả sẽ ra:

Day la data ne

Ngoài ra, bạn có thể chơi trội bằng cách xử dụng shorthand như vầy:

loadData(url: "niviki.com/toppost/json"){

print($0)

}

Vì có một tham số nên bạn biết result lúc này tương đương với $0. Xem thêm về closure tại đây.

Vậy nên xài function hay trailing closure? Câu trả lời là tùy sở thích của bạn nhé!

Bạn đã học được gì?

  1. Khi nào dùng Completion Handlers
  2. Cách khai báo function có Completion Handlers
  3. Hai cách gọi hàm có Completion Handlers

Tuy nhiên bài viết vẫn chưa đề cập đến Completion Handlers có kiểu trả về (return). Bạn đọc có thể tìm hiểu thêm.

Rất hoan nghênh mọi đóng góp, phản hồi, khiếu nại từ bạn đọc gần xa qua ô bình luận phía dưới, còn ngại ngần gì nữa mà không thể hiện khả năng anh hùng bàn phím của bạn!

Awaiting for your comment!!!

Bài liên quan
0