Swift - Closure: Bài 2: CallBack/ Completion (Part 2)
swift
65
ios
53
Closure
6
White

Bùi Khánh Duy viết ngày 26/04/2018

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

3. Closure with arguments
Dữ liệu của ta thường là các kiểu của Networking service, không phải kiểu đơn giản load file local json như bài 1, mà là nhận API, rồi lấy data từ đó, mặc dù nói chung vẫn trả về kiểu json tương tự.
Chúng ta bắt đầu pass data ở đây thông qua completion của ta. Ta có thể cho thêm arguments vào bên trong completion closure. Và ta thêm như sau:

  func getPeople(completion: (Bool, Any?, Error?) -> 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(true, names, nil)
    } catch {
      print(error)
      completion(false, nil, error)
    }
  }

Để ý dòng code đầu, getPeople(completion: (Bool, Any?, Error?) -> Void), biến đầu tiên sẽ là Bool, biến thứ hai sẽ là Any? và cuối cùng là Error? - cũng là 1 optional. Tức là khi bạn gọi completion, bạn phải truyền giá trị vào cho mỗi chú, bắt buộc. VÌ không thể gọi 1 function mà không truyền giá trị tương ứng.

Trong đoạn chỗ do, ta chắc chắn khi nó load phần này thì nó đã thành công, và ta sẽ đặt true, và thông tin ta cần pass đến nơi mà gọi function này là mảng names, cho nên ta đặt names, và đương nhiên như đã nói ở trên, phần này không có error, nên ta trả về nil.

Ta làm tương tự cho phần dưới, trong catch block, nó sẽ false và ta chẳng có data nào muốn chuyển trong phần nào cả, cái thông tin ta cần lấy ở đây chính là error mà được gen automatically bởi catch block nào. Bây giờ comment getPeople đang có hiện tại và type getPeople, bạn sẽ thấy như sau:
alt text

Bấm ok, thì nó sẽ ra code bên trong với các argument name, ta rename lại chúng và sử dụng chúng, đặt tên gì cũng được hết, nên ta đặt như sau:

getPeople { (success, response, error) in

    }

Thực ra bạn đặt gì cũng được nhưng đây là general practice, nên làm theo, h ta cần làm là nếu success == true thì nhận/ xử lý data, không thì xem error là gì

getPeople { (success, response, error) in
      if success {
        guard let names = response as? [String] else { return }
        print(names)
      } else {
        if let error = error {
          print(error)
        }
      }

Nhìn dễ hiểu hơn đúng không mọi người, ta sử dụng những values ở đây dựa trên cái mà được chuyển đến.
Đối với success, the response chính là names array mà ta vừa chuyển đến, là String array, nhưng mà ta rõ ràng ta vẫn không biết vì ta ném nó vào completion handler, do đó nó là Any Object, muốn dùng thì phải down cast nó xuống.
Đối với error thì đó là error từ khối catch block mà ta đã có được. Lưu ý ở đây cả hai phần response, error đều đang là optional nên ta unwrap nó bằng cách chaining. Bạn có thể nil-coalescing hoặc force.

Như đã nói, phần getPeople này sẽ nằm ở phần khác chứ không phải ngay chính VC này, nên tất cả những thông tin này sẽ được xử lý và ném qua completion handler

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

White

Bùi Khánh Duy

28 bài viết.
8 người follow
Kipalog
{{userFollowed ? 'Following' : 'Follow'}}
Cùng một tác giả
White
3 3
RxSwift: Bài 1 Observable và Just, Of, From Đôi lời: Mình viết loạt bài này không phải là loạt bài tut, nó chỉ là những kiến thức mình tự hiểu và ...
Bùi Khánh Duy viết 3 tháng trước
3 3
White
2 3
RxSwift: Bài 2 Subscribing to observables 1. Khái niệm Subscribe (đăng kí) đến một RxSwift observable khá giống như NotificationCenter, thay vì a...
Bùi Khánh Duy viết 3 tháng trước
2 3
White
2 0
RxSwift: Bài 3 Disposing and terminating 1. Đặt vấn đề: Nhắc lại là 1 observable sẽ không làm bất kì điều gì cho đến khi nó nhận một subscribe. C...
Bùi Khánh Duy viết 3 tháng trước
2 0
Bài viết liên quan
White
2 3
Xin chào mọi người. Mình xin chia sẽ một UILabel Helper nhỏ dùng trong truờng hợp cần tính chiều cao của UILabel để xác định "Show More" button có ...
DonDinh viết 3 năm trước
2 3
{{like_count}}

kipalog

{{ comment_count }}

bình luận

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


White
{{userFollowed ? 'Following' : 'Follow'}}
28 bài viết.
8 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á!