luke
luke

Reputation: 2773

populating JSON in tableview

So I'm trying to populate multiple tableviews with the json code below:

{   "company":[
    {   "company_id":"0",
        "name": "Company Name",
        "phone_number":"0123978978",
        "website":"http:\/\/www.Company.co.uk\/",
        "email":"[email protected]",
        "address":"123 Alm Street...",
        "employees":[
            {
                "company_id": "0",
                "name":"Steve",
                "age":"25",
                "description":"desc"},
            {
                "company_id": "0",
                "name":"Paul",
                "age":"35",
                "description":"desc"}]

        }
    ]
}

below is the model of fetching the json and formatting it into something I can use

class Company: NSObject {
var name: String
var phoneNumber: String
var website: String
var email: String
var address: String
var employees: [Employee]

override init() {

}

init(name: String, phoneNumber: String, website: String, email: String, address: String, employees: [Employee]) {
    self.name = name
    self.phoneNumber = phoneNumber
    self.website = website
    self.email = email
    self.address = address
    self.employees = employees
}
}

class Employee : NSObject {
var name:String
var age:Int
var information:String

override init() {

}

init(name: String, age: Int, information: String) {
    self.name = name
    self.age = age
    self.information = information
}
}

func getJSON(completion: (array: [Company])->()) {

var companyArray = [Company]()

let requestURL: NSURL = NSURL(string: urlString)!
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) {
        print("Everything is fine, file downloaded successfully.")

        do{

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

            if let companies = json["companies"] as? NSArray {

                for companyDict in companies {

                    let company = Company()
                    let employee = Employee()
                    var employeeArray = [Employee]()

                    if let name = companyDict["name"] as? String,
                        let phoneNumber = companyDict["phone_number"] as? String,
                        let website = companyDict["website"] as? String,
                        let email = companyDict["email"] as? String,
                        let address = companyDict["address"] as? String {

                            company.name = name
                            company.phoneNumber = phoneNumber
                            company.website = website
                            company.email = email
                            company.address = address
                        }
                    if let employees = companyDict["employees"] as? NSArray {
                        for employeesDict in employees {
                            if let name = employeesDict["name"] as? String,
                                let age = employeesDict["age"] as? Int,
                                let information = employeesDict["information"] as? String {
                                var employeeArray = [Employee]()
                                let employee = Employee()

                                employee.name = name
                                employee.information = information
                                employee.age = age
                                employeeArray.append(employee)
                                company.employees = employeeArray
                            }
                        }
                    }
                    companyArray.append(company)

                }
                dispatch_async(dispatch_get_main_queue()) {
                    completion(array: companyArray)
                }

            }

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

    }

}

task.resume()
}

This is where the problem arrises, I can populate my first tableview fine. Each cell displays the data fine. The problem occurs when I try to populate my second tableview based on selection of a cell in my first tableview.

let selectedCompany:Company?

func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return self.selectedCompany!.employees!.count //ignore force unwrap
}

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let employee = self.selectedCompany!.employees![indexPath.row] //ignore force unwrap

    cell.employeeName.text = employee.name


    return cell
}

The line let employee = self.selectedCompany!.employees![indexPath.row] displays a compiler error of type has no subscript members. I think I know why - I need to populate the second table view as an array. At the moment, Employee is not an array. I've tried several different methods to make it an array but I can't seem to do it. What I've tried usually returns nil and the app crashes or i get compiler errors

Upvotes: 0

Views: 94

Answers (1)

vadian
vadian

Reputation: 285079

You have to declare employees in Company as array

var employees = [Employee]() 

and also in the initializer

init(name ... , employees: [Employee]) {

and – very very important – you have to create the Employee instance in the repeat loop, otherwise you have employees.count times the same object (due to reference semantics of classes)

   ...
   for employeesDict in employees {
       if let name = employeesDict["name"] as? String,
          let age = employeesDict["age"] as? Int,
          let information = employeesDict["information"] as? String {
             let employee = Employee(name:name, age:age, information:information)
             employeeArray.append(employee)
          }
       }
   } 
   company.employees = employeeArray
   ...

You have to use the initializer anyway. And you have to assign the array after the repeat loop.

Upvotes: 1

Related Questions