Alamofire convert bool on int - swift

I have func for request and have dictionary for params. Dictionary contained [String, Any]. And i need send Bool in parameters but alamofire convert my Bool on Int and server can't get it. How i can send Bool?
my func:
func postDataFor(methodPath: String, params:[String:Any], completion: #escaping (Any)->()) {
guard let url = URL(string:baseURL+methodPath) else {print("fail url"); return}
let token_type = KeychainWrapper.standard.string(forKey: "token_type")
let access_token = KeychainWrapper.standard.string(forKey: "access_token")
let headers:HTTPHeaders? = ["Authorization": "\(token_type ?? "") \(access_token ?? "")"]
Alamofire.request(url, method: .post, parameters: params, encoding: URLEncoding.queryString, headers: headers).response { response in
if let data = response.data {
completion(data)
} else {
print("error")
}
}
}
This i try send:
▿ 2 elements
▿ 0 : 2 elements
- key : "promoId"
- value : 6
▿ 1 : 2 elements
- key : "isFavorite"
- value : true
But this send alamofire:
?isFavorite=1&promoId=6

I guess all these values are stored in params. If so, change isFavorite to a string:
let params = [
"promoId": 6,
"isFavorite": String(isFavorite)
]

Related

Parse responseJSON to ObjectMapper

I'm currently making a migration from Android to iOS, better said Java to Swift, I got a generic response in JSON, but I'm not able to use it as an object and show it in the storyboard. I'm really new to Swift so I've been stuck for a while.
I've tried ObjectMapper and also JSON decode with no result at all.
I declared this response as I used in Java(Android)
class ResponseObjectMapper<T,R>: Mappable where T: Mappable,R:Mappable{
var data:T?
var message:String!
var error:R?
required init?(_ map: Map) {
self.mapping(map: map)
}
func mapping(map: Map) {
data <- map["data"]
message <- map["message"]
error <- map["error"]
}
}
class UserMapper :Mappable{
var email:String?
var fullName:String?
var id:CLong?
var phoneNumber:String?
var token:CLong?
required init?(_ map: Map) {
}
func mapping(map: Map) {
email <- map["email"]
fullName <- map["fullName"]
id <- map["id"]
phoneNumber <- map["phoneNumber"]
token <- map["token"]
phoneNumber <- map["phoneNumber"]
}
}
In my Android project I use the Gson dependency and I was able to use my JSON as an object
class ErrorMapper:Mappable{
var message:String?
var code:Int?
required init?(_ map: Map) {
}
func mapping(map: Map) {
message <- map["message"]
code <- map["code"]
}
}
This is the Alamofire that gave me the JSON.
func login(params: [String:Any]){Alamofire.request
("http://192.168.0.192:8081/SpringBoot/user/login", method: .post,
parameters: params,encoding: JSONEncoding.default, headers:
headers).responseJSON {
response in
switch response.result {
case .success:
let response = Mapper<ResponseObjectMapper<UserMapper,ErrorMapper>>.map(JSONString: response.data)
break
case .failure(let error):
print(error)
}
}
}
If I print the response with print(response) I got
SUCCESS: {
data = {
email = "vpozo#montran.com";
fullName = "Victor Pozo";
id = 6;
phoneNumber = 099963212;
token = 6;
};
error = "<null>";
message = SUCCESS;
}
and if I use this code I can got a result with key and value but I don't know how to use it as an object
if let result = response.result.value {
let responseDict = result as! [String : Any]
print(responseDict["data"])
}
console:
Optional({
email = "vpozo#gmail.com";
fullName = "Victor Pozo";
id = 6;
phoneNumber = 099963212;
token = 6;
})
I would like to use it in an Object, like user.token in a View Controller, probably I'm really confused, trying to map with generic attributes.
Type 'ResponseObjectMapper<UserMapper, ErrorMapper>' does not conform to protocol 'BaseMappable'
First of all you will need a Network Manager which uses Alamofire to make all your requests. I have made generalized one that looks something like this. You can modify it as you want.
import Foundation
import Alamofire
import SwiftyJSON
class NetworkHandler: NSObject {
let publicURLHeaders : HTTPHeaders = [
"Content-type" : "application/json"
]
let privateURLHeaders : HTTPHeaders = [
"Content-type" : "application/json",
"Authorization" : ""
]
enum RequestType {
case publicURL
case privateURL
}
func createNetworkRequestWithJSON(urlString : String , prametres : [String : Any], type : RequestType, completion:#escaping(JSON) -> Void) {
let internetIsReachable = NetworkReachabilityManager()?.isReachable ?? false
if !internetIsReachable {
AlertViewManager.sharedInstance.showAlertFromWindow(title: "", message: "No internet connectivity.")
} else {
switch type {
case .publicURL :
commonRequest(urlString: baseURL+urlString, parameters: prametres, completion: completion, headers: publicURLHeaders)
break
case .privateURL:
commonRequest(urlString: baseURL+urlString, parameters: prametres, completion: completion, headers: privateURLHeaders)
break
}
}
}
func commonRequest(urlString : String, parameters : [String : Any], completion : #escaping (JSON) -> Void , headers : HTTPHeaders){
print("urlString:"+urlString)
print("headers:")
print(headers)
print("parameters:")
print(parameters)
let url = NSURL(string: urlString)
var request = URLRequest(url: url! as URL)
request.httpMethod = "POST"
request.httpHeaders = headers
request.timeoutInterval = 10
let data = try! JSONSerialization.data(withJSONObject: parameters, options: JSONSerialization.WritingOptions.prettyPrinted)
let json = NSString(data: data, encoding: String.Encoding.utf8.rawValue)
if let json = json {
print("parameters:")
print(json)
}
request.httpBody = json!.data(using: String.Encoding.utf8.rawValue)
let alamoRequest = AF.request(request as URLRequestConvertible)
alamoRequest.validate(statusCode: 200..<300)
alamoRequest.responseJSON{ response in
print(response.response?.statusCode as Any )
if let status = response.response?.statusCode {
switch(status){
case 201:
print("example success")
SwiftLoader.hide()
case 200 :
if let json = response.value {
let jsonObject = JSON(json)
completion(jsonObject)
}
default:
SwiftLoader.hide()
print("error with response status: \(status)")
}
}else{
let jsonObject = JSON()
completion(jsonObject)
SwiftLoader.hide()
}
}
}
}
After this when ever you need to make a request you can use this function. This will take in parameters if any needed and once the request is complete it will execute a call back function in which you can handle the response. The response here will be of SWIFTYJSON format.
func makeNetworkRequest(){
let networkHandler = NetworkHandler()
var parameters : [String:String] = [:]
parameters["email"] = usernameTextField.text
parameters["pass"] = passwordTextField.text
networkHandler.createNetworkRequestWithJSON(urlString: "http://192.168.0.192:8081/SpringBoot/user/login", prametres: parameters, type: .publicURL, completion: self.handleResponseForRequest)
}
func handleResponseForRequest(response: JSON){
if let message = response["message"].string{
if message == "SUCCESS"{
if let email = response["data"]["email"].string{
//Do something with email.
}
if let fullName = response["data"]["fullName"].string{
//Do something with fullName.
}
if let id = response["data"]["id"].int{
//Do something with id.
}
if let phoneNumber = response["data"]["phoneNumber"].int64{
//Do something with phoneNumber.
}
if let token = response["data"]["token"].int{
//Do something with token.
}
}else{
//Error
}
}
}
Hope this helps. Let me know if you get stuck anywhere.

