Alamofire swift4 InvalidURL - ios

Note: Test Api Used
I am using the latest 4.0 version of Alamofire with Swift4.0 and am trying to make a api request (GET) however what I get is a FAIULRE: INvalid URL
func getFlightData(airportCode: String, minutesBehind: String, minutesAhead:String){
let securityToken: String = "Basic YWFnZTQxNDAxMjgwODYyNDk3NWFiYWNhZjlhNjZjMDRlMWY6ODYyYTk0NTFhYjliNGY1M2EwZWJiOWI2ZWQ1ZjYwOGM="
var headers: HTTPHeaders = [:]
headers["Authorization"] = securityToken
var params: Parameters = [:]
params["city"] = airportCode
params["minutesBehind"] = minutesBehind
params["minuteAhead"] = minutesAhead
Alamofire.request("https://api.qa.alaskaair.com/1/airports/‬SEA/flights/flightInfo?city=SEA&minutesBehind=10&minutesAhead=120", method: .get, headers: headers).responseJSON { (response) in
print(response)
}
The result I get is:
FAILURE: invalidURL("https://api.qa.alaskaair.com/1/airports/‬SEA/flights/flightInfo?city=SEA&minutesBehind=10&minutesAhead=120")
Do i need to encode my url? if yes then how? The same request works great with the URL provided by Alamofire documentation:
Alamofire.request("https://httpbin.org/get")

You need to encode parameters like this:
let parameters: Parameters = ["city": "SEA", "minutesBehind" : "10"] // Add all parameters
Alamofire.request("https://api.qa.alaskaair.com/1/airports/‬SEA/flights/flightInfo", parameters: parameters)

Related

Alamofire GET request with åäö (special characters), invalid url

I'm trying to send an API get request with alamofire, but when i use the following url: https://stuntmans.evosale.se/admin/api/dräkt , the special character in "dräkt" is returning an invalid url as response. How would i go about using special characters with alamofire?
Thanks in advance!
Here is a part of the code:
let headers: HTTPHeaders = [
.authorization(username: "Username", password: "Password"),
.accept("application/json")]
AF.request(https://stuntmans.evosale.se/admin/api/dräkt, headers: headers).validate().responseJSON { response in
You could percent encode the URL with URLComponents
var components = URLComponents(string: "https://stuntmans.evosale.se")!
components.path = "/admin/api/dräkt"
guard let url = components.url else { return }
AF.request(url, headers: headers).validate().responseJSON { response in
Solved this by replacing the characters "åäö" with the corresponding characters they're supposed to represent in url, below is the code:
var result = Url
zip(["å", "ä", "ö"],["%C3%A5", "%C3%A4", "%C3%B6"]).forEach {
result = result.replacingOccurrences(of: $0, with: $1, options: .literal)
}
print (result) // the result

Vapor 3 - send a HTTPRequest

How do you send an API request in Vapor 3 with the HTTPRequest struct?
I tried variations of the following code..
var headers: HTTPHeaders = .init()
let body = HTTPBody(string: a)
let httpReq = HTTPRequest(
method: .POST,
url: URL(string: "/post")!,
headers: headers,
body: body)
let httpRes: EventLoopFuture<HTTPResponse> = HTTPClient.connect(hostname: "httpbin.org", on: req).map(to: HTTPResponse.self) { client in
return client.send(httpReq)
}
The compile error Cannot convert value of type '(HTTPClient) -> EventLoopFuture<HTTPResponse>' to expected argument type '(HTTPClient) -> _'
I have tried other variations of code that worked.
Vapor 3 Beta Example Endpoint Request
let client = try req.make(Client.self)
let response: Future<Response> = client.get("http://example.vapor.codes/json")
I read and re-read:
https://api.vapor.codes/http/latest/HTTP/Structs/HTTPRequest.html
https://api.vapor.codes/http/latest/HTTP/Classes/HTTPClient.html
https://docs.vapor.codes/3.0/http/client/
Your problem is .map(to: HTTPResponse.self). Map needs to transform its result into a new result regularly, like you would map an array. However, the result of your map-closure returns an EventLoopFuture<HTTPResponse>. This results in your map function returning an EventLoopFuture<EventLoopFuture<HTTPResponse>>.
To avoid this complexity, use flatMap.
var headers: HTTPHeaders = .init()
let body = HTTPBody(string: a)
let httpReq = HTTPRequest(
method: .POST,
url: URL(string: "/post")!,
headers: headers,
body: body)
let client = HTTPClient.connect(hostname: "httpbin.org", on: req)
let httpRes = client.flatMap(to: HTTPResponse.self) { client in
return client.send(httpReq)
}
EDIT:
If you want to use the Content APIs you can do so like this:
let data = httpRes.flatMap(to: ExampleData.self) { httpResponse in
let response = Response(http: httpResponse, using: req)
return try response.content.decode(ExampleData.self)
}
HTTPClient.connect returns Future<HTTPClient> and it is mapping to a Future<HTTPResponse> not a EventLoopFuture<HTTPResponse>.
If you're expecting a single HTTPResponse use HttpClient.send instead of HTTPClient.connect.
If you're expecting multiple HTTPResponses then .map(to: HTTPResponse.self) must be changed to properly map to a EventLoopFuture<HTTPResponse>

servlet request.parameter() function returns null when i post post request using swift 4 and alamofire4

I was trying to do a post request from ios swift4 using alamofire4.And my server side is a servelet file.
The Swift4 code is as follows
var datasDicts = [String: Any]()
datasDicts["phoneNumber"] = phoneNumber
datasDicts["tokenId"] = fcmDeviceToken
let parameters: Parameters = ["UploadData": datasDicts]
Alamofire.request(DDGeneralData.globalDatas.url+"/Sample", method: .post, parameters: Parameters, encoding:
JSONEncoding.default).responseJSON
{ (response:DataResponse) in
print("response result \(response.result)")
}
}
The request is successfully called the servlet but when i call request.getparameter(); it returns null. the servlet code is asfollows
String json_data = request.getParameter("UploadData");
System.out.println(config.getLogTime()+" DdbLogin json
parsed"+json_data);
how can i solve. when i read the request using request.reader i am able to get the string but request.getParameter() returns null

Postman Body Raw Request To Swift Alamofire

I'm trying to re-create this Postman settings for posting in Alamofire. This is my first time to see an API that requires both Parameters and a body with Raw Json.
I'm done with gathering and formatting my data (either in Json using SwiftyJSON or Dictionary [String : Any] / Parameters) for the said requirement.
While I did see a similar question to this: Postman request to Alamofire request but it doesn't have a valid answer. Assume that I'm quite experienced with posting/getting/etc data from various API but I just don't know how to pass raw data just like in the photo above. Please check out my comments too in the code.
Here's what I'm doing with my function for this request:
/** Apply to job with Shift.
* This service function creates a json data for applying.
*/
func someFuncService(_ job: Job, daySchedules: [(Int, String, Schedule)], withBlock completion: #escaping JobServiceCommonCallBack) {
AuthService.someFunc { (currentCustomer, accessToken) in
guard let lalala = currentCustomer?.id,
let accessT = accessToken else {
completion(LalaErrors.currentCustomerError)
return
}
guard let jobId = job.id else {
completion(LalaErrors.modelError)
return
}
let coreService = LalaCoreService()
let applicantEndpoint = LalaCoreService.Endpoint.Applicant
let parameters = [
"param1" : customerId,
"param2" : jobId,
"accessToken" : accessToken,
"shift" : self.generateDataFromDaySchedules(daySchedules) // this returns [String : Any], can be printed into Json using JSON(x)
] as Parameters
GPLog(classSender: self, log: "FINAL PARAMETER: \(parameters)")
coreService.request = Alamofire.request(
applicantEndpoint,
method: .post,
parameters: parameters,
encoding: URLEncoding.default, // I already have tried .httpbody too.
headers: nil
)
coreService.request {
(response, result) in
if let error = result?.error {
if response!.statusCode == 500 {
completion(GPKitError.newError(description: "Failed to apply. Please contact the admin."))
return
}
completion(error)
return
}
// Success
completion(nil)
return
}
}
}
EDIT: So the question is, what I'm doing wrong here? API returns me status code 500 internal server error.
coreService.request = Alamofire.request(
applicantEndpoint,
method: .post,
parameters: parameters,
encoding: URLEncoding.default, // I already have tried .httpbody too.
headers: nil
)
should be
coreService.request = Alamofire.request(
applicantEndpoint + accessToken,
method: .post,
parameters: parameters,
encoding: JSONEncoding.default,
headers: nil
)

{ error = "invalid_request"; "error_description" = "Required parameter is missing: grant_type"; } In swift

I am trying with this but every time I will get
{ error = "invalid_request"; "error_description" = "Required parameter is missing: grant_type"; }
Request String:
let headers = [ "Content-Type" : "application/x-www-form-urlencoded"]
let urlString = "https://accounts.google.com/o/oauth2/token?"
Alamofire.request(urlString, method: .post, parameters: ["grant_type":"authorization_code","code":"4/FAOYR1mQo1lN1Gdg9jDnigwZ8RP76NUrqPbYZlMCSP28","client_id":"387376833747-12pbtud9tepr4di0insdhc0d4qpf5e9m.apps.googleusercontent.com","client_secret":"xOacVhLavM9fH8SpOK4I2dRJ","redirect_uri":"https://stackoverflow.com"], encoding: JSONEncoding.default, headers : headers)
.responseJSON { response in
print(response)
print(response.result)
}
Also try with passing request parameter like this but still doesn't work for me.
You can't send appended parameter with url while post request.
Pass parameter as below this
let headers = [ "Content-Type" : "application/x-www-form-urlencoded","grant_type" : "authorization_code"" ]
let urlString = "https://accounts.google.com/o/oauth2/token?"
Alamofire.request(urlString, method: .post, parameters: ["code":"4/FAOYR1mQo1lN1Gdg9jDnigwZ8RP76NUrqPbYZlMCSP28","client_id":"apps.googleusercontent.com","client_secret":"","redirect_uri":"https://stackoverflow.com"], encoding: JSONEncoding.default, headers : headers)
.responseJSON { response in
print(response)
print(response.result)
}
These error invalid_request occurs only below cases so please check with your server side what is missing or invalid.
The request is missing a required parameter, includes an unsupported
or invalid parameter value, repeats a parameter,includes multiple
credentials, utilizes more than one mechanism for authenticating the
client, or is otherwise malformed.

Resources