首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Google Books API解析

Google Books API解析
EN

Stack Overflow用户
提问于 2017-08-08 23:17:27
回答 1查看 957关注 0票数 1

所以我正在尝试解析Google Books API respond。我想要得到标题,描述,thumbnailUrl,作者和出版的数据。以下是问题所在:

代码语言:javascript
复制
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视图控制器上,我有

代码语言:javascript
复制
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)
        }
    }

所以这是非常简单的解析,但是...当我想要将项目映射到Book对象中时,我必须:

代码语言:javascript
复制
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循环,您必须在底部返回Book,而VolumeInfo是next Dictionary,所以我真的不知道如何准确地映射它并获取示例作者,因为它是next数组。

一个示例JSON对象:

代码语言:javascript
复制
   {  
   "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 : Value数组时,这非常简单,但是当您有字典VolumeInfo或字符串数组(如authors )时,应该如何正确地映射呢?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-08-08 23:50:14

我个人发现用URLSession在swift中解析对象的方法比较笨拙。只要有可能,我就会将AlamofireAlamofireObjectMapper结合使用。

这允许您创建一个简单的对象。例如:

代码语言:javascript
复制
class Book: Mappable {
      var title: String?
      var subtitle: String?
      var description: String?

      required init?(map: Map){

      }

      func mapping(map: Map) {
        title <- map["title"]
        subtitle <- map["subtitle"]
        description <- map["description"]
      }
}

当您发出请求时,您可以使用responseObject方法直接解析您的对象并分配适当的类型。

代码语言:javascript
复制
Alamofire.request(URL).responseObject { (response: DataResponse<Book>) in
  let book = response.result.value
  print(book?.title)
}

在本例中,我只解析了一本书。但是这个概念也可以很容易地扩展到数组或嵌套的json对象。我个人认为这比直接使用URLSession的代码干净得多。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45572149

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档