- vừa được xem lúc

Swift Codable

0 0 8

Người đăng: Pham Van Duc D

Theo Viblo Asia

Cách đây rất lâu, chúng ta đã từng sử dụng class JsonSerialization để chuyển đổi sang và từ các đối tượng tùy chỉnh dữ liệu JSON trong iOS. Trong khi truy xuất dữ liệu từ sever web (API), trước tiên, chúng tôi chuyển đổi dữ liệu thành Đối tượng JSON và sau đó nhập truyền các thuộc tính từ Đối tượng JSON đó sang các loại phù hợp.

Swift 4 đã thay đổi hoàn toàn điều này với việc giới thiệu codable Protocols. Codable Protocol là thành phần của hai giao thức được gọi là 'Encodable' và 'Decodable'.

JSON :

Trong máy tính, JavaScript Object Notation hay JSON là một định dạng tệp tiêu chuẩn mở sử dụng văn bản có thể đọc được của con người để truyền các đối tượng dữ liệu bao gồm các cặp giá trị thuộc tính và kiểu dữ liệu mảng (hoặc bất kỳ giá trị có thể tuần tự hóa nào khác). Đây là một định dạng dữ liệu rất phổ biến được sử dụng cho giao tiếp browser–server không đồng bộ, bao gồm cả việc thay thế cho XML trong một số hệ thống kiểu AJAX (Wiki).

JSON là một định dạng dữ liệu văn bản và độc lập với ngôn ngữ mà nhiều dịch vụ web sử dụng.

JSON sử dụng và chấp nhận các kiểu dữ liệu sau:

String, Int, Double, URL, Date, Data, Array và Dictionary

Ưu điểm:

  • Tất cả các ngôn ngữ lập trình đều hỗ trợ tạo, đọc và giải mã các Đối tượng JSON.

  • Có thể mã hóa bất kỳ định dạng dữ liệu nào thành json và giải mã json sang bất kỳ định dạng dữ liệu nào. Điều này làm cho JSON trở nên mạnh mẽ như vậy.


{ "id": 1, "name": "chair", "price": 350, "tags": [ "recliner", "foldable" ], "stock": { "warehouse": 300, "retail": 20 }
} 

Codable Protocols :

  • Codable protocol chứa hai phương pháp: phương thức đầu tiên là func encode(to encoder: Encoder) là từ Encodable

  • “Func init (from decoder: Decoder)” là từ giao thức Decodable.

Hai lớp trong Foundation Framework của swift, được gọi là:

JSONEncoder & JSONDecoder sử dụng hai phương pháp trên để thực hiện các hoạt động mã hóa và giải mã trên các loại tùy chỉnh được xác nhận với các giao thức được đề cập ở trên.

Thực hiện encoding and decoding

Đối với điều này, tốt hơn là sử dụng các tên thuộc tính tương tự như với các tên thuộc tính có trong cấu trúc JSON cho tất cả các loại tùy chỉnh được xác nhận với các giao thức ở trên.

Nếu bạn muốn sử dụng các tên khác cho các thuộc tính với cấu trúc JSON, bạn cần viết thêm một đoạn code và xác định một enum có tên là CodingKeys, thuộc loại String và được xác nhận với CodingKey Type.

Trên thực tế, các giao thức codable sử dụng enum này trong nội bộ ngay cả khi bạn không xác định trong loại tùy chỉnh của mình. Khi bạn sử dụng các tên thuộc tính khác nhau, bạn phải xác định enum này trong các loại tùy chỉnh của mình để làm cho các biến khác nhau đó dễ hiểu đối với các giao thức. Chúng ta sẽ xem các ví dụ sau.

struct Stock: Codable { var warehouse: Int var retail: Int
} struct Product: Codable { var id: Int var name: String var price: Int var tags: [String] var stock: Stock } func fetchDataFromRemote() { //Taking Json as a String type for example purpose
//Normally we will get this from web service calls let jsonString = """ { "id": 1, "name": "chair", "price": 350, "tags": [ "recliner", "foldable" ], "stock": { "warehouse": 300, "retail": 20 } } """ if let jsonData = jsonString.data(using: String.Encoding.utf8) as? Data { let decoder = JSONDecoder() let product = try! decoder.decode(Product.self, from: jsonData) print(product) }
} OutPut :
Product(id: 1, name: "chair", price: 350, tags: ["recliner", "foldable"], stock: GoalPost.Stock(warehouse: 300, retail: 20)) 
struct Stock: Codable { var warehouse: Int var retail: Int
} struct Product: Codable { var id: Int var name: String var price: Int var types: [String] var stockInfo: Stock enum CodingKeys: String, CodingKey { case id case name case price case types = "tags" case stockInfo = "stock" } } func fetchDataFromRemote() { let jsonString = """ { "id": 1, "name": "chair", "price": 350, "tags": [ "recliner", "foldable" ], "stock": { "warehouse": 300, "retail": 20 } } """ if let jsonData = jsonString.data(using: String.Encoding.utf8) as? Data { let decoder = JSONDecoder() let product = try! decoder.decode(Product.self, from: jsonData) print(product) print("************************") print(product.stockInfo) print(product.types) } } Output :-
Product(id: 1, name: "chair", price: 350, types: ["recliner", "foldable"], stockInfo: GoalPost.Stock(warehouse: 300, retail: 20))
************************
Stock(warehouse: 300, retail: 20)
["recliner", "foldable"] 

