Convert NSData to an Array of JSON objects - json

I am accessing a HTTP GET method in my swift code. this method is returning an NSData variable. This data is essentially just an array of json objects, like so:
[{"author": "meowmeow", "platform": "Google"}, {"author": "adasd", "platform": "Dropbox"}
and is stored in the variable data.
I want to cast this NSData variable into an array of json objects I can easily access but just can't figure out how to do this with swifty json.
I have tried the following:
let jsonString = NSString(data: data! as! Data, encoding: String.Encoding.utf8.rawValue)
But when I do this after:
var jj = JSON.init(parseJson: jsonString!)
for j in jj {
print(j)
print("------")
}
Nothing is printed, implying the JSON.init method is not succesfully parsing the string and returning an Array that can be looped through. How can I cast the NSData into an array of JSON objects i can access like:
print(jj[0]["author"])

From SwiftyJSON GitHub page
let json = JSON(data: data) //use this method
for dict in json {
//do the stuff
}

Related

Swift JSON parsing with no particular structure

I have a JSON object of this type, very pratical do loop (for each key => value)
It's like JSON of JSON
But I'm not able to decode it in Swift.
I'm trying to know if this type of data is decodable in Swift.
If it would be easy for you, could you please help to decode it? In an array for example.
{"1":{"1":"some text"},"2":{"1":"some text","2":"some text","3":"some text","4":"some text"},"3":{"1":" some text","2":"some text","3":"some text"},"4":{"1":"some text","2":"some text"},"5":{"1":"some text"},"6":{"1":"some text","2":"some text","3":"some text"}}
let jsonDict = json_text
let jsonDictData = jsonDict.data(using: .utf8)!
let object = try? JSONSerialization.jsonObject(
with: jsonDictData,
options: []
)
// Cast to a Swift Dictionary
let dict = object as? [AnyHashable:Any]
// Cast to an NSDictionary
let nsDict = object as? NSDictionary
print(nsDict)
it returns nil
Finally, I parse it by myself.
With .components(separatedBy: "},")
and .components(separatedBy: "\",\"")
and sweeping some characters with .replacingOccurrences(of: pattern, with: "")
pattern id for example pattern = "\"1\":\""

Alamofire in Swift: converting response data in usable JSON dictionary

I would like to handle a JSON string that is returned as data from a HTTP call made using Alamofire.
This question uses SwiftyJSON.
However I wanted to go a little bit "lower level" and understand how to convert the response object into a dictionary.
Reasoning is that it feels that a dictionary may be a simple / easy way to access to the JSON values in the response (rather than having to go through the process of converting the response to a JSON object).
This is under the assumption that JSON objects and dictionaries are the same thing (are they?).
Here is the sample function that I wrote:
func question() -> Void{
let response : DataRequest = Alamofire.request("http://aapiurl", parameters: nil)
// Working with JSON Apple developer guide:
// https://developer.apple.com/swift/blog/?id=37
response.responseJSON { response in
if let JSON = response.result.value
{
print("JSON: \(JSON)") // Works!
let data = JSON as! NSMutableDictionary
// Casting fails
// Could not cast value of type '__NSCFArray' (0x19f952150) to 'NSMutableDictionary' (0x19f9523f8).
print("Data: \(data)")
}
}
}
EDIT:
The JSON object seems to be of type Any and does not have any of the methods that are suggested in the answers below.
I have tried to convert it to a Dictionary and got the error below:
A JSON object IS a Dictionary (or possibly an Array at top level).
Note that you should not be using NSMutableDictionary or NSDictionary (or NSArray or NSMutableArray) in Swift.
Also, JSON objects are not working objects. JSON is a way to move data around. It is not to be used as a data source.
If you want to edit the information you get from JSON then you should construct proper data objects from that JSON and work with them.
If you then need to send JSON from this new data then you take your data objects and convert them back to dictionaries and arrays (i.e. JSON objects) and send that data.
Alamofire has the result value of type Any because it usually would be an array or a dictionary. In Swift you normally shouldn't use NS* classes, but rather native swift types such as Array and Dictionary.
You can (should) use optionals to look into the returned JSON object:
if let array = response.result.value as? [Any] {
print("Got an array with \(array.count) objects")
}
else if let dictionary = response.result.value as? [AnyHashable: Any] {
print("Got a dictionary: \(dictionary)")
}
...
Depending on what you expect from your backend, you can treat each of the cases as a success or a failure.
Alamofire.request(myUrl)
.responseJSON {
response in
if let dict = response.result.value as? [String : Any] {
debugPrint(dict)
wishLists.removeAll() //[[String:Any]]
let lists = dict["wishlists"] as! [String: Any]
debugPrint(lists)
for (key, value) in lists {
var list = value as! [String: Any]
wishLists.append(list)
}
debugPrint(wishLists)
self.tableView.reloadData()
}
}

Iterate over AnyObject. Error: Type 'AnyObject' does not conform to protocol 'SequenceType'

I'm using Alamofire to get a data from a JSON file. Example of the output:
[{"image_name":"vacation"},{"image_name":"graduation"}]
I have a problem when I try to access the information from the JSON output.
Alamofire.request(.GET, url).responseJSON { (response) -> Void in
if let JSON = response.result.value {
for json in JSON{
print(json)
}
}
The problem I have is that my JSON output is an AnyObject and I cannt iterate over an AnyObject. If I do the following:
print(JSON[0]["image_name"])
Then I can see the output correctly. How can I iterate over an AnyObject?
You may need to explicitly state the type of JSON as an array of dictionaries:
if let JSON = response.result.value as [[String : AnyObject]] {
// ...
}

Convert JSON output to an array with SwiftyJSON

I have this subJSON["guestpics"] as JSON data from SwiftyJSON.
When I print(subJSON["guestpics"]) I have this:
[
"/images\/profile_pic\/1.jpg",
"/images\/profile_pic\/2.jpg",
"/images\/profile_pic\/3.jpg"
]
How can I convert this to an array ?
for (_, subJSON): (String, JSON) in json[0]["data"] {
print(subJSON["guestpics"])
}
SwiftyJSON has already parsed your JSON data and prepared typed objects.
If the key subJSON["guestpics"] contains an array, then use SwiftyJSON's optional getter .array to get it:
if let guestPicsArray = subJSON["guestpics"].array {
// here "guestPicsArray" is your array
}
Why not directly storing the value of the key in the array? as it look like array
Does it show any error/crash when you are trying to store ?
if let arrGuest = subJSON["guestpics"] as? Array<String> {
}
Or if you are more familiar with Objective-c
if let arrGuest = arr as? NSArray {
}
you can get the array in the arrGuest object

Alamofire response contain text before JSON content use it with SwiftyJSON

I'm requesting a JSON object with Alamofire and accessing it with SwiftyJSON.
The response of my request is this :
// JSON webservice ...
[
{
"message":"Please connect"
}
]
As you can see I need to remove the string "// JSON webservice ..." because it is actually not a valid JSON object.
Note that I'm using the .responseString otherwise I could not remove the string part.
So in order to remove the string I'm doing :
let jsonString = data?.stringByReplacingOccurrencesOfString("// JSON webservice ...", withString: "", options: NSStringCompareOptions.LiteralSearch, range: nil)
Now I'm with my String I can do :
var json = SwiftyJSON.JSON(jsonString!)
and I can print the json :
println(json)
BUT whatever I print a value
println(json[0]["message"].string)
is nil.
I finally found myself a solution :
We get our string (data) from the .responseString method
We remove the part that cause the fail of the serialization of the JSON object
We convert our string to NSData and try to serialize our JSON object :
let data = jsonString?.dataUsingEncoding(NSUTF8StringEncoding)
let jsonData = NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.MutableContainers, error: nil) as NSArray?
Now it should be fine and everything is working when trying to print a value of the JSON object
var json = SwiftyJSON.JSON(jsonData!)
println(json[0]["message"])
It prints the right value.