Alamofire with YouTube API Issues (Swift 3) - swift

I'm having some trouble converting my old Alamofire code to the new Swift 3 version. I'm getting the error: Extra argument 'method' in call
// Fetch the videos dynamiclly through the YouTube Data API
Alamofire.request("https://www.googleapis.com/youtube/v3/playlistItems", method: .get, parameters: ["part":"snippet", "playlistId":UPLOADS_PLAYLIST_ID,"key":API_KEY], encoding: ParameterEncoding.URL, headers: nil)
Can someone help me with this?

The problem is not in the method argument but in the encoding which you can set to URLEncoding.default also since the header is nil then i guess you dont need it
let parameters: Parameters = ["part":"snippet",
"playlistId":UPLOADS_PLAYLIST_ID,
"key":API_KEY]
let url = "https://www.googleapis.com/youtube/v3/playlistItems"
Alamofire.request(url,
method: .get,
parameters: parameters,
encoding: URLEncoding.default)
.responseData(completionHandler: { response in
//do what you want
})
by the way you can change responseData back to what you already have

Related

Can't make post request using params as dictionary with Swift 4 & Alamofire

I'm trying to learn to call API with/without library. But the problem here confuses me.
I have params like this:
let parameters: [String:String] =
["key":"MY_KEY" ,
"q":sourceText,
"source": sourceLanguage),
"target": target)]
let headers: HTTPHeaders = [ "Content-type": "application/json"]
I make a post call like this:
Alamofire.request(urlString, method: HTTPMethod.post, parameters: parameters, headers: headers)
.responseJSON{ response in
guard response.result.error == nil else {
print("error calling POST on /todos/1")
print(response.result.error!)
return
}
// make sure we got some JSON since that's what we expect
guard let json = response.result.value as? [String: Any] else {
print("didn't get todo object as JSON from API")
print("Error: \(response.result.error)")
return
}
By this I get an error 403, saying that I do not have a valid API key (I tested the key with postman, and it is okay).
After many efforts, I have to change the code like this
let stringparams = "key=MY_KEY&q=\(sourceText)&source=\(sourceLanguage)&target=\(target)"
request.httpBody = stringparams.data(using: String.Encoding.utf8)
and using this: Alamofire.request(request)
it works!
I'm using Google Cloud Translation api. And the web use a REST api as said here: https://cloud.google.com/translate/docs/reference/translate
So why can't I use params as dictionary, but using the string (like formdata) will work here?
My guess is Alamofire didn't make the right BODY for the request from the parameters because other arguments is okay. But I don't know why.
And I think Google should accept a json params as they mentioned, in stead of using form data? I did try the original method, but it didn't work with JSON.
From what actually works for you it looks like you need to encode the parameters in the same style as a query. Try this:
struct ParameterQueryEncoding: ParameterEncoding {
func encode(_ urlRequest: URLRequestConvertible, with parameters: Parameters?) throws -> URLRequest {
var request = try urlRequest.asURLRequest()
request.httpBody = parameters?
.map { "\($0)=\($1)" }
.joined(separator: "&")
.data(using: .utf8)
return request
}
}
You should then be able to perform the original call that you had before:
Alamofire.request(urlString,
method: HTTPMethod.post,
parameters: parameters,
encoding: ParameterQueryEncoding(),
headers: headers)
.responseJSON { response in
...
}
Try by using JSON encoding. Make sure you have removed ) from dictionary.
Alamofire.request(URL, method: method, parameters: parameters, encoding: JSONEncoding.default, headers: headers)

Alamofire 4 sends method as POST but server reads it GET

I have a very weird problem here, using Alamofire 4 Swift 4 Xcode 9.1
let manager = Alamofire.SessionManager.default
manager.session.configuration.timeoutIntervalForRequest = 30
manager.session.configuration.requestCachePolicy = .reloadIgnoringLocalAndRemoteCacheData
let request = manager.request(
url,
method: HTTPMethod.post,
parameters: [:])
But server replies with method not allowed because it reads it as GET, however, if I change HTTPMethod.put or .delete or any other method, the server reads it correctly, the problem is with post specifically!
By debugging Alamofire's class 'SessionManager', specially the following method:
open func request(
_ url: URLConvertible,
method: HTTPMethod = .get,
parameters: Parameters? = nil,
encoding: ParameterEncoding = URLEncoding.default,
headers: HTTPHeaders? = nil)
-> DataRequest
The method here is correct, POST, so it's just fine before it goes out the application, what's wrong?
It was adding '/' at the end of the URL that was causing this.

Is there a simple way to send a key, value in Alamofire in the body NOT param?

