2017-09-21 6 views
0

스위프트 4의 새로운 디코드 프로토콜을 구현하려고하는데 어려움이 있습니다.중첩 된 JSON 서버 응답에 Swift 4의 디코드 프로토콜 사용

이 내 JSON 서버 응답입니다 :

{ 
    "success": true, 
    "errorCode": 0, 
    "message": "Succcess", 
    "data": { 
    "name": "Logan Howlett", 
    "nickname": "The Wolverine", 
    "image": "http://heroapps.co.il/employee-tests/ios/logan.jpg", 
    "dateOfBirth": 1880, 
    "powers": [ 
     "Adamantium Bones", 
     "Self-Healing", 
     "Adamantium Claws" 
    ], 
    "actorName": "Hugh Jackman", 
    "movies": [ 
     { 
     "name": "X-Men Origins: Wolverine", 
     "year": 2009 
     }, 
     { 
     "name": "The Wolverine", 
     "year": 2013 
     }, 
     { 
     "name": "X-Men: Days of Future Past", 
     "year": 2014 
     }, 
     { 
     "name": "Logan", 
     "year": 2017 
     }, 
    ] 
    } 
} 

것은 무엇 응답의 data 부분을 디코딩하는 가장 좋은 방법이 될 것입니다? 또한 data이 오브젝트 대신 갑자기 array 인 경우 어떻게됩니까? 두 데이터 유형을 모두 지원하려면 어떻게해야합니까?

고마워요 :)

+0

'갑자기 데이터가 객체가 아닌 배열 인 경우 어떻게됩니까? 두 데이터 유형을 모두 지원하려면 어떻게해야합니까? '- 연관된'enum's를 사용하십시오 유형에 값이 있습니까? 하나는'array', 다른 하나는'dictionary'입니다. – user28434

+0

JSON 표현을 미러링하는 유형을 작성하는 방법은 코드 작성 가능 문서의 [사용자 정의 유형 인코딩 및 디코딩] (https://developer.apple.com/documentation/foundation/archives_and_serialization/encoding_and_decoding_custom_types)을 읽어야합니다. 대부분이 유형을 작성하고 코드 가능을 준수해야하며, 나머지는 당신을 위해 수행되어야합니다. –

답변

0

먼저 당신이 도우미로 확장 만들 수 있습니다

protocol Encode: Codable { 
    init(with dictionary: [String: Any]) 
    init(with data: Data) 
} 
: 당신이 당신의 객체를 구축하는 데 도움이

extension Data { 
    func decode <Generic: Codable>() -> Generic? { 
     let decoder = JSONDecoder() 
     let object = try? decoder.decode(Generic.self, from: self) 
     return object 
    } 
} 


extension Dictionary { 
    func decode <Generic: Codable>() -> Generic? { 
     let data = try? JSONSerialization.data(withJSONObject: self, 
               options: JSONSerialization.WritingOptions.prettyPrinted) 
     guard let d = data else { 
      return nil 
     } 
     return d.decode() 
    } 
} 

는 그런 다음 프로토콜을 만들 수 있습니다 기본 구현 인

:

extension Encode { 
    init(with data: Data) { 
     let object: Self? = data.decode() 
     guard let obj = object else { 
      fatalError("fail to init object with \(data)") 
     } 
     self = obj 
    } 

    init(with dictionary: [String: Any]) { 
     let object: Self? = dictionary.decode() 
     guard let obj = object else { 
      fatalError("fail to init object with \(dictionary)") 
     } 
     self = obj 
    } 

그런 다음 y Codable 프로토콜을 준수하는 구조체로 개체를 만듭니다. 당신이해야 할 데이터가 갑자기 배열 될 경우

if let dic = json["data"] as? [String: Any] { 
    let user: User = User(with: dic) 
    // Do stuff here 
} 

:

struct User: Codable { 
    var name: String? 
    var nickname: String? 
    ... 
    // If needed declare CodingKey here 
    // enum CodingKeys: String, CodingKey { 
    //  case date = "dateOfBirth" 
    //  ... 
    // } 
} 

struct Movies: Codable { 
    var name: String? 
    var year: Int? 
} 

지금 당신은 당신의 응답 데이터의 사용자 사전을 추출하고 새 초기화 방법을 적용해야합니다 것처럼 보일 것이다 (이 예제에서 User의 배열처럼)

+0

내 대답이 적절하지 않아서이를 대체하거나 개선 할 수없는 이유를 설명해주십시오. 감사합니다 –

+0

나는 당신의 대답을 누가 downvoted 모르겠지만 그것은 아니었다. 나는 내일 아침에 그것을 읽고 그것을 시도 할 것이다. 그것이 어떻게되었는지 알려 줄 것입니다 :) – EpicSyntax