JSON Encoding And Decoding - Swift 4

1/Giới thiệu qua về JSON encoding and decoding trong Swift 4.

  • Swift 4 cho phép chúng ta có thể làm việc dễ dàng hơn với JSON. Hãy thử tượng tượng đơn giản là chúng ta tạo một app nơi chúng ta làm việc với hồ sơ người sử dụng. Chỉ cần phương thức GET chúng ta sẽ nhận được thông tin người dùng. Trước tiên hãy tạo một struct:
struct Person: Codable {
    let name: String
    let age: Int
    
    func getString() -> String {
        return "Name: \(name), Age: \(age)"
    }
}
  • Bây giờ chúng ta sẽ khởi tạo 1 instance của struct và sẽ in ra data để đảm bảo chúng ta khởi tạo đúng:
//Create A Person Struct
let person = Person(name: "Ken", age: 26)
print("Original Person Struct: " + person.getString() + "\n")

//Prints - Original Person Struct: Name: Ken, Age: 26
  • Nếu chúng ta cần encode instance dưới dạng data chúng ta chỉ cần thực hiện:
//Encode Person Struct as Data
let encodedData = try? JSONEncoder().encode(person)
  • Hãy nghĩ rằng khi bạn cần gửi instance này cho server dưới dạng JSON bạn sẽ phải convert nó sang data trước tiên rồi mới khởi tạo JSON:
//Create JSON
var json: Any?
let encodedData = try? JSONEncoder().encode(person)

if let data = encodedData {
    json = try? JSONSerialization.jsonObject(with: data, options: .allowFragments)
    if let json = json {
      print("Person JSON:\n" + String(describing: json) + "\n")
      //Prints: Person JSON: { age = 26; name = Ken; }
    }
}
  • If you received a person as a JSON and you need to convert it to a struct instance firstly you have to convert it in Data and then you may convert it in a struct :
  • Nếu bạn nhận được person dưới dạng JSON và bạn cần convert nó với ngược trở lại struct bạn cần làm như sau:
//Convert JSON back to Data
var jsonData: Data?
var decodedPerson: Person?

if let json = json {
   jsonData = try? JSONSerialization.data(withJSONObject: json)
 
   //Convert JSON Data back to Person Struct
   if let data = jsonData {
     decodedPerson = try? JSONDecoder().decode(Person.self, from: data)
     
     //Print Person Struct
     if let decodedPerson = decodedPerson {
       print("Decoded Person Struct: " + decodedPerson.getString())
       //Prints: Decoded Person Struct: Name: Yuri, Age: 20
     }
   }
}

2/Nested Types:

  • Điều thú vị trong Swift 4 là decoding và encoding nested types không khác gì so với ví dụ bên trên. Sử dụng Person Struct bên trên để tạo 1 struct Family mới:
//Nested Type Abbreviated Example
struct Family: Codable {
   let familyName: String
   var familyMembers: [Person]
   
   init(familyName: String, familyMembers: [Person] = [Person]()) {
       self.familyName = familyName
       self.familyMembers = familyMembers
   }
   
   mutating func addFamilyMember(relative person: Person) {
       familyMembers.append(person)
   }
}

let mother = Person(name: "Arlene", age: 35)
let father = Person(name: "Calvin", age: 36)

var family = Family(familyName: "Hinton")
family.addFamilyMember(relative: mother)
family.addFamilyMember(relative: father)

print("\n\n***Encoding and Decoding complex types***\n")
print("Family Struct")
for person in family.familyMembers {
   print("Family Member: " + person.getString())
}

/*
Prints:

***Encoding and Decoding complex types***

Family Struct
Family Member: Name: Arlene, Age: 35
Family Member: Name: Calvin, Age: 36
*/
  • Như ví dụ bên trên nếu chúng ta muốn biểu diễn struct Family dưới dạng JSON chúng ta cần convert nó sang dạng Data và sau đó mới là dạng JSON:
//Encode Family Struct as Data
let familyData = try? JSONEncoder().encode(family)

//Create JSON
var familyJson: Any?
if let data = familyData {
   familyJson = try? JSONSerialization.jsonObject(with: data, options: .allowFragments)
}

//Print JSON Object
if let json = familyJson {
   print("\nFamily JSON:\n" + String(describing: json) + "\n")
}

/*
Prints:
Family JSON:
{
    familyMembers =     (
        {
            age = 35;
            name = Arlene;
        },
        {
            age = 36;
            name = Calvin;
        }
    );
    familyName = Hinton;
}
*/
  • Nếu chúng ta muốn convert Family JSON trở lại struct chúng ta cần convert nó sang dạng Data và sau đó là struct:

//Convert JSON back to Data
if let json = familyJson {
   jsonData = try? JSONSerialization.data(withJSONObject: json)
}

//Convert JSON Data back to Person Struct
var decodedFamily: Family?
if let data = jsonData {
   decodedFamily = try? JSONDecoder().decode(Family.self, from: data)
}

//Print Family Struct
print("\nDecoded Family Struct:")
if let decodedFamily = decodedFamily {
   for person in decodedFamily.familyMembers {
       print("Family Member: " + person.getString())
   }
}

/*
Prints:

Decoded Family Struct:
Family Member: Name: Arlene, Age: 35
Family Member: Name: Calvin, Age: 36
*/

3/Conclusion:

  • Như chúng ta đã thấy, công việc với JSON đã trở nên dễ dàng hơn nhiều với nhiều dạng dữ liệu trong Swift 4. Bạn có thể encode và decode kể cả vớistruct, class và nested types.