Loop through JSON response from Alamofire - ios

I am using xcode 7.2 and swift 2.1.1. using Alamofire for server communication. I have a tableview that display's dynamic data.Data includes username , useremail , profilePicture etc. I Tried to implement this code from stackoverflow. But I am getting a warning message says Cast from 'JSON' to unrelated type '[Dictionary]' always fails My json response is
{
"JsonRequestBehavior" : 1,
"MaxJsonLength" : null,
"ContentType" : null,
"Data" : {
"_id" : "5658444778a7531f4c79c23d",
"Photo" : "",
"AllowSharing" : "YES",
"MemberCount" : 5,
"Users" : [
{
"_id" : "5658443478a7531f4c79c23c",
"Photo" : "",
"MembershipDate" : "0001-01-01T00:00:00",
"MiddleName" : null,
"FirstName" : "Gohan",
"LastName" : null,
"Email" : "gohan#gmail.com"
},
{
"_id" : "566ea5f1dfead62350cf0fad",
"Photo" : "",
"MembershipDate" : "0001-01-01T00:00:00",
"MiddleName" : null,
"FirstName" : null,
"LastName" : null,
"Email" : "sachin#gmail.com"
}
],
"MembershipDate" : "2015-12-14T12:03:12.819Z",
"CreatedBy" : "5658443478a7531f4c79c23c"
},
"ContentEncoding" : null,
"RecursionLimit" : null
}
How can I loop through Users in JSON response ?
EDIT as per JohnyKutty's answer I tried the same code in my Project. The code for the same is
Alamofire.request(.GET,App.AppHomeURL() + "Load_Group", parameters: ["groupid":"\(groupId)"]).responseJSON
{
response in
print("\(response.data)")
switch response.result
{
case .Success(let _data):
let jsonData = JSON(_data)
print("Admin Response : \(jsonData)")
do
{
let json = try NSJSONSerialization.JSONObjectWithData(_data as! NSData, options: .AllowFragments) as! NSDictionary
if let DataObject = json["Data"] as? NSDictionary
{
if let users = DataObject["Users"] as? [NSDictionary]
{
for user in users
{
print("User id : \(user["_id"])")
}
}
}
}
catch let error as NSError
{
print(error.localizedDescription)
}
in this line let json = try NSJSONSerialization.JSONObjectWithData(_data as! NSData, options: .AllowFragments) as! NSDictionary
At first I used "_data" and then Xcode suggested a change and it changed from _data to _data as! NSData.

Your son structure is like following
JSON(Dictionary) -> Data(Dictionary) -> Users(Array of Dictionaries). So first you should pick the Users array from raw json then iterate through it.
Since alamofire is already serializing your response, No need to use JSONSerializer again, I am updating my answer.
UPDATE
Try this code inside the case
if let DataObject = _data["Data"] as? NSDictionary {
if let Users = DataObject["Users"] as? [NSDictionary] {
for user in Users {
print(user["_id"],user["MembershipDate"],user["FirstName"],user["Email"], separator: " ", terminator: "\n")
}
}
}
Full code:
Alamofire.request(.GET,App.AppHomeURL() + "Load_Group", parameters: ["groupid":"\(groupId)"]) .responseJSON { response in
switch response.result {
case .Success(let _data):
print(_data)
if let DataObject = _data["Data"] as? NSDictionary {
if let Users = DataObject["Users"] as? [NSDictionary] {
for user in Users {
print(user["_id"],user["MembershipDate"],user["FirstName"],user["Email"], separator: " ", terminator: "\n")
}
}
}
default:
break;
}
}

Related

Parse alamofire response into JSON return nil

I'm trying to parse data from alamofire response. If i print all response it works good, but if i want to print specific parametr form JSON, for example "firstName" it is returning nil.
AF.request("http://localhost:5000/api/users").responseJSON(completionHandler: { (res) in
switch res.result {
case let .success(value):
let xjson : JSON = JSON(res.value)
print(xjson["firstName"].string)
case let .failure(error):
print(error)
}
})
No errors in console
Code below
AF.request("http://localhost:5000/api/users").responseJSON(completionHandler: { (res) in
switch res.result {
case let .success(value):
let xjson : JSON = JSON(res.value)
print(xjson)
print(xjson["firstName"].string)
case let .failure(error):
print(error)
}
})
returns
[
{
"dateOfBirth" : "1998-11-18T00:00:00.000Z",
"_id" : "5f6a29ed16444afd36e9fe15",
"email" : "sdasd#mail.com",
"__v" : 0,
"firstName" : "adam",
"lastName" : "kowalski",
"accountCreateDate" : "2020-09-22T16:44:29.692Z",
"userPassword" : "12345",
"userLogin" : "loginakowalski"
}
]
nil
This xjson is an Array of JSON(looks User) objects. So you need to access the array elements as below,
let xjson : JSON = JSON(res.value)
if let firstUser = xjson.array?.first {
print(firstUser["firstName"] as? String)
}
You can also put your JSON response here and get the required data types and decoding code for free.
Thanks to everyone for your help. Below is the code that returns the correct value:
AF.request("http://localhost:5000/api/users").responseJSON(completionHandler: { (res) in
switch res.result {
case let .success(value):
let xjson : JSON = JSON(res.value)
if let firstUser = xjson.array?.first {
print(firstUser["firstName"].string!)
}
case let .failure(error):
print(error)
}
})

Parsing json string crashes

I'm trying to parse a json string:
if let jsonStr = asd.value(forKey: "orderData") as? String {
print(jsonStr)
let data = jsonStr.data(using: String.Encoding.utf8, allowLossyConversion: false)!
do {
let json = try JSONSerialization.jsonObject(with: data, options: []) as! [String: AnyObject] // CRASHES HERE
if let names = json["product_name"] as? [String] {
print(names)
}
} catch let error as NSError {
print("Failed to load: \(error.localizedDescription)")
}
}
But at the line let json = try JSONSeri... it crashes saying Could not cast value of type '__NSArrayI' to 'NSDictionary'.
Also tried changing this as! [String: AnyObject] to as! [[String: AnyObject]]. But it still doesn't work.
This is my json string structure:
[
{
"product_id" : "1",
"category_json" : {
"category_id" : "1",
"category_name" : "nvm"
},
"selling_price" : "200",
"product_name" : "nvm",
},
{
"product_id" : "2",
"category_json" : {
"category_id" : "2",
"category_name" : "cas"
},
"selling_price" : "800",
"product_name" : "cas",
}
]
You should not be force casting with ! unless you are 100% sure that it will succeed.
I would suggest you use the following:
let jsonArray = try? JSONSerialization.jsonObject(with: data, options: .allowFragments) as? [[String: Any]]
This will return you a list of products. If you want a list of the product names than you need to iterate over it and extract the product name of each item. You can do this like so:
let names = jsonArray.map({ $0["product_name"] as? String })
As already mentioned the object is an array, you have to use a for loop to get all items
...
let data = Data(jsonStr.utf8)
do {
if let json = try JSONSerialization.jsonObject(with: data) as? [[String: Any]] {
for item in json {
if let name = item["product_name"] as? String {
print(name)
}
}
}
} catch {
print("Failed to load: \(error.localizedDescription)")
}

Alamofire response for base64 string

I am using Alamofire for networking request. It works fine except one issue.
manager!.request(mutableURLRequest).responseJSON { (response) in
switch response.result {
case .Success:
if let value = response.result.value {
print("JSON: \(value)") //**problem**
}
case .Failure(let error):
print(error)
}
}
The server response format is :
"result" : [
{
"rec_name" : "1.jpg",
"data": {
"base64": "/9j/4AAQSkZ",
"__class__": "bytes"
},
"id" : 9,
"name" : "1.jpg"
},
{
"rec_name" : "2.jpg",
"data": {
"base64": "/9j/4AAQSkZ",
"__class__": "bytes"
},
"id" : 10,
"name" : "2.jpg"
}
],
"id" : 0
}
But I am getting as follow: data(base64 String) is null
"result" : [
{
"rec_name" : "1.jpg",
"data" : null,
"id" : 9,
"name" : "1.jpg"
},
{
"rec_name" : "2.jpg",
"data" : null,
"id" : 10,
"name" : "2.jpg"
}
],
"id" : 0
}
Did I miss something for base64 string?
I think it is working before a month but now I am getting issue.
If I make same request via POSTMAN then it works fine!
Thank you,
I can advice you library SwiftyJSON. This library allows you to parse JSON in Swift easily. Also, there is extension AlamofireSwiftyJSON that unites Alamofire and SwiftyJSON. Here is an example for your request:
if let urlToTest = URL.init(string: "your_URL") {
Alamofire.request(urlToTest,
method: .get,
parameters: nil,
encoding: JSONEncoding.default,
headers: nil)
.responseSwiftyJSON(completionHandler: { (response:DataResponse<JSON>) in
let jsonResult = response.result
if let jsonResultValue = jsonResult.value {
if let resultArray = jsonResultValue["result"].array {
if resultArray.count > 0 {
if let itemData = resultArray[0]["data"].dictionary {
if let itemDataBase64 = itemData["base64"]?.string {
print("Base 64 field value \(itemDataBase64)")
}
}
}
}
}
})
}

