Swift - Closure: Bài 2: CallBack/ Completion (Part 1)
swift
68
Closure
6
ios
54
Male avatar

Bùi Khánh Duy viết ngày 30/06/2018

Swift - Closure: Bài 2: CallBack/ Completion (Part 1)

=====
Updated ngày 30/06

Updated một chút: Vì những bất tiện và không rõ ràng về thông tin của kipalog, mình mới dọn về nhà mới ở đây, thoải mái, đẹp đẽ rõ ràng hơn kipalog. Mong các bạn có thể theo dõi tại trang web của mình để cập nhật thêm nha

Mình mới viết một loạt bài về chủ đề Clean Architecture và Service Locator. Các bạn có thể theo dõi.
Page trên facebook ở đây: ở đây

=====
Trước khi mình vào bài này mình xin giới thiệu các bài 1 nguồn học Swift cực kì hay, đó là Kilo loco youtuber. Các bạn có thể search.

1. Đặt chủ đề
Vào chủ đề, callback functions trong Swift và cách sử dụng chúng khi làm việc ở background thread. Mình sẽ nói rõ toàn bộ callback functions (completion handlers) hoạt động như thế nào và tại sao nên dùng chúng, cách đảm bảo completion handler được hoạt động trên main thread.

Callbacks là phần chính khi làm việc với networking như URLSession hay Alamofire v..v, nhưng bạn cần có 1 vài kiến thức về cách hoạt động của các thread và tại sao trả về main queue lại quan trọng. Mình sẽ tạo 1 app khá đơn giản, load dữ liệu data lên tableView. Note trước, mình sẽ tạo 1 file JSON với data JSON tự tạo, các bạn tự tạo 1 file JSON nhé, có id, name, vài thuộc tính nhỏ nhỏ.

2. Callback/ Completion không tham số
Bước 1: Để đi nhanh, mình tạo tableView và setup cell cho nó dựa trên 1 mảng String. Phần này dễ mình không đề cập nhiều. Các bạn có thể xem sơ qua:
alt text
Bây giờ ta cần load dữ liệu từ data lên, phần load JSON mình cũng đã có viết rất nhiều cách load json. Các bạn có thể vào facebook Chia Sẻ Swift để xem kĩ hơn.

Bước 2: Load dữ liệu từ file JSON lên, phần này mình chỉ show lại code:
alt text

Nào bây giờ run thử và ta thấy dữ liệu json đã được trả về:
alt text

Bây giờ ta chỉ muốn lấy name của các phần tử trong list json trả về, code như sau:
alt text

Kết quả sẽ là:
alt text

OK BẮT ĐẦU
Bây giờ ta vào phần callback, callback là gì? Đó là một closure, được dùng như một parameter trong main function của bạn. Khi bạn gọi closure đó bên trong function của bạn, nó cho phép bạn viết nhiều code hơn tại nơi bạn thực sự sử dụng nó. Bạn thấy rối chưa chứ mình thấy rối rồi đó. Mình sẽ giải thích rõ hơn khi code.

Ta muốn có những cái tên này được truyền qua qua đây (tại VC này) đến mảng names của mình. Nhưng vấn đề là thường đoạn này không nằm bên trong VC này như đoạn code này. Xin lỗi mọi người, đây là 1 bad practice nếu xử lý networking, coi như mình nợ, mình sẽ có practice tốt hơn ở bài 3. Thường đoạn xử lý code này thường nằm ở file khác (thường là Service or ViewModel) mà ta không có ở đây. Thông thường, bạn sẽ dùng callback, callback thì nó cũng kiểu như completion, nếu các bạn thấy trong phần networking mà có completion thì các bạn hiểu đó là callback

Nên ta sẽ cứ làm theo những gì các tiền bối đã làm, same thing, same pattern, và truyền vào hàm getPeople() một parameter là 1 closure, đặt tên là completion như sau:

