parse JSON Array from GET request Alamofire Swift 2 - ios

I'm new to Swift, my task is to get data from GET request and present its data on UI. Below is my code:
let credentialData = "\(user):\(password)".dataUsingEncoding(NSUTF8StringEncoding)!
let base64Credentials = credentialData.base64EncodedStringWithOptions([])
let headers = ["Authorization": "Basic \(base64Credentials)"]
Alamofire.request(.GET, myUrl, headers: headers)
.responseJSON{ JSON in
if let jsonResult = JSON as? Array<Dictionary<String, String>> {
let title = jsonResult[0]["title"]
print(title)
}
}
I'm able to get data with request but I don't know how to parse JSON object in some format (probably json array) that can be later used to present in TableView. Please help
Data example:
[
{
"title": "Sony",
"content": "Tech content",
"image": "http://google.com/content/device.jpg?06"
},
{
"title": "Nexus",
"content": "Nexus 6 is a new beginning",
"image": "http://google.com/content/device.jpg?01"
} ]

JSON data can be represented in different forms. It can be encoded as a string or converted into known data types on the platform. The main components of json are arrays, associative arrays (or dictionaries), and values.
The swift struct you are displaying reads as follows.
It's an array. Array content displayed here starts and ends with [] like [1,2,3] would be an array of ints.
The data in the the array a list of dictionaries. dictionary start and ends with {} . like {"key":"value"}
Those dictionaries contain the keys "title","content" and "image".
because you requested responseJSON from alamo file you will be returned a parsed structure and all you need to do read it like you would normal arrays and dictionaries as that is what it is.
You should read this documentation on how to make safe code that uses the above logic.
http://www.raywenderlich.com/82706/working-with-json-in-swift-tutorial

Related

Alamofire 5.5 responseDecodable on JSON array

