How to fetch the following data into the tableview using Swift? - swift

First lets see the json data.
[
{
"id": "244",
"name": "PIZZAS",
"image": "",
"coupon": "1",
"icon": "",
"order": "1",
"aname": "",
"options": "2",
"subcategory": [
{
"id": "515",
"name": "MARGARITA",
"description": "Cheese and Tomato",
"image": "",
"icon": "",
"coupon": "1",
"order": "1",
"aname": "",
"options": "2",
"item": [
{
"id": "1749",
"name": "9 Inch Thin & Crispy Margarita",
"description": "",
"price": "3.40",
"coupon": "1",
"image": "",
"options": "2",
"order": "1",
"addon": "495",
"aname": "",
"icon": ""
}]
}]
}]
I have used Alamofire and getting response through this code below:
Alamofire.request(.GET, myUrl, parameters:nil , encoding: .JSON)
.validate()
.responseString { response in
print("Response String: \(response.result.value)")
}
.responseJSON { response in
print("Response JSON: \(response.result.value)")
if let jsonResult = response as? Array<Dictionary<String,String>> {
let Name = jsonResult[0]["name"]
let ID = jsonResult[0]["id"]
let Order = jsonResult[0]["order"]
print("JSON: Name: \(Name)")
print("JSON: ID: \(ID)")
print("JSON: Order: \(Order)")
}
}
But after getting response data I am not able to get any value. Here I want to fetch all data like name,id and subcategory - how to implement this?

You have more than one problem there.
First response is of type Response<Anyobject, NSError>, it's not the parsed object you're looking for, instead you should use response.result.value as you did for the log.
Second even if you tried to cast response.result.value to Array<Dictionary<String,String>> it will not pass because in your json data you have ann inner array subcategory which cannot be casted to Dictionary<String, String>
This code should work for you:
Alamofire.request(.GET, myUrl, parameters:nil , encoding: .JSON)
.validate()
.responseString { response in
print("Response String: \(response.result.value)")
}
.responseJSON { response in
print("Response JSON: \(response.result.value)")
let array = response.result.value as! Array<NSDictionary>
for item in array
{
let Name = item["name"]
let ID = item["id"]
let Order = item["order"]
let Subcategories = item["subcategory"] as! Array<NSDictionary>
for subCategory in Subcategories
{
let subId = subCategory["id"]
}
}
}
And here is the results in the playground:
Cheers.

Related

"Swift" Parse json .. getting response but not true in swift 5