array as params is not working with Alamofire

I have an API where I need to send data as object so there I pass data as below and it works fine.
["fname" : "First 1", "lname": "Last 1"]
But for one of the API, web developer need API as Array as below.
[["fname" : "First 1", "lname": "Last 1"]]
Any idea what is going wrong?
Below is the code I have
parameters = ..... data that I passed as [String : Any] // e.x. ["fname" : "First 1", "lname": "Last 1"]
var finalWebParams : Any
var webParams2 : [[String : Any]] = [[String : Any]]()
if (webserviceFor=="array") {
webParams = parameters as [String:Any]
webParams2.append(webParams)
}
if (webserviceFor=="array") {
finalWebParams = webParams2
} else {
finalWebParams = webParams
}
print("finalWebParams==\(finalWebParams)")
request(url, method: webMethod, parameters: finalWebParams as? Parameters, encoding: myEncoding, headers: headers)
For print I get result as below, means I am passing correct data however I get 500 error.
[["fname" : "First 1", "lname": "Last 1"]]
Any idea what I am doing wrong?
Edit 1
below is the model that web developer need
[
{
"fname" : "First 1",
"lname" : "Last 1"
}
]
The answer is I need to add ArrayEncoding as below.
var finalWebParams : [String : Any]
var webParams2 : [[String : Any]] = [[String : Any]]()
if (webserviceFor=="array") {
webParams = parameters as [String:Any]
webParams2.append(webParams)
}
if (webserviceFor=="array") {
finalWebParams = webParams2.asParameters()
} else {
finalWebParams = webParams
}
Now add extension
private let arrayParametersKey = "arrayParametersKey"
/// Extenstion that allows an array be sent as a request parameters
extension Array {
/// Convert the receiver array to a `Parameters` object.
func asParameters() -> Parameters {
return [arrayParametersKey: self]
}
}
/// Convert the parameters into a json array, and it is added as the request body.
/// The array must be sent as parameters using its `asParameters` method.
struct ArrayEncoding: ParameterEncoding {
/// The options for writing the parameters as JSON data.
public let options: JSONSerialization.WritingOptions
/// Creates a new instance of the encoding using the given options
///
/// - parameter options: The options used to encode the json. Default is `[]`
///
/// - returns: The new instance
public init(options: JSONSerialization.WritingOptions = []) {
self.options = options
}
public func encode(_ urlRequest: URLRequestConvertible, with parameters: Parameters?) throws -> URLRequest {
var urlRequest = try urlRequest.asURLRequest()
guard let parameters = parameters,
let array = parameters[arrayParametersKey] else {
return urlRequest
}
do {
let data = try JSONSerialization.data(withJSONObject: array, options: options)
if urlRequest.value(forHTTPHeaderField: "Content-Type") == nil {
urlRequest.setValue("application/json", forHTTPHeaderField: "Content-Type")
}
urlRequest.httpBody = data
} catch {
throw AFError.parameterEncodingFailed(reason: .jsonEncodingFailed(error: error))
}
return urlRequest
}
}