trong ví dụ trên, chúng ta có type "Product" được xác nhận với Codable’ protocol. trong ‘product’, có một biến ‘Stock’, đây là một loại ‘Stock’ cũng được xác nhận là Codable. Tất cả các tên biến trong các loại tùy chỉnh đó được đặt tên chính xác như cấu trúc json. để decoding, trước tiên chúng ta cần có dữ liệu.

trong ví dụ, chúng tôi đã khởi tạo một biến "decoder" với lớp JSONDecoder. Sau đó, chúng tôi gọi phương thức có tên là ‘func decode (Codable.Type, from:)’ chấp nhận 2 tham số, tham số đầu tiên là kiểu được xác nhận với Codable và tham số thứ hai là kiểu đối tượng của Dữ liệu. Hàm này có thể throwable, vì vậy chúng ta cần xử lý các trường hợp lỗi.

Điều gì sẽ xảy ra nếu thuộc tính JSON khác với thuộc tính Product type ?


struct Stock: Codable { var warehouse: Int var retail: Int
} struct Product: Codable { var id: Int var name: String var price: Int var types: [String] var stockInfo: Stock enum CodingKeys: String, CodingKey { case id case name case price case types = "tags" case stockInfo = "stock" } } func fetchDataFromRemote() { let jsonString = """ { "id": 1, "name": "chair", "price": 350, "tags": [ "recliner", "foldable" ], "stock": { "warehouse": 300, "retail": 20 } } """ if let jsonData = jsonString.data(using: String.Encoding.utf8) as? Data { let decoder = JSONDecoder() let product = try! decoder.decode(Product.self, from: jsonData) print(product) print("************************") print(product.stockInfo) print(product.types) } } Output :-
Product(id: 1, name: "chair", price: 350, types: ["recliner", "foldable"], stockInfo: GoalPost.Stock(warehouse: 300, retail: 20))
************************
Stock(warehouse: 300, retail: 20)
["recliner", "foldable"]

Trong ví dụ trên, hãy quan sát các thuộc tính Product type, hai thuộc tính cuối cùng khác nhau thì ở cấu trúc json.

Vì vậy, để làm cho chúng dễ hiểu với protocols, để encoding và decoding, chúng ta phải sử dụng các CodingKeys liệt kê, trong loại đó. Khi chúng ta khai báo enum, chúng ta cần define điều đó với tất cả các thuộc tính của custom type, bao gồm các raw values giống như trong json cho những thuộc tính khác với trong json. Vì vậy, sau đó Codables biết cách map chúng với các biến thích hợp assign và get values trong encoding và decoding.

struct Stock: Codable { var warehouse: Int var retail: Int
} struct Product: Codable { var id: Int var name: String var price: Int var types: [String] var stockInfo: Stock enum CodingKeys: String, CodingKey { case id case name case price case types = "tags" case stockInfo = "stock" } } func exampleEncodeFunction() { let tableStock = Stock.init(warehouse: 114, retail: 16) let table = Product.init(id: 112, name: "Long Table", price: 450, types: ["Long", "Study", "Short"], stockInfo: tableStock) let encoder = JSONEncoder() let productData = try! encoder.encode(table.self) let productStr = String.init(data: productData, encoding: .utf8) print("String from Product data is \(productStr ?? "No data")") } Output :-
String from Product data is {"id":112,"tags":["Long","Study","Short"],"name":"Long Table","price":450,"stock":{"retail":16,"warehouse":114}}

Bạn define Stock và Product types,Sau đó với sự trợ giúp của object JSONEncoder, bằng cách gọi hàm func encode (_ to: Encodable), Chúng ta đã encoded product type thành dữ liệu json. Ví dụ, mục đích để hiển thị dữ liệu được encoded data đó, chúng ta đã chuyển đổi object to String và print out.

Bình luận

Bài viết tương tự

- vừa được xem lúc

Swift: Tạo custom phép toán tử (Operator) của riêng bạn!

Swift cho phép bạn tạo các toán tử có thể tùy chỉnh của riêng bạn. Điều này đặc biệt hữu ích khi bạn xử lý các loại dữ liệu của riêng mình. Operator Types in Swift. Có năm loại toán tử chính trong Swift.

0 0 45

- vừa được xem lúc

Code ngắn gọn hơn với OptionSet trong Swift

. Nếu bạn muốn biết cách xử lý với Bitmasks trong Swift hay là bạn đã từng nghe đến OptionSet chưa? Bài viết này sẽ giúp bạn hiểu hơn về điều đó . 1.

0 0 26

- vừa được xem lúc

Chương 6 Protocol oriented programming.

Cuốn sách này là về lập trình hướng protocol. Khi Apple thông báo swift 2 ở WWDC 2015.

0 0 29

- vừa được xem lúc

Ví dụ về UIActivityViewController

Trên iOS, UIActivityViewController cung cấp giao diện thống nhất để người dùng chia sẻ và thực hiện các hành động trên văn bản, hình ảnh, URL và các mục khác trong ứng dụng. let string = "Hello, world!". let url = URL(string: "https://nshipster.com").

0 0 46

- vừa được xem lúc

Quản lý self và cancellable trong Combine.

. . Công việc quản lý bộ nhớ memory management thường trở nên phức tạp khi chúng ta thực hiện các tác vụ bất đồng bộ asynchronous vì chúng ta thường phải lưu giữ một số object nằm ngoài scope mà object được define trong khi vẫn phải đảm bảo được việc giải phóng object đó được thực hiện đúng quy trìn

0 0 29

- vừa được xem lúc

[SWIFT] Sử dụng Dependency Injection với Storyboards

1. Lời mở đầu:.

0 0 31