【问题标题】:how to parse a JSON with Array of Dictionaries iOS swift如何使用字典数组iOS swift解析JSON
【发布时间】:2018-09-26 03:01:00
【问题描述】:

我有一个如下所示的 JSON 数组:

func fetchProfessionalData() {

    guard let url = URL(string:"urlString") else { return }

    let parameters = ["Address":""] as [String : Any]

    Alamofire.request(url, method: .post, parameters:parameters,encoding: JSONEncoding.default, headers: nil).responseJSON {
        response in
        switch response.result {
        case .success:      

            let jsonData = response.result.value as! NSArray

            print("response:\(jsonData)")
        }
            self.listTableView.reloadData()

            break
        case .failure(let error):

            print(error)
        }
    }
  }

这是我打印时得到的输出:

response: [
        {
            "userId": 2,
            "userName": "jhonsmith",
            "password": "1234",
            "userTypeId": 3,
            "firstName": "jhon",
            "lastName": "smith",
            "dob": "0004-03-04T00:00:00",
            "phoneNumber": "40556677",
            "mobile": "324",
            "email": "jhon",
            "profilePic": "avatar3.jpg",
            "profileImage": null,
            "isDeleted": false,
            "company": "",
            "experience": "2 years",
            "about": "I am expertised in beauty care",
            "addressId": 2,
            "addressLine1": "7 Freymuth Rd",
            "addressLine2": "",
            "city": "St.Louis",
            "state": "MO",
            "country": "USA",
            "zipCode": "63367",
            "serviceProviderId": 0,
            "serviceId": 0,
            "subServiceId": 0,
            "relevantExp": null,
            "costPerHour": 0,
            "spbRow": null,
            "lstServiceProviders": [
                {
                    "serviceId": 3,
                    "serviceName": "BeautyCare",
                    "serviceDescription": null,
                    "serviceLogo": null,
                    "serviceIsDeleted": false,
                    "serviceIdFK": 0,
                    "subServiceId": 5,
                    "subServiceName": "HairCare",
                    "subServiceDescription": null,
                    "subServiceLogo": null,
                    "subServiceIsDeleted": false,
                    "costPerHour": 500,
                    "serviceProviderId": 2,
                    "providerServiceId": 1
                },
                {
                    "serviceId": 4,
                    "serviceName": "Carpentry",
                    "serviceDescription": null,
                    "serviceLogo": null,
                    "serviceIsDeleted": false,
                    "serviceIdFK": 0,
                    "subServiceId": 6,
                    "subServiceName": "All Carpentry",
                    "subServiceDescription": null,
                    "subServiceLogo": null,
                    "subServiceIsDeleted": false,
                    "costPerHour": 400,
                    "serviceProviderId": 2,
                    "providerServiceId": 1002
                }
            ],
            "rating": 3,
            "price": 0,
            "searchLocationId": 0
        },
        {
            "userId": 4,
            "userName": "User",
            "password": "new",
            "userTypeId": 3,
            "firstName": "Emma",
            "lastName": "Williams",
            "dob": "1998-06-23T00:00:00",
            "phoneNumber": "7787787887",
            "mobile": "9879789990",
            "email": "user@testmail.com",
            "profilePic": "avatar4.jpg",

            "profileImage": null,
            "isDeleted": false,
            "company": "",
            "experience": "2 years",
            "about": "Test",
            "addressId": 4,
            "addressLine1": "Big river dr",
            "addressLine2": "",
            "city": "St.Louis",
            "state": "MO",
            "country": "USA",
            "zipCode": "63367",
            "serviceProviderId": 0,
            "serviceId": 0,
            "subServiceId": 0,
            "relevantExp": null,
            "costPerHour": 0,
            "spbRow": null,
            "lstServiceProviders": [
                {
                    "serviceId": 1,
                    "serviceName": "Cleaning",
                    "serviceDescription": null,
                    "serviceLogo": null,
                    "serviceIsDeleted": false,
                    "serviceIdFK": 0,
                    "subServiceId": 1,
                    "subServiceName": "Dusting",
                    "subServiceDescription": null,
                    "subServiceLogo": null,
                    "subServiceIsDeleted": false,
                    "costPerHour": 2,
                    "serviceProviderId": 4,
                    "providerServiceId": 3
                }
            ],
            "rating": 0,
            "price": 0,
            "searchLocationId": 0
        },
        {
            "userId": 5,
            "userName": "RobertThomas",
            "password": "rb",
            "userTypeId": 3,
            "firstName": "Robert",
            "lastName": "Thomas",
            "dob": "1999-01-04T00:00:00",
            "phoneNumber": "889955643",
            "mobile": "1234567890",
            "email": "rb1234@testmail.com",
            "profilePic": "th.jpg",
            "profileImage": null,
            "isDeleted": false,
            "company": "",
            "experience": "1 Year",
            "about": "Robert Thomas",
            "addressId": 5,
            "addressLine1": "Little Piney Dr",
            "addressLine2": "",
            "city": "St.Louis",
            "state": "MO",
            "country": "USA",
            "zipCode": "63367",
            "serviceProviderId": 0,
            "serviceId": 0,
            "subServiceId": 0,
            "relevantExp": null,
            "costPerHour": 0,
            "spbRow": null,
            "lstServiceProviders": [
                {
                    "serviceId": 2,
                    "serviceName": "ChildCare",
                    "serviceDescription": null,
                    "serviceLogo": null,
                    "serviceIsDeleted": false,
                    "serviceIdFK": 0,
                    "subServiceId": 3,
                    "subServiceName": "Baby Sitting",
                    "subServiceDescription": null,
                    "subServiceLogo": null,
                    "subServiceIsDeleted": false,
                    "costPerHour": 7,
                    "serviceProviderId": 5,
                    "providerServiceId": 4
                }
            ],
            "rating": 0,
            "price": 0,
            "searchLocationId": 0
        }
    ]

