iOS & Swift 공부 - JSON & Codable

김영채 (Kevin)·2021년 2월 6일
1

iOS & Swift

목록 보기
68/107

Encoding & Decoding


인코딩(Encoding) 은 정보의 형태나 형식을 표준화, 보안, 처리 속도 향상, 저장 공간 절약 등을 위해서 다른 형태나 형식으로 변환하는 처리 혹은 그 처리 방식을 뜻한다.

디코딩(Decoding) 은 인코딩의 반대 작업을 수행하는 것을 뜻한다.

Codable


스위프트 4 버전에서는 스위프트의 인스턴스를 다른 데이터 형태로 변환하고 그 반대의 역할을 수행하는 방법을 제공한다.

스위프트의 인스턴스를 다른 데이터 형태로 변환할 수 있는 기능을 Encodable 프로토콜 로 표현하였고, 그 반대의 역할을 할 수 있는 기능을 Decodable 로 표현해 두었습니다. 그 둘을 합한 타입을 Codable 로 정의해 두었습니다.

typealias Codable = Decodable & Encodable

→ JSON 형식으로 서버와 애플리케이션이 통신한다면 Codable 프로토콜을 이용해 편리하게 인코딩 및 디코딩할 수 있다.

선언 예제

struct Coordinate: Codable {
	var latitude: Double
	var longitude: Double
}

struct Landmark: Codable {
    var name: String
    var foundingYear: Int
    var vantagePoints: [Coordinate]
    var metadata: [String: String]
    var website: URL?
}

CodingKey


JSON 형태의 데이터로 상호 변환하고자 할 때는 기본적으로 인코딩/디코딩할 JSON 타입의 키 (Key) 와 애플리케이션의 사용자 정의 프로퍼티 가 일치해야 한다.

ex. JSON response 예제

{
"status": "ok",
"totalResults": 4873,
+"articles": []
}

→ API 요청을 보내서 위와 같이 JSON 형태로 response 가 오면 앱 내에서도 원래는 Key 값을 똑같이 정의해야 한다. (JSONDecoder 를 사용하기 위해서는 말이다)

struct Results: Codable{
	let status: String
	let totalResults: Int
	let articles: [String]
}
  • 만약 JSON의 키 이름을 구조체 프로퍼티의 이름과 다르게 표현하려면 타입 내부에 String 타입의 원시값을 갖는 CodingKeys 라는 이름의 열거형을 선언하고 CodingKey 프로토콜을 준수하도록 하면 된다.
struct Results: Codable{
	var currentStatus: String
	let results: Int
	let myArticles: [String]

	enum CodingKeys: String, CodingKey{
		case currentStatus = "status"
		case results = "totalResults"
		case myArticles = "articles"
	}
}

JSONEncoder / JSONDecoder


JSONEncoder : 스위프트 타입의 인스턴스를 JSON 데이터로 인코딩

JSONDecoder : JSON 데이터에서 스위프트 타입의 인스턴스로 디코딩

JSONEncoder

Codable 프로토콜을 준수하는 GroceryProduct 구조체의 인스턴스를 JSON 데이터로 인코딩하는 방법

struct GroceryProduct: Codable {
    var name: String
    var points: Int
    var description: String?
}

let pear = GroceryProduct(name: "Pear", points: 250, description: "A ripe pear.")

let encoder = JSONEncoder()
encoder.outputFormatting = .prettyPrinted

do {
	let data = try encoder.encode(pear)
	print(String(data: data, encoding: .utf8)!)
} catch {
	print(error)
}

// ----- 출력
 {
   "name" : "Pear",
   "points" : 250,
   "description" : "A ripe pear."
 }

JSONDecoder

JSON 데이터를 Codable 프로토콜을 준수하는 GroceryProduct 구조체의 인스턴스로 디코딩하는 방법

struct GroceryProduct: Codable {
    var name: String
    var points: Int
    var description: String?
}

/// 스위프트 4 버전부터 """를 통해 여러 줄 문자열을 사용할 수 있습니다.
let json = """
{
    "name": "Durian",
    "points": 600,
    "description": "A fruit with a distinctive scent."
}
""".data(using: .utf8)!

let decoder = JSONDecoder()

do {
	let product = try decoder.decode(GroceryProduct.self, from: json)
	print(product.name)
} catch {
	print(error)
}
// ----- 출력 
"Durian"

위 내용은 "https://www.boostcourse.org/mo326/lecture/18732" 을 참고하여 공부한 내용을 개인적으로 정리하였습니다.

profile
맛있는 iOS 프로그래밍

0개의 댓글