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:
- Function
- Closures
- 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
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:
Bê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 completion
là String
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:Với 2 đối số là url
và completion
. (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
là (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à result và in 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ì?
- Khi nào dùng Completion Handlers
- Cách khai báo function có Completion Handlers
- 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!!!