2017-10-18 3 views
0

URL에서 검색하는 큰 JSON 문자열을 구문 분석하려고합니다. 나는 시험에 사용하고있는 JSON은 다음과 같습니다 : 다음과 같이 정보를 인쇄하고Swift에서 Decodable 및 CodingKeys를 사용하여 JSON 구문 분석 4

struct Genre: Decodable { 
    let name: String 
} 

struct Book: Decodable { 
    let author: String 
    let artworkURL: URL 
    let genres: [Genre] 
    let name: String 
    let releaseDate: String 
} 

struct BookCollection { 
    let title: String 
    let books: [Book] 

    enum CodingKeys: String, CodingKey { 
     case feed 
    } 

    enum FeedKeys: String, CodingKey { 
     case title, results 
    } 

    enum ResultKeys: String, CodingKey { 
     case author, artworkURL, genres, name, releaseDate 
    } 

    enum GenreKeys: String, CodingKey { 
     case name 
    } 
} 

extension BookCollection: Decodable { 
    init(from decoder: Decoder) throws { 
     let values = try decoder.container(keyedBy: CodingKeys.self) 

     let feed = try values.nestedContainer(keyedBy: FeedKeys.self, 
    forKey: .feed) 
     self.title = try feed.decode(String.self, forKey: .title) 
     self.books = try feed.decode([Track].self, forKey: .results) 
    } 
} 

:

do { 
    let response = try JSONDecoder().decode(BookCollection.self, from: json) 
    for book in response.books { 
     print(book.genres) 
    } 
} catch { 
    print(error) 
} 
let json = """ 
{ 
"feed": { 
    "title": "Harry Potter", 
    "test": "I dont want this value", 
    "results": [ 
     { 
     "author": "JK Rowling", 
     "artworkURL": "A url", 
     "genres": [ 
      { 
       "name": "Fantasy" 
      }, 
      { 
       "name": "Scifi" 
      } 
     ], 
      "name": "Goblet of Fire", 
      "releaseDate": "2000-07-08" 
     }, 
     { 
     "author": "JK Rowling", 
     "artworkURL": "A url", 
     "genres": [ 
      { 
       "name": "Fantasy" 
      }, 
      { 
       "name": "Scifi" 
      } 
      ], 
      "name": "Half Blood Prince", 
      "releaseDate": "2009-07-15" 
      } 
     ] 
    } 
} 
""".data(using: .utf8)! 

내가에 데이터를 배치 할 몇 가지 데이터 구조체를

장르 이외의 모든 정보를 인쇄하는 데 성공했습니다. 이것은 장르 배열을 제공하지만, 액세스 할 수없는 book.genres.name 이름에 액세스 할 수 없습니다. 나는 사용해야한다 : book.genres[0] 그리고 저에게 다만 첫번째 색인을위한 결과를 준다.

BookCollection 확장에 내 JSON 디코딩을 완벽하게 할 수있는 방법이 있습니까? book.genres.name을 사용 하시겠습니까? 당신이 정말로 여분의 name 재산, 당신은 새로운 확장에 그렇게 할 수있는 필요한 경우

당신에게

+0

'book.genres.name'이 반환해야하는 값은 무엇입니까? –

+0

@PauloMattos 각 책에 대한 배열을 반환해야합니다. 첫 번째 책은'판타지'와'사이 피'가 될 것입니다. –

+0

@DominicPilla 당신이 당신의 책 구조체'확장 책을 읽기 전용 계산 된 속성을 추가 할 수 있습니다 { var에 allGenres : [문자열] { 반환 genres.map {$ 0.name} } }'와 사용'인쇄 (book.allGenres)' –

답변

1

감사합니다

이 밖에 모든 [Genre] 값으로 상기 name 속성을 추가
extension Array where Element == Genre { 
    var name: [String] { 
     return self.map { $0.name } 
    } 
} 

, 유형은 Book입니다. 그것이 실제로 당신이 무엇인지 알고 있어야합니다. (해당 확장명을 private으로 선언하면 해당되는 신속한 파일에서 사용할 수 있습니다.)

+0

굉장! 그게 효과가 있었어. 하지만 내 BookCollection 확장 내에서이 작업을 수행 할 방법이 없다는 것을 확인하려면? 나는이 확장 밖에서 이것을 추가했고 잘 동작했다. –

+0

@DominicPilla 아니요, 불가능합니다. –

+0

각 데이터 구조체에 대해 'extensions'을 만들려고했지만 성공하지 못했습니다. 올바르게 구현 되었다면 효과가 있다고 말하는 것입니까? –

0

많은 enum codingKeys를 사용하고 유형을 수동으로 디코딩해야하는 필요성을 없애기 위해 데이터 구조를 변경하여 JSON 구조 형식을 매핑 할 수 있습니다. 아래 코드는 구조체를 중첩 할 필요가 없으므로 병렬로 배치 할 수도 있습니다. 이 코드는 인코딩 된 JSON 데이터로 테스트됩니다.

public struct HarryPotterFeed: Codable { 
    public let feed: BookCollection 

    public struct BookCollection: Codable { 
    public let title: String 
    public let books: [Book] 

    // map properties books to json's "results" 
    enum CodingKeys: String, CodingKey { 
     case title // needs to come along 
     case books = "results" 
    } 

    public struct Book: Codable { 
     public let author, name, artworkURL, releaseDate : String 
     public let genres: [Genre] 

     public struct Genre: Codable { 
     public let name: String 
     } 
    } 
    } 
} 

// Decode JSON 

do { 
    let response = try JSONDecoder().decode(HarryPotterFeed.self, from: json) 
    for book in response.feed.books { 
    for name in book.genres { 
     print(name) 
    } 
    } 
} catch { 
    print("PROBLEM DECODING JSON \(error)") 
} 
+0

귀하의 의견을 보내 주셔서 감사합니다. JSON 데이터 구조에는 필요하지 않은 여러 개의 키가 있었으며 내 데이터 구조를 쓸모없는 값으로 채웠습니다. –