codable은 encodable과 decodable이 합쳐진 프로토콜이다. codable이 붙은 오브젝트는 외부의 표현 방법으로 변환하거나 외부의 표현 방법을 받아들일 수 있다는 뜻이다.(JSON을 swift 오브젝트로 변환하거나 swift 오브젝트를 JSON으로 변환이 가능하다)
let json = """
{
"type": "US Robotics",
"model": "Sportster"
}
"""
struct Modem: Codable {
let type: String
let model: String
}
let jsonData = json.data(using: .utf8)!
let result = try! JSONDecoder().decode(Modem.self, from: jsonData)
JSONDecoder를 이용하여 JSON을 swift object로 변환할 수 있다.
var modem = Modem(type: "Hayes", model: "5611")
let jsonData2 = try! JSONEncoder().encode(modem)
let json2 = String(data: jsonData2, encoding: .utf8)!
JSON과 Swift 프로퍼티의 이름이 다를 경우 사용한다
struct User:Codable
{
var firstName:String
var lastName:String
var country:String
enum CodingKeys: String, CodingKey {
case firstName = "first_name"
case lastName = "last_name"
case country
}
}
let jsonUser = """
{
"first_name": "John",
"last_name": "Doe",
"country": "United Kingdom"
}
"""
let jsonUserData = jsonUser.data(using: .utf8)!
let userResult = try! JSONDecoder().decode(User.self, from: jsonUserData)
Date 타입으로 받으면 된다
// If iso8601 use dateEncodingStrategy.
let jsonIso = """
{
"date" : "2017-06-21T15:29:32Z"
}
"""
let isoData = jsonIso.data(using: .utf8)!
let isoDecoder = JSONDecoder()
isoDecoder.dateDecodingStrategy = .iso8601
let isoResult = try! isoDecoder.decode(DateRecord.self, from: isoData)
isoResult.date
URLSession.shared.dataTask(with: url) { data, response, error in
guard let data = data, error == nil else {
completion(.failure(.serverError))
return
}
do {
let profile = try JSONDecoder().decode(Profile.self, from: data)
completion(.success(profile))
} catch {
completion(.failure(.decodingError))
}
}.resume()
@escaping -> 클로저가 비동기적으로 일어날 수 있다는 뜻

코드블록 백그라운드에서 비동기적으로 실행되므로 UI를 변경할 때는 꼭 메인 스레드에서 실행되게 해야한다.
근데 그냥 URLSession 클로저 블록 전체를 메인스레드 블록으로 묶어버려도 되는 것 같다.
DispatchQueue.main.async {
// On main thread
}
Success와 Failure(Error type)를 가진 Enum
뷰모델, configure
모델(JSON받아오는), URLSession
모델 초기화, 뷰모델 초기화, URLSession포함된 함수 호출(Result 타입이니까 switch로 받는다),
configure로 뷰모델 보내서 UI 업데이트