2017-09-21 4 views
0

json에서 Swift 4의 코드 가능 기능을 사용하고 싶지만 일부 키에는 설정 이름이 없습니다. 오히려이 배열 그리고 그들은 당신이 181 개 ID를 참조Swift 4 JSON 코드를 키로 사용

{ 
"status": "ok", 
"messages": { 
    "generalMessages": [], 
    "recordMessages": [] 
}, 
"foundRows": 2515989, 
"data": { 
    "181": { 
    "animalID": "181", 
    "animalName": "Sophie", 
    "animalBreed": "Domestic Short Hair/Domestic Short Hair/Mixed (short coat)", 
    "animalGeneralAge": "Adult", 
    "animalSex": "Female", 
    "animalPrimaryBreed": "Domestic Short Hair", 
    "animalUpdatedDate": "6/26/2015 2:00 PM", 
    "animalOrgID": "12", 
    "animalLocationDistance": "" 

같은 식별자입니다. 누구든지 181을 다루는 방법을 알고 열쇠로 지정할 수 있습니까? 숫자는 임의의 숫자가 될 수 있으며 각 숫자는 서로 다릅니다.

사전에이

struct messages: Codable { 
    var generalMessages: [String] 
    var recordMessages: [String] 
} 

struct data: Codable { 
    var 
} 

struct Cat: Codable { 
    var Status: String 
    var messages: messages 
    var foundRows: Int 
    //var 181: [data] //What do I place here 
} 

감사 같은 것을하고 싶습니다.

+0

'181'은 거기에있는 문자열입니다 (' ""'로 둘러싸여 있음). 그래서 당신은 element [ "data"] [181]'이 아니라 element [ "data"] [ "181"]'에 접근합니다 (큰 따옴표에주의하십시오). 니가 원하는거야? –

+0

답변 해 주셔서 감사합니다. 나 자신을 더 분명하게하려고 내 질문을 업데이트했다. –

답변

2

확인하시기 바랍니다 : 나는 이런 식으로 뭔가를 제안

struct ResponseData: Codable { 
    struct Inner : Codable { 
     var animalID : String 
     var animalName : String 

     private enum CodingKeys : String, CodingKey { 
      case animalID  = "animalID" 
      case animalName = "animalName" 
     } 
    } 

    var Status: String 
    var foundRows: Int 
    var data : [String: Inner] 

    private enum CodingKeys: String, CodingKey { 
     case Status = "status" 
     case foundRows = "foundRows" 
     case data = "data" 
    } 
} 

let json = """ 
    { 
     "status": "ok", 
     "messages": { 
      "generalMessages": ["dsfsdf"], 
      "recordMessages": ["sdfsdf"] 
     }, 
     "foundRows": 2515989, 
     "data": { 
      "181": { 
       "animalID": "181", 
       "animalName": "Sophie" 
      }, 
      "182": { 
       "animalID": "182", 
       "animalName": "Sophie" 
      } 
     } 
    } 
""" 
let data = json.data(using: .utf8)! 
let decoder = JSONDecoder() 

do { 
    let jsonData = try decoder.decode(ResponseData.self, from: data) 
    for (key, value) in jsonData.data { 
     print(key) 
     print(value.animalID) 
     print(value.animalName) 
    } 
} 
catch { 
    print("error:\(error)") 
} 
0

숫자를 변수 이름으로 선언 할 수 있다고 생각하지 않습니다. Apple's doc에서 :

상수와 변수 이름은 공백 문자, 수학 기호, 화살표, 개인 사용 (또는 무효) 유니 코드 포인트, 라인 및 상자 그리기 문자를 포함 할 수 없습니다. 번호는 으로 시작할 수 없지만 숫자는 이름의 다른 곳에 포함될 수 있습니다.

적절한 방법은 key을 캡처하는 속성을 사용하는 것입니다.

struct Cat: Codable { 
    var Status: String 
    var messages: messages 
    var foundRows: Int 
    var key: Int // your key, e.g., 181 
} 
+0

당신은 맞습니다. 그러나 제가 거기에 놓아야 할 것을 알아 내려고 노력하고 있습니다. –

+0

변수를 사용하여 키를 저장하면됩니다. – Lawliet

0

: -

struct ResponseData: Codable { 
struct AnimalData: Codable { 
    var animalId: String 
    var animalName: String 

    private enum CodingKeys: String, CodingKey { 
     case animalId = "animalID" 
     case animalName = "animalName" 
    } 
} 

var status: String 
var foundRows: Int 
var data: [AnimalData] 

private enum CodingKeys: String, CodingKey { 
    case status = "status" 
    case foundRows = "foundRows" 
    case data = "data" 
} 

struct AnimalIdKey: CodingKey { 
    var stringValue: String 
    init?(stringValue: String) { 
     self.stringValue = stringValue 
    } 
    var intValue: Int? { return nil } 
    init?(intValue: Int) { return nil } 
} 

init(from decoder: Decoder) throws { 
    let container = try decoder.container(keyedBy: CodingKeys.self) 
    let animalsData = try container.nestedContainer(keyedBy: AnimalIdKey.self, forKey: .data) 

    self.foundRows = try container.decode(Int.self, forKey: .foundRows) 
    self.status = try container.decode(String.self, forKey: .status) 
    self.data = [] 
    for key in animalsData.allKeys { 
     print(key) 
     let animalData = try animalsData.decode(AnimalData.self, forKey: key) 
     self.data.append(animalData) 
    } 
    } 
} 

let string = "{\"status\":\"ok\",\"messages\":{\"generalMessages\":[],\"recordMessages\":[]},\"foundRows\":2515989,\"data\":{\"181\":{\"animalID\":\"181\",\"animalName\":\"Sophie\"}}}" 
let jsonData = string.data(using: .utf8)! 
let decoder = JSONDecoder() 
let parsedData = try? decoder.decode(ResponseData.self, from: jsonData) 

이 방법은 당신의 디코더 초기화 자체가 키를 처리합니다.