无法从Google-Books JSON API中获取价值

时间:2015-08-20 00:21:12

标签: ios json swift kvc google-books

我正在使用条形码扫描程序使用google books api获取扫描书籍的数据。我成功调用了API并获取了一个JSON对象。

我正在尝试获取路径items.volumeInfo.title之后的书名。

当我在API返回的JSON对象上调用valueForPath并尝试打印它(标题)时,我最终打印出来了:

  

可选((       “与龙共舞”   ))

我似乎无法弄清楚如何从打印的可选项中实际获取字符串。我尝试了as! StringjsonResult.valueForKeyPath("items.volumeInfo.title")!,但第一个只是向我抱怨,第二个只删除了可选的外部括号。

func getBookInfo(isbn: String) {
        var url: String = "https://www.googleapis.com/books/v1/volumes?q=isbn:" + isbn;
        var request: NSMutableURLRequest = NSMutableURLRequest()
        request.URL = NSURL(string: url)
        request.HTTPMethod = "GET"

        NSURLConnection.sendAsynchronousRequest(request, queue: NSOperationQueue(), completionHandler:{ (response:NSURLResponse!, data: NSData!, error: NSError!) -> Void in
            var error: AutoreleasingUnsafeMutablePointer<NSError?> = nil
            let jsonResult: NSDictionary! = NSJSONSerialization.JSONObjectWithData(data, options:NSJSONReadingOptions.MutableContainers, error: error) as? NSDictionary

            if (jsonResult != nil) {

                println(jsonResult.valueForKeyPath("items.volumeInfo.title"))
                //self.json.setValue(jsonResult.valueForKeyPath("items.volumeInfo.title")!, forKey: "title")

            } else {
                GlobalConstants.AlertMessage.displayAlertMessage("Error fetching data from barcode, please try again.", view: self)
            }


        })
    }

1 个答案:

答案 0 :(得分:3)

您从API获得的响应是​​一系列标题。

我建议使用if let来解包从KVC获得的Optional值,并将结果类型转换为字符串的Swift数组。

Swift 1

func getBookInfo(isbn: String) {
    var url: String = "https://www.googleapis.com/books/v1/volumes?q=isbn:" + isbn
    var request: NSMutableURLRequest = NSMutableURLRequest()
    request.URL = NSURL(string: url)
    request.HTTPMethod = "GET"

    NSURLConnection.sendAsynchronousRequest(request, queue: NSOperationQueue(), completionHandler:{ (response:NSURLResponse!, data: NSData!, error: NSError!) -> Void in
        var error: AutoreleasingUnsafeMutablePointer<NSError?> = nil

        if let jsonResult = NSJSONSerialization.JSONObjectWithData(data, options: nil, error: error) as? NSDictionary {

            if let arrayOfTitles = jsonResult.valueForKeyPath("items.volumeInfo.title") as? [String] {
                let titles = ", ".join(arrayOfTitles)
                println(titles)
            } else {
                // error: no title found
            }

        } else {

            GlobalConstants.AlertMessage.displayAlertMessage("Error fetching data from barcode, please try again.", view: self)

        }

    })
}

getBookInfo("0553283685")  // prints "Hyperion"

Swift 2

对于此版本,我们使用NSURLSession,因为现在不推荐使用NSURLConnection。

func getBookInfo(isbn: String) {
    let urlString = "https://www.googleapis.com/books/v1/volumes?q=isbn:" + isbn
    if let url = NSURL(string: urlString) {
        NSURLSession.sharedSession().dataTaskWithURL(url, completionHandler: {data, _, error -> Void in
            if let error = error {
                print(error.localizedDescription)
            } else {
                if let data = data,
                    jsonResult = try? NSJSONSerialization.JSONObjectWithData(data, options: []),
                    arrayOfTitles = jsonResult.valueForKeyPath("items.volumeInfo.title") as? [String] {
                    let titles = arrayOfTitles.joinWithSeparator(", ")
                    print(titles)
                } else {
                    GlobalConstants.AlertMessage.displayAlertMessage("Error fetching data from barcode, please try again.", view: self)
                }
            }
        }).resume()
    }
}

getBookInfo("0553283685") // prints "Hyperion"

Swift 3

与Swift 2相同,但有一些语法更改。我还添加了“作者”示例,现在我正在使用guard。只是为了展示与前一个例子不同的东西。

func getBookInfo(isbn: String) {
    guard let url = URL(string: "https://www.googleapis.com/books/v1/volumes?q=isbn:\(isbn)") else {
        print("the url is not valid")
        return
    }
    URLSession.shared().dataTask(with: url, completionHandler: {data, response, error -> Void in
        guard error == nil else {
            print(response)
            print(error!.localizedDescription)
            return
        }
        guard let data = data else {
            print("no error but no data")
            print(response)
            return
        }
        guard let jsonResult = try? JSONSerialization.jsonObject(with: data, options: []) else {
            print("the JSON is not valid")
            return
        }
        if let arrayOfTitles = jsonResult.value(forKeyPath: "items.volumeInfo.title") as? [String] {
            print(arrayOfTitles)
        }
        if let arrayOfAuthors = jsonResult.value(forKeyPath: "items.volumeInfo.authors") as? [[String]] {
            print(arrayOfAuthors)
        }
    }).resume()
}

getBookInfo(isbn: "0553283685")