how to make get request with Authorization api key value in header Swift - swift

below is my get request code. but getting 403 error ...please help!
func getUser(completion: #escaping(Result<User?, AuthenticationError>)-> Void) {
let loginVM = LoginViewModel()
let token = loginVM.accessToken
guard let url = URL(string: myURL) else {
completion(.failure(.custom(errorMessage: "URL is not correct")))
return
}
var request = URLRequest(url:url)
request.httpMethod = "GET"
request.setValue("Bearer \(token)", forHTTPHeaderField: "Authorization")
URLSession.shared.dataTask(with: request) { (data, response, error) in
guard let data = data, error == nil else {
completion(.failure(.custom(errorMessage: "No data")))
return
}
guard let registerResponse = try? JSONDecoder().decode(User.self, from: data) else{
completion(.failure(.custom(errorMessage: "no response")))
return
}
completion(.success(User))
}.resume()
}
and instruction from my backend guy for this part is this :
I tested on Postman It work as like charm. It must be happen in my request code with Authorization....

Related

swiftUI : How I can try to do POST API Call with parameters and headers

class TranslateModel : ObservableObject {
func translateCall() {
guard let url = URL(string: "https://openapi.naver.com/v1/papago/n2mt") else { return }
print(1)
let param = "source=en&target=kr&text=hi"
let paramData = param.data(using: .utf8)
var request = URLRequest(url: url)
print(2)
request.httpMethod = "POST"
request.httpBody = paramData
print(3)
request.addValue("application/x-www-form-urlencoded; charset=UTF-8", forHTTPHeaderField: "Content-Type")
request.addValue("3Bwy8lMkuAgZOyDHm1Z3", forHTTPHeaderField: "X-Naver-Client-Id")
request.addValue("gg391Jc1Ge", forHTTPHeaderField: "X-Naver-Client-Secret")
print(4)
let data = URLSession.shared.dataTask(with: request) { data, response, error in
guard let data = data else { fatalError() }
print(5)
guard error == nil else { fatalError()}
print(6)
guard let response = response as? HTTPURLResponse, response.statusCode >= 200 && response.statusCode < 300 else {return}
print(7)
print(data)
}
}
}
Firstly, Please check my code and screenshot.
I tried to do POST API with parameters and headers.
However, when I call the method, It's not working.
So, I checked the step of method, And found that the URLsession with request was not working.
But, I don't know what the problem is.
I think maybe parameters or headers faults.
could you let me know how I can solve this?

How can I make a POST Request in Swift with parameters using URLSession