`Extra argument method in call` in Alamofire

I am trying to send the following data using Alamofire version 3 and Swift 3. And the error that I get is Extra argument method in call.
Here is what I have done so far:
struct userGoalServerConnection {
let WeightsUserGoal_POST = "http://api.umchtech.com:3000/AddWeightsGoal"
}
struct wieghtsUserGoal {
let id : Int
let token : String
let data : [ String : String ]
}
func syncInitialUserGaolValuesWithServer (userID : Int , userToken : String ){
let serverConnection = userGoalServerConnection()
let weightValue = wieghtsUserGoal.init(id: userID,
token: userToken,
data: ["weight_initial":"11","weight_end":"11","weight_difference":"11","calories_deficit":"11","difficulties":"11","weight_loss_week":"11","start_date":"2016-12-12","end_date":"2016-12-23","days_needed":"11"])
Alamofire.request(userGoalServerConnection.WeightsUserGoal_POST, method:.post, parameters: weightValue, encoding: JSONEncoding.default, headers:nil).responseJSON { response in
print(response.request as Any) // original URL request
print(response.response as Any) // URL response
print(response.result.value as Any) // result of response serialization
}
I am quite new to this so please dont mind if my question is a little bit too noob. I have gone through similar questions here but they did not help me out figuring where am i making a mistake :)
You are passing weightValue as POST param in request, it can't be. If you are using JSONEncoding then pass type of Parameters object.
let params: Parameters = [
"Key1": "value1",
"key2": "value2"
]
You can only pass dictionary type a alamofire request, you cannot post a struct type.
you can send [String : String], [String : Any] etc in a Alamofire request
You can try this way out
let WeightsUserGoal_POST = "http://api.umchtech.com:3000/AddWeightsGoal"
func Serialization(object: AnyObject) -> String{
do {
let stringData = try JSONSerialization.data(withJSONObject: object, options: [])
if let string = String(data: stringData, encoding: String.Encoding.utf8){
return string
}
}catch _ {
}
return "{\"element\":\"jsonError\"}"
}
func syncInitialUserGaolValuesWithServer (userID : Int , userToken : String ){
let data = ["weight_initial":"11","weight_end":"11","weight_difference":"11","calories_deficit":"11","difficulties":"11","weight_loss_week":"11","start_date":"2016-12-12","end_date":"2016-12-23","days_needed":"11"] as! [String : String]
let dataSerialized = Serialization(object: data as AnyObject)
let param = ["id" : userID,
"token" : userToken,
"data" : dataSerialized ]
Alamofire.request(WeightsUserGoal_POST, method: .post, parameters: param ,encoding: JSONEncoding.default, headers: nil).responseJSON { response in
print(response.request as Any) // original URL request
print(response.response as Any) // URL response
print(response.result.value as Any) // result of response serialization
}
}

Cannot convert value of type 'Int?' to expected argument type 'String'

