3

I have an issue with loading JSON results within swift (php connection).

I can retrieve JSON data but it will not let me assign it to a variable.

it always assigns the results as Optional.

The JSON Data:

{
"country": [{
    "id": 1,
    "name": "Australia",
    "code": 61
}, {
    "id": 2,
    "name": "New Zealand",
    "code": 64
}]
}

The xCode Output:

 ["country": <__NSArrayI 0x60000002da20>(
 {
     code = 61;
     id = 1;
     name = Australia;
 },
 {
     code = 64;
     id = 2;
     name = "New Zealand";
 }
 )
 ]
 Country Name: Optional(Australia)
 Country Name: Optional(New Zealand)

The .swift file:

//function did_load
override func viewDidLoad() {
    super.viewDidLoad()

    //created RequestURL
    let requestURL = URL(string: get_codes)

    //creating NSMutable
    let request = NSMutableURLRequest(url: requestURL!)

    //setting the method to GET
    request.httpMethod = "GET"

    //create a task to get results
    let task = URLSession.shared.dataTask(with: request as URLRequest) {
        data, response, error in

        if error != nil{
            print("error is \(String(describing: error))")
            return;
        }

        //lets parse the response
        do {
            let json = try JSONSerialization.jsonObject(with: data!, options: .allowFragments) as! [String: Any]
            print(json)
            if let countries = json["country"] as? [[String: AnyObject]] {
                for country in countries {
                    print("Country Name: \(String(describing: country["name"]))")
                    print("Country Code: \(String(describing: country["code"]))")
                    if let couname = country["name"] as? [AnyObject] {
                        print(couname)
                    }

                    if let coucode = country["code"] as? [AnyObject] {
                        print(coucode)
                    }
                }
            }
        } catch {
            print("Error Serializing JSON: \(error)")
        }
    }
    //executing the task
    task.resume()
}
Rajamohan S
  • 7,229
  • 5
  • 36
  • 54
BarryWhite
  • 37
  • 6
  • Dictionary subscripting returns an optional, see for example https://stackoverflow.com/questions/25979969/println-dictionary-has-optional (or the Swift language reference). `country["name"] as? [AnyObject]` makes no sense because the value is a string, not an array. – Martin R Jul 07 '17 at 09:16
  • 1
    Note that `String(describing:)` is almost *never* what you want and hides the actual type problem. – Martin R Jul 07 '17 at 09:17
  • Recommended reading: https://developer.apple.com/swift/blog/?id=37 and https://stackoverflow.com/questions/39423367/correctly-parsing-json-in-swift-3. – Martin R Jul 07 '17 at 09:18
  • @RAJAMOHAN-S: The backticks are for `code`, not for general emphasis. There is no reason to format "JSON" as `JSON` or "variable" as `variable`. – Martin R Jul 07 '17 at 09:40
  • @MartinR , okay thank you bro :) i noted that. – Rajamohan S Jul 07 '17 at 09:41

1 Answers1

3

You need to unwrap the optional before you try to use it via string interpolation. The safest way to do that is via optional binding:

Please use below code, which will work for you.

  if let countries = json["country"] as? [[String: AnyObject]] {
            for country in countries {
                print("Country Name: \(country["name"] as! String)")
                print("Country Code: \(country["code"] as! String)")
                if let couname = country["name"] as? String {
                    print(couname)
                }

                if let coucode = country["code"] as? Int {
                    print(coucode)
                }
            }
        }
Aman.Samghani
  • 2,151
  • 3
  • 12
  • 27