comment est-il possible d'envoyer une demande POST avec une simple chaîne dans le corps HTTP avec Alamofire dans mon application iOS?
Par défaut, Alamofire a besoin de paramètres pour une requête:
Alamofire.request(.POST, "http://mywebsite.com/post-request", parameters: ["foo": "bar"])
Ces paramètres contiennent des paires clé-valeur. Mais je ne veux pas envoyer de requête avec une chaîne clé-valeur dans le corps HTTP.
Je veux dire quelque chose comme ça:
Alamofire.request(.POST, "http://mywebsite.com/post-request", body: "myBodyString")
Votre exemple Alamofire.request(.POST, "http://mywebsite.com/post-request", parameters: ["foo": "bar"])
contient déjà la chaîne "foo = bar" en tant que corps ..____. Mais si vous voulez vraiment une chaîne au format personnalisé. Tu peux le faire:
Alamofire.request(.POST, "http://mywebsite.com/post-request", parameters: [:], encoding: .Custom({
(convertible, params) in
var mutableRequest = convertible.URLRequest.copy() as NSMutableURLRequest
mutableRequest.HTTPBody = "myBodyString".dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)
return (mutableRequest, nil)
}))
Remarque: parameters
ne devrait pas être nil
UPDATE (Alamofire 4.0, Swift 3.0):
Dans Alamofire 4.0, l'API a changé. Donc pour l'encodage personnalisé, nous avons besoin de valeur/objet conforme au protocole ParameterEncoding
.
extension String: ParameterEncoding {
public func encode(_ urlRequest: URLRequestConvertible, with parameters: Parameters?) throws -> URLRequest {
var request = try urlRequest.asURLRequest()
request.httpBody = data(using: .utf8, allowLossyConversion: false)
return request
}
}
Alamofire.request("http://mywebsite.com/post-request", method: .post, parameters: [:], encoding: "myBody", headers: [:])
Tu peux le faire:
Mettez dans httpBody les données
var request = URLRequest(url: URL(string: url)!)
request.httpMethod = HTTPMethod.post.rawValue
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
let pjson = attendences.toJSONString(prettyPrint: false)
let data = (pjson?.data(using: .utf8))! as Data
request.httpBody = data
Alamofire.request(request).responseJSON { (response) in
print(response)
}
Si vous utilisez Alamofire, il suffit de coder le type "URLEncoding.httpBody"
Avec cela, vous pouvez envoyer vos données sous forme de chaîne dans httpbody, bien que vous les ayez définies json dans votre code.
Cela a fonctionné pour moi ..
MISE À JOUR pour
var url = "http://..."
let _headers : HTTPHeaders = ["Content-Type":"application/x-www-form-urlencoded"]
let params : Parameters = ["grant_type":"password","username":"mail","password":"pass"]
let url = NSURL(string:"url" as String)
request(url, method: .post, parameters: params, encoding: URLEncoding.httpBody , headers: _headers).responseJSON(completionHandler: {
response in response
let jsonResponse = response.result.value as! NSDictionary
if jsonResponse["access_token"] != nil
{
access_token = String(describing: jsonResponse["accesstoken"]!)
}
})
J'ai modifié la réponse de @ Silmaril pour étendre le gestionnaire d'Alamofire. Cette solution utilise EVReflection pour sérialiser directement un objet:
//Extend Alamofire so it can do POSTs with a JSON body from passed object
extension Alamofire.Manager {
public class func request(
method: Alamofire.Method,
_ URLString: URLStringConvertible,
bodyObject: EVObject)
-> Request
{
return Manager.sharedInstance.request(
method,
URLString,
parameters: [:],
encoding: .Custom({ (convertible, params) in
let mutableRequest = convertible.URLRequest.copy() as! NSMutableURLRequest
mutableRequest.HTTPBody = bodyObject.toJsonString().dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)
return (mutableRequest, nil)
})
)
}
}
Ensuite, vous pouvez l'utiliser comme ceci:
Alamofire.Manager.request(.POST, endpointUrlString, bodyObject: myObjectToPost)
Si vous voulez poster une chaîne en tant que corps brut dans la demande
return Alamofire.request(.POST, "http://mywebsite.com/post-request" , parameters: [:], encoding: .Custom({
(convertible, params) in
let mutableRequest = convertible.URLRequest.copy() as! NSMutableURLRequest
let data = ("myBodyString" as NSString).dataUsingEncoding(NSUTF8StringEncoding)
mutableRequest.HTTPBody = data
return (mutableRequest, nil)
}))
func paramsFromJSON(json: String) -> [String : AnyObject]?
{
let objectData: NSData = (json.dataUsingEncoding(NSUTF8StringEncoding))!
var jsonDict: [ String : AnyObject]!
do {
jsonDict = try NSJSONSerialization.JSONObjectWithData(objectData, options: .MutableContainers) as! [ String : AnyObject]
return jsonDict
} catch {
print("JSON serialization failed: \(error)")
return nil
}
}
let json = Mapper().toJSONString(loginJSON, prettyPrint: false)
Alamofire.request(.POST, url + "/login", parameters: paramsFromJSON(json!), encoding: .JSON)
Je l'ai fait pour tableau de chaînes. Cette solution est ajustée pour la chaîne dans le corps.
Le chemin "natif" d'Alamofire 4:
struct JSONStringArrayEncoding: ParameterEncoding {
private let myString: String
init(string: String) {
self.myString = string
}
func encode(_ urlRequest: URLRequestConvertible, with parameters: Parameters?) throws -> URLRequest {
var urlRequest = urlRequest.urlRequest
let data = myString.data(using: .utf8)!
if urlRequest?.value(forHTTPHeaderField: "Content-Type") == nil {
urlRequest?.setValue("application/json", forHTTPHeaderField: "Content-Type")
}
urlRequest?.httpBody = data
return urlRequest!
}
}
Et ensuite faites votre demande avec:
Alamofire.request("your url string", method: .post, parameters: [:], encoding: JSONStringArrayEncoding.init(string: "My string for body"), headers: [:])
J'ai utilisé la réponse de @afrodev comme référence. Dans mon cas, je considère les paramètres de ma fonction comme des chaînes qui doivent être postées dans une requête. Alors, voici le code:
func defineOriginalLanguage(ofText: String) {
let text = ofText
let stringURL = basicURL + "identify?version=2018-05-01"
let url = URL(string: stringURL)
var request = URLRequest(url: url!)
request.httpMethod = HTTPMethod.post.rawValue
request.setValue("text/plain", forHTTPHeaderField: "Content-Type")
request.httpBody = text.data(using: .utf8)
Alamofire.request(request)
.responseJSON { response in
print(response)
}
}
Basé sur la réponse de Illya Krit
import Alamofire
struct BodyStringEncoding: ParameterEncoding {
private let body: String
init(body: String) { self.body = body }
func encode(_ urlRequest: URLRequestConvertible, with parameters: Parameters?) throws -> URLRequest {
guard var urlRequest = urlRequest.urlRequest else { throw Errors.emptyURLRequest }
guard let data = body.data(using: .utf8) else { throw Errors.encodingProblem }
urlRequest.httpBody = data
return urlRequest
}
}
extension BodyStringEncoding {
enum Errors: Error {
case emptyURLRequest
case encodingProblem
}
}
extension BodyStringEncoding.Errors: LocalizedError {
var errorDescription: String? {
switch self {
case .emptyURLRequest: return "Empty url request"
case .encodingProblem: return "Encoding problem"
}
}
}
Alamofire.request(url, method: .post, parameters: nil, encoding: BodyStringEncoding(body: text), headers: headers).responseJSON { response in
print(response)
}