Send JSON with array of objects as parameter in Alamofire with swift - ios

I am very new with Swift and Alamofire, what I want to accomplish is to send a data structure, like this:
{
"name" : "Test name",
"intention" : "Purpose of practice test",
"id_frequency" : "1",
"member": [
{
"id_member" : "1",
"email" : "member1#gmail.com",
"id_member_type" : 1
},
{
"id_member" : "4",
"email" : "member2#gmail.com",
"id_member_type" : 3
},
{
"id_member" : "7",
"email" : "member3#gmail.com",
"id_member_type" : 3
},
{
"id_member" : "5",
"email" : "member4#gmail.com",
"id_member_type" : 3
},
{
"id_member" : "6",
"email" : "member5#gmail.com",
"id_member_type" : 3
}
]
}
The way I am proceeding to structure the desired json, is as follows:
var membersArray = [AnyObject]()
for i in 0..<members.count {
let json: [String: Any] = [
"id_member": members[i].idMember!,
"email": members[i].email!,
"id_member_type": "\(Int(members[i].idMemberType)!)",
]
membersArray.append(json as AnyObject)
}
let jsonMembers = JSON(membersArray)
let jsonObject: [String: Any] = [
"member" : jsonMembers,
"name": name!,
"intention": intention!,
"id_frequency": frequency!
]
let jsonUpdate = JSON(jsonObject)
With this structured json, lines above (jsonUpdate). I proceed to execute the webService.
WevServices.createRequest(requestInfo: jsonUpdate) { (result) in
print(result)
}
My webservice method, looks like this:
static func createRequest(requestInfo: JSON, completion: #escaping (_ result: String) -> Void){
let url = URL(string: "http://ws.someURL.com/CreateRequest")
let parameters: [String : Any] = ["name" : "\(requestInfo["name"])", "intention" : "\(requestInfo["intention"])", "id_frequency" : "\(requestInfo["id_frequency"])", "member": requestInfo["member"]]
Alamofire.request(url!, method: .post, parameters: parameters, encoding: URLEncoding.httpBody).responseString { response in
print(response)
}
}
I'm get an error from the server that the send data would not be correct.
Note: My application use Lumen as backend.

