UPDATED Question:
I got in touch with the WhenIWork Team and discovered that they need the username and password to be passed in the body but with our a form. So I have solved. If you look at the answer below, it works.
Thanks everyone!
I am trying to get the access token from WhenIWork using Swift and Alamofire on Xcode, the json returned Success but says "Application Not Found Error"
I've been looking for documentation from WhenIWork Doc but without success on error code. (They don't have any error in the 1xxx range)
Ideas? I am new to Swift (and coding in general) so any help would be appreciated.
Thanks!
Below is the Terminal answer:
SUCCESS: {
code = 1110;
error = "Application not found";
}
[Request]: POST https://api.wheniwork.com/2/login/
[Response]: <NSHTTPURLResponse: 0x6080000325e0> { URL: https://api.wheniwork.com/2/login/ } { status code: 401, headers {
"Access-Control-Allow-Headers" = "Authorization, Origin, X-Requested-With, W-Date-Format, Content-Type, Accept, W-Token, W-UserId, W-Key, branch";
"Access-Control-Allow-Methods" = "GET, HEAD, POST, PUT, PATCH, DELETE, OPTIONS";
"Access-Control-Allow-Origin" = "*";
"Cache-Control" = "no-cache";
Connection = "keep-alive";
"Content-Type" = "application/json";
Date = "Thu, 17 Aug 2017 17:11:08 GMT";
Server = nginx;
"Transfer-Encoding" = Identity;
"X-Database" = ro;
"X-State" = "RequestId: 0f853dd4-836f-11e7-90f4-0242e14cb0c5, LoginId: 0, AccountId: 0";
"X-Timer-Database" = "0.0052359104156494";
"X-Timer-Total" = "0.012078046798706";
} }
Code:
func logInWhenIWork() {
let parameters: Parameters = [
"username": "cxxxx#xxxx.ca",
"password": "xxxxxxx",
"W-Key": "xxxxxxxxxxxxxsxx"
]
Alamofire.request("https://api.wheniwork.com/2/login", method: .post, parameters: parameters, encoding: JSONEncoding.default).responseJSON { response in
print(response)
debugPrint(response)
if let json = response.result.value {
print("JSON: \(json)")
} else {
print(response)
}
}
I don't use Alamofire much but I tried the following:
let parameters = ["username":"user#example.com",
"password": "*******"]
let headers = ["W-Key": "iworksoharditsnotfunny"]
var req = Alamofire.request("https://api.wheniwork.com/2/login",
parameters: parameters,
encoding: JSONEncoding.default,
headers: headers)
The request ends up looking like this:
curl -v \
-H "Content-Type: application/json" \
-H "Accept-Language: en-US;q=1.0" \
-H "User-Agent: Unknown/Unknown (Unknown; build:Unknown; OS X 10.12.6) Alamofire/1.0" \
-H "W-Key: iworksoharditsnotfunny" \
-H "Accept-Encoding: gzip;q=1.0, compress;q=0.5" \
-d "{\"username\":\"user#example.com\",\"password\":\"*******\"}" \
"https://api.wheniwork.com/2/login"
Which seems to pretty much match the example given in the WhenIWork API documentation. I don't have an account so I can't test it directly.
For those of you who wanted the answer. I finally figured it out. Here it is
func logInWhenIWork() {
let url = URL(string: "https://api.wheniwork.com/2/login")!
var urlRequest = URLRequest(url: url)
urlRequest.httpMethod = "POST"
urlRequest.allHTTPHeaderFields = ["W-Key": "xxxxxxxxxxx","Content-Type":"application/json"]
let parameters = ["username": "ss#xxx.ca", "password": "sssdsds"]
do {
urlRequest.httpBody = try JSONSerialization.data(withJSONObject: parameters, options: [])
} catch {
// No-op
}
urlRequest.setValue("application/json", forHTTPHeaderField: "Content-Type")
Alamofire.request(urlRequest).responseJSON { response in
switch response.result {
case .success(let value):
let json = JSON(value)
// print("JSON: (json)")
let token = json["token"].stringValue
let newUserID = json["users"][0]["id"].int
print(newUserID)
self.wUserID = String(describing: newUserID)
// print(token)
self.wToken = token
if self.wToken != "" {
print("Successfully logged in")
} else {
print("Log In Failed")
}
case .failure(let error):
print(error)
}
}
}
Related
This is my curl url
curl -X POST https://fax.twilio.com/v1/Faxes \
--data-urlencode "From=+15017122661" \
--data-urlencode "To=+15558675310" \
--data-urlencode "MediaUrl=https://www.twilio.com/docs/documents/25/justthefaxmaam.pdf" \
-u ACXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX:your_auth_token
How can i implement this in Almofire?
I am trying like this way.
AF.request(URL(string: "https://fax.twilio.com/v1/Faxes")!, method: .post, parameters: params, encoding: JSONEncoding.default, headers: headers).authenticate(username: "", password: "").responseJSON { response in
print(response)
}
how can i implement data-urlencode "From=+15017122661" in almofire?
Try this code with Alamofire:
if let url = URL(string: "https://fax.twilio.com/v1/Faxes") {
let parameters = [
"From": "+15017122661",
"To": "+15558675310",
"MediaUrl": "https://www.twilio.com/docs/documents/25/justthefaxmaam.pdf"
]
AF.request(url, method: .post, parameters: parameters, encoder: URLEncodedFormParameterEncoder.default, headers: nil, interceptor: nil)
.authenticate(username: "ACXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", password: "your_auth_token")
.responseJSON { response in
switch response.result {
case .success(let json):
print(json)
case .failure(let error):
print(error)
}
}
}
I've tested with my creds - it should be work, but I haven't real devices for in/out fax
For upload image to server I am using Alamofire 4.4 and Swift 3.
Swager information:
curl -X POST "url/id/upload" -H "accept: application/json" -H "Authorization: Bearer token" -H "Content-Type: multipart/form-data" -F "file=#craneB.png;type=image/png"
My Swift code:
let headers = [
"Authorization": "Bearer \(GlobalToken.appToken)",
"Content-Type": "multipart/form-data" ]
let url = BaseUrl+"1f510b93-5177-4880-447d-08d6fe7a9498"+"/upload"
let data = UIImageJPEGRepresentation(selectedImage, 0.9)
Alamofire.upload(multipartFormData: { (multipartFormData) in
if let data = data{
multipartFormData.append(data, withName: "name", fileName: "filename", mimeType: "image/png")
}
}, usingThreshold: UInt64.init(), to: url, method: .post, headers: headers) { (result) in
switch result{
case .success(let upload, _, _):
// upload.validate(statusCode: 200..<299)
upload.responseJSON{ response in
print("Succesfully uploaded")
switch response.result {
case .success(let JSON):
case .failure(_):
}
if let err = response.error{
print(err)
return
}
}
upload.uploadProgress(closure: { (progress) in
})
case .failure(let error):
print("Error in upload: \(error.localizedDescription)")
}
}
Respons:
Upload Progress: 1.0
Succesfully uploaded .
But I have error :
POST BaseUrl/1f510b93-5177-4880-447d-08d6fe7a9498/upload (500) {
Message = "Internal Server Error. - System.NullReferenceException: Object reference not set to an instance of an object. \n at
MaterialService.UploadAsync(Guid Id, IFormFile file)
I guid Id send in URL, file with multipartFormData. Upload on Sawager is work. TY
I'm getting error 401 trying to make a request using custom headers, when I print the headers, it is there, just like I make a call using postman, the difference is that in postman the request works, but in the app I get that error, I don't think it is the headers, because as I said they are there, what am I missing here?
func getUserByID(completion: #escaping CompletionHandler) {
let url_id = URL_USER_ID + String(self.userID)
let header:HTTPHeaders = [
"Content-Type": "application/json",
"Authorization": "Token " + AuthService.instance.authToken
]
Alamofire.request(url_id, method: .get, parameters: nil, encoding: JSONEncoding.default, headers: header).responseJSON{
(response) in
guard let data = response.data else {return}
let json = try? JSON(data: data)
if response.response?.statusCode == 200 {
let user = json!["user"]
let id = user["id"].stringValue
let email = user["email"].stringValue
let img = user["img"].stringValue
let tipo_usuario = user["tipo_usuario"].intValue
let nome_comp = user["nome_comp"].stringValue
let end_cep = user["end_cep"].stringValue
let end_logr = user["end_logr"].stringValue
let end_num = user["end_num"].stringValue
let end_bairro = user["end_bairro"].stringValue
let end_complm = user["end_complm"].stringValue
let cidade = user["cidade"]
let cidadeID = cidade["id"].intValue
let cidadeNome = cidade["nome"].stringValue
let cidadeEstado = cidade["estado"].stringValue
let telefone = user["telefone"].stringValue
let whatsapp = user["whatsapp"].stringValue
let pontos = user["pontos"].intValue
let cnpj_cpf = user["cnpj_cpf"].stringValue
let razao_social = user["razao_social"].stringValue
let nome_fantasia = user["nome_fantasia"].stringValue
let insc_estadual = user["insc_estadual"].stringValue
let categoria = user["categoria"].intValue
let nota = user["nota"].stringValue
let cidadeUser = Cidades(id: cidadeID, nome: cidadeNome, estado: cidadeEstado)
UserDataService.instance.setUserData(id: id, email: email, img: img, tipo_usuario: tipo_usuario, nome_comp: nome_comp, end_cep: end_cep, end_logr: end_logr, end_num: end_num, end_bairro: end_bairro, end_complm: end_complm ,cidade: cidadeUser, telefone: telefone, whatsapp: whatsapp, pontos: pontos, cnpj_cpf: cnpj_cpf, razao_social: razao_social, nome_fantasia: nome_fantasia, insc_estadual: insc_estadual, categoria: categoria, nota: nota)
self.userEmail = email
self.userID = Int(id)!
completion(true)
} else if response.response?.statusCode == 400 {
completion(false)
} else {
debugPrint(response.result.error as Any)
}
}
}enter code here
and the error message:
Error=-25300, query={
atyp = http;
class = inet;
"m_Limit" = "m_LimitAll";
ptcl = http;
"r_Attributes" = 1;
sdmn = "api.ddns.net";
srvr = "api.ddns.net";
sync = syna;
}
$ curl -v \
-H "Content-Type: application/json" \
-H "Accept-Language: en;q=1.0, pt-BR;q=0.9" \
-H "Authorization: Token 4e97e608c72636052583a1bb1c170485417a739b" \
-H "User-Agent: clubelocal/1.0 (com.api; build:1; iOS 11.2.0) Alamofire/4.7.0" \
-H "Accept-Encoding: gzip;q=1.0, compress;q=0.5" \
"http://api.ddns.net:8000/users/25"
Optional({
"detail" : "the user credentials was not provided."
})
I faced similar issue like:
Postman performed request with success, but alamofire
with 401 JWT Token not found. So the response was a failure, but server performed action for the request like it was success.
In my case it turned out to be redirection.
You should check if it is not due to redirection, because by default Alamofire doesn't pass authorization field in header to redirected request (this seems to be reasonable behavior in such case).
So to make authorization transmissible you can do it like:
Alamofire.SessionManager.default.delegate.taskWillPerformHTTPRedirection = { session, task, response, request in
var redirectedRequest = request
if let originalRequest = task.originalRequest,
let headers = originalRequest.allHTTPHeaderFields,
let authorizationHeaderValue = headers["Authorization"]
{
var mutableRequest = request
mutableRequest.setValue(authorizationHeaderValue, forHTTPHeaderField: "Authorization")
redirectedRequest = mutableRequest
}
return redirectedRequest
}
//now use your requests i.e:
Alamofire.request(url, method: .post, parameters: params, encoding: JSONEncoding.default, headers: header)
.validate()
.responseJSON(completionHandler: { (response) in
switch response.result {
case .success:
//success
break
case .failure(let error):
//fail
break
}
})
If you want to return to default behavior just simply:
Alamofire.SessionManager.default.delegate.taskWillPerformHTTPRedirection = nil
I am trying to receive an access token from PayPal's server using the authorization code in a Sandbox environment. I believe the problem is in converting curl to an Alamofire request, but I'm not sure. Any help is appreciated.
Here is my code for sending authorization to server:
func sendAuthorizationToServer(authorization: [AnyHashable: Any]) {
let jsonAuth = JSON(authorization)
let headers = [
"content-type": "application/x-www-form-urlencoded; charset=utf-8",
]
let parameters = [
"client_id": Constants.payPalSandboxID,
"client_secret": Constants.payPalSandboxSecret,
"grant_type": "authorization_code",
"redirect_uri": "urn:ietf:wg:oauth:2.0:oob",
"code": jsonAuth["response"]["code"].stringValue
]
Alamofire.request("https://api.sandbox.paypal.com/v1/oauth2/token", method: .post, parameters: parameters, encoding: URLEncoding.default, headers: headers).responseJSON { response in
print(response.request)
print(response.response)
print(response.data)
print(response.error)
}
}
I've checked jsonAuth["response"]["code"].stringValue and it is returning a correct authorization code.
My doubts are if it should be a .post request or a .get request, and if my credentials in the parameters are in the correct order/structure.
Here is the output of the last print statements:
Here is the SDK link for exchanging an authorization code for the access token:
https://github.com/paypal/PayPal-iOS-SDK/blob/master/docs/future_payments_server.md#exchange-authorization-code-for-refresh--access-tokens
import SwiftyJSON
import Alamofire
// ... ...
// ... ...
// ... ...
let credentialData = "\(paypalClientId):\(paypalSecret)".data(using: String.Encoding.utf8)!
let base64Credentials = credentialData.base64EncodedString(options: [])
let headers = [
"Authorization": "Basic \(base64Credentials)",
]
let params:[String: Any] = [
"grant_type": "client_credentials",
]
Alamofire.request(tokenAPI, method: .post, parameters: params, encoding: URLEncoding.default, headers: headers)
.validate()
.responseJSON { (response) in
debugPrint(response)
switch response.result {
case .success(let data):
let json = JSON(data)
let accessToken = json["access_token"].stringValue
break;
case .failure(let error):
debugPrint(error)
debugPrint(response.data)
}
}
Please note that encoding must be URLEncoding.default not the JSONEncoding.default
I have this curl post that works fine, but for the life of me I can't get it to work with either NSURLSession or Alamofire. The curl that returns fine is:
curl https://api.truevault.com/v1/vaults/XXXXXX-XXXX-XXXX-XXXX-XXXXXXXX/blobs \
-X POST \
-u yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyy: \
--form "file=#foo.pdf" \
-H "Content-Type:multipart/form-data"
No matter what variation of curl or NSURLSession I do I get a 401 error, but it completes successful with curl! Please help! Thanks!
CURRENT ALAMOFIRE ATTEMPT
let headers = ["Authorization": Config.trueVaultKey, "Content-Type": "multipart/form-data"]
Alamofire.upload(
Alamofire.Method.POST,
url!,
headers: headers,
multipartFormData: { multipartFormData in
multipartFormData.appendBodyPart(
data: dat!,
name: "file",
fileName: "license.png",
mimeType: "image/png"
)
},
encodingCompletion: { encodingResult in
switch encodingResult {
case .Success(let upload, _, _):
upload.responseString { response in
//JSON = response.result.value! as String
debugPrint(response)
print("\n\n\nREQUEST HEADER: \(response.request!.allHTTPHeaderFields!)")
print("\n\n\nREQUEST BODY: \(response.request!.HTTPBody)")
print("\n\n\nREQUEST BODY STREAM: \(response.request!.HTTPBodyStream)")
}
case .Failure(let encodingError):
print(encodingError)
}
})
try to build your URL like this :
let userAuth = "username:password" // credential
let url = "https://\(userAuth)#api.truevault.com/v1/vaults/XXXXXX-XXXX-XXXX-XXXX-XXXXXXXX/blobs" // notice the at(#) sign
do not set the headers, they will be set automatically.