I am trying to decode an api response that just responds with an array. All the examples I see for using responseDecodable are a dictionary with a data key or something. But when I just pass [Movie].self into as the decoder I get:
failure(Alamofire.AFError.responseSerializationFailed(reason: Alamofire.AFError.ResponseSerializationFailureReason.decodingFailed(error: Swift.DecodingError.keyNotFound(CodingKeys(stringValue: "name", intValue: nil), Swift.DecodingError.Context(codingPath: responseDecodable
I'm assuming I'm not doing this right, looking for some help
GET /request
Response:
[{"id": 1, "name": "test"}]
struct Movie: Codable, Hashable {
let id: Int
let name: String
}
AF.request("http://localhost/request", parameters: parameters)
.responseDecodable(of: [Movie].self) { response in
debugPrint(response)
}
You will need to first assign a variable to accept the JSON data. From there, you can display the result. To illustrate:
AF.request("http://localhost/request", parameters: parameters)
.responseDecodable(of: [Movie].self) { response in
let myresult = try? JSON(data: response.data!)
then print it:
debugPrint(myresult)
If your JSON data is sound, then you should have no problem receiving the data. If your JSON is nested, then, you can drill-down into it:
let myresult = try? JSON(data: response.data!)
let resultArray = myresult!["result"]
and so on.
As for the "KeyNotFound" error ... It's because of what you said ... it's looking for a dictionary key/value pair. That should be resolved once you try the above example. Also, it's good practice to place your "method" in your AF request. :)
According to the error, your JSON didn't return a name value, so check that's it's actually supposed to be that key, or mark the value as optional if it's not always returned. let name: String?

How to correctly send array with objects in JSON Swift iOS

Hello I am beginner and trying to understand how to send an array with objects. Does the server understand what an array is like Int, Strings or Booleans? Do you have to send the array in a string for JSON? What I do not understand?
var productsResult = ""
let encoder = JSONEncoder()
let productObject = ProductUsed(name: "Custom name", reason: "This Reason", apply_way: "Intravenous infusion", dosing: "2x", date_start: "22-02-1999", date_end: "22-03-2003")
do {
let result = try encoder.encode([productObject])
if let resultString = String(data: result, encoding: .utf8) {
print(resultString)
productsResult = resultString
}
} catch {
print(error)
}
json["products_used"] = productsResult
And I sent to server with parameters like this:
parameters: ["pregnancy_week": 0, "body_height": 198, "initials": "John Appleseed", "heavy_effect": false, "sex": "Male", "pregnancy": false, "month_of_birth": 3, "reaction": "No option checked", "additional_info": "Eeee", "products_used": "[{\"date_end\":\"22-03-2003\",\"dosing\":\"2x\",\"date_start\":\"22-02-1999\",\"apply_way\":\"Intravenous infusion\",\"name\":\"Custom name\",\"reason\":\"This Reason\"}]", "description": "Eeee", "result": "Recovery without lasting consequences", "year_of_birth": 1983, "day_of_birth": 11, "issue_date": "15-11-2020", "body_weight": 78]
but printed "resultString" in log and looks good...
[{"date_end":"22-03-2003","dosing":"2x","date_start":"22-02-1999","apply_way":"Intravenous infusion","name":"Custom name","reason":"This Reason"}]
What's wrong in my code and why I have " \ " between words in "products_used" key?
JSON, unlike XML, does not specify the structure and type explicitly. This means that the server must know what JSON data to expect.
In JSON there are a few value types (https://www.w3schools.com/js/js_json_syntax.asp):
a string
a number
an array
a boolean
null
a JSON object (a dictionary with tags like { "first" : "John", "last" : "Doe" }). This allows nesting.
A JSON object is a set of tag-value pairs. The tag and value are separated by : and pairs are separated by ,.
An array is a list of JSON values. So for example [ "hello", world" ] is a JSON array with 2 strings and [ 12, 54 ] is a JSON array with two numbers.
Your parameter list ["pregnancy_week": 0, "body_height": 198, ... is not an array but a dictionary instead. A Swift dictionary is translated to an JSON object, not a JSON array.
The \ you see printed acts as escape character. This escape character is used to allow you to have a " inside the string.
That's just a few things that I hope will help understand things a bit better. Your questions are pretty basic, which is fine and it's great you want to understand things. But instead of us explaining everything here, I think it would be best if you'd read about the structure of JSON and how JSON works in Swift on your own.

How to insert and delete objects in json file swift

So I have this json which has an array of some objects.
[
{
"id": 1,
"title": "First Object"
},
{
"id": 2,
"title": "Second Object"
},
{
"id": 3,
"title": "Third Object"
}
]
I'm parsing the json with the following code,
struct MyModel: Codable {
let id: Int?
let title: String?
}
var myModel = [MyModel]()
func decodeData(url: URL) {
do {
let jsonData = try Data(contentsOf: url)
let decoder = JSONDecoder()
myModel = try decoder.decode([MyModel].self, from: jsonData)
} catch let jsonError {
print("Error serializing json", jsonError)
}
}
Everything works fine when it comes to reading the json. What I can seem to figure out is how to delete and insert object into the same json file.
For example, delete object with "id"=2, or insert a new object after object with "id"=3 or between objects with "id"=1 and "id"=2.
What I was thinking was to read the entire json file into an array. Then modify the data in the array by deleting and appending elements in the array then overwriting the json file with everything in the modified array.
For some reason this approach doesn't seem practical. Might be fine for a small numbers of objects but what happens if/when the number of objects reach a number in the 100+ range.
Am I taking the right approach by reading the contents of the json file into an array then modifying and overwriting the json file with the contents of the modify array or is there a proper way of achieving this?
You can delete any object from Dictionary using this piece of code, convert json to Dictionary.
if let index = values.index(forKey: id) {
values.remove(at: index)
}
and in the same way you can get the index of particular object where you want to insert new object.

How to read data inside JSON object in swift

[
{
"id": "dcf8df3f8ce5963d7fa8",
"title": "MySurvey",
"description": "Guest Survey"
}
]
Above is json data response from api. I've read above json data with SwiftyJSON in my ios project as follow.
let swiftyJsonVar = JSON(responseData.result.value!)
print(swiftyJsonVar["title"])
I can't read and print above json data. Please let me know how to read above json data with SwiftyJSON.
The response is Array not Dictionary, try to access this
let arr = swiftyJsonVar.arrayObject
print(arr[0]["title"])
print(arr[0]["id"])
print(arr[0]["description"])

Send an array as a parameter in a Alamofire POST request

My app is currently using AWS API Gateway and Alamofire to access different lambda functions that act as my backend.
I have the need to send an array as one of the parameters to one of those API end points, for that I am using the following code:
var interests : [String]
interests = globalInterests.map({ (interest) -> String in
return interest.id!
})
// Parameters needed by the API
let parameters: [String: AnyObject] = [
"name" : name,
"lastName" : lastName,
"interests" : interests
]
// Sends POST request to the AWS API
Alamofire.request(.POST, url, parameters: parameters, encoding: .JSON).responseJSON { response in
// Process Response
switch response.result {
case .Success:
print("Sucess")
case .Failure(let error):
print(error)
}
}
But that is not working because of the array is not being recognized by the API, but if I create a "static" array
let interests = ["a", "b", "c"]
Everything works as it is supposed to.
How can I fix this situation given that the array of interests come from another part of the code, how should I declare it or construct it?
A friend managed to accomplish this in Android using an
ArrayList<String>
EDIT:
Printing the parameters array shows me this:
["name":test, "interests": <_TtCs21_SwiftDeferredNSArray 0x7b05ac00>( 103, 651, 42), "lastName": test]
By using NSJSONSerialization to encode JSON, you can build your own NSURLRequest for using it in Alamofire, here's a Swift 3 example:
//creates the request
var request = URLRequest(url: try! "https://api.website.com/request".asURL())
//some header examples
request.httpMethod = "POST"
request.setValue("Bearer ACCESS_TOKEN_HERE",
forHTTPHeaderField: "Authorization")
request.setValue("application/json", forHTTPHeaderField: "Accept")
//parameter array
let values = ["value1", "value2", "value3"]
request.httpBody = try! JSONSerialization.data(withJSONObject: values)
//now just use the request with Alamofire
Alamofire.request(request).responseJSON { response in
switch (response.result) {
case .success:
//success code here
case .failure(let error):
//failure code here
}
}
}
AnyObject can only represent class type. In Swift, Array and Dictionary are struct, instead of the class type in many other languages. The struct cannot be described into AnyObject, and this is why Any comes in. Besides of class, Any can be utilized in all other types too, including struct and enum.
Therefore whenever we type cast array or dictionary to AnyObject _TtCs21_SwiftDeferredNSArray error occurs.So we have to Any instead of AnyObject.
let parameters: [String: Any] = [
"name" : name,
"lastName" : lastName,
"interests" : interests
]
The problem is that you have just declared the array and not initialized it. That makes the interest array as nil even if u try to insert the data. Try writing
var interests = [String]()
instead of
var interests : [String]
let ValueArray = ["userid": name,"password":password]
pass ValueArray [parameters: ValueArray] also verify the encoding accepted by the API.
It turned out to be a problem with duplicated ids in the array. The code behind the API threw an exception that was not being send back as an error.
All the other answers are correct, I tested them after finding the problem and everything worked so I am going to up-vote them.
Thank you very much.

Resources