2

我正在使用条形码扫描仪使用 google 图书 api 获取扫描图书的数据。我成功调用了 API 并返回了一个 JSON 对象。

我正在尝试获取遵循路径的书名items.volumeInfo.title

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

可选((“魔龙的狂舞”))

我似乎无法弄清楚如何从打印的可选中实际获取字符串。我试过as! Stringand jsonResult.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)
            }


        })
    }
4

1 回答 1

4

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

我建议使用if let解包从 KVC 获得的 Optional 值,并将结果类型转换为 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"

斯威夫特 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"

斯威夫特 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")
于 2015-08-20T01:16:39.093 回答