现在我有一个 tableViewCell,我必须在“lstServiceProviders”下显示“userName”、“profilePic”、“rating”、“email”和“serviceName”。到目前为止,我可以显示名称、图像、电子邮件,rating 但“lstServiceProviders”是另一个字典数组。我想在单元格中显示该 serviceProvider 提供的所有服务。

让我们在 json 1st dict 中说,“userName”:“jhonsmith”有“lstServicePrpviders”,其中包含两个字典,其中“serviceName”:“BeautyCare”在 1st Dict 和“serviceName”:“Carpentry”在 2nd Dict .我想在一个单元格中同时展示 BeautyCare 和 Carpentry。如何做到这一点。

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

    let listCell = tableView.dequeueReusableCell(withIdentifier: "listCell", for: indexPath) as! ListTableViewCell

    let string = "imageBaseUrl\(models![indexPath.row].profilePic!)"

    let escapedAddress = string.addingPercentEncoding(
        withAllowedCharacters: CharacterSet.urlQueryAllowed)

    listCell.listCellImage.image = UIImage(url: URL(string: escapedAddress!))
    listCell.listCellNamesLabel.text = models![indexPath.row].userName!
    let rating = models![indexPath.row].rating!
    listCell.listCellRating.text = "(\(rating)/5 & 5 Comments)"
    listCell.listCellStarRating.text = ratingArray[indexPath.row]

for i in 0..< models![indexPath.row].lstServiceProviders!.count {

       listCell.listCellServicesLbl.text =                      
              models![indexPath.row].lstServiceProviders[i].serviceName
    }
    return listCell
    }

【问题讨论】:

  • 你可以使用 AlamofireObjectMapper。
  • @Mehul Sojitra 我真的对此一无所知,也不知道它对我的案子有什么用处
  • 请花时间深入学习。一切都在他们的文档中给出。

标签: ios arrays json dictionary swift4


【解决方案1】:

[Swift 4] 您可以使用具有 Codable 的模型来轻松管理您的 tableviewcell。

查看下面的代码并在操场上运行,你会明白我已经创建了易于循环和管理的模型对象:

