ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [iOS] Codable에 관하여
    STUDYING/iOS 2018. 11. 28. 09:45
    728x90

    Codable

    Codable이란 ?

    A type that can convert itself into and out of an external representation. - Apple Doc

    외부 표현을 변환할때 사용한다.

    • 우리가 사용하는 이유는 JSON 데이터를 우리가 만들 애플리케이션에서 사용하기 편하도록 객체에 맵핑하기 위해 사용한다.

      • Decodable : 자신을 외부표현으로부터 디코딩할수있는 타입.

      • Encodable : 자신을 외부표현으로 인코딩 할수있는 타입.

    • JSON기준에서

      • 서버파트에서 JSON데이터를 보내 줄 것이고, 현재 나와있는 거의 모든 API들이 JSON으로 뿌려준다.

    //JSONData
    {
    "a":"나는 a입니다.",
    "b":"나는 b입니다."
    }
    //Codable로 구성된 모델
    struct Sample: Codable{
       var a:String
       var b:String  
       
       enum CodingKeys: String, CodingKey {
           case a
           case c = "b"
       }
    }

    JSON을 Codable로 처리할 때, 밑줄 표기법을 낙타 표기법으로 바꾼다거나 JSON에 있는 이름과 완전히 다른 이름으로 사용하려면 CodingKey를 따로 정의하면 된다.

    let sampleDecoding = try! JSONDecoder().decode(Sample.self, from: sampleData)

    앞서 Codable 정의에서 설명한 것 처럼 우리는 외부 표현 , 즉 JSON을 우리 애플리케이션에서 사용하기위해서 Decoding해서 사용해야한다.

    JSONDecoder 를 사용할 때 error를 검출하기 위해서 try 이를 사용한다.

    (정확한 데이터를 사용한다면 강제언래핑 처럼 try! 를 사용, 옵셔널이라면 try? 를 사용하고 데이터를 사용할때 if let 문으로 옵셔널 해제를 해줘야한다.)


    • JSONData 가 바뀌었을 경우 ?

      JSONData 가 바뀌어 원래 지정했던 키가 없을 경우가 있으므로

      모델 구조체 자체에서 JSON데이터를 디코딩 해서 keyNotFound 에러를 처리할수있다.

      키와 값이 없을 경우를 미리 정해놓는 것

      import UIKit
      //바뀐 JSON데이터
      let sample1Data = """
      {
         "a": "aa"
      }
      """.data(using: .utf8)!

      //아까 설정한
      struct Sample: Codable{
         var a:String
         var c:String
         
         enum CodingKeys: String, CodingKey {
             case a = "a"
             case c = "b"
         }
         
         init(from decoder: Decoder) throws {
             let values = try decoder.container(keyedBy: CodingKeys.self)
           
             a = try values.decodeIfPresent(String.self, forKey: .a) ?? "값이없습니다."
             c = try values.decodeIfPresent(String.self, forKey: .c) ?? "값이없습니다."
         }
         
      }
      let data = try! JSONDecoder().decode(Sample.self, from: sample1Data)

      init(from decoder: Decoder)에 a 와 c 라는 key 값이 매핑 됬을 경우 를 처리 해놨다.

      JSON데이터에 key "a"값만 보내주고 있으므로 "c"값에 대한 처리가 필요하다.

      try 를 해서 error 즉 실패 했을 경우 "값이 없습니다"를 key의 value에 할당해서 보여주는것이다.


    • JSON Array

    {
       "status": 200,
       "message": "모든 글 조회 성공",
       "data": [
          {
               "id": 11,
               "title": "글 제목2",
               "contents": "내용내용내용",
          },
          {
               "id": 20,
               "title": "10",
               "contents": "",
          }
      ]
    }

    위 JSON데이터 처럼 배열 형태의 데이터가 있을 때는

    struct ArraySample : Codable {
       var status: Int
       var message: String
       var userData: [UserArray]
     
       enum CodingKeys: String, CodingKey {
           case status
           case message
           case userData = "userArray"
       }
       
    }
    struct UserArray : Codable {
       var id: Int
       var title: String
       var contents: String
       
    }

    let arraySampleDecoding = try! JSONDecoder().decode(ArraySample.self, from: arrayJSONData)
    print(arraySampleDecoding)

    이렇게 모델을 중첩해서 사용하면 된다.


    [tip] 한번에 JSON객체 만들 수 있는 사이트 : www.json4swift.com





Designed by Tistory.