Alamofire response contain text before JSON content use it with SwiftyJSON - json

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.

Related

Convert NSData to an Array of JSON objects

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
}

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]] {
// ...
}

Can't convert string into Json object

I have a json string (text2):
"{\"MsgType\":103,\"Msg\":\"{\"UserObject\":{\"SecretId\":\"dsofgihsdaoifhad=\",\"FirstName\":\"ASDGF\",\"LastName\":\"hdsa\",\"IsFemale\":0,\"PhoneOffice\":\"\",\"ISDCode\":\"\",\"PhonePersonal\":\"91923426989\",\"Designation\":\"\",\"Company\":\"\",\"TagLine\":\"helping
mplemented\",\"FbId\":\"\",\"FbURL\":\"\",\"FbToken\":\"\",\"GplusId\":\"\",\"GplusURL\":\"\",\"GplusToken\":\"\",\"LinkedinId\":\"\",\"LinkedinURL\":\"\",\"LinkedinToken\":\"\",\"Status\":\"\",\"Email\":\"\",\"DisplayPicture\":\"\",\"IsPrivatePhoneOffice\":0,\"IsPrivatePhonePersonal\":1,\"IsPrivateEmail\":0,\"DeviceType\":\"android\",\"NotificationRegistrationID\":\"APA9HZ_RmEy7gfbQtN-QBxXr7dafG394oT9Dg1HpAv7OaWbUsMOsfpMI1a_7Qa2aNkqBOWB3M29djtsRW0fWl4oZSG0bwVv1zEPDBAseZvv1eHfqVj_JUI8tZixX\",\"Location\":\"\",\"Latitude\":18.69943,\"Longitude\":77.12576,\"IsPrivate\":0},\"ConnectionStatus\":3,\"ConnectionType\":1,\"PreviousMeetings\":[{\"SecretId\":\"sadfosdfjasdf=\",\"FriendSecretId\":\"dsofgihsdaoifhad=\",\"MeetingTime\":1447088420440,\"Status\":\"\",\"MeetingNotes\":\"\",\"Location\":\"\",\"Latitude\":28.6994,\"Longitude\":77.1258,\"ContactType\":\"\"},{\"SecretId\":\"sadfosdfjasdf=\",\"FriendSecretId\":\"dsofgihsdaoifhad=\",\"MeetingTime\":1447088335275,\"Status\":\"\",\"MeetingNotes\":\"\",\"Location\":\"\",\"Latitude\":28.6994,\"Longitude\":77.1258,\"ContactType\":\"\"},{\"SecretId\":\"sadfosdfjasdf=\",\"FriendSecretId\":\"dsofgihsdaoifhad=\",\"MeetingTime\":1447088229120,\"Status\":\"\",\"MeetingNotes\":\"\",\"Location\":\"\",\"Latitude\":28.6994,\"Longitude\":77.1258,\"ContactType\":\"\"},{\"SecretId\":\"sadfosdfjasdf=\",\"FriendSecretId\":\"dsofgihsdaoifhad=\",\"MeetingTime\":1447088014838,\"Status\":\"\",\"MeetingNotes\":\"\",\"Location\":\"\",\"Latitude\":28.6994,\"Longitude\":77.1258,\"ContactType\":\"\"},{\"SecretId\":\"sadfosdfjasdf=\",\"FriendSecretId\":\"dsofgihsdaoifhad=\",\"MeetingTime\":1444547028931,\"Status\":\"\",\"MeetingNotes\":\"\",\"Location\":\"\",\"Latitude\":28.6994,\"Longitude\":77.1258,\"ContactType\":\"\"}]}\"}"
It contains a json object having 2 fields: MsgType and Msg. Msg further containes a serialized json object in form of string.
I need to read the value of MsgType as number and Msg as a json object.
I have tried couple of things:
Firstly:
if let dataFromString = text2.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false) {
let json = JSON(data: dataFromString)
print("swiftyjson:\(json)")
}
Source: https://github.com/SwiftyJSON/SwiftyJSON#initialization
Output:
swiftyjson:null
Secondly:
let data = text2.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)!
do {
let jsonSys = try NSJSONSerialization.JSONObjectWithData(data, options: [])
print("jsonSys:\(jsonSys)")
} catch let error as NSError {
print("Failed to load: \(error.localizedDescription)")
}
Output:
Failed to load: The data couldn’t be read because it isn’t in the
correct format.
Your JSON string is not properly escaped.
The "Msg" opening dictionary { shouldn't be preceded by a double quote, it should be like this:
"{\"MsgType\":103,\"Msg\":{\"UserObject\" ...
Same error at the end, it should be:
... 77.1258,\"ContactType\":\"\"}]}}"

How would I parse this type of JSON using SwiftyJSON?

[
{
"ID": 0,
"Name": "PHI"
},
{
"ID": 0,
"Name": "ATL"
}
]
I'm using SwiftyJSON and Alamofire. This is what is being returned. I want to loop through each of these objects now in my code. I'm having trouble getting this information though.
json[0]["Name"].string seems to return nil, and I'm not sure why. The JSON object is definitely getting the JSON, when I print it to the console it looks exactly like above.
I also tried:
var name = json[0].dictionary?["Name"]
Still nil though.
Any ideas?
EDIT
Here's the code I'm using to retrieve the JSON.
Alamofire.request(.GET, "url", parameters: nil, encoding: .JSON, headers: nil).responseJSON
{
(request, response, data, error) in
var json = JSON(data!)
//var name = json[0].dictionary?["Name"]
}
Your JSON is valid (at least this snippet is), and your first method to retrieve the data from SwiftyJSON is correct.
On the other hand, the Alamofire snippet you showed didn't compile for me, I had to change the signature.
Given that in the comments you say that not only json[0]["Name"] is nil but json[0] is also nil, I think you have a problem with how your data is fetched.
I tested this version of the Alamofire method in a sample app and it worked well:
Alamofire.request(.GET, yourURL).responseJSON(options: nil) { (request, response, data, error) in
let json = JSON(data!)
let name = json[0]["Name"].string
println(name)
}
In the screenshot, the URL is my local server, with your JSON copy pasted in "test.json".
This "answer" is an extension of my comment, I needed room to show more info...
I think you might try this.
first convert JSON(data) using swifyJSON
let json = JSON(data!)
then count the array element in data.
let count: Int? = json.array?.count
after that use for loop to reach array element one.
for index in 0...count-1 {
self.idArray.append(json[index]["ID"].stringValue)
self.nameArray.append(json[index]["Name"].stringValue)
}
you will get sorted data in "idArray" and "nameArray". try to print both the array.
You do not have to use index to parse array. You can get single json object from array and use it to access the data:
for (index: String, subJson: JSON) in json {
println("Current Index = \(index)")
if let _id = subJson["ID"].int {
println("ID = \(_id)")
} else {
println("Error ID")
}
if let _name = subJson["Name"].string {
println("Name = \(_name)")
} else {
println("Error Name")
}
}