I have a post request that I want to make using URLSession.
The post request looks like this:
curl -X POST 'https://smartdevicemanagement.googleapis.com/v1/enterprises/privatekey/devices/devicekey:executeCommand' -H 'Content-Type: application/json' -H 'Authorization: authtoken' --data-raw '{
"command" : "sdm.devices.commands",
"params" : {
"commandName" : "cmdValue"
}
}'
As this is a POST request, I want to only decode if the response is an error message.
Here is the code I currently have:
guard let url = URL(string: "https://smartdevicemanagement.googleapis.com/v1/enterprises/\(project_id)/devices") else {return}
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
request.addValue("token", forHTTPHeaderField: "Authorization")
let cmdParams: [String: String] = ["command":"sdm.devices.commands", "params" : ["commandName": "cmdValue"]]
do {
request.httpBody = try JSONSerialization.data(withJSONObject: cmdParams)
} catch let error {
print(error.localizedDescription)
}
URLSession.shared.dataTask(with: request) { (data, response, error) in
guard error == nil else {print(error!.localizedDescription); return }
guard let data = data else {print("empty data"); return }
The cmdParams are throwing an error, so I'm not sure how to structure the params request properly, a successful POST will result in the API returning {} an unsuccessful request will return some error.
How can I adjust my code to get this working?
You need to encode the JSON string as data. Then you can add it as the httpBody. Don't forget to add the token to the request.
// Encode your JSON data
let jsonString = "{ \"command\" : \"sdm.devices.commands\", \"params\" : { \"commandName\" : \"cmdValue\" } }"
guard let jsonData = jsonString.data(using: .utf8) else { return }
// Send request
guard let url = URL(string: "https://smartdevicemanagement.googleapis.com/v1/enterprises/\(project_id)/devices") else {return}
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.httpBody = jsonData
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
request.setValue("token", forHTTPHeaderField: "Authorization") // Most likely you want to add some token here
// request.setValue("Bearer \(accessToken)", forHTTPHeaderField: "Authorization")
let task = URLSession.shared.dataTask(with: request) { (data, response, error) in
if let error = error {
// Handle HTTP request error
} else if let data = data {
// Handle HTTP request response
} else {
// Handle unexpected error
}
}
task.resume()
You could try using "urlencoded" to encode your request body. Here is my test code:
(note, since I do not have a paid subscription to this service I cannot fully test my code)
struct ContentView: View {
let project_id = 123 // <-- adjust to your needs
var body: some View {
Text("testing")
.onAppear {
if let url = URL(string: "https://smartdevicemanagement.googleapis.com/v1/enterprises/\(project_id)/devices") {
doPOST(url: url)
}
}
}
func doPOST(url: URL) {
var request = URLRequest(url: url)
request.httpMethod = "POST"
// try urlencoding
request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
request.setValue("token", forHTTPHeaderField: "Authorization") // <-- your api "token" here
var components = URLComponents(url: url, resolvingAgainstBaseURL: false)!
components.queryItems = [
URLQueryItem(name: "command", value: "sdm.devices.commands"),
URLQueryItem(name: "params", value: "{ \"commandName\" : \"cmdValue\" }")
]
if let query = components.url!.query {
print("--> query: \(query)")
request.httpBody = Data(query.utf8)
}
let task = URLSession.shared.dataTask(with: request) { data, response, error in
showResponse(data) // <-- for debuging
guard error == nil else { print("--> error: \(error)"); return }
guard let data = data else { print("empty data"); return }
}
task.resume()
}
func showResponse(_ data: Data?) {
if let data = data, let json = try? JSONSerialization.jsonObject(with: data, options: .mutableContainers), let jsonData = try? JSONSerialization.data(withJSONObject: json, options: .prettyPrinted) {
print("\n---> response: " + String(decoding: jsonData, as: UTF8.self))
} else {
print("=========> error")
}
}
}
If this does not work, have a look at this doc:
https://developers.google.com/nest/device-access/reference/rest/v1/enterprises.devices/executeCommand
In particular: The URL uses gRPC Transcoding syntax. It may be relevant.

POST to Web API always returns nil

I'm just learning Web APIs with Swift.
And I've done as follows
Make some basic configuration
let session = URLSession(configuration: .default)
// Prepare URL #the URL is virtual now
let url = URL(string: "http://something.com/api")
guard let requestUrl = url else { fatalError() }
// Prepare URL Request Object
var request = URLRequest(url: requestUrl)
request.httpMethod = "POST"
Set Post parameter
let parameters: [String: String] = [
"user_ID": "1",
]
let jsonData = try JSONEncoder().encode(parameters)
request.httpBody = jsonData
Take request to our web api
// Perform HTTP Request
let task = URLSession.shared.dataTask(with: request) { (data: Data?, response: URLResponse?, error: Error?) in
// Check for Error
if let error = error {
print("Error took place \(error)")
return
}
guard let data = data else { return }
do {
let myEnterprise = try JSONDecoder().decode(Enterprise.self, from: data)
print("Response data:\n \(myEnterprise)")
print("Response data:\n \(myEnterprise.returnData)")
} catch let jsonErr {
print(jsonErr)
}
}
task.resume()
myEnterprise is always nil. Can anyone help me?

Call Rest API from Swift3

I trying to send a POST request in swift for example :
url = "http://localhost:9080/mfp/api/az/v1/token"
Headers :
Authorization = "Basic UGlua0NhclBhc3NlbmdlcjoxMjM0"
Content-Type = "application/x-www-form-urlencoded"
Body :
grant_type = client_credentials
scope = RegisteredClient messages.write push.application.com.XXX
What's simple way to do it ?
I've tried by use IBMMobileFirstPlatformFoundation SDK, it's return error "Can't not connect to server",but i'm sure that the connect still good... Here's my code :
let urlString = "http://localhost:9080/mfp/api/az/v1/token"
let url1 = URL(string: urlString)
let request1 = WLResourceRequest(url: url1! as URL, method: WLHttpMethodPost)!
request1.addHeaderValue("Basic UGlua0NhclBhc3NlbmdlcjoxMjM0" as NSObject, forName: "Authorization")
request1.addHeaderValue("application/x-www-form-urlencoded" as NSObject, forName: "Content-Type")
request1.send(withBody: "{\"grant_type\":\"client_credentials\",\"scope\":\"RegisteredClient messages.write push.application.com.XXX\"}", completionHandler: { (response, error) in
if error == nil {
print("Response : ")
print(response)
} else {
print("Error : ")
print(error)
}
})
You can use Alamofire as ZassX suggested or you can use URLSession.
I have some code as an example:
func postRequest(toUrl url: String, accessKey: String?, completion: #escaping(Data?, HTTPURLResponse?, Error?, AnyObject?) -> Void){
let requestUrl = NSURL(string: url)
let request = NSMutableURLRequest(url: requestUrl! as URL)
if accessKey != nil {
request.setValue("\(accessKey!)", forHTTPHeaderField: "Authorization")
}
request.addValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
request.httpMethod = "POST"
request.httpBody = yourBody
URLSession.shared.dataTask(with: request as URLRequest, completionHandler: { (data,response,error) in
if let content = data{
do{
let myJSON = try JSONSerialization.jsonObject(with: content, options: JSONSerialization.ReadingOptions.mutableContainers) as AnyObject
completion(data as Data?, response as? HTTPURLResponse, error, myJSON)
}
catch{
print("JSON ERROR")
}
}else{
completion(data as Data?, response as? HTTPURLResponse, error, nil)
}
}).resume()
}
First, you don't manually manage the security token when you're using the MobileFirst SDK, it's handled automatically.
Next, WLResourceRequest() takes a URL that is relative to the MobileFirst server URL (http://localhost:9080/mfp, in your case). You can see that "base" URL in your mfpclient.plist file.
Your code will then look something like
let request = WLResourceRequest(
URL: NSURL(string: "/adapters/MyAdapter/myResource"),
method: WLHttpMethodGet
)
See https://mobilefirstplatform.ibmcloud.com/tutorials/en/foundation/8.0/application-development/resource-request/ios/

Swift 3 IBM Lotus Domino authentication

I am very new to XCODE and iOS and I can't figure out how to do an authentication on IBM Domino server. I am trying to do a simple app to get some data from the server.
This is the latest version of my attempt. Bear in mind, that couldn't find information on what IBM Domino server needs. But I've done tons of authentications with javascript. I've deliberatly left the commented part, which is one of the attempts to do a login.
func doLogin(){
print("entered doLogin")
let myUrl: String = "https://url.com/names?login"
guard let url = URL(string: myUrl.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)!)else {
print("Error: cannot create URL")
return
}
var request = URLRequest.init(url: url)
request.httpMethod = "POST"
let params = ["Username":String(describing: self.username), "Password":String(describing: self.password)]
request.httpBody = try? JSONSerialization.data(withJSONObject: params, options: [])
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
//URLSession.shared.dataTask(with: request) { (data:Data?, response:URLResponse?, error:Error?) in
// if let safeData = data{
// print("response: \(String(data:safeData, encoding:.utf8))")
// }
//}
//let postString = "Username=\(String(describing: self.username))&Password=\(String(describing: self.password))"
//request.httpBody = postString.data(using:String.Encoding.utf8)
request.timeoutInterval = 30.0
//print(request)
let configuration = URLSessionConfiguration.default
let session = URLSession(configuration : configuration)
//let session = URLSession(configuration: configuration, delegate: self as! URLSessionDelegate, delegateQueue: nil)
let task = session.dataTask(with: request) {
(data : Data?, response:URLResponse?, error) in
// check for any errors
guard error == nil else {
print("error calling POST on url")
print(error!)
return
}
// make sure we got data
guard let responseData = data else {
print("Error: did not receive data")
return
}
do {
print ("responseData:")
print(responseData)
}
}
//print ("response:")
//print(task.response)
task.resume()