2017-08-08 11 views
0

GoogleブックスAPIの応答を解析しようとしています。タイトル、説明、サムネイルURL、著者、公開データを取得したいここで問題です: GoogleブックスAPIの解析

func getBooksFrom(completion: @escaping (Result<[[String: AnyObject]]>) -> Void) { 
    URLSession.shared.dataTask(with: url) { (data, response, error) in 
     guard error == nil else { return completion(.Error(error!.localizedDescription)) } 
     guard let data = data else { return 
      completion(.Error(error!.localizedDescription)) } 
     do { 
      if let json = try JSONSerialization.jsonObject(with: data, options: [.mutableContainers]) as? [String: AnyObject] { 
       if let items = json["items"] as? [[String: AnyObject]] { 
        DispatchQueue.main.async { 
         completion(.Succes(items)) 
        } 
       } 
      } 
     } catch let error { 
      print(error.localizedDescription) 
      return completion(.Error(error.localizedDescription)) 
     } 
    }.resume() 
} 

とのviewDidLoadで、私のビューコントローラ上の

iは

let service = ApiService() 
    service.getBooksFrom { (result) in 
     switch result { 
     case .Succes(let data): 
      self.parseData(array: data) 
     case .Error(let message): 
      self.showAlertWith(title: "Error", and: message) 
     } 
    } 

を持っているが... を私はブックオブジェクトに項目をマッピングしたいので、それは非常に単純構文解析のですが、私

それを行うには、スーパーひどい方法です
func parseData(_ data: [[String: AnyObject]]) -> [Book]{ 
    for item in data { 
     if let volumeInfo = item["volumeInfo"] as? [String: AnyObject] { 
     let books = data.map { (jsonDictionary) -> Book in 
      let title = volumeInfo["title"] as? String ?? "" 
      let publishedData = volumeInfo["publishedDate"] as? String ?? "" 
      let authors = volumeInfo["authors"] as? [String] ?? [""] 

      let description = volumeInfo["description"] as? String ?? "" 
      let newBook = Book(title: title, publishedData: publishedData, description: description) 
      return newBook 
     } 
     return books 
     } 
    } 
    return [Book]() 
} 

..あなたが原因で、forループの、一番下に本を返却しなければならない、と VolumeInfoは次のディックです:する必要がtionary、それが次の配列ですので、私は本当に、それをマッピングし、例の作者のために取得するために、正確に方法がわからない...

1つのサンプルのJSONオブジェクト:

{ 
    "items":[ 
     { 
     "volumeInfo":{ 
      "title":"The Ancestor's Tale", 
      "subtitle":"A Pilgrimage to the Dawn of Life", 
      "authors":[ 
       "Richard Dawkins", 
       "Yan Wong" 
      ] 
      "publishedDate":"2016-04-28", 
      "description":"A fully updated ", 
      "imageLinks":{ 
       "smallThumbnail":"http://books.google.com/books/content?id=vzbVCQAAQBAJ&printsec=frontcover&img=1&zoom=5&edge=curl&source=gbs_api", 
       "thumbnail":"http://books.google.com/books/content?id=vzbVCQAAQBAJ&printsec=frontcover&img=1&zoom=1&edge=curl&source=gbs_api" 
      } 
}  
]} 

あなたが持っているときに、これは非常に簡単ですStringの配列:値ですが、適切な方法でマップする必要があります。辞書VolumeInfoの辞書や、著者のような文字列の配列がある場合はどうすればよいでしょうか?

+0

'authors'は、辞書ではなくStringの配列です。 – Larme

+0

@Larmeはい、そうです:) – Magnifique

+0

コメント内のリンクの代わりにJSONサンプルを使用して質問を編集してください。これは便利なことです... 'volumeInfo [" description "] as is?文字列?? ""すべての論文 "?"代わりにBookの 'init'メソッドでテストを行い、ここでより分かりやすい構文解析を行うことができます。 – Larme

答えて

1

私は個人的に、URLSessionを使って迅速にオブジェクトをパースする方法を見つけるのが比較的厄介です。私ができる場合はいつでも、AlamofireAlamofireObjectMapperを組み合わせて使用​​します。

これにより、単純なオブジェクトを作成できます。例:

リクエストをすると、responseObjectメソッドを使用してオブジェクトを直接解析し、適切なタイプを割り当てることができます。

Alamofire.request(URL).responseObject { (response: DataResponse<Book>) in 
    let book = response.result.value 
    print(book?.title) 
} 

この例では、単純に1つの本のみを解析しました。しかし、このコンセプトは、配列や入れ子になったjsonオブジェクトにも簡単に拡張できます。個人的には、URLSessionを直接使用するよりもはるかにクリーンなコードにつながります。

+0

ありがとうございました! <3この典型的なJSONの返答では、reponseArrayとkayPathを使用する必要がありますが、すべてが完璧に動作し、ずっと簡単です! :) – Magnifique

+0

うれしい私は助けることができる:) –

関連する問題