func getPeople(completion: () -> Void) {
    guard let path = Bundle.main.path(forResource: "someJson", ofType: "json") else { return }
    let url = URL(fileURLWithPath: path)
    do {
      let data = try Data(contentsOf: url)
      let json = try JSONSerialization.jsonObject(with: data, options: .mutableContainers)
      guard let array = json as? [[String: Any]] else { return }
      var names = [String]()
      for user in array {
        guard let name = user["name"] as? String else { continue }
        names.append(name)
      }
//      print(names)
      completion()
    } catch {
      print(error)
    }
  }

Các bạn để ý 2 dòng code sau:

func getPeople(completion: () -> Void)

// print(names)
completion()

Cái ta sẽ làm ở đây là truyền vào 1 hàm và không cần trả lại gì hết (chỉ cần print ra thôi). Bây giờ ta call completion() bên trong hàm chính của mình. Và ta gọi lại hàm getPeople ở viewDidLoad(). Lúc ta, viết rara, thì ta có thể thấy nó hiển thị ở autocompletion:
alt text

Việc tiếp theo là ta in ra đại 1 chữ gì đó, và xem thử completion working như thế nào:
alt text

Nó hiển thị Hello world. Ok, mình xin tóm tắt lại như sau:

Closure là 1 function được dùng như 1 parameter trong 1 function lớn hơn, mà khi ta dùng function lớn hơn đó, ta có thể code thêm tuỳ ý tại nơi mà ta gọi function lớn đó nhờ vào closure.
Ở ví dụ này, function lớn là getPeople(), nó làm các việc bên trong + completion(). Và khi mình gọi function lớn là getPeople() ở viewDidLoad thì ngoài việc thực các việc bên trong, mình còn có thể thông qua closure completion này để thông báo/ làm cái gì đó (cụ thể là báo pass or fail)

Có vẻ như hơi nhiều, mình sẽ để phần tiếp theo qua bài 3.

Bình luận


White
{{ comment.user.name }}
Bỏ hay Hay
{{comment.like_count}}
Male avatar
{{ comment_error }}
Hủy
   

Hiển thị thử

Chỉnh sửa

Male avatar

Bùi Khánh Duy

29 bài viết.
11 người follow
Kipalog
{{userFollowed ? 'Following' : 'Follow'}}
Cùng một tác giả
Male avatar
3 3
RxSwift: Bài 1 Observable và Just, Of, From ===== Updated ngày 30/06 Updated một chút: Vì những bất tiện và không rõ ràng về thông tin của kipalo...
Bùi Khánh Duy viết 6 tháng trước
3 3
Male avatar
3 0
Autolayout và lifecycle trong IOS ===== Updated ngày 30/06 Updated một chút: Vì những bất tiện và không rõ ràng về thông tin của kipalog, mình mớ...
Bùi Khánh Duy viết 4 tháng trước
3 0
Male avatar
2 3
RxSwift: Bài 2 Subscribing to observables ===== Updated ngày 30/06 Updated một chút: Vì những bất tiện và không rõ ràng về thông tin của kipalog,...
Bùi Khánh Duy viết 6 tháng trước
2 3
Bài viết liên quan
White
11 4
(Link) (Link) (Link) Ở 2 phần tut trước, mình đã hướng dẫn khá chi tiết cách viết một ứng dụng camera có tích hợp chức năng nhận diện khuôn mặ...
HoangPH viết 3 năm trước
11 4
White
27 4
Chào mừng sự trở lại sau kì nghỉ, đây cũng là bài viết cuối cùng trong năm 2015 của tôi. Trong bài viết này tôi sẽ giới thiệu với các bạn về Closur...
Hoàng Nguyễn viết hơn 2 năm trước
27 4
{{like_count}}

kipalog

{{ comment_count }}

bình luận

{{liked ? "Đã kipalog" : "Kipalog"}}


Male avatar
{{userFollowed ? 'Following' : 'Follow'}}
29 bài viết.
11 người follow

 Đầu mục bài viết

Vẫn còn nữa! x

Kipalog vẫn còn rất nhiều bài viết hay và chủ đề thú vị chờ bạn khám phá!