Lampros Tzanetos
Lampros Tzanetos

Reputation: 323

Accessing Object Attributes from JSON, Swift3

    let url = URL(string: "http://192.168.30.243:5000/trippy/destination/info?id=4864cc0a-8")

    let task = URLSession.shared.dataTask(with: url!) { (data, response, error) in
        if error != nil {
            print ("ERROR")
        }
        else {
            if let content = data {
                do {
                    //Array
                    let myJson = try JSONSerialization.jsonObject(with: content, options: JSONSerialization.ReadingOptions.mutableContainers) as AnyObject
                    print(myJson)

                    if let information = myJson as? NSDictionary { 
                        print (information.value(forKey: "EmergencyNumbers")!)
                        if let number = information.value(forKey: "EmergencyNumbers") as? NSArray {

 //This is the part I am unsure about

                            if let description = number[0] as? AnyObject {
                               //I know do not know how to access the object's attribute values

                            }
                        }
                    }
                }
                catch {

                }
            }
        }
    }
    task.resume()

}

I have used JSON to parse data from the web. I have utilized a dictionary to access the information and then an array to get the data from the certain key. Within this array are lie some objects. How do I access each of these objects' properties' values?

JSON Example:

{
    Currency = testCurrency;
    DestinationId = "4864cc0a-8";
    DialCode = testDialCode;
    DoesntUseMetricSystem = 0;
    DrinkingAge = 16;
    DriverLicense = 1;
    EmergencyNumbers =     (
                {
            Description = "Emergency Pizza Delivery";
            Id = 1;
            Number = 6969;
        }
    );
    Id = 1;
    IsNorthHemisphere = 1;
    OfficialLanguage =     {
        Id = 1;
        Name = testLanguage;
    };
    PowerGridVoltage = 226;
    PowerSocket = dk;
    Telecoms = nonern;
    Tipping = 2;
    WidelySpokenLanguages =     (
                {
            Id = 2;
            Name = testtLanguage;
        }
    );
    WrongSideOfRoad = 0;
}

Upvotes: 0

Views: 1880

Answers (2)

Ozgur Vatansever
Ozgur Vatansever

Reputation: 52173

I see you are coming from Objective-C world, so first I'd recommend you give up using NSArray, NSDictionary etc. in favor of their Swift counterparts Array and Dictionary:

let task = URLSession.shared.dataTask(with: url!) { data, response, error in
  ...
  let JSON = try? JSONSerialization.jsonObject(with: data!, options: [])
  if let dictionary = JSON as? [String: Any], 
     let emergencyNumbers = dictionary["EmergencyNumbers"] as? [[String: Any]]
  {
    emergencyNumbers.forEach { numbers in
      print(numbers["Description"] as? String)
      print(numbers["Id"] as? Int)
      print(numbers["Number"] as? Int)
    }
  }
}

By the way [String: Any] is just a syntactic sugar for Dictionary<String, Any>. Same applies to arrays as well: [[String: Any]] is for Array<Dictionary<String, Any>>.

Upvotes: 2

vadian
vadian

Reputation: 285140

As always, don't use NSArray / NSDictionary in Swift. You throw away the type information.

The root object is a dictionary ([String:Any]), the value for key EmergencyNumbers is an array ([[String:Any]]). Use a loop to iterate thru the array.

if let root = try JSONSerialization.jsonObject(with: content) as? [String:Any] {
    print(myJson)

    if let emergencyNumbers = root["EmergencyNumbers"] as? [[String:Any]] {
        for emergencyNumber in emergencyNumbers {
            let description = emergencyNumber["Description"] as? String
            let id = emergencyNumber["Id"] as? Int
            let number = emergencyNumber["Number"] as? Int

            print("description", description ?? "n/a")
            print("id", id ?? "n/a")
            print("number", number ?? "n/a")
        }
}

Some other bad habits:

  • .mutableContainers is completely meaningless in Swift. The hilarious thing is, everybody who passes the option .mutableContainers assigns the result to an immutable constant.
  • The unspecified JSON type in Swift 3+ is Any not AnyObject
  • valueForKey, a KVC method, is inappropriate for this purpose, use objectForKey or key subscription. With Swift native types don't use it at all.

Upvotes: 1

Related Questions