var json = """
[
    {
        "userId": 2,
        "userName": "jhonsmith",
        "password": "1234",
        "userTypeId": 3,
        "firstName": "jhon",
        "lastName": "smith",
        "dob": "0004-03-04T00:00:00",
        "phoneNumber": "40556677",
        "mobile": "324",
        "email": "jhon",
        "profilePic": "avatar3.jpg",
        "profileImage": null,
        "isDeleted": false,
        "company": "",
        "experience": "2 years",
        "about": "I am expertised in beauty care",
        "addressId": 2,
        "addressLine1": "7 Freymuth Rd",
        "addressLine2": "",
        "city": "St.Louis",
        "state": "MO",
        "country": "USA",
        "zipCode": "63367",
        "serviceProviderId": 0,
        "serviceId": 0,
        "subServiceId": 0,
        "relevantExp": null,
        "costPerHour": 0,
        "spbRow": null,
        "lstServiceProviders": [
        {
        "serviceId": 3,
        "serviceName": "BeautyCare",
        "serviceDescription": null,
        "serviceLogo": null,
        "serviceIsDeleted": false,
        "serviceIdFK": 0,
        "subServiceId": 5,
        "subServiceName": "HairCare",
        "subServiceDescription": null,
        "subServiceLogo": null,
        "subServiceIsDeleted": false,
        "costPerHour": 500,
        "serviceProviderId": 2,
        "providerServiceId": 1
        },
        {
        "serviceId": 4,
        "serviceName": "Carpentry",
        "serviceDescription": null,
        "serviceLogo": null,
        "serviceIsDeleted": false,
        "serviceIdFK": 0,
        "subServiceId": 6,
        "subServiceName": "All Carpentry",
        "subServiceDescription": null,
        "subServiceLogo": null,
        "subServiceIsDeleted": false,
        "costPerHour": 400,
        "serviceProviderId": 2,
        "providerServiceId": 1002
        }
        ],
        "rating": 3,
        "price": 0,
        "searchLocationId": 0
    },
    {
        "userId": 4,
        "userName": "User",
        "password": "new",
        "userTypeId": 3,
        "firstName": "Emma",
        "lastName": "Williams",
        "dob": "1998-06-23T00:00:00",
        "phoneNumber": "7787787887",
        "mobile": "9879789990",
        "email": "user@testmail.com",
        "profilePic": "avatar4.jpg",

        "profileImage": null,
        "isDeleted": false,
        "company": "",
        "experience": "2 years",
        "about": "Test",
        "addressId": 4,
        "addressLine1": "Big river dr",
        "addressLine2": "",
        "city": "St.Louis",
        "state": "MO",
        "country": "USA",
        "zipCode": "63367",
        "serviceProviderId": 0,
        "serviceId": 0,
        "subServiceId": 0,
        "relevantExp": null,
        "costPerHour": 0,
        "spbRow": null,
        "lstServiceProviders": [
        {
        "serviceId": 1,
        "serviceName": "Cleaning",
        "serviceDescription": null,
        "serviceLogo": null,
        "serviceIsDeleted": false,
        "serviceIdFK": 0,
        "subServiceId": 1,
        "subServiceName": "Dusting",
        "subServiceDescription": null,
        "subServiceLogo": null,
        "subServiceIsDeleted": false,
        "costPerHour": 2,
        "serviceProviderId": 4,
        "providerServiceId": 3
        }
        ],
        "rating": 0,
        "price": 0,
        "searchLocationId": 0
    },
    {
        "userId": 5,
        "userName": "RobertThomas",
        "password": "rb",
        "userTypeId": 3,
        "firstName": "Robert",
        "lastName": "Thomas",
        "dob": "1999-01-04T00:00:00",
        "phoneNumber": "889955643",
        "mobile": "1234567890",
        "email": "rb1234@testmail.com",
        "profilePic": "th.jpg",
        "profileImage": null,
        "isDeleted": false,
        "company": "",
        "experience": "1 Year",
        "about": "Robert Thomas",
        "addressId": 5,
        "addressLine1": "Little Piney Dr",
        "addressLine2": "",
        "city": "St.Louis",
        "state": "MO",
        "country": "USA",
        "zipCode": "63367",
        "serviceProviderId": 0,
        "serviceId": 0,
        "subServiceId": 0,
        "relevantExp": null,
        "costPerHour": 0,
        "spbRow": null,
        "lstServiceProviders": [
        {
        "serviceId": 2,
        "serviceName": "ChildCare",
        "serviceDescription": null,
        "serviceLogo": null,
        "serviceIsDeleted": false,
        "serviceIdFK": 0,
        "subServiceId": 3,
        "subServiceName": "Baby Sitting",
        "subServiceDescription": null,
        "subServiceLogo": null,
        "subServiceIsDeleted": false,
        "costPerHour": 7,
        "serviceProviderId": 5,
        "providerServiceId": 4
        }
        ],
        "rating": 0,
        "price": 0,
        "searchLocationId": 0
    }
]
""".data(using: .utf8)

struct LstServiceProviders : Codable {
    let serviceId : Int?
    let serviceName : String?
    let serviceDescription : String?
    let serviceLogo : String?
    let serviceIsDeleted : Bool?
    let serviceIdFK : Int?
    let subServiceId : Int?
    let subServiceName : String?
    let subServiceDescription : String?
    let subServiceLogo : String?
    let subServiceIsDeleted : Bool?
    let costPerHour : Int?
    let serviceProviderId : Int?
    let providerServiceId : Int?

    enum CodingKeys: String, CodingKey {

        case serviceId = "serviceId"
        case serviceName = "serviceName"
        case serviceDescription = "serviceDescription"
        case serviceLogo = "serviceLogo"
        case serviceIsDeleted = "serviceIsDeleted"
        case serviceIdFK = "serviceIdFK"
        case subServiceId = "subServiceId"
        case subServiceName = "subServiceName"
        case subServiceDescription = "subServiceDescription"
        case subServiceLogo = "subServiceLogo"
        case subServiceIsDeleted = "subServiceIsDeleted"
        case costPerHour = "costPerHour"
        case serviceProviderId = "serviceProviderId"
        case providerServiceId = "providerServiceId"
    }
}

