So I want to create a post request with the following output:
"user"=>{"email"=>"test#test.com", "password"=>"[FILTERED]", "password_confirmation"=>"[FILTERED]"}
Instead I get:
{"user[password_confirmation]"=>"[FILTERED]", "user[email]"=>"test#test.com", "user[password]"=>"[FILTERED]", "user"=>{}}
This is the code I use to make this post request:
let request = NSMutableURLRequest(URL: NSURL(string: urlString)!)
let session = NSURLSession.sharedSession()
let params = ["user[email]":username.text!, "user[password]":password.text!, "user[password_confirmation]":passwordRepeated.text!]
request.HTTPBody = try? NSJSONSerialization.dataWithJSONObject(params, options: [])
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
request.addValue("application/json", forHTTPHeaderField: "Accept")
request.HTTPMethod = "POST"
let task = session.dataTaskWithRequest(request, completionHandler: { data, response, error -> Void in
print(request.HTTPBody)
print(params)
print(error)
print(response)
print(data)
})
task.resume()
So how do I correctly create my params?
You are composing params incorrectly.
Do it like this,
let params = [
"user": [
"email": username.text!,
"password": password.text!,
"password_confirmation": passwordRepeated.text!
]
]
Related
I am trying to add a subscriber to my mailing list from my Swift 5 iOS app. I am seeing the following error when trying to do this:
{
detail = "Your request did not include an API key.";
instance = "3f4cb654-c674-4a97-adb8-b4eb6d86053a";
status = 401;
title = "API Key Missing";
type = "http://developer.mailchimp.com/documentation/mailchimp/guides/error-glossary/";
}
Of course this indicates that I am missing my API Key, however I am specifying it in the Authorization header (see below code). I have tried a mix of the answer here and the guide here but I'm not having much luck so far. Here's my current code for setting up the request:
let mailchimpAPIURL = "https://us3.api.mailchimp.com/3.0"
let requestURL = NSURL(string: mailchimpAPIURL)!
let apiCredentials = "anystring:<API_KEY>"
let loginData = apiCredentials.data(using: String.Encoding.utf8)!.base64EncodedString()
let params = [
"list_id": "<LIST_ID>",
"email_address": email,
"status": "subscribed",
"merge_vars": [
"FNAME": firstName,
"LNAME": lastName
]
] as [String: Any]
let request = NSMutableURLRequest(url: requestURL as URL)
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
request.addValue("application/json", forHTTPHeaderField: "Accept")
request.setValue("Basic \(loginData)", forHTTPHeaderField: "Authorization")
do {
request.httpBody = try JSONSerialization.data(withJSONObject: params, options: [])
} catch {
return
}
You need to send api key in the authorization header like this:
let params: [String: AnyObject] = ["email_address": email, "status": "subscribed"]
guard let url = "https://us10.api.mailchimp.com/3.0/lists/<listID>/members/".stringByAddingPercentEscapesUsingEncoding(NSUTF8StringEncoding) else { return }
let credentialData = "user:<apikey>".dataUsingEncoding(NSUTF8StringEncoding)!
let base64Credentials = credentialData.base64EncodedStringWithOptions([])
let headers = ["Authorization": "Basic \(base64Credentials)"]
Alamofire.request(.POST, url, headers: headers, parameters: params, encoding: .URL)
.responseJSON { response in
if response.result.isFailure {
}
else if let responseJSON = response.result.value as? [String: AnyObject] {
}
}
Okay, I got it. #Sam's answer helped me realise that the URL I was using was wrong, and I needed to add the ListID into that URL. I also changed setValue to addValue, and changed NSMutableURLRequest to URLRequest. I also added request.httpMethod = "POST" Here is my updated, working code:
let subscribeUserURL = "https://us3.api.mailchimp.com/3.0/lists/<LISTID>/members/"
let requestURL = NSURL(string: subscribeUserURL)!
let apiCredentials = "anystring:<APIKEY>"
let loginData = apiCredentials.data(using: String.Encoding.utf8)!.base64EncodedString()
let params = [
"email_address": email,
"status": "subscribed",
"merge_fields": [
"FNAME": firstName,
"LNAME": lastName
]
] as [String: Any]
var request = URLRequest(url: requestURL as URL)
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
request.addValue("application/json", forHTTPHeaderField: "Accept")
request.addValue("Basic \(loginData)", forHTTPHeaderField: "Authorization")
request.httpMethod = "POST"
do {
request.httpBody = try JSONSerialization.data(withJSONObject: params, options: [])
} catch {
return
}
request.httpMethod = "POST"
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
let httpbody = object.data(using: String.Encoding.utf8)
request.httpBody = httpbody
You can directly generate a code from postman itself. Also, for your reference, you can call post request with row body as given below.
let headers = [
"content-type": "application/json",
"cache-control": "no-cache"
]
let parameters = ["order": ["line_items": [
["variant_id": 18055889387589,
"quantity": 1]
]]] as [String : Any]
let postData = try? JSONSerialization.data(withJSONObject: parameters, options: [])
if let data = postData {
let request = NSMutableURLRequest(url: NSURL(string: "http://")! as URL,
cachePolicy: .useProtocolCachePolicy,
timeoutInterval: 10.0)
request.httpMethod = "POST"
request.allHTTPHeaderFields = headers
request.httpBody = data as Data
let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
if (error != nil) {
print(error?.localizedDescription ?? "")
} else {
let httpResponse = response as? HTTPURLResponse
print(httpResponse?.statusCode ?? 0)
let reponseData = String(data: data!, encoding: String.Encoding.utf8)
print("responseData: \(reponseData ?? "Blank Data")")
}
})
dataTask.resume()
}
Let me know if you have any query.
Thanks.
I'm trying to send an email with the Mailjet API v3 with a http post request but I'm getting an error 400.
I used the exact same body with success in Javascript, but I guess the error 400 is related with it...
Any ideas ?
var recipients = [Any]()
recipients.append(["Email": "email#gmail.com"])
var body: [String: Any] = [
"FromEmail": "anEmail#gmail.com",
"FromName": "Me",
"Subject": "YEEES",
"Text-part": "Greetings from IOS ;)",
"Recipients": recipients
]
var request = URLRequest(url: self.apiURL)
request.httpMethod = "POST"
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
request.setValue("Authorization", forHTTPHeaderField: "Basic <keysInBase64>")
do {
request.httpBody = try JSONSerialization.data(withJSONObject: body, options: [])
}
catch {
print("error during JSON serialization")
dump(error)
return
}
let session = URLSession.shared
let task = session.dataTask(with: request, completionHandler: { (data, response, error) in
print(error)
print(response)
print(data)
})
task.resume()
Headers was wrong...
I was doing :
request.setValue("Authorization", forHTTPHeaderField: "Basic <keysInBase64>")
Instead of :
request.setValue("Basic <keysInBase64>", forHTTPHeaderField: "Authorization")
Using the Charles Proxy as suggested by #LouFranco, I was able to find the mistake.
I'm trying to send a Patch request with a serialized JSON Body.
For some reason the server is not able to receive the body properly. I have a feeling that there seems to be a problem with the PATCH method in combination with the http request body.
let sessionConfig = NSURLSessionConfiguration.defaultSessionConfiguration()
let session = NSURLSession(configuration: sessionConfig, delegate: nil, delegateQueue: nil)
var URL = B2MFetcher.urlForBooking(event.unique, bookingID: booking.unique)
let request = NSMutableURLRequest(URL: URL)
request.HTTPMethod = "PATCH"
// Headers
println(token)
request.addValue(token, forHTTPHeaderField: "Authorization")
request.addValue("gzip, identity", forHTTPHeaderField: "Accept-Encoding")
// JSON Body
let bodyObject = [
"op": "cancel"
]
var jsonError: NSError?
request.HTTPBody = NSJSONSerialization.dataWithJSONObject(bodyObject, options: nil, error: &jsonError)
/* Start a new Task */
let task = session.dataTaskWithRequest(request, completionHandler: { (data : NSData!, response : NSURLResponse!, error : NSError!) -> Void in
completion(data: data, response:response , error: error)
})
task.resume()
You could try to add a Content-Type header to the request:
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
or use one of the other JSON Content-Type formats described here.
I tested it with an ExpressJS server and without the Content-Type header the server got an empty body, but with a Content-Type header it worked well.
in swift 3/4 :
let request = NSMutableURLRequest(url: NSURL(string: "http://XXX/xx/xxx/xx")! as URL)
request.httpMethod = "PATCH"
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
do{
let json: [String: Any] = ["status": "test"]
let jsonData = try? JSONSerialization.data(withJSONObject: json)
request.httpBody = jsonData
print("jsonData: ", String(data: request.httpBody!, encoding: .utf8) ?? "no body data")
} catch {
print("ERROR")
}
let task = URLSession.shared.dataTask(with: request as URLRequest) {
data, response, error in
if error != nil {
print("error=\(error)")
completion(false)
return
}
let responseString = NSString(data: data!, encoding: String.Encoding.utf8.rawValue)
print("responseString = \(responseString)")
completion(true)
return
}
task.resume()
Simple Way to use patch without using HTTPBody
If you want to just use patch, you just need to change the value of the name of a specific user then it will be like:
let myurl = URL(string: "https://gorest.co.in/public-api/users/"+"\(id)?"+"name=abc")!
var request = URLRequest(url:myurl)
request.addValue("Bearer yourAuthorizationToken",forHTTPHeaderField:"Authorization")
request.httpMethod = "PATCH"
let dataTask = URLSession.shared.dataTask(with: request)
dataTask.resume()
Note: here "id" will be userId
I figured it out solution at the bottom
I am trying to make an HTTP post request to my server. Here's what I did
var request : NSMutableURLRequest = NSMutableURLRequest(URL : NSURL(string : "myURL")
let session : NSURLSession = NSURLSession.sharedSession()
request.allHTTPHeaderFields = (headers as [NSObject : AnyObject])
request.HTTPShouldHandleCookies = true
request.HTTPMethod = "POST"
var postData = "frontend=iOS"
request.HTTPBody = postData.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: true)
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
request.addValue("application/json", forHTTPHeaderField: "Accept")
NSHTTPCookieStorage.sharedHTTPCookieStorage().cookieAcceptPolicy = NSHTTPCookieAcceptPolicy.Always
println(request.allHTTPHeaderFields)
println(request.HTTPBody)
let task = session.dataTaskWithRequest(request, completionHandler: {data, response, error -> Void in
let json:JSON = JSON(data: data)
println(json)
onCompletion(json, error)
})
task.resume()
this is not setting the HTTPRequest.POST
I tried printing the request to the server on the server side. IT said post was empty
POST : [QueryDict : {}]
What am I missing here? Any help is appreciated
Solution :
I mistakenly set the content-value to application/json when in fact it
was not a json body. Removing it solved the problem
use https://github.com/Alamofire/Alamofire
easy networking :)
Alamofire.request(.GET, "http://httpbin.org/get", parameters: ["foo": "bar"])
.response { (request, response, data, error) in
println(request)
println(response)
println(error)
}
you can use all of the below.
public enum Method: String {
case OPTIONS = "OPTIONS"
case GET = "GET"
case HEAD = "HEAD"
case POST = "POST"
case PUT = "PUT"
case PATCH = "PATCH"
case DELETE = "DELETE"
case TRACE = "TRACE"
case CONNECT = "CONNECT"
}
Heres the method I used in my logging library: https://github.com/goktugyil/QorumLogs
var url = NSURL(string: urlstring)
var request = NSMutableURLRequest(URL: url!)
request.HTTPMethod = "POST"
request.setValue("application/x-www-form-urlencoded; charset=utf-8", forHTTPHeaderField: "Content-Type")
request.HTTPBody = postData.dataUsingEncoding(NSUTF8StringEncoding)
var connection = NSURLConnection(request: request, delegate: nil, startImmediately: true)
See How to escape the HTTP params in Swift on the way to correctly encode key-value pairs into the data string.