The best way for doing what you need is :
func JSONToString(json: [String : String]) -> String?{
do {
let mdata = try JSONSerialization.data(withJSONObject: json, options: JSONSerialization.WritingOptions.prettyPrinted) // json to the data
let convertedString = String(data: mdata, encoding: String.Encoding.utf8) // the data will be converted to the string
print("the converted json to string is : \(convertedString!)") // <-- here is ur string
return convertedString!
} catch let myJSONError {
print(myJSONError)
}
return ""
}
and for alamofire request do this :
static func createRequest(requestInfo: [String :String], completion: #escaping (_ result: String) -> Void){
let url = URL(string: "http://ws.someURL.com/CreateRequest")
let parameters: [String : Any] = ["request" : JSONToString(json : requestInfo)!]
Alamofire.request(url!, method: .post, parameters: parameters, encoding: URLEncoding.httpBody).responseString { response in
print(response)
}

Related

Using API in Swift (Postman,Alamofire,SwiftyJson)

I have an admin panel which admin can insert question and gives 3 options of answers to users to choose. The admin is able to insert questions according to different chapters...its like a quiz game..The correct answer is then given an int value so in my collection of 3 buttons, I am able to know which is the correct button user has chosen. But now my problem is, in my Postman:
in my swift code
func getaQuestionaByaChapter(chapterName: String,question: String, answer1: String, answer2 : String, answer3: String, answer: Int, completion: #escaping (JSON?, Error?) -> Void) {
let parameters: [String : Any] = [
"secret_key" : "b3370e1590a2cf2b430e8cf8a8b361bd",
"_action" : "GETQUESTIONBYCHAPTER",
"GETQUESTIONBYCHAPTER" : chapterName,
"question" : question,
"option1" : answer1,
"option2" : answer2,
"option3" : answer3,
"answer" : answer
]
is this a declaration correct?
as for my storyboard:
and after this, i would be doing
button1.setTitle = answer1
questionlabel.text = question
in my swift file for the part where i link my API
import SwiftyJSON
import Alamofire
public class EduappRestClient {
enum ContentType: String {
case json = "application/json"
case jpeg = "image/jpeg"
case formEncoded = "application/x-www-form-urlencoded"
case none = "" //Content type will be empty
}
private static let url: URL = URL(string: "http://192.168.0.127:81/project/Online_Question/API/actiona")! //NSURL depreciated now using URL)
//singleton
static let sharedClient: EduappRestClient = EduappRestClient()
class func request(with url: URL,
method: HTTPMethod = .get,
parameters: Parameters? = nil,
contentType: ContentType = .json,
encoding: ParameterEncoding = JSONEncoding.default,
additionalHeaders: [String: String] = [:],
completion: #escaping(JSON?, Error?) -> Void
) {
//MARK: Configure Headers
var headers: [String: String] = [:]
//if contenttype is specified as none type, leave content-type header field empty
if contentType != .none {
headers["Content-Type"] = contentType.rawValue
}
for (key, value) in additionalHeaders {
headers[key] = value
}
Alamofire.request(url, method: method, parameters: parameters, encoding: encoding, headers: headers).responseJSON(completionHandler: { (response) in
guard response.result.error == nil, let value = response.result.value else {
completion(nil, response.result.error)
return
}
let jsonData = JSON(value)
completion(jsonData, nil)
})
}
//MARK: - Getting questions by chapters
func getaQuestionaByaChapter(chapterName: String,question: String, answer1: String, answer2 : String, answer3: String, answer: Int, completion: #escaping (JSON?, Error?) -> Void) {
let parameters: [String : Any] = [
"secret_key" : "b3370e1590a2cf2b430e8cf8a8b361bd",
"_action" : "GETQUESTIONBYCHAPTER",
"GETQUESTIONBYCHAPTER" : chapterName,
"question" : question,
"option1" : answer1,
"option2" : answer2,
"option3" : answer3,
"answer" : answer
]
let URLString = EduappRestClient.url
EduappRestClient.request(with: URLString, method: .post, parameters: parameters) { (json, error) in
guard error == nil, let json = json else {
completion(nil, error)
return
}
let result: JSON = json[1]
//result will print
//"question": [
// {
//"question": "10+10",
//"chapter_name": "Chapter 2",
//"option1": "10",
//"option2": "20",
//"option3": "30",
//"answer": "20"
//}
//]
completion(result, nil)
}
}}
it will show my data accordingly??
After API response, you have to use.
class QuestionModel: Codable {
let questions: [Details]
}
class Details: Codable {
let question: String?
let chapter_name: String?
let option1: Int?
let option2: Int?
let option3: Int?
}
And after this, you have to parse the response in the model data:
func getaQuestionaByaChapter(chapterName: String, completion: #escaping (QuestionModel?, Error?) -> Void) {
let parameters: [String : Any] = [
"secret_key" : "b3370e1590a2cf2b430e8cf8a8b361bd",
"_action" : "GETQUESTIONBYCHAPTER",
"GETQUESTIONBYCHAPTER" : chapterName
]
let URLString = EduappRestClient.url
EduappRestClient.request(with: URLString, method: .post, parameters: parameters) { (json, error) in
guard error == nil, let json = json else {
completion(nil, error)
return
}
do {
let jsonData = try JSONSerialization.data(withJSONObject: json, options: JSONSerialization.WritingOptions.prettyPrinted)
let result = try JSONDecoder().decode(QuestionModel.self, from: jsonData)
completion(result, nil)
} catch let message {
print("JSON serialization error:" + "\(message)")
}
}
}}
Then in QuizViewController: You have to set the data:
EduappRestClient.sharedClient.getaQuestionaByaChapter(chapterName: "Chapter 2", completion: { (response, error) in
//json is the result from rest client
let firstQuestion = response?.questions.first
self.questionsLabel.text = firstQuestion?.question
self.answerButtons.setTitle("\(firstQuestion?.option1)", for: UIControlState.normal)
self.answerButtons.setTitle("\(firstQuestion?.option2)", for: UIControlState.normal)
self.answerButtons.setTitle("\(firstQuestion?.option3)", for: UIControlState.normal)
})

Alamofire .post api error: Code=3840 "Invalid value around character 1

Using Alamofire for .post api, api giving data in postman but not in my code. Posting below the code, please guide what wrong i am doing here:
// API calling method:
parameters = [
"Address" : "" as AnyObject,
"Name" : "" as AnyObject,
"ServiceID" : "" as AnyObject,
"Rating" : "" as AnyObject,
"Price" : "" as AnyObject
]
let headers: Dictionary = [
"" : ""
]
print(parameters)
ApiServices.requestPOSTURL(strURL, params: parameters, headers: headers, success:{
(JSONResponse) -> Void in
CommonMethodsClass.hideHUD(targetView: self.view)
print(JSONResponse["message"])
let strMsg = JSONResponse["message"].stringValue
if (JSONResponse["status"].intValue == 1)
{
}
else
{
CommonMethodsClass.showAlertMessage(vc: self, titleStr: "Error!", messageStr: strMsg)
}
}) {
(error) -> Void in
print(error)
CommonMethodsClass.hideHUD(targetView: self.view)
}
// Api request method:
class func requestPOSTURL(_ strURL : String, params : [String : AnyObject]?, headers : [String : String]?, success:#escaping (JSON) -> Void, failure:#escaping (Error) -> Void){
Alamofire.request(strURL, method: .post, parameters: params, encoding: JSONEncoding.default).responseJSON { (responseObject) -> Void in
print(responseObject)
if responseObject.result.isSuccess {
let resJson = JSON(responseObject.result.value as Any)
success(resJson)
}
if responseObject.result.isFailure {
let error : Error = responseObject.result.error!
failure(error)
}
}
}
Error: FAILURE:
responseSerializationFailed(Alamofire.AFError.ResponseSerializationFailureReason.jsonSerializationFailed(Error
Domain=NSCocoaErrorDomain Code=3840 "Invalid value around character
1." UserInfo={NSDebugDescription=Invalid value around character 1.}))
Update: Response to parse, may also needs to be changed.
{
"status": true,
"message": "",
"data": [
{
"SalonID": "1",
"SalonName": "Affinity",
"SalonEmail": "vay.chaan#th-rce.com",
"SalonPhone": "9999888877",
"SalonMobile": "9999888877",
"SalonAddress": "C-28, Sec-58, India",
"Latitude": "18.5806",
"Longitude": "27.36273",
"Image": null,
"SalonImage": "",
"TimeIntervalminutes": 20,
"AverageRating": 4,
"IsActive": 1
},
{
"SalonID": "3",
"SalonName": "Looks",
"SalonEmail": "rad#th-rce.com",
"SalonPhone": "99998828877",
"SalonMobile": "99998388877",
"SalonAddress": "GP Mall,India",
"Latitude": "",
"Longitude": "",
"Image": null,
"SalonImage": "",
"TimeIntervalminutes": 30,
"AverageRating": 5,
"IsActive": 1
}
]
}
Replace responseJSON with responseString.
You need to convert the string for values. Can you update the string in your question?
You can use this function to convert response string into JSON:
func convertToDictionary(text: String) -> [String: Any]? {
if let data = text.data(using: .utf8) {
do {
return try JSONSerialization.jsonObject(with: data, options: []) as? [String: Any]
} catch {
print(error.localizedDescription)
}
}
return nil
}
String: let str = "{\"name\":\"James\"}"
USAGE: let dict = convertToDictionary(text: str)
Try responseString instead of responseJSON and it will work
Alamofire.request("URL").responseString { response in
print(response)
if let json = response.result.value {
print("JSON: \(json)")
}
}
Change responseJSON to responseString and it will work :)
Alamofire.request("URL").responseString { response in
print(response)
if let json = response.result.value {
print("JSON: \(json)")
}
}

Swift Alamofire Request Error - Extra Argument in call

I am getting an error when I am trying to request using Alamofire. The error says that there is an 'extra argument in call'.
class SwiftStockKit {
class func fetchStocksFromSearchTerm(term: String, completion:#escaping (_ stockInfoArray: [StockSearchResult]) -> ()) {
DispatchQueue.global(priority: DispatchQueue.GlobalQueuePriority.default).async {
let searchURL = "http://autoc.finance.yahoo.com/autoc"
Alamofire.request(.GET, searchURL, parameters: ["query": term, "region": 2, "lang": "en"]).responseJSON { response in
if let resultJSON = response.result.value as? [String : AnyObject] {
if let jsonArray = (resultJSON["ResultSet"] as! [String : AnyObject])["Result"] as? [[String : String]] {
var stockInfoArray = [StockSearchResult]()
for dictionary in jsonArray {
stockInfoArray.append(StockSearchResult(symbol: dictionary["symbol"], name: dictionary["name"], exchange: dictionary["exchDisp"], assetType: dictionary["typeDisp"]))
}
dispatch_async(dispatch_get_main_queue()) {
completion(stockInfoArray: stockInfoArray)
}
}
}
}
}
}
The line that is giving me an error is:
Alamofire.request(.GET, searchURL, parameters: ["query": term, "region": 2, "lang": "en"]).responseJSON { response in
if anyone could fix this I would be really grateful, thanks
Try change your request to something like this:
Alamofire.request(searchURL, method: .get, parameters: ["query": term, "region": 2, "lang": "en"], encoding: JSONEncoding.default, headers: nil)

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