无法弄清楚如何在Swift

时间:2016-05-22 14:26:00

标签: ios json swift rest nsurlsession

大家好日子。首先,我想通知您,我在编程方面非常新。因此,如果我没有任何意义,我想提前道歉。我已经为iOS Swift做了一个训练营,但是没有包含Rest或解析JSON。我现在正在努力教自己做我能找到的所有教程。我知道那里的Alamofire让它变得更容易,但我想首先学习如何使用NSURLSession。我找到了一个用旧版Swift编写的教程,现在我已经被困了好几天了。我已经尝试了我在这里和Google上可以找到的所有选项。但我仍然无法理解我做错了什么。这是我的代码;在它下面,我已经描述了我认为问题发生的地方。 在此先感谢您的帮助。

import Foundation
import UIKit

class FlickrHelper: NSObject {

class func UrlForSearchString(searchString: String) -> String {
    let apiKey:String = "733e5b6f446812afdec3c021454dd9bb"
    let search:String = searchString.stringByAddingPercentEscapesUsingEncoding(NSUTF8StringEncoding)!
    return "https://api.flickr.com/services/rest/?method=flickr.photos.search&api_key=\(apiKey)&text=\(search)&per_page=20&format=json&njsoncallback=1"

}
class func UrlForFlickrPhoto(photo:FlickrPhoto, size:String) -> String {
    var _size = size
    if _size.isEmpty {
        _size = "m"
    }
    return "http://farm.\(photo.farm).staticflickr.com/\(photo.photoID)_\(photo.secret)_\(_size).jpg"
}

func searchFlickrForString(searchStr:String, completion:(searchString:String!, flickrPhotos:NSMutableArray!, error:NSError!) -> ()) {

    let searchUrl:String = FlickrHelper.UrlForSearchString(searchStr)
    let queue:dispatch_queue_t = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)

    dispatch_async(queue, {

        var error:NSError?

        let searchResultString:String! = try! String(contentsOfURL: NSURL(string: searchUrl)!, encoding: NSUTF8StringEncoding)

        if error != nil {
            completion(searchString: searchStr, flickrPhotos: nil, error: error)
        } else {
            // Parse json response.

            let jsonData:NSData! = searchResultString.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)

            let resultDict = try? NSJSONSerialization.JSONObjectWithData(jsonData, options: []) as! [String:AnyObject] as NSDictionary

            let status:String = resultDict?.objectForKey("stat") as! String

            if status == "fail" {
                let stError:NSError? = NSError(domain: "FlickrSearch", code: 0, userInfo: [NSLocalizedFailureReasonErrorKey:(resultDict?.objectForKey("message"))!])

                completion(searchString: searchStr, flickrPhotos: nil, error: stError)
            } else {
                let resultArray:NSArray = (resultDict?.objectForKey("photos")?.objectForKey("photo"))! as! NSArray

                let flickrPhotos:NSMutableArray = NSMutableArray()

                for photoObject in resultArray {
                    let photoDict:NSDictionary = photoObject as! NSDictionary

                    var flickrPhoto:FlickrPhoto = FlickrPhoto()
                    flickrPhoto.farm = photoDict.objectForKey("farm") as! Int
                    flickrPhoto.server = photoDict.objectForKey("server") as! String
                    flickrPhoto.secret = photoDict.objectForKey("secret") as! String
                    flickrPhoto.photoID = photoDict.objectForKey("id") as! String

                    let searchURL:String = FlickrHelper.UrlForFlickrPhoto(flickrPhoto, size: "m")
                    do {
                    let imageData:NSData = try NSData(contentsOfURL: NSURL(string: searchURL)!, options: NSDataReadingOptions())

                        let image:UIImage = UIImage(data:imageData)!

                        flickrPhoto.thumbnail = image

                        flickrPhotos.addObject(flickrPhoto)

                    } catch {
                        print(error)
                    }

                    completion(searchString: searchStr, flickrPhotos: flickrPhotos, error: nil)

                }
            }
        }
    })
  }
}

我收到了jsonData,但是没有将它分配给我的resultDict。我的resultDict是零。我的项目崩溃的行是这一行:

 let status:String = resultDict?.objectForKey("stat") as! String

但我猜这个问题就在这一行:

let resultDict = try? NSJSONSerialization.JSONObjectWithData(jsonData, options: []) as! [String:AnyObject] as NSDictionary

2 个答案:

答案 0 :(得分:0)

试试这个。

不要将空数组传递给NSJSONSerialization.JSONObjectWithData,而是使用allow with fragment类型,如下所示:

let resultDict = try? NSJSONSerialization.JSONObjectWithData(jsonData, NSJSONReadingOptions.AllowFragments)

这可能会解决问题。否则尝试其他一些选项。

另一种方法可能就是这样。

            let json = try! NSJSONSerialization.JSONObjectWithData(json!, options: .AllowFragments)
            print("=====")
            if let item = json.objectForKey("prices") as! NSArray? {
                self.uberPriceField.text = item[0].objectForKey("estimate") as? String
            }

我在自己的代码中使用了这个,因为返回的JSON实际上只是顶层的一个数组。也许它对你也有用。

答案 1 :(得分:0)

以下是我在我的项目中使用的代码,请参阅相同内容,如果问题仍然存在,请告诉我: -

 let requestURL: NSURL = NSURL(string: "(Ur URL)/get_SearchList.php?cth=\(cth),\(kwValue)")!
        let urlRequest: NSMutableURLRequest = NSMutableURLRequest(URL: requestURL)
        let session = NSURLSession.sharedSession()
        let task = session.dataTaskWithRequest(urlRequest) {
            (data, response, error) -> Void in

            let httpResponse = response as! NSHTTPURLResponse
            let statusCode = httpResponse.statusCode

            if (statusCode == 200) {

                do{

                    let json = try NSJSONSerialization.JSONObjectWithData(data!, options:.AllowFragments)



                    if let products = json["product"] as? [[String: AnyObject]] {
                        dispatch_async(dispatch_get_main_queue(), {
                        for product in products {

                                if let cth = product["cth"] as? String {


                                    if let name = product["productname"] as? String {
                                        self.cthArray.append(cth);
                                        self.prodArray.append(name);


                                    }

                                }


                        }//for loop
                            dispatch_async(dispatch_get_main_queue(),{
                                self.tableView.reloadData()
                            })
                        })

                    }// if loop

                }
                catch
                {
                    print("Error with Json: \(error)")

                }

            }
            else
            {
                // No internet connection
                // Alert view controller
                // Alert action style default


            }

        }

        task.resume()