본문 바로가기

iOS

[iOS] JSON개념공부 및 사용해보기(feat. Codable, Decoder, Encoder)

# XML JSON YAML

- 위는 주는 사람과 받는 사람이 사용하는 공통된 협약된 언어

- 사람도 읽을 수 있으면서 컴퓨터끼리도 읽을 수 있는 공통된 규약 언어

 

- XML은 <tag/>를 사용하며 웹에서 많이 사용한다.
필요이상으로 장황하다느 느낌이 잇을 수 있다.

- 태그를 두번씩 입력하고 가독성이 좋다고 판단되지않은데 이를 개선하여 나타낼 수 있는게 JSON이다.
그렇다고 XML이 JSON보다 뒷떨어지는건 아니다.
각 장단점이 있는데 XML은 오탈자가 있어도 작동을 잘하지만 JSON엄격해서 이부분에서 에러가 발생한다. 사소한 콤마같은거에 에러가 발생할 수 있음

- YAML은 주석과 상속을 사용해 효율 적으로 작성할 수 있으며 카테고리가 예쁘게 정해져있기때문에 가독성이 좋다.

 

# JSON(JavaScript Object Notation)

- 서버통신의 시작이 JSON이라고 할 수 있다.

- Client와 Server가 어떻게 통신할 수 있는지를 정의한 것이 HTTP이다.(HyperText Transfer Protocol)

데이터 전송할때

- Client의 01010101 객체를 -> DataType으로 변환이름: 홍길동 JSON으로 변환한다 01010011 -> 이를 Server의 객체로 변환한다. 10101010

요청방식
Client -> Request -> Server
Server -> Response -> Client
JSON표현식
{}: 딕셔너리
[]: 배열
“”: 문자열
- Key: Value로 이루어져 있는데 swift에서는 딕셔너리
- XML의 단점을 개선하기위해 사용되고 있는게 JSON이다

JSON 특징

  • 텍스트를 기반으로 데이터를 주고받을때 사용하느 가장 간단한 포맷
  • 읽기 쉽고
  • Key와 Value로 이루어져있음
  • 텍스트기반으로 가볍고
  • 직렬화하고 데이터를 전송할때 사용한다.
  • 제일 중요한 포인트를 프로그램 언어와 플랫폼에 상관없이 사용할 수 있다는 것이 핵심입니다.

# JSON 공부방법

serialize(JSON객체로 직렬화)

  • 오브젝트를 직렬화해서 JSON으로 어떻게 변환할 것인지?
    • JSONEncoder
// MARK: 데이터타입의 인스턴스를 JSON객체로 인코딩하는 방법
"""
[Codable]
- 외부로 표현하거나 외부표현으로 변환 할 수 있는 형식이다.
[구현부]
typealias Codable = Decodable & Encodable
[설명]
Codable은 Encodable 및 Decodable 프로토콜의 유형 별칭이다.
Codable을 유형 또는 일반 제약조건으로 사용하면 두 프로토콜을 모두 준수하는 모든 유형과 일치한다.
"""
struct GroceryProduct: Codable {
    var name: String
    var points: Int
    var description: String?
}
let pear = GroceryProduct(name: "Pear", points: 250, description: "A ripe pear.")

// JSONEncoder: 데이터 타입의 인스턴스를 JSON객체로 코드화해주는 기능
let encoder = JSONEncoder()
// outputFormatting: 인코딩된 JSON개체의 가독성, 크기 및 요소 순서를 결정하는 값
encoder.outputFormatting = .prettyPrinted

"""
- open func encode<T>(_ value: T) throws -> Data where T : Encodable
- encode(): 제공한 값의 JSON인코딩 표현을 반환한다.
- parameter value: 인코딩할 값
- returns: 인코딩된 JSON데이터를 포함하는s새 Data값
- throws: 인코딩 중에 부적합한 부동 소수점 값이 발생하고 인코딩 전략이 throw이면 EndogingError.invalidValue가 발생한다.
- throws: 인코딩 중에 값이 오류를 발생하면 오류를 던집니다.
"""
let data = try encoder.encode(pear)

// String utf8은 String의 유니코드 스칼라 값을 8bit 정수로 인코딩한다.
print(String(data: data, encoding: .utf8)!)
// print..
{
  "name" : "Pear",
  "points" : 250,
  "description" : "A ripe pear."
}

deserialize(직렬화된 객체를 데이터 객체로 재구성)

  • 직렬화된 JSON을 오브젝트로 어떻게 다시변환할 것인지?
    • JSONDecoder
// MARK: JSON객체를 데이터타입의 인스턴스로 디코딩 하는 방법

let json =
"""
{
    "name": "Durian",
    "points": 600,
    "description": "A fruit with a distinctive scent."
}
""".data(using: .utf8)! // key: value입력시 문자열일 "" 숫자는 ""없음 이부분 조심할것

// JSONEncoder: JSON객체를 데이터타입의 인스턴스로 디코딩 해주는 기능
let decoder = JSONDecoder()
"""
decode(): JSON개체에서 디코딩된 지정한 유형의 값을 반환한다.
- func decode<T>(_ type: T.Type, from data: Data) throws -> T where T : Decodable
- type: 제공된 JSON객체에서 디코딩할 값의 유형
- data: 디코딩할 JSON객체
- returns: 디코더가 데이터를 구문 분석할 수 있는 경우 지정된 유형의 값을 반환
만일 데이터가 유효한 JSON이 아닌 경우 이메서드는 DecodingError.dataCorrupted(_:)오류를
발생시킨다. JSON내의 값이 디코딩에 실패하면 이 메서드를 해당 오류를 발생시킴
"""
let product = try decoder.decode(GroceryProduct.self, from: json)
print(product.name) // Durian

 

# Reference