访问另一个数组中的JSON数组

时间:2016-01-04 16:44:01

标签: ios swift

到目前为止,我只需要处理只有一个数组的简单JSON数组。我现在将2个阵列组合在一起,这样我就可以获得用户数据和该用户的所有评论:

[
{
    "user_id": "16",
    "name": "Jonh",
    "lastName": "appleseed",
    "username": "jonh@me.com",
    "sex": "male",
    "image_url": "",
    "review": [
        {
            "reviewID": "4",
            "merchant_id": "17",
            "rating": "5",
            "user_id": "16",
            "comments": "Very good customer. Strongly suggested",
            "date": "0000-00-00",
            "reviewYear": "",
            "publish": "1"
        },
        {
            "reviewID": "8",
            "merchant_id": "16",
            "rating": "2",
            "user_id": "16",
            "comments": "Automatic review due to "NO SHOW" without informing the merchant",
            "date": "0000-00-00",
            "reviewYear": "",
            "publish": "1"
        }
    ]
}
]

在我添加评论之前,我的模型看起来像这样:

import Foundation

class Users {
    let userImage:String?
    let name:String?
    let sex:String?
    let image_url:String?

    init(dictionary:NSDictionary) {            
        userImage = dictionary["userImage"]    as? String
        name = dictionary["name"]    as? String
        sex = dictionary["sex"]    as? String
        image_url = dictionary["image_url"]    as? String
    }
}

func loadUser(completion:(([Users])-> Void), userId: String){
    let myUrl = NSURL(string: "http://www.myWebSite.com/api/v1.0/users.php")
    let request = NSMutableURLRequest(URL: myUrl!)
    request.HTTPMethod = "POST"
    let postString = "user_id=\(userId)"
    request.HTTPBody = postString.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: true)
    let task = NSURLSession.sharedSession().dataTaskWithRequest(request)
        { data, response, error in        
            if error != nil {        
                print("error\(error)")    
            } else {
                do {     
                    let json = try NSJSONSerialization.JSONObjectWithData(data!, options: .MutableContainers) as! NSArray
                    print(json)

                    var users = [Users]()    
                    for user in json{                            
                        let user = Users(dictionary: user as! NSDictionary)    
                        users.append(user)    
                        let priority = DISPATCH_QUEUE_PRIORITY_DEFAULT
                            dispatch_async(dispatch_get_global_queue(priority, 0 )){
                            dispatch_async(dispatch_get_main_queue()){        
                                    completion(users)
                            }
                        }    
                    }        
                } catch{   
                }
            }
        }
    task.resume()
}

然后我可以在我的viewController中使用:

func loadModel() {
    let loadingNotification = MBProgressHUD.showHUDAddedTo(self.view, animated: true)
    loadingNotification.mode = MBProgressHUDMode.Indeterminate
    loadingNotification.labelText = "updating your deals..."
    users = [Users]()
    let api = Api()
    api.loadUser(didLoadUsers , userId: "16")    
}

func didLoadUsers(users:[Users]){        
    self.users = users
    self.tableView.reloadData()
    MBProgressHUD.hideAllHUDsForView(self.view, animated: true)
}

我可以获取review字段,以便将其显示在表格视图控制器中吗?

2 个答案:

答案 0 :(得分:1)

我在您的Users课程中添加了一系列评论,这些评论将填入您的用户init()方法中。我建议您查看struct Review并将您的用户类设为结构,并将NSDictionary更改为快速Dictionary

   struct Review {
    let reviewID:String?
    let merchant_id:String?
    let user_id:String?
    //to be continued with your own implementation...

    init(dictionary:[String:String]) {
        reviewID = dictionary["reviewID"]
        merchant_id = dictionary["merchant_id"]
        user_id = dictionary["user_id"]
        //to be continued with your own implementation...
    }
}
class Users {

    let userImage:String?
    let name:String?
    let sex:String?
    let image_url:String?
    var reviews:[Review]

    init(dictionary:[String:AnyObject]) {

        userImage = dictionary["userImage"]    as? String
        name = dictionary["name"]    as? String
        sex = dictionary["sex"]    as? String
        image_url = dictionary["image_url"]    as? String
        reviews = [Review]()
        if let userReviews = dictionary["review"] as? [[String:AnyObject]] {
            for review  in userReviews {

                if let unwrapedReview = review as? [String:String] {
                    let r = Review(dictionary: unwrapedReview)
                    reviews.append(r)
                }
            }
        }
    }
}

此外,我建议您将来使用SwiftyJSON解析JSON,并使用Alamofire来处理网络请求。

答案 1 :(得分:0)

完成。这比我想象的要容易。我只需要添加UserReview类并更改loadUser函数的签名:

 func loadUser(completion:((user: [Users], review: [UserReview])-> Void), userId: String){

    let myUrl = NSURL(string: "http://www.myWebsite.com/api/v1.0/users.php")
    let request = NSMutableURLRequest(URL: myUrl!)
    request.HTTPMethod = "POST"
    let postString = "user_id=\(userId)"
    request.HTTPBody = postString.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: true)
    let task = NSURLSession.sharedSession().dataTaskWithRequest(request)
        { data, response, error in

            if error != nil {

                print("error\(error)")

            }else{

                do{
                    let json = try NSJSONSerialization.JSONObjectWithData(data!, options: .MutableContainers) as! NSArray

                    var users = [Users]()


                    for user in json{

                        let user = Users(dictionary: user as! NSDictionary as! [String : AnyObject])

                        users.append(user)

        //*********** now I can access the reviews from my son***************
                     let reviewArray = json[0]["review"] as! NSArray
                        var reviews = [UserReview]()


                        for review in reviewArray{

                            let review = UserReview(dictionary: review as! NSDictionary as! [String : AnyObject])

                            reviews.append(review)

                        }

                        let priority = DISPATCH_QUEUE_PRIORITY_DEFAULT
                        dispatch_async(dispatch_get_global_queue(priority, 0 )){

                            dispatch_async(dispatch_get_main_queue()){

                                completion(user: users, review: reviews)
                            }
                        }

                    }

                } catch{

                }
            }
    }
    task.resume()
}

所以我可以在tableViewController中使用它

     var users: [Users]?
     var reviews: [UserReview]?

    func loadModel() {
    let loadingNotification = MBProgressHUD.showHUDAddedTo(self.view, animated: true)
    loadingNotification.mode = MBProgressHUDMode.Indeterminate
    loadingNotification.labelText = "updating..."
    users = [Users]()
    reviews = [UserReview]()
    let api = Api()
    api.loadUser(didLoadUsers , userId: "16")
}

func didLoadUsers(users:[Users], reviews:[UserReview] ){

        self.users = users
        self.reviews = reviews
        self.tableView.reloadData()
        MBProgressHUD.hideAllHUDsForView(self.view, animated: true)    

    }

    override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {

    if section == 0 {

        return users!.count

    }
    if section == 1 {   

        return 1  

    }
    if section == 2 {

    return reviews!.count
    }
    return 0
}

所以在cellForRowAtIndexPath我现在可以加载所有评论

if indexPath.section == 2 {

        let review = reviews![indexPath.row]


        let reviewCell = tableView.dequeueReusableCellWithIdentifier("reviewCell", forIndexPath: indexPath) as! UserReviewsTableViewCell
        reviewCell.useReview(review)

        return reviewCell
    }