swift 5.1 JSon 전환 의 Codable
swift 는 Codable 인 코딩 과 디 코딩 기능 을 도입 했다. 쉽게 말 하면 json 을 자신 이 만 들 고 Codable 프로 토 콜 을 따 르 는 데이터 모델 로 전환 하 는 것 을 지원 하 는 것 이다. 클래스 일 수도 있 고 구조 체 struct 일 수도 있 으 며 구조 체 에 있어 이것 은 제3자 에 게 없 는 기능 이다.애플 은 구조 체 를 사용 하 는 것 을 공식 적 으로 추천 하 며 편리 하고 안전 하 며 메모리 사용량 이 적 으 며 메모리 방출 문 제 를 걱정 하지 않 아 도 좋 은 점 이 많다.struct 에 대해 서 말씀 드 리 겠 습 니 다.
우선 제 이 슨 데 이 터 를 만 듭 니 다:
{
"name": " ",
"age": 20,
"birthday": "1990-06",
"location": " ",
"job": " "
}
그리고 우 리 는 구조 체 모델 을 만들어 서 이 데 이 터 를 받 습 니 다.
struct UserModel: Codable {
var name = "";
var age = 0;
var birthday = "";
var location = "";
var job = "";
}
이 구조 체 모델 은 반드시 Codable 프로 토 콜 을 실현 해 야 한 다 는 것 을 설명 한다.
그리고 우 리 는 decode 디 코딩 을 하 러 간다.
let dict = """
{
"name": " ",
"age": 20,
"birthday": "1990-06",
"location": " ",
"job": " "
}
"""
let decode = JSONDecoder();
if let data = dict.data(using: .utf8) {
let item = try? decode.decode(UserModel.self, from: data);
print("item: \(item)");
}
인쇄 와 함께 우 리 는 struct 의 각 값 을 정상적으로 출력 할 수 있 고 사용 하기 가 이렇게 간단 하 다 는 것 을 알 게 되 었 다.
2. 복잡 한 제 이 슨 에 대해 서도 우 리 는 해석 할 수 있다.다음 제 이 슨
{
"name": " ",
"age": 20,
"birthday": "1990-06",
"location": " ",
"job": " ",
"students": [
{
"name": " ",
"age": 12,
"id": 1234,
"sex": " "
},
{
"name": " ",
"age": 11,
"id": 1235,
"sex": " "
},
{
"name": " ",
"age": 14,
"id": 1237,
"sex": " "
}
]
}
위 에 이것 은 비교적 복잡 한 것 입 니 다. 한 대상 은 배열 을 포함 하고 배열 안에 대상 이 있 습 니 다. 그러면 이 struct 모델 에 대해 우 리 는 이렇게 만 들 수 있 습 니 다.
struct UserModel: Codable {
var name = "";
var age = 0;
var birthday = "";
var location = "";
var job = "";
var students: [StudentsModel]!
}
struct StudentsModel: Codable {
var name = "";
var age = 0;
var id = 0;
var sex = "";
}
위 에 있 는 그 방법 을 사용 하면 students 가 인쇄 한 것 이 배열 이라는 것 을 볼 수 있 습 니 다.
그러나 가끔 은 상황 이 우리 가 상상 하 는 것 처럼 완벽 하지 않다. 특히 명명 규칙 에 있어 배경 에 하강 봉 이 있 는 명명 방식 이 나타 날 수 있다. 예 를 들 어 studentname 등 형식 입 니 다. swift 는 보통 낙타 봉 이 라 고 명명 되 어 있 습 니 다. 예 를 들 어 student Name 은 하나의 문 제 를 가 져 왔 습 니 다. 이 두 가지 표 시 는 일치 하지 않 습 니 다. 그러면 우 리 는 이 문 제 를 어떻게 해결 합 니까? 예 를 들 어 우 리 는 다음 과 같은 json 데이터 가 있 습 니 다.
{
"name": " ",
"phone_number": 18467898765,
"pic_url": " "
}
이 럴 때 나 는 수 동 으로 속성 과 값 을 대응 해 야 한다.
struct UserModel: Codable {
var name = "";
var phoneNumber = 0;
var picURL = "";
enum UserKeys: String, CodingKey {
case phoneNumber = "phone_number"
case picURL = "pic_url"
case name = "name"
}
init(from decoder: Decoder) throws{
let value = try? decoder.container(keyedBy: UserKeys.self);
phoneNumber = (try? value?.decode(Int.self, forKey: .phoneNumber)) ?? 0;
picURL = (try? value?.decode(String.self, forKey: .picURL)) ?? "";
name = (try? value?.decode(String.self, forKey: .name)) ?? "";
}
}
위 에서 도 알 수 있 듯 이 키 와 값 의 유형 이 다 를 때 우 리 는 전환 할 수 있다.
swift 의 Codable 은 매우 간단 하고 강력 합 니 다. 만약 에 우리 가 실제 개발 할 때 백 스테이지 에서 돌아 온 데이터 가 완전 하지 않 으 면 그 값 이 없 으 면 돌아 오지 않 을 수도 있 습 니 다. 이때 우리 위의 문제 가 드 러 났 습 니 다.구체 적 으로 무슨 잘못 일 까요?우 리 는 데이터 json 의 name 을 제거 하고 다음 과 같은 형식 으로 바 꾸 었 다.
:
{
"age": 12,
"birthday": "2000-01"
}
:
struct UserModel: Codable {
var name = "";
var age = 0;
var birthday = "";
}
테스트 방법 도 우리 가 바 꿔 보 자.
let decode = JSONDecoder();
if let data = stringValue.data(using: .utf8) {
do {
let item = try decode.decode(UserModel.self, from: data);
print("item: \(item)");
} catch {
print("error =\(error)");
}
}
다음 오류 정 보 를 인쇄 합 니 다:
error =keyNotFound(CodingKeys(stringValue: "name", intValue: nil), Swift.DecodingError.Context(codingPath: [], debugDescription: "No value associated with key CodingKeys(stringValue: \"name\", intValue: nil) (\"name\").", underlyingError: nil))
바로 우리 가 정의 하 는 name 은 반드시 있어 야 하지만 배경 이 돌아 오지 않 아서 오류 가 발생 했 습 니 다. 이 럴 때 우 리 는 선택 가능 한 유형 으로 정의 해 야 합 니 다. 다음 과 같 습 니 다.
struct UserModel: Codable {
var name: String?
var age: Int?
var birthday: String?
}
이 럴 때 안심 하고 사용 할 수 있 습 니 다. 성공 승낙 치 는 name 만 비어 있 습 니 다.
사실 우 리 는 이러한 속성의 값 을 우리 가 사용 하 는 과정 에서 일반적으로 읽 는 것 을 발견 했다. 이 의 도 를 잘 표현 하기 위해 우 리 는 일반적으로 다음 과 같이 정의 하여 데이터 의 안전 을 확보 했다.
struct UserModel: Codable {
let name: String?
let age: Int?
let birthday: String?
}
이 Codable 기능 을 더 잘 사용 하기 위해 서 는 JSONdecoder 에 확장 자 를 추가 할 수 있 습 니 다. 문 제 는 다음 과 같 습 니 다.
extension JSONDecoder {
class func jsonDecoder(_ type: T.Type,from data: Data?) -> T? {
guard let data = data else {
return nil;
}
let json = JSONDecoder();
var jsonItem: T? = nil;
do {
jsonItem = try json.decode(type, from: data)
} catch {
printObject("data convert json error: \(error)");
}
return jsonItem;
}
class func jsonDecoder(_ type: T.Type,fromAny data: Any?) -> T? {
if let data = data as? Data {
return jsonDecoder(type, from: data);
}
guard let data = data else {
return nil;
}
if let stringValue = data as? String {
return jsonDecoder(type, from: stringValue.data(using: .utf8));
}
let jsonData = try? JSONSerialization.data(withJSONObject: data, options: .prettyPrinted);
return jsonDecoder(type, from: jsonData);
}
}
이렇게 사용 하면 많이 편리 해진 다.자, Codable 의 사용 에 대해 이렇게 많이 말 했 습 니 다. 그리고 인 코딩 도 똑 같 습 니 다. 스스로 탐색 할 수 있 습 니 다.
아니면 그 옛말: 공부 하 는 길에 노력 하 는 사람 이 부족 하지 않다.점점
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
백그라운드에서 값을 계산하고 Swift 동시성 이후에 결과 사용값을 계산해야 하고 메인 스레드를 차단하지 않으려면 계산된 값을 반환하는 Swift Task 구조에서 해당 값을 계산하면 됩니다. Swift 동시성 이전에는 백그라운드 대기열로 이동하여 필요한 값을 계산하고 필요한 ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.