如何使用字典数组iOS swift解析JSON

时间:2018-04-16 11:28:00

标签: ios arrays json dictionary swift4

我有一个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,我必须在其中显示" userName"," profilePic"," rating"," email"和" serviceName"在" lstServiceProviders"。到目前为止,我能够显示名称,图像,电子邮件,评级,但" lstServiceProviders"是另一组词典。我想在单元格中显示该serviceProvider提供的所有服务。

让我们在json 1st dict中说" userName":" jhonsmith"正在拥有" lstServicePrpviders"带有两个字典的数组,其中包含" serviceName":" BeautyCare"在第一个Dict和" serviceName":" Carpentry"在第二个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
    }

1 个答案:

答案 0 :(得分: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中,声明varibale

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: ", ")