This is input of Api:
{
"key" : "1", // Questionnaire response : key
"answer" : { // Questionnaire response : options value
"0":"19 to 27,10",
"1":"Below 5 years,10",
"2":"Second class upper & above,10",
"3":"Yes,10",
"4":"Below 2 years,10"
}
}
This is func when iam calling Api:
func callEligibility(with model: [VisaEligibility], completion: #escaping(Result<[VisaEligibility], Error>)-> ()) {
guard let url = URL(string: eligibility_url)
else {
return }
let body: [String: Any] = [
"key": model[0].key,
"answer": model[0].answer
]
let finalBody = try? JSONSerialization.data(withJSONObject: body)
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.httpBody = finalBody
request.allHTTPHeaderFields = ["Token":"birdview#v1"]
URLSession.shared.dataTask(with: request){
(data , response, error) in
guard let data = data, error == nil else {
print(error?.localizedDescription ?? "No data")
completion(.failure(error?.localizedDescription as! Error))
return
}
guard let response = response else {
return
}
print(response)
let responseJSON = try? JSONSerialization.jsonObject(with: data, options: [])
if let responseJSON = responseJSON as? [String: Any] {
print(responseJSON)
}
}.resume()
}
This is Model:
struct VisaEligibility: Codable, Hashable {
let key: String
let answer: [String: String]
}
This are answer outputs:
["[\"0\", \"1\", \"2\", \"3\", \"4\", \"5\", \"6\"]": "[\"22 to 29\", \"Bachelor’s degree\", \"Yes\", \"Yes\", \"Yes\", \"3 years or more\", \"Yes\"],[\"20\", \"5\", \"10\", \"0\", \"0\", \"5\", \"5\"]"]
["0", "1", "2", "3", "4", "5", "6"],["22 to 29", "Bachelor’s degree", "Yes", "Yes", "Yes", "3 years or more", "Yes"],["20", "5", "10", "0", "0", "5", "5"]
This are my answer input
Here I am calling Api,
QuestionCount,QuestionName and QuestionPoins are my textfields text
let answerr = ["\(questionCounts)":"\(questionNames),\(questionPoints)"]
let model = [VisaEligibility(key: "45", answer: answerr)]
ApiManager.shared.callEligibility(with: model) { result in
switch result {
case.success(let answ):
print(answ)
self.eligiblity = answ
self.percentLabel.text = answ[0].key
case.failure(let error):
print(error)
}
}
When iam calling api it should calculate my textfieldt text each of text has own point
and it shuold return answer.but it just shows result is 0%
Headers {
"Cache-Control" = (
"no-store, no-cache, must-revalidate"
);
Connection = (
"Keep-Alive"
);
"Content-Type" = (
"text/html; charset=UTF-8"
);
Date = (
"Thu, 08 Sep 2022 13:12:35 GMT"
);
Expires = (
"Thu, 19 Nov 1981 08:52:00 GMT"
);
"Keep-Alive" = (
"timeout=5, max=100"
);
Pragma = (
"no-cache"
);
Server = (
Apache
);
"Transfer-Encoding" = (
Identity
);
} }
["code": 200, "result": 0%]
when iam calling it in postmant it shows me true result.
what should i do?
this is questions api's input which i am calling questions
and after calling questions i have to pass them like dictionary to another api for to get result
{
"code": "200",
"result": [
{
"key": "2",
"questions": [
{
"key": "0",
"question": "How old are you? ",
"options": [
{
"option": "22 to 29",
"point": "20",
"plus": 0
},
{
"option": "30 to 34",
"point": "10",
"plus": 0
},
**problem is in my textfields give's me**
Count["[\"0\", \"1\", \"2\", \"3\", \"4\", \"5\", \"6\"]":Name"[\"22 to 29\", \"Bachelor’s degree\", \"Yes\", \"Yes\", \"Yes\", \"3 years or more\", \"Yes\"],[\"20\", \"5\", \"10\", \"0\", \"0\", \"5\", \"5\"]"]
**Point**["0", "1", "2", "3", "4", "5", "6"],["22 to 29", "Bachelor’s degree", "Yes", "Yes", "Yes", "3 years or more", "Yes"],["20", "5", "10", "0", "0", "5", "5"]
but i need they should be.
**["0":"22 to 29 , 20" ]**
**[TfCount first:TfName first,Tfpoint first]**

Multipart Form Data POST with spesific JSON Requirement

I'm new to Alamofire and now using Alamofire 5. I want to create a POST request with multipart form data, but there's a specific requirement for the JSON body. Here it is:
"item": [
{
"name": "Upload image",
"request": {
"method": "POST",
"header": [],
"body": {
"mode": "formdata",
"formdata": [
{
"key": "files[]",
"type": "file",
"src": []
},
{
"key": "mode",
"value": "public",
"type": "text"
}
]
},
"url": {
"raw": "https://jsonplaceholder.typicode.com/api/image/upload",
"protocol": "https",
"host": [
"jsonplaceholder",
"typicode",
"com"
],
"path": [
"api",
"image",
"upload"
]
}
},
"response": []
},
]
Anyone can help me how to post the data but with multipart form data? Please help.
(It's okay if the POST request is using URLSession)
Whatever I understand from your question and comments, I have created a method from your previous question.
func postImage(images: [UIImage],imgName : [String]) {
var arrFormData = [[String:Any]]()
var imgDataArray: [Data] = []
for image in images {
guard let imgData = image.jpegData(compressionQuality: 0.50) else { return }
imgDataArray.append(imgData)
}
let param1: [String: Any] = [
"key":"files[]",
"type": "file",
"src": imgName
]
let param2: [String: Any] = [
"key": "mode",
"value": "public",
"type": "text"
]
var arrParam = [[String:Any]]()
arrParam.append(param1)
arrParam.append(param2)
arrFormData.append(contentsOf: arrParam)
var param : [String:Any] = [:]
if let theJSONData = try? JSONSerialization.data(
withJSONObject: arrFormData,
options: []) {
let theJSONText = String(data: theJSONData,
encoding: .ascii)
print("JSON string = \(theJSONText!)")
param = ["formData" : theJSONText ?? ""]
}
print(param)
Alamofire.upload(multipartFormData: {
multipartFormData in
for i in 0..<images.count{
if let imageData = images[i].jpegData(compressionQuality: 0.6) {
multipartFormData.append(imageData, withName: "file", fileName: "name.png", mimeType: "image/png")
}
}
for (key, value) in param {
multipartFormData.append((value as AnyObject).data(using: String.Encoding.utf8.rawValue)!, withName: key)
}
}, usingThreshold: 10 * 1024 * 1024,to: apiurl, method: .post, headers: headers, encodingCompletion: { encodingResult in
switch encodingResult {
case .success(let upload, _, _):
upload.responseJSON {
response in
print(response.result)
}
case .failure(let encodingError):
print(encodingError)
}
})
}

How to update value of dictionary in iOS Swift?

var request: [String: Any] = [
"Token": "Token",
"Request": [
"CityID": "CityID",
"Filters": [
"IsRecommendedOnly": "0",
"IsShowRooms": "0"
]
]
]
//
print(request)
Console output:
["Token": "Token", "Request": ["CityID": "CityID", "Filters": ["IsRecommendedOnly": "0", "IsShowRooms": "0"]]]
Here I want to update value of "IsShowRooms" key from value "0" to value "1", I was tried different steps but I am unable to do so, can anyone help me out in this?
You can get the value by typecasting Any to its type and store its value back
if var requestVal = request["Request"] as? [String: Any], var filters = requestVal["Filters"] as? [String: String] {
filters["IsShowRooms"] = "1"
requestVal["Filters"] = filters
request["Request"] = requestVal
}
Output
["Token": "Token", "Request": ["CityID": "CityID", "Filters": ["IsRecommendedOnly": "0", "IsShowRooms": "1"]]]
OR
Instead of storing values in Dictionary create a struct. It will be easier to update its properties
You can do this following way.(Dictionary in swift is treated as value type)
if var reqObj = request["Request"] as? [String: Any] {
if var obj = reqObj["Filters"] as? [String: Any] {
obj["IsShowRooms"] = "1"
reqObj["Filters"] = obj
}
request["Request"] = reqObj
}
print(request)
OUTPUT
["Request": ["CityID": "CityID", "Filters": ["IsShowRooms": "1", "IsRecommendedOnly": "0"]], "Token": "Token"]

SwiftyJSON YouTube API

I am using SwiftyJSON to retrieve data from the youtube api.
I am writing swift 4 code.
I'm trying to print out the description
Here is what I have:
func getFeedVideos() {
Alamofire.request(API_URL, method: .get, parameters: ["part":"snippet", "playlistId":PLAYLIST_ID,"key":API_KEY], encoding: URLEncoding.default, headers: nil).responseJSON { (response) in
if let value = response.result.value {
let json = JSON(value)
print(json["items"]["snippet"]["description"].stringValue)
}
}
}
But no description is being printed out.
Below is the youtube API:
"items" : [
{
"kind": "youtube#playlistItem",
"etag": etag,
"id": string,
"snippet": {
"publishedAt": datetime,
"channelId": string,
"title": string,
"description": string,
"thumbnails": {
(key): {
"url": string,
"width": unsigned integer,
"height": unsigned integer
}
},
"channelTitle": string,
"playlistId": string,
"position": unsigned integer,
"resourceId": {
"kind": string,
"videoId": string,
}
},
}
If you look closely at the first line of the response, you'll notice the following:
"items" : [
The [ indicates items is an array, which means you should try
items[0]["snippet"]["description"].stringValue

restkit, how to access object in response without object mapping

How can I access the original response json data without using object mapping. I have the followingresponse data. it contains a nextSyncToken which used to execute the query and a collection of items (within the items session).
I created a object mapping of the Item object which represent the contents in items. However, I also need the nextSyncToken field. How can I access it without object mapping. Since the syncToken has no relationship with object mapping. How can i deal with this.
{
"kind": "calendar#events",
"nextSyncToken": "COib8eSw78gCEOib8eSw78gCGAU=",
"items": [
{
"id": "_74rk4cpg84o42b9k8or3gb9k74s34b9p8ks34b9m851kac9m64rk4ci36g",
"created": "2010-04-16T11:09:31.000Z",
"updated": "2010-04-16T11:10:27.487Z",
"summary": "iCal test 1",
"start": {
"dateTime": "2010-03-16T21:00:00+08:00"
},
"end": {
"dateTime": "2010-03-16T22:00:00+08:00"
}
},
{
"id": "_752j2h1j6cq4cba68csjeb9k8p33eba1692k4ba284qj8ea688rj2chh6c",
"status": "confirmed",
"created": "2011-10-18T09:36:02.000Z",
"updated": "2011-10-18T09:36:02.000Z",
"summary": "New Event",
"start": {
"dateTime": "2011-10-18T03:45:00+08:00"
},
"end": {
"dateTime": "2011-10-18T08:15:00+08:00"
}
}
]
}
My code of mapping:
let eventMapping = RKEntityMapping(forEntityForName: "SGEvent", inManagedObjectStore: managedObjectStore)
eventMapping.addAttributeMappingsFromDictionary([
"id": "identifier",
"summary": "summary",
"created": "createdAt",
"updated": "updatedAt",
"location": "location",
"description": "notes",
"start.date": "allDayStart",
"end.date": "allDayEnd"
])
let startTimeMapping = RKAttributeMapping(fromKeyPath: "start.dateTime", toKeyPath: "startTime")
startTimeMapping.valueTransformer = self.googleDateTransformer
eventMapping.addPropertyMapping(startTimeMapping)
let endTimeMapping = RKAttributeMapping(fromKeyPath: "end.dateTime", toKeyPath: "endTime")
endTimeMapping.valueTransformer = self.googleDateTransformer
eventMapping.addPropertyMapping(endTimeMapping)
eventMapping.identificationAttributes = ["identifier"]
let responseDescriptor = RKResponseDescriptor(mapping: eventMapping, method: .GET,
pathPattern: "calendars/:calendarId/events", keyPath: "items",
statusCodes: RKStatusCodeIndexSetForClass(RKStatusCodeClass.Successful))
objectManager.addResponseDescriptor(responseDescriptor)
My request operation:
objectManager.getObjectsAtPath("calendars/\(identifier)/events",
parameters: [self.ACCESS_TOKEN: accessToken], success: { (operation, results) -> Void in
callback?(results: nil, error: nil)
}) { (_, error) -> Void in
print(error)
}
Generally you would add other response descriptors with appropriate mappings to deal with this issue.
When using objectManager.getObjectsAtPath you can get the raw data, assuming that you have some other response descriptor which will result in the success block being called, by navigating to the response data in the HTTP operation (which you can then unpack however you see fit):
operation.HTTPRequestOperation.responseData
(or use responseString instead of responseData).
if let dict = try? NSJSONSerialization.JSONObjectWithData(operation.HTTPRequestOperation.responseData, options: .AllowFragments) as? [String: AnyObject],
let nextSyncToken = dict?["nextSyncToken"] as? String{
print(nextSyncToken)//get the nextSyncToken
}