Reputation: 75
i have i code that takes JSON data from web php file, the data goes to data
var using contentOfUrl
then converted to jsonarray
var typed AnyObject using NSJSONSerialization.JSONObjectWithData
.
but the problem is when i want to use it from the jsonarray
var i searched for tow days and i found one but didn't work because his AnyObject var structure is different.
so how can i use it?
Code:
import Foundation
class DBConnectController{
func ViewControllerConnect(DeviceID : Int) -> String{
let data : NSData = NSData(contentsOfURL : NSURL(string: "http://xx.com/xc.php")!)!
var jsonarray : AnyObject
do {
jsonarray = try NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.AllowFragments)
print(jsonarray["2"]) // tried this but didn't work
print(jsonarray["2"].value) // tried this but didn't work
// and tried other
} catch {
print("Error decoding json using NSJSONSerialization.JSONObjectWithData")
}
return "f"
}
}
jsonarray
structure (showed when make a break point before the return
:
Upvotes: 2
Views: 714
Reputation: 437592
The Swift 2 rendition of the answer is as follows:
let task = NSURLSession.sharedSession().dataTaskWithURL(url) { data, response, error in
guard data != nil else {
print("dataTaskWithURL error: \(error)")
return
}
do {
if let jsonarray = try NSJSONSerialization.JSONObjectWithData(data!, options: []) as? [[String: AnyObject]],
let status = jsonarray.first?["status"] as? String {
// use `status` here
print(status)
}
} catch {
print("Error decoding json using NSJSONSerialization.JSONObjectWithData: \(error)")
}
}
task.resume()
This:
Uses asynchronous request rather than synchronous NSData(contentsOfURL:)
... never use synchronous network calls from the main thread of the app;
Guards against network errors (rather than forced unwrapping with !
which would crash if there was some unpreventable network error);
Gracefully unwrap jsonarray
and status
rather than forced unwrapping;
Log the JSON parsing error if any; and
Use .first
with optional chaining rather than [0]
, because the latter can crash if you get empty array and you end up exceeding the bounds of the array.
Upvotes: 0
Reputation: 8718
What you have there is an array of dictionary objects. (BTW I'm on Xcode 6 / Swift 1.2 so you may not need the 'err' parameter there.)
(By the way, your array appears to have only one element, so check: myStructuredData.count
before overrunning it.)
func viewControllerConnect(deviceID: Int) -> String? {
var err: NSError?
var retVal: String?
if let url = NSURL(string: "http://xx.com/xc.php"),
data = NSData(contentsOfURL: url), // BAD You're doing long-running network task in UI thread, address this soon
jsonData: AnyObject = NSJSONSerialization.JSONObjectWithData(data, options: .AllowFragments, error: &err) {
if let myStructuredData = jsonData as? [[String: AnyObject]] { // You have an array of dictionaries there
retVal = myStructuredData[0]["status"] as? String // For example, not sure of your exact needs & conventions
}
else {
println("JSON data had unexpected structure: \(err?.localizedDescription)")
}
}
else {
println("Could not load JSON data")
}
return retVal
}
Upvotes: 2