Codable 프로 토 콜 로 빠 른 JSON 해석 실현

9093 단어
개발 경험 이 있 는 개발 자 라면 데이터 분석 에 문제 가 있 을 것 입 니 다.가장 흔히 볼 수 있 는 것 은 JSON 데이터 의 분석 입 니 다. 당신 의 앱 은 항상 각종 정보 목록, 설정 데이터 등 서버 데 이 터 를 요청 해 야 합 니 다.
하면, 만약, 만약...  Objective-C  그렇다면 너 는 틀림없이 옳다  NSJSONSerialization  낯 설 지 않다.그것 의 전체 절 차 는 대체로 이렇다.  Data 대상 에서 분석  NSDictionary  혹시  NSArray 그리고 이 안에서 속성 명칭 에 따라 필요 한 값 을 꺼 내 고 마지막 으로 이 값 으로 실체 대상 에 게 값 을 부여 합 니 다.
전체적으로 말 하면 이 조작 은 쉽 지 않 고 오류 가 발생 하기 쉽다. 예 를 들 어 분석 코드 를 쓸 때 속성 명 을 잘못 썼 거나 어떤 것 을 잘못 썼 다.  nil  판단 이 정확 하지 않 아 프로그램 이 예상 치 못 하 게 무 너 져 디 버 깅 하 는 데 많은 시간 이 필요 하 다.
Codable
저희 주 제 는 당연히 아니에요.  NSJSONSerialization Swift 에서 제공 하 는 것 입 니 다.  Codable  협의그것 은 전자 와 비슷 한 역할 을 하지만 응용 범위 가 더욱 넓 고 사용 하기 쉽다.일단 볼 게 요.  Codable  프로 토 콜 의 정의: typealias Codable = Decodable
& Encodable
얘 는 사실 다른 두 개 예요.  Protocol  집합  Decodable  화해시키다  Encodable 。 하 나 는 데이터 분석 으로, 다른 하 나 는 데이터 인 코딩 으로 사용 된다.다른 것 은 말 할 것 도 없 이, 우리 먼저 실례 를 보 자. 우 리 는 먼저 실체 류 를 성명 하 자.  Person  그것 은 성명 이 실현 되 었 다.  Codable :struct Person : Codable {
var name: String
var gender: String
var age: Int
}
성명  Codable  그 밖 에 이 실체 류 는 다른 코드 가 없고 몇 개의 속성 성명 만 있 습 니 다.만약 우리 가 그의 인 스 턴 스 를 JSON 문자열 로 인 코딩 해 야 한다 면, 이렇게 할 수 있 습 니 다.
let
person = Person(name:
"swift", gender:
"male", age:
24)
let
encoder = JSONEncoder()
let
data = try! encoder.encode(person)
let
encodedString = String(data: data, encoding: .utf8)!
print (encodedString) / / 출력 {
"name":
"swift",
"age":
24,
"gender":
"male"}
위 에서 보 듯 이 먼저 하 나 를 초기 화 했다.  Person  실례그리고 하 나 를 초기 화 했 어 요.  JSONEncoder 。 재 호출  encode  방법, person 인 스 턴 스 를 인 코딩 합 니 다.후 JSON 인 코딩 작업 이 완료 되 었 습 니 다.
어떻게 해석 하 는 지 다시 봅 시다.
let
jsonString =
"{\"name\
":\"swift\
",\"age\
":22,\"gender\
":\"female\
"}"
let
jsonData = jsonString.data(using: .utf8)!
let
decoder = JSONDecoder()
let
result = try! decoder.decode(Person.self, from: jsonData)
print (result) / / 출력: Person (이름:
"swift", gender:
"female", age:
22)
해석 할 때 JSONDEcoder 대상 을 사용 하여 해석 할 인 스 턴 스 형식 을 decode 방법 으로 전달 합 니 다 -  Person.self,  ,분석 할 데이터 대상 까지.  jsonData  JSON 데이터 분석 이 완료 되 었 습 니 다.
쓰다  Codable  프로 토 콜 은 이렇게 간단 합 니 다. 구체 적 인 분석 코드 가 필요 하지 않 습 니 다. 실체 류 속성 이름과 JSON 데이터 가 대응 할 수 있 기만 하면 내용 의 분석 을 완성 할 수 있 습 니 다.이렇게 비교 하 다  NSJSONSerialization  보아하니 많이 간소화 되 었 고 실수 하기 가 쉽 지 않다.
여기 에는 단지 한 가지 주의 가 필요 하 다. 우리 가 방금 예 에서 본 것 에 대해 서 는.  Person  클래스  Codable  프로 토 콜 외 에 모든 속성 도 따라 야 합 니 다.  Codable  라 고 적 었 다.Swift 시스템 라 이브 러 리 의  String , Int , Double , Date , URL , Data  이런 것들 은 모두 실현 되 었 다.  Codable  라 고 적 었 다.사용자 정의 속성 이 다른 유형 이 라면 그것 도 실현 되 었 는 지 주의해 야 합 니 다.  Codable
이외에  JSONEncoder  화해시키다  JSONDecoder  그 밖 에 Swift 는 다른 유형의 데이터 에 디 코딩 능력 을 제공 했다. 예 를 들 어  PropertyListEncoder plist 데이터 형식 을 인 코딩 할 수 있 습 니 다.
지정 한 속성 인 코딩
기본 적 인 상황 에서 성명 이 계승 되면  Codable  프로 토 콜, 이 인 스 턴 스 의 모든 속성 은 인 코딩 범위 내 에 있 습 니 다.일부 속성 만 디 코딩 하려 면 방법 이 있 습 니 다. 사용자 정의 클래스 에서 CodingKeys 매 거 진 속성 을 설명 할 수 있 습 니 다.
struct Person : Codable {
var
name: String
var
gender: String =
""
var
age: Int
enum CodingKeys: String, CodingKey {
case name
case age
}
}
역시  Person  클래스, 이번에 우 리 는 CodingKeys 속성 을 추가 하고 두 개의 매 거 진 값 을 정의 했다.  name  화해시키다  age CodingKeys 에서 지정 한 속성 명 만 인 코딩 할 수 있 습 니 다. 만약 에 저희 가 다시  Person  인 코딩 을 진행 하면 다음 과 같은 결 과 를 얻 을 수 있 습 니 다: {
"name":
"swift",
"age":
24}
gender 속성 이 없 기 때문에  CodingKeys  인 코딩 되 지 않 습 니 다.하면, 만약, 만약...  CodingKeys  CodingKeys  에서 설명 한 속성 은 기본 값 이 있어 야 합 니 다. 위의 코드 에서 gender 속성 에 도 기본 값 을 설명 합 니 다.
우 리 는 아직 사용 할 수 있다.  CodingKeys  인 코딩 속성의 이름 변경:
struct Person : Codable {
var
name: String
var
gender: String =
""
var
age: Int
enum CodingKeys: String, CodingKey {
case name =
"title"
case age
}
}
아니면  Person  예 를 들 면, 이번에 우 리 는  CodingKeys  매 거 진 에서 name 속성 을 title 로 다시 정의 합 니 다.비록  Person  클래스 중, 이 속성 명 은 역시  name 그러나 인 코딩 된 JSON 에서 속성 명 은  title
위의 클래스 에 인 코딩 을 실행 한 후 얻 은 결 과 는 다음 과 같 습 니 다: {
"title":
"swift",
"age":
24}
JSON 의 첫 번 째 속성 명 이 바 뀌 었 어 요.  title Person 류 에 대응 하 는  name  속성
사용자 정의 인 코딩 프로 세 스
전체 인 코딩 과 디 코딩 과정 을 사용자 정의 할 수 있 습 니 다.약간 복잡 한 데이터 구조 에 있어 서 이 능력 은 여전히 자주 사용 할 것 이다.예 를 들 어 저 희 는 Person 에 게 키 와 몸무게 두 가지 속성 을 더 해 주 고 싶 습 니 다.
struct Person : Codable {
var
name: String
var
gender: String =
""
var
age: Int
var
height: Int
var
weight: Int
enum CodingKeys: String, CodingKey {
case name =
"title"
case age
case body
}
enum BodyKeys: String, CodingKey {
case height
case weight
}
}
여기 새로 생 긴 거.  height  화해시키다  width  속성, 각각 체중 과 키 에 대응 합 니 다.그리고 또 다른 속성 이 추가 되 었 습 니 다.  BodyKeys 。 왜 이 속성 을 추가 합 니까?저희 가 이번에 준 비 를 해서 그래 요.  height  화해시키다  width  단독 대상 에 넣다.우리 가 추가 하지 않 으 면 다음 과 같이 설명 하 는 것 이 좀 더 직관 적일 수 있다.  BodyKeys  속성  CodingKeys  안에서 그렇게 생 성 된 JSON 구 조 는 대체로 다음 과 같다. {
"name" :
xxx
"age": xxx
"height" :
xxx
"weight": xxx
}
하지만 우 리 는 단독으로  height  화해시키다  weight  정의  BodyKeys  매 거 속성.그리고 그것 을 성명 했다.  CodingKeys  맞다이번  CodingKeys  하나 더 생 겼 다  body  속성  BodyKeys  이 매 거.이 대응 관계 가 어떻게 확립 되 었 는 지 는 잠시 후에 어떤 기술 을 배 우 는 것 이 좋 은 지 이야기 할 것 이다.{
"name" : xxx
"age": xxx
"body": {
"height" : xxx
"weight": xxx
}
}
이렇게 하면 제 생각 에는 설명 이 될 것 같 아 요.  BodyKeys  의 역할 을 했다.이렇게 성명 을 다 해도 안 되 고, 우 리 는 수 동 으로 그들 간 의 대응 관 계 를 확립 해 야 한다. 이것 은 다시 실 어야 한다.  Codable  의 두 가지 방법: extension Person {
init(from decoder: Decoder) throws {
let vals = try decoder
.container(keyedBy: CodingKeys
.self)
name = try vals
.decode(String
.self, forKey: CodingKeys
.name)
age = try vals
.decode(Int
.self, forKey: CodingKeys
.age)
let body = try vals
.nestedContainer(keyedBy: BodyKeys
.self, forKey:
.body)
height = try body
.decode(Int
.self, forKey:
.height)
weight = try body
.decode(Int
.self, forKey:
.weight)
}
func encode(to encoder: Encoder) throws {
var container = encoder
.container(keyedBy: CodingKeys
.self)
try container
.encode(name, forKey:
.name)
try container
.encode(age, forKey:
.age)
var body = container
.nestedContainer(keyedBy: BodyKeys
.self, forKey:
.body)
try body
.encode(height, forKey:
.height)
try body
.encode(weight, forKey:
.weight)
}
} init(from decoder: Decoder)  데이터 분석 에 사용,  encode(to encoder: Encoder)  방법 은 데 이 터 를 인 코딩 하 는 데 쓰 인 다.위의 코드 는 너무 많이 설명 하지 않 아 도 이해 하기 쉽다 고 생각 합 니 다.decoder.container()  방법 은 먼저 CodingKey 의 대응 관 계 를 가 져 옵 니 다. 여기 서 우리 가 먼저 들 어 갑 니 다.  CodingKeys.self  우리 가 이전에 성명 한 유형 을 나타 낸다.그리고 호출  vals.decode()  방법, 어떤 단독 속성 을 분석 하 는 데 사용 합 니 다.다음 호출  vals.nestedContainer()  방법 은 내 장 된 등급 을 얻 는 것 이다. 즉, 우리 가 이전에 성명 한 것 이다.  BodyKeys 。그리고 계속 해석 해.
인 코딩 의 관련 처리 도 대동소이 하여 위의 디 코딩 방법 중의 논 리 를 반대로 처리 하 였 다.
이렇게, 만약 우리 가 새로운 것 에 대해  Person  인 스 턴 스 를 다시 인 코딩 하면 다음 과 같은 결 과 를 얻 을 수 있 습 니 다: {
"title":
"swift",
"age":
24,
"body":{
"weight":
80,
"height":
180}}
레이 어드 된 JSON 데이터 가 생 성 된 것 을 볼 수 있다.
총결산Codable  프로 토 콜 의 디자인 은 우리 가 더 좋 은 코드 구 조 를 생산 하 는 데 도움 을 줄 수 있다.간단 한 데이터 모델 에 대해 서 는 아무런 처리 없 이 사용 할 수 있다.그리고 약간 복잡 한 데이터 구 조 는 분석 규칙 을 실체 류 에 밀봉 하면 코드 구조의 혼란 을 효과적으로 피 할 수 있다.
한 마디 로 하면 데이터 분석 과 같은 조작 은 평소의 개발 작업 에서 비교적 많다.만약 당신 이 Swift 프로젝트 를 개발 하고 있다 면, 그것 은 당신 이 알 만 한 특성 입 니 다.

좋은 웹페이지 즐겨찾기