AlamofireImage seems to be supposed to request with GET method in general. But in our project, to download images we have to request with POST method, because we send access token. I have searched for the similar question in Stack Overflow, but I couldn't find enough answers. Does anyone know how to download with POST request?
The URL is as follow:
https://host_name/project_name/GetImage
You can use af_setImage method from AlamofireImage extension of UIImageView and pass any URLRequestConvertible parameter. For example, create URLRequest instance with Alamofire initializer:
let urlPath = "https://host_name/project_name/GetImage"
if var imageRequest = try? URLRequest(url: urlPath, method: .post) {
imageRequest.addValue("token", forHTTPHeaderField: "token_field")
imageView.af_setImage(withURLRequest: imageRequest)
}
Because We have to send parameters in HTTPBodyData, following the Loe's answer, I made some changes to our code. The following is our new code:
let urlPath = "https://host_name/project_name/GetImage"
let parameters:[String: Any] = [
"token": "tokenValue",
"imageName": "imageName"
]
let dataRequest = Alamofire.request(urlPath,
method: HTTPMethod.post,
parameters: parameters,
encoding: JSONEncoding.default,
headers: [:])
guard let imageRequest = dataRequest.request else {
return
}
imageView.af_setImage(withURLRequest: imageRequest)
The Point is first, we create a DataRequestobject and then convert it to URLRequest Type with Alamofire.request()method.
Related
We are facing the following networking error when the response is somehow large(14kb) on iOS 13.
[-1103] Error Domain=NSURLErrorDomain Code=-1103 "resource exceeds maximum size"
As we are using Alamofire, this problem is treated as error result which breaks our treatments of the results.
The strange thing is that if we use NSURLSession directly, though this error is still seen from logging, we don't actually receive it in the callback of
session.dataTask(with: request) { value, response, error in ... }
So the result can treated correctly.
This problem is never seen before. Anyone has got some idea on that ?
With the help of the Slack community, we find the answer is that
on iOS13, it is not allowed to add a body in GET request. To make it work again, we can either switch to a POST/PUT request or add body value via url parameters of the GET request.
Pass query parameters in GET request like the following:
let parameters: Parameters = [
"param": value
]
Alamofire.request(urlString, method: .get, parameters: parameters, encoding: URLEncoding.queryString)
I have face same issue and find out the solution.
You can't pass parameter in body while using GET.
Either use POST method if API support or pass it in URL like below.
AnyURL?Parameter=Value&Parameter=Value
Finally found the answer. For GET services I was trying to add an httpBody. Something like this:
do {
request.httpBody = try JSONSerialization.data(withJSONObject: parameters, options: .prettyPrinted)
} catch let error {
errorCompletion(error)
return
}
The solution was just to add an if to avoid that chunk of code if httpMethod is a GET. Seems like an iOS 13 new behavior and the error message given by Swift definitely not helps at all
Alamofire: You should try this!
Alamofire.request(urlString, method: .get, parameters: parameters, encoding: URLEncoding.queryString)
Just avoid the httpBody for the GET API request.
if requestType != .get{
request.httpBody = data
}
#OR
For GET request append parameter into URL instead of the HTTP body
Use the below extension to create a query parameter from the dictionary.
extension NSObject {
func buildQueryString(fromDictionary parameters: [String:String]) -> String {
var urlVars = [String]()
for (var k, var v) in parameters {
let characters = (CharacterSet.urlQueryAllowed as NSCharacterSet).mutableCopy() as! NSMutableCharacterSet
characters.removeCharacters(in: "&")
v = v.addingPercentEncoding(withAllowedCharacters: characters as CharacterSet)!
k = k.addingPercentEncoding(withAllowedCharacters: characters as CharacterSet)!
urlVars += [k + "=" + "\(v)"]
}
return (!urlVars.isEmpty ? "?" : "") + urlVars.joined(separator: "&")
}
}
I used default url encoding instead of default json encoding and it's worked for me.
Alamofire.request(url, method: .get, parameters: param, encoding: URLEncoding.default)
OR
If you using URLRequestConvertible
enum NetworkRouter: URLRequestConvertible {
case someCase(lang:String)
var method: HTTPMethod {
return .get
}
var parameters: Parameters? {
switch self {
case .someCase(let param):
return ["lang": param.lang]
default:
return nil
}
}
var url: URL {
switch self {
case .someCase(let param):
return URL(string: Constants.baseURL + Constants.endPoint)!
default:
return URL(string: Constants.baseURL)!
}
}
var encoding: ParameterEncoding {
return URLEncoding.default
}
func asURLRequest() throws -> URLRequest {
var urlRequest = URLRequest(url: url)
urlRequest.httpMethod = method.rawValue
return try encoding.encode(urlRequest, with: parameters)
}
}
I got that issue because i pass empty parameters in Alamofire when send get request. So, instead of sending empty parameters i simply replace it for nil.
My fix is I only set .parameters to nil, then everything works fine. Because in Swift it still initialize the value of .parameters.
self.request.parameters = nil
Here you might have missing the method of the URL request that you are passing to data task. You have to add POST/PUT/DELETE to the URL request method parameter like below.
var request: URLRequest = URLRequest(url: SOME_VALID_URL)
request.body = SOME_VALID_DATA_IN_BYTES
request.method = "post" --> You are missing this.
I only see this issue when I build with Xcode 11. If I revert back to Xcode 10.3 I do not have the same issue anymore. While not a forever fix, if you're needing to push out code you can revert until you have time to fix it.
I want to add the JSON object in GET request with URL. Please refer below URL.
https://testdata.com/xyz/&form={"id":"12", "data": "3"}
I am getting nil while converting String to URL
let serviceUrl = URL(string: url)
Thanks in advance.
I was already tried below solution but unfortunately no luck.
JSONSerialization.data
converting to string with utf8
removed whitespaces if any
addingPercentEncoding with URL host allowed
It's not recommended, to send a request body with GET request. GET request means to fetch all the resources/content that this URL has to offer. If they are parsing the GET body on server side, it's against the semantics. But if you really need to do it. Use Almofire. Here's a Sample Code.
let parameters : [String : Any] = [
"id":"12",
"data":"3"
]
func getContent(parameters: [String: Any]) {
Alamofire.request("http://18.218.235.193:3000/user/securedtoken", method:
.get, parameters: parameters, encoding: JSONEncoding.default)
.responseObject {(response:
DataResponse<YOUR RESPONSE MODEL HERE>) in
let response = response.result.value
//Do Something (Success)
}
}
I recommend you to use Alamofire library. You can do what you want using following code snippet
Alamofire.request(.GET, "http://httpbin.org/get", parameters: ["form": ["id": 12, "data": 3]])
.response { request, response, data, error in
print(request)
print(response)
print(error)
}
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)
I'm following Alamofire's CRUD and authorization section:
enum Router: URLRequestConvertible {
So what I want to accomplish is basically a simple PUT request which looks like this:
http://localhost:8080/rest/users/add?id=
So in my code I have:
let requestParam : [String : AnyObject] = ["id" : "\(SOMEID)"]
Alamofire.request(Router.AddUser(parameters: requestParam))
.validate()
.responseString { response in
switch response.result {
case .Success:
..
However, following my server doesn't get this id parameter.
Debugging the NSMutableURLRequest, I find that the id parameter isn't added.
case .AddUser(let parameters):
print(parameters)
let encodedURL = Alamofire.ParameterEncoding.URL.encode(mutableURLRequest, parameters: parameters).0
print (encodedURL)
Console output:
["id": 5649fec6d4c662c573d39fb4]
{ URL: http://localhost:8080/rest/users/add }
This is really strange, because I had another method written almost identically but I wasn't getting the same issue.
Edit:
It turns out after some trials that it's because the method is PUT. If it was GET method then parameters were added correctly. Does anyone know why I can't put request parameters for PUT? Is this intentional?
In your router, why don't you use NSURLComponents to build your url and then return NSMutableURLRequest like that:
enum Router: URLRequestConvertible {
...
var URLRequest: NSMutableUrlRequest {
var urlComponents = NSURLComponents()
urlComponents.host = // something
urlComponents.scheme = // probably wanna use https
switch self {
case .AddUser(let parameters):
// set urlComponents.path here
urlComponents.query = parameters.queryString
// depending on your code you may want to check before force unwrapping URL below
return NSMutableUrlRequest(URL: urlComponents.URL!)
}
}
}
then you can extend dictionary with a computed property of type String.
Hope that helps!
I have a question about Alamofire.
I'm doing this:
var mutableURLRequest = NSMutableURLRequest(URL:url!)
mutableURLRequest.setValue(response!.allHeaderFields["TOKEN"] as! String, forHTTPHeaderField: "X-AUTH-TOKEN")
mutableURLRequest.HTTPMethod = "GET"
let manager = Alamofire.Manager.sharedInstance // or create a new one
let request = manager.request(mutableURLRequest)
request.responseJSON { (request, response, string, error) in
println(response!.statusCode)
println(string!)
}
When I print string the output is JSON. I want to search for a single element (f.e. username or something else) in that JSON response.
How can I do that?
Thank you and best regards,
Alban Veliu
You can do it in Swift, but IMHO it's a lot easier using the SwiftyJSON framework. It has an excellent tutorial and documentation and you should be up an running in no time : https://github.com/SwiftyJSON/SwiftyJSON