struct RootModel : Codable {
    let userId : Int?
    let userName : String?
    let password : String?
    let userTypeId : Int?
    let firstName : String?
    let lastName : String?
    let dob : String?
    let phoneNumber : String?
    let mobile : String?
    let email : String?
    let profilePic : String?
    let profileImage : String?
    let isDeleted : Bool?
    let company : String?
    let experience : String?
    let about : String?
    let addressId : Int?
    let addressLine1 : String?
    let addressLine2 : String?
    let city : String?
    let state : String?
    let country : String?
    let zipCode : String?
    let serviceProviderId : Int?
    let serviceId : Int?
    let subServiceId : Int?
    let relevantExp : String?
    let costPerHour : Int?
    let spbRow : String?
    let lstServiceProviders : [LstServiceProviders]?
    let rating : Int?
    let price : Int?
    let searchLocationId : Int?

    enum CodingKeys: String, CodingKey {

        case userId = "userId"
        case userName = "userName"
        case password = "password"
        case userTypeId = "userTypeId"
        case firstName = "firstName"
        case lastName = "lastName"
        case dob = "dob"
        case phoneNumber = "phoneNumber"
        case mobile = "mobile"
        case email = "email"
        case profilePic = "profilePic"
        case profileImage = "profileImage"
        case isDeleted = "isDeleted"
        case company = "company"
        case experience = "experience"
        case about = "about"
        case addressId = "addressId"
        case addressLine1 = "addressLine1"
        case addressLine2 = "addressLine2"
        case city = "city"
        case state = "state"
        case country = "country"
        case zipCode = "zipCode"
        case serviceProviderId = "serviceProviderId"
        case serviceId = "serviceId"
        case subServiceId = "subServiceId"
        case relevantExp = "relevantExp"
        case costPerHour = "costPerHour"
        case spbRow = "spbRow"
        case lstServiceProviders = "lstServiceProviders"
        case rating = "rating"
        case price = "price"
        case searchLocationId = "searchLocationId"
   }
}


let Models = try! JSONDecoder().decode([RootModel].self, from: json!)

print(Models.count)
for item in Models {
    print(item.lstServiceProviders?.count)
}

[编辑 1] 如果响应是数据,请使用以下内容:

URLSession.shared.dataTask(with: gitUrl) { (data, response
            , error) in      
            guard let data = data else { return }
            do {
                let decoder = JSONDecoder()
                let models = try decoder.decode([RootModel].self, from: data)

            } catch let err {
                print("Err", err)
         }
   }.resume()

如果响应是像您的输出一样的 Json 对象,请使用以下内容:

func fetchProfessionalData() {

    guard let url = URL(string:"urlString") else { return }

    let parameters = ["Address":""] as [String : Any]

    Alamofire.request(url, method: .post, parameters:parameters,encoding: JSONEncoding.default, headers: nil).responseJSON {
        response in
        switch response.result {
        case .success:      

           // let jsonData = response.result.value as! NSArray

            let jsonData = try JSONSerialization.data(withJSONObject: response.result, options: .prettyPrinted)
    models = try JSONDecoder().decode([RootModel].self, from: jsonData)
            print("response:\(jsonData)")
        }
           // self.listTableView.reloadData()

            break
        case .failure(let error):

            print(error)
        }
    }
  }    

在你的 viewController 中,声明变量

var models: [RootModel]? {
        didSet {
            self.listTableView.reloadData()
        }
    }

在您的 tableview 委托方法中

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return models.count ?? 0
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

   // Update your cell using models
   // cell.text = models[indexPath.row].userName
}

[编辑2]添加所有字符串,然后显示值。

var stringArray:[String] = []
for i in 0..< models![indexPath.row].lstServiceProviders!.count {
 stringArray.append( models![indexPath.row].lstServiceProviders[i].serviceName)
}

listCell.listCellServicesLbl.text = stringArray.joined(separator: ", ")

【讨论】:

  • @Razib Mollick 嘿,感谢您的回复,我是初学者,正在尝试了解它是如何工作的。我只是不明白 var json = """[{...}]""" 是我的 json 响应,对。所以,你的意思是我必须将我的 json 响应存储在 var json = response.result.value! 中是吗?
  • 不,您是否收到了类似 json 数组或数据的响应?请参阅编辑 1。
  • @Razib Mollick 嘿,伙计,我已经编辑了我的问题,请看一次,然后告诉我该怎么做..提前谢谢..
  • @Razib Mollick 嘿 razib 看到我的编辑我试过了,但它显示了每个数组中的最后一个 serviceName。不确定如何显示每次迭代的所有 serviceName。
  • @VenkateshChejarla,请参阅编辑 2。或告诉我您希望如何查看输出。不要忘记接受我的回答。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-07-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多