I am working on a social media type app and i want to implement the block feature for users but I'm encountering an error " Cannot convert value of type 'Int?' to expected argument type 'String'"
below is a sample of my code
i first declared the current user ID and Pageuser ID
var currentUserId: Int!
var userPageId: Int!
then the main code that gives the error
self.userHelper.checkBanUser(with: userPageId, toUser: defaults.string(forKey: "userId")!) { (data) in
if data {
self.blockLabel.isHidden = false
}
else {
//
}
}
the error comes from the "userPageID "
update. this is the function to check banned users
func checkBanUser(with fromUser: String,toUser: String,completionHandler : #escaping ((_ isResponse : Bool) -> Void)) {
let urlRequest = String(format: "%#%#",BASE_BACKEND_URL,ENDPOINT_CHECK_BANN)
Alamofire.request( urlRequest,method: .post, parameters: ["X-API-KEY": API_GENERAL_KEY,"fromUser":fromUser,"toUser":toUser])
.responseJSON { response in
let itemz = response.result.value as! NSDictionary!
let resp = itemz?.value(forKey: "respon") as! String
if (resp == "banned"){
completionHandler (true)
} else {
completionHandler (false)
}
}
}
You're passing an Int where it needs a string. Try this instead:
self.userHelper.checkBanUser(with: "\(userPageId)", toUser: defaults.string(forKey: "userId")!)

Alamofire Upload get returned JSON

question on getting at the result data in an Alamofire.upload call.
I am sending multipart form data to a server using the following code:
sessionManager.upload(
multipartFormData: { multipartFormData in
if let name = currentPlace.name,
let data = name.data(using:String.Encoding.utf8) {
multipartFormData.append(data, withName: "placename", mimeType: "text/plain")
}
if let lat = currentPlace.location?.coordinate.latitude {
multipartFormData.append(String(describing: lat).data(using:String.Encoding.utf8)!, withName: "latitude", mimeType: "text/plain")
}
if let lon = currentPlace.location?.coordinate.longitude {
multipartFormData.append(String(describing: lon).data(using:String.Encoding.utf8)!, withName: "longitude", mimeType: "text/plain")
}
multipartFormData.append((User.current.scanMode.rawValue).data(using:String.Encoding.utf8)!, withName: "state", mimeType: "text/plain")
},
to: (url?.absoluteString)!, headers: headers,
encodingCompletion: { encodingResult in
switch encodingResult {
case .success(let upload, _, _):
upload.responseJSON { response in
print(response.request) // original URL request
print(response.response) // URL response
print(response.data) // server data
print(response.result) // result of response serialization
if let JSON = response.result.value as? NSArray {
for element in JSON {
print(element)
}
}
}
case .failure(let encodingError):
print(encodingError)
}
})
My challenge is to get the value of response.result.value in a form that I can validate. The current debug output is:
(lldb) po response.result.value
▿ Optional<Any>
▿ some : 4 elements
▿ 0 : 2 elements
- key : code
- value : 200
▿ 1 : 2 elements
- key : id
- value : 78230c53954a3adbf14b49cda127bf55
▿ 2 : 2 elements
- key : message
- value : Successfully updated OID to DISTRIBUTED.
▿ 3 : 2 elements
- key : state
- value : DISTRIBUTED
Looks like a array, but can't seem to get this casted or reflected into something I can use. Usually I would use EVOReflection to get at this data as in:
sessionManager.request((url?.absoluteString)!, method: .get, parameters: postParameters, encoding: URLEncoding.httpBody, headers: headers)
.responseObject { (response: DataResponse<AssetStateResponse>) in
if let response = response.result.value {
completionHandler(response)
} else {
// LATER: Better error handling
}
}
Any help appreciated, have been looking at this for a few days now, missing something simple I suspect.
That respose.result.value looks like a dict, not an array.
Did you try casting it that way?
if let jsonDict = response.result.value as? NSDictionary {
print(jsonDict)
}
Alamofire response will result in a dictionary.
So your response.result.value is a dictionary
print(response.result) After this line call a function funcJSONParsing
self.funcJSONParsing(response.result.value!)
Write the parsing in a separate function like below.
func funcJSONParsing(let json:AnyObject)
{
if json is NSDictionary{
let jsonResponse = json as! NSDictionary
//Parse the below jsonResponse according to your needs
}
}
upload.responseJSON { (result) in
do {
let decoder = JSONDecoder()
let model = try decoder.decode(FormResponse2.self,from: result.data!)
let selectDoctorForChat = self.storyboard?.instantiateViewController(withIdentifier: "SelectDoctorForChat") as! SelectDoctorForChat
selectDoctorForChat.chatFormId = model.chat?.id
self.navigationController?.pushViewController(selectDoctorForChat, animated: true)
} catch let parsingError {
print("Error", parsingError)
}
// MARK: - FormResponse
struct FormResponse2: Codable {
let chat: Chat2?
}
// MARK: - Chat
struct Chat2: Codable {
let id: Int?
let patient, doctor: String?
let specialty: Specialty22?
let state, createdAt: String?
enum CodingKeys: String, CodingKey {
case id, patient, doctor, specialty, state
case createdAt = "created_at"
}
}
// MARK: - Specialty
struct Specialty22: Codable {
let id: Int?
let name: String?
}