Unable to convert this JSON to a string

Please see below the json output
{
"queryLogs" : [
{
"status" : "false",
"query" : {
"contents" : {
"updated" : "",
"id" : 1488199579,
"created" : "",
"patient_count" : 60,
"isactive" : "1",
"status_id" : 0,
"starttime" : "",
"queue_status_id" : 0,
"date_consult" : ""
},
"conditions" : "{}"
},
"tableName" : "consultation",
"type" : "I",
"logId" : {
"id" : "261489537666",
"doctorId" : "100"
}
}
]
}
Need to convert above json into below format
{"queryLogs":[{ "logId":{"id":"76148951287","doctorId":"100"},
"tableName":"queue", "type":"I", "query":"{ \"contents\":{
\"patient_name\":\"queryLog Test\", \"status_id\":1,
\"queue_no\":\"6\", \"isactive\":1, \"id\":\"148956612\",
\"mobile\":\"9567969610\", \"updated\":\"2017-03-15 11:31:26
GMT+05:30\", \"created\":\"2017-03-15 11:31:26 GMT+05:30\",
\"consultation_id\":\"1495085636\"}, \"conditions\":{}
}","status":"false"}]}
First code is what i get when i convert the JSON, But how can i get the JSON like the second code.
i used below code to get the first output.
var f = ["queryLogs":[["status":"false","tableName":"consultation","type":"I","logId":ids,"query":logfile]]] as [String : Any]
let JSON = try? JSONSerialization.data(withJSONObject: f,
options:.prettyPrinted)
if let content = String(data: JSON!, encoding:
String.Encoding.utf8) {
print(content)
}
If you want response like that then you need to also make JSON string for your logfile dictionary also.
What you can do is make one extension of Dictionary, so that no need to write same code of JSONSerialization at every place.
extension Dictionary where Key: ExpressibleByStringLiteral {
var jsonString: String? {
guard let data = try? JSONSerialization.data(withJSONObject: self),
let string = String(data: data, encoding: .utf8) else {
return nil
}
return string
}
}
Now use this extension to get JSON string from your dictionaries.
let id‌​s = ["id" : "261489537666", "doctorId" : "100"]
let logfile = [
"contents" : [
"updated" : "",
"id" : 1488199579,
"created" : "",
"patient_count" : 60,
"isactive" : "1",
"status_id" : 0,
"starttime" : "",
"queue_status_id" : 0,
"date_consult" : ""
],
"conditions" : "{}"
] as [String : Any]
if let queryLogString = logfile.jsonString {
let f = ["queryLogs":[["status":"false","tableName":"consultation","‌​type":"I","logId": id‌​s,"query":queryLogString]]] as [String : Any]
if let content = f.jsonString {
print(content)
}
}
Output:
{"queryLogs":[{"status":"false","query":"{\"contents\":{\"updated\":\"\",\"id\":1488199579,\"created\":\"\",\"patient_count\":60,\"isactive\":\"1\",\"status_id\":0,\"starttime\":\"\",\"queue_status_id\":0,\"date_consult\":\"\"},\"conditions\":\"{}\"}","tableName":"consultation","‌​type":"I","logId":{"id":"261489537666","doctorId":"100"}}]}
once try like,
let data = try? JSONSerialization.data(withJSONObject: dic, options: JSONSerialization.WritingOptions(rawValue: 0))
if let content = String(data: data!, encoding:
String.Encoding.utf8) {
print(content)
}

Alamofire Parameters - NSDictionary is not convertible to [String : AnyObject]

So I am trying to send a json object as parameters with Alamofire. I think I have followed example in their documentation but I get this error with the method call.
#IBAction func saveButton(sender: AnyObject) {
var url = "http://b857aaa4.ngrok.io/recruit"
let parameters = [
"_id" : firstNameTextField.text,
"alt_email" : "",
"forename" : firstNameTextField.text,
"phone" : recruteePhone.text,
"recruiter" : [
"comments" : "",//TODO comments
"date_met" : "",//TODO tdoays date
"email" : "",//TODO recruiter email
"event_name" : ""//TODO event name
],
"surname" : lastNameTextField.text
]
Alamofire.request(.PUT, url, parameters: parameters, encoding: .JSON)
.responseJSON { (req, res, json, error) in
if(error != nil) {
NSLog("Error: \(error)\n")
} else {
var json = JSON(json!);
println("success");
}
}
Declare parameters as
let parameters: [String: AnyObject] = [
and it compiles okay.

Resources