I need to send a list of strings under a key in the body. Alamofire makes parameters super simple but I can't figure out how to do it in the body of the request. This doesn't help me since its for a simple string and I can't figure out how to make it work for an array of strings: POST request with a simple string in body with Alamofire . This one is titled about a JSON body but the answer is giving them as params Alamofire 4, Swift 3 and building a json body . Does anyone have an answer or a link to something that actually solves my problem?
Code as requested:
var params = ["phone_numbers": [6314560046, 8458200476]] as [String: Any]
Alamofire.request(url, method: .post, parameters: params, encoding: JSONEncoding.default, headers: headers).responseJSON() { response in
With Alamofire, the parameters are the body of the request. This creates your key with value of array of strings:
let parameters = ["Key": ["String1", "String2", "String3"]]
Then use the parameters in making the request:
Alamofire.request(URL, method: .post, parameters: paramaters, encoding: JSONEncoding.default)
.responseJSON { response in
print(response)
}

How do I see Alamofire Request? [duplicate]

This question already has an answer here:
URL Encode Alamofire GET params with SwiftyJSON
(1 answer)
Closed 6 years ago.
I am trying to use Alamofire for an Api that has a Json body and a header requirement that needs Basic Authentication. When I test the call in Postman it works fine, however with AlamoFire I am getting a server error.
I am trying to see what the call is that's going out from Alamofire - but I can't seem to see it: (this is the code I am using)
edit:
Error is below
["errors": { }, "errorMessages": <__NSSingleObjectArrayI 0x6000000035c0>( Internal server error ) ]
Request is below
Alamofire.request(endpoint, method: .post, parameters: paramsEncoded, encoding: JSONEncoding.default, headers: headers)
.responseJSON(completionHandler: { (response) in
print(response.request) // This returns just the url eg "http://api.com
print(response.request?.httpBody) // This returns `Optional(85 bytes)`
})
I assume the request is not being created properly, but would be useful to understand what I should be seeing.
Edit: this line helped from the other question :
NSLog("Request: \(request!.httpMethod!) - \(request!.url!.absoluteString)\n\(request!.httpBody.map { body in String(data: body, encoding: .utf8) ?? "" } ?? "")")
Thanks to the question I have linked to as a duplicate for the help.
Print the whole request like this :
let request = Alamofire.request(endpoint, method: .post, parameters: paramsEncoded, encoding: JSONEncoding.default, headers: headers)
.responseJSON(completionHandler: { (response) in
print(response.request)
print(response.request?.httpBody)
})
print("REQUEST = \(request)")
I'm not sure you can get any more info than that though.
You need to add headers with your request.
let urlString = "https://httpbin.org/get"
let headers = ["Authorization": "123456"]
Alamofire.request(urlString, method: .post, parameters: ["foo": "bar"],encoding: JSONEncoding.default, headers: headers).responseJSON { response in
print(response.result.value)
}

Extra argument in 'method' in call

let playlistUrl = NSURL(string: "https://www.googleapis.com/youtube/v3/playlistItems")!
let params = ["key":API_KEY,"part":"snippet","playlistId":PLAYLIST_ID]
Alamofire.request(playlistUrl, method: HTTPMethod.get, parameters: params, encoding: ParameterEncoding.URL, headers: nil)
Swift 3.0 and Alamofire 4
The thing which you are doing wrong is passing a NSURL as the first argument. Don't pass that as a URL, pass it as a string instead. Also you are doing the wrong encoding here.
So the modified code will be as follows:-
Alamofire.request("https://www.googleapis.com/youtube/v3/playlistItems", method: HTTPMethod.get, parameters: params, encoding: JSONEncoding.default, headers: nil)
The result here is unused. So take the result in a closure.
Alamofire.request("https://www.googleapis.com/youtube/v3/playlistItems", method: HTTPMethod.get, parameters: params, encoding: JSONEncoding.default, headers: nil).responseData { (response:DataResponse<Data>) in
switch(response.result) {
case .success(_):
if let data = response.result.value{
print(data)
}
break
case .failure(_):
print(response.result.error)
break
}
}
Also do check the encoding required. Check this link for more details.
https://github.com/Alamofire/Alamofire/blob/master/Documentation/Alamofire%204.0%20Migration%20Guide.md#parameter-encoding-protocol
Also check this answer posted by me.
Alamofire Swift 3.0 Extra parameter in call
JSONEncoding.default or URLEncoding.default totally depends on the type of API architecture made at backend.
for alamofire 4,
Alamofire.request(playlistUrl, method: .get, parameters: params, encoding: JSONEncoding.default)
Hope this will help you.
For more about latest change in alamofire visit,
https://github.com/Alamofire/Alamofire/blob/master/Documentation/Alamofire%204.0%20Migration%20Guide.md#parameter-encoding-protocol
//Correct code is:
let playlistUrl = NSURL(string:
"https://www.googleapis.com/youtube/v3/playlistItems")!
let params:Parameters =
["key":API_KEY,"part":"snippet","playlistId":PLAYLIST_ID]
Alamofire.request(playlistUrl, method: HTTPMethod.get, parameters:
params, encoding: ParameterEncoding.URL, headers: nil)