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]**
Related
I have data which type [AnyHashable] given in below;
"options": [
{
"index": 0,
"label": "Choice 1"
},
{
"index": 1,
"label": "Choice 2"
},
{
"index": 2,
"label": "Choice 3"
}
],
I want to get all "label" values an the other [AnyHashable] . I cant find the best way. How can I do it?
You can define related models and decode JSON to your model like this:
let jsonString = """
{
"options": [
{
"index": 0,
"label": "Choice 1"
},
{
"index": 1,
"label": "Choice 2"
},
{
"index": 2,
"label": "Choice 3"
}
]
}
"""
struct Option: Codable {
let index: Int
let label: String
}
struct Model: Codable {
let options: [Option]
}
let data = jsonString.data(using: .utf8)!
let decoder = JSONDecoder()
let model = try! decoder.decode(Model.self, from: data)
let labels = model.options.map(\.label)
print(labels)
//["Choice 1", "Choice 2", "Choice 3"]
Thanks for your useful recommendation. I think it is some weirds but works.
func options(for question: [String : Any?]) -> [AnyHashable] {
var qoptions: [String] = []
for val in question["options"] as! [[String:Any]] {
let value = val["label"] as! String
qoptions.append(value)
}
return qoptions as! [AnyHashable]
}
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)
}
})
}
I'm having this bizarre problem in which I cannot do a simple POST request to a REST service I do not control based on GraphQL.
The problem is that no matter what I set in the httpMethod property of the URLRequest class, it always uses GET instead.
I have done a few tests to discard some problems. For example, I set up a header in the Request and I can verify that the header is being sent to the server (verified with Charles Proxy).
This is the code you can paste and run in a Playground:
import PlaygroundSupport
import Foundation
PlaygroundPage.current.needsIndefiniteExecution = true
let url = URL(string: "http://graphql.anilist.co/")!
let internalSession = URLSession(configuration: .default)
var request = URLRequest(url: url)
request.httpMethod = "POST"
let headers = ["content-type": "application/json"]
request.allHTTPHeaderFields = headers
request.httpBody =
"""
{"query":"query (\n\t$season: MediaSeason,\n\t$year: Int,\n\t$format: MediaFormat,\n\t$excludeFormat: MediaFormat,\n\t$status: MediaStatus,\n\t$minEpisodes: Int,\n\t$page: Int,\n){\n\tPage(page: $page) {\n\t\tpageInfo {\n\t\t\thasNextPage\n\t\t\ttotal\n\t\t}\n\t\tmedia(\n\t\t\tseason: $season\n\t\t\tseasonYear: $year\n\t\t\tformat: $format,\n\t\t\tformat_not: $excludeFormat,\n\t\t\tstatus: $status,\n\t\t\tepisodes_greater: $minEpisodes,\n\t\t\tisAdult: false,\n\t\t\ttype: ANIME,\n\t\t\tsort: TITLE_ROMAJI,\n\t\t) {\n\t\t\t\nid\nidMal\ntitle {\n\tromaji\n\tnative\n\tenglish\n}\nstartDate {\n\tyear\n\tmonth\n\tday\n}\nendDate {\n\tyear\n\tmonth\n\tday\n}\nstatus\nseason\nformat\ngenres\nsynonyms\nduration\npopularity\nepisodes\nsource(version: 2)\ncountryOfOrigin\nhashtag\naverageScore\nsiteUrl\ndescription\nbannerImage\ncoverImage {\n\textraLarge\n\tcolor\n}\ntrailer {\n\tid\n\tsite\n\tthumbnail\n}\nexternalLinks {\n\tsite\n\turl\n}\nrankings {\n\trank\n\ttype\n\tseason\n\tallTime\n}\nstudios(isMain: true) {\n\tnodes {\n\t\tid\n\t\tname\n\t\tsiteUrl\n\t}\n}\nrelations {\n\tedges {\n\t\trelationType(version: 2)\n\t\tnode {\n\t\t\tid\n\t\t\ttitle {\n\t\t\t\tromaji\n\t\t\t\tnative\n\t\t\t\tenglish\n\t\t\t}\n\t\t\tsiteUrl\n\t\t}\n\t}\n}\n\nairingSchedule(\n\tnotYetAired: true\n\tperPage: 2\n) {\n\tnodes {\n\t\tepisode\n\t\tairingAt\n\t}\n}\n\n\t\t}\n\t}\n}","variables":{"season": WINTER,"year": 2019,"page": 1, "perPage": 100}}
""".data(using: .utf8)
print("THE REQUEST \(String(describing: request.httpMethod))")
let task = internalSession.dataTask(with: request, completionHandler: { (data, response, error) in
if let e = error {
print("ERROR: \(e)")
} else if let response = response as? HTTPURLResponse {
print("THE RESPONSE: \(response)")
let json = try! JSONSerialization.jsonObject(with: data!, options: [])
print(json)
}
})
task.resume()
(Please ignore all the forced unwrap optionals and forced try!, this is test code).
Expected Result
I expect the web service to return a JSON similar to this (simplified):
{
"data": {
"Page": {
"pageInfo": {
"hasNextPage": true,
"total": 81
},
"media": [
{
"id": 102882,
"idMal": 37956,
"title": {
"romaji": "3D Kanojo: Real Girl 2",
"native": "3D彼女 リアルガール 2",
"english": "Real Girl 2"
},
"startDate": {
"year": 2019,
"month": 1,
"day": 9
},
"endDate": {
"year": null,
"month": null,
"day": null
},
"status": "RELEASING",
"season": "WINTER",
"format": "TV",
"genres": [
"Romance",
"Slice of Life",
"Comedy"
],
"synonyms": [],
"duration": 23,
"popularity": 3298,
"episodes": 12,
"source": "MANGA",
"countryOfOrigin": "JP",
"hashtag": "#3D彼女リアルガール #3D彼女",
"averageScore": 61,
"siteUrl": "https://anilist.co/anime/102882",
"description": "The second season of <i>3D Kanojo</i>.",
"bannerImage": null,
"coverImage": {
"extraLarge": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/large/nx102882-lKp3ExWNzoE6.jpg",
"color": "#e4bb93"
},
"trailer": {
"id": "x6yokzp",
"site": "dailymotion",
"thumbnail": "https://www.dailymotion.com/thumbnail/video/x6yokzp"
},
"externalLinks": [
{
"site": "Official Site",
"url": "http://www.3dkanojo-anime.com/"
},
{
"site": "Twitter",
"url": "https://twitter.com/3Dkanojo_anime"
}
],
"rankings": [
{
"rank": 16,
"type": "RATED",
"season": null,
"allTime": false
},
{
"rank": 19,
"type": "POPULAR",
"season": null,
"allTime": false
},
{
"rank": 16,
"type": "RATED",
"season": "WINTER",
"allTime": false
},
{
"rank": 15,
"type": "POPULAR",
"season": "WINTER",
"allTime": false
}
],
"studios": {
"nodes": [
{
"id": 346,
"name": "Hoods Entertainment",
"siteUrl": "https://anilist.co/studio/346"
}
]
},
"relations": {
"edges": [
{
"relationType": "PREQUEL",
"node": {
"id": 100526,
"title": {
"romaji": "3D Kanojo: Real Girl",
"native": "3D彼女 リアルガール",
"english": "Real Girl"
},
"siteUrl": "https://anilist.co/anime/100526"
}
},
{
"relationType": "SOURCE",
"node": {
"id": 80767,
"title": {
"romaji": "3D Kanojo: Real Girl",
"native": "3D彼女 〈リアルガール〉",
"english": "Real Girl"
},
"siteUrl": "https://anilist.co/manga/80767"
}
}
]
},
"airingSchedule": {
"nodes": [
{
"episode": 7,
"airingAt": 1550595540
},
{
"episode": 8,
"airingAt": 1551200340
}
]
}
}
]
}
}
}
Obtained Result
Instead, I get this:
{
"data": null,
"errors": [
{
"message": "Not Found.",
"hint": "Use POST request to access graphql subdomain.",
"status": 404
}
]
}
The service complains that the request is a GET request and should be POST, and I am explicitly telling URLRequest to use POST instead. If you look at the request in Charles or another proxy, you will indeed see that the request is being done as a GET request, and the httpBody property is being discarded. If you edit the headers and add another header, like so:
let headers = ["content-type": "application/json", "foo": "bar"]
You will see in your proxy that the header is being properly sent.
The only conclusion I can arrive is that there is an internal problem with URLSessionDataTask that forces to do GET requests only. I tried changing it to to a download task, but the same problem is happening. So there must be a problem with my code, but I cannot find it.
EDIT:
Per request, this is the request Postman uses. I have exported the request to CURL to make it easily importable.
curl -X POST \
https://graphql.anilist.co/ \
-H 'Content-Type: application/json' \
-H 'Postman-Token: 49d7e55e-35c2-4a3c-82f0-4eccb1250fc0' \
-H 'cache-control: no-cache' \
-d '{"query":"query (\n\t$season: MediaSeason,\n\t$year: Int,\n\t$format: MediaFormat,\n\t$excludeFormat: MediaFormat,\n\t$status: MediaStatus,\n\t$minEpisodes: Int,\n\t$page: Int,\n){\n\tPage(page: $page) {\n\t\tpageInfo {\n\t\t\thasNextPage\n\t\t\ttotal\n\t\t}\n\t\tmedia(\n\t\t\tseason: $season\n\t\t\tseasonYear: $year\n\t\t\tformat: $format,\n\t\t\tformat_not: $excludeFormat,\n\t\t\tstatus: $status,\n\t\t\tepisodes_greater: $minEpisodes,\n\t\t\tisAdult: false,\n\t\t\ttype: ANIME,\n\t\t\tsort: TITLE_ROMAJI,\n\t\t) {\n\t\t\t\nid\nidMal\ntitle {\n\tromaji\n\tnative\n\tenglish\n}\nstartDate {\n\tyear\n\tmonth\n\tday\n}\nendDate {\n\tyear\n\tmonth\n\tday\n}\nstatus\nseason\nformat\ngenres\nsynonyms\nduration\npopularity\nepisodes\nsource(version: 2)\ncountryOfOrigin\nhashtag\naverageScore\nsiteUrl\ndescription\nbannerImage\ncoverImage {\n\textraLarge\n\tcolor\n}\ntrailer {\n\tid\n\tsite\n\tthumbnail\n}\nexternalLinks {\n\tsite\n\turl\n}\nrankings {\n\trank\n\ttype\n\tseason\n\tallTime\n}\nstudios(isMain: true) {\n\tnodes {\n\t\tid\n\t\tname\n\t\tsiteUrl\n\t}\n}\nrelations {\n\tedges {\n\t\trelationType(version: 2)\n\t\tnode {\n\t\t\tid\n\t\t\ttitle {\n\t\t\t\tromaji\n\t\t\t\tnative\n\t\t\t\tenglish\n\t\t\t}\n\t\t\tsiteUrl\n\t\t}\n\t}\n}\n\nairingSchedule(\n\tnotYetAired: true\n\tperPage: 2\n) {\n\tnodes {\n\t\tepisode\n\t\tairingAt\n\t}\n}\n\n\t\t}\n\t}\n}","variables":{"year":2019,"season":"WINTER","page":1, "limit": 12}}'
Only difference I am seeing here is http:// in your Playground and https:// in your Postman.
So just replace http:// with https:// in your Playground.
I'm learning swift and objective-c. I want to extract the "show_name" in my Json for all shows.
This is my json :
{
"data": {
"12 Monkeys": {
"air_by_date": 0,
"anime": 0,
"cache": {
"banner": 1,
"poster": 1
},
"indexerid": 272644,
"language": "en",
"network": "Syfy",
"next_ep_airdate": "",
"paused": 0,
"quality": "SD",
"show_name": "12 Monkeys",
"sports": 0,
"status": "Continuing",
"subtitles": 1,
"tvdbid": 272644
},
"2 Broke Girls": {
"air_by_date": 0,
"anime": 0,
"cache": {
"banner": 1,
"poster": 1
},
"indexerid": 248741,
"language": "en",
"network": "CBS",
"next_ep_airdate": "2016-10-10",
"paused": 0,
"quality": "SD",
"show_name": "2 Broke Girls",
"sports": 0,
"status": "Continuing",
"subtitles": 0,
"tvdbid": 248741
},
"American Horror Story": {
"air_by_date": 0,
"anime": 0,
"cache": {
"banner": 1,
"poster": 1
},
"indexerid": 250487,
"language": "en",
"network": "FX (US)",
"next_ep_airdate": "2016-09-14",
"paused": 0,
"quality": "SD",
"show_name": "American Horror Story",
"sports": 0,
"status": "Continuing",
"subtitles": 0,
"tvdbid": 250487
},
This is my code and I use swiftyJson :
class ViewController: UIViewController {
let baseURL = "http://xxx.xxx.xxx.xxx:8083/api/api/?cmd=shows&sort=name&paused=0"
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
getJSON()
}
func getJSON(){
let url = NSURL(string: baseURL)
let request = NSURLRequest(URL: url!)
let session = NSURLSession(configuration: NSURLSessionConfiguration.defaultSessionConfiguration())
let task = session.dataTaskWithRequest(request)
{ (data, response, error) -> Void in
if error == nil {
let swiftyJSON = JSON(data: data!)
print(swiftyJSON)
let title = swiftyJSON["data"]["Sense8"]["show_name"]
print(title)
}else {
print("there was an error")
}
}
task.resume()
}
}
Your swiftyJSON is an array of JSON, (i.e. [JSON]), therefore you are not able to access it by subscript.
You can parse it as follow :
if let dataArray = swiftyJSON.array{
for json in dataArray {
// data information
let showName = json["show_name"].stringValue
let status = json["status"].stringValue
let subtitles = json["subtitles"].stringValue
print(showName)
print(status)
print(subtitles)
}
}
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.