2015-01-09 3 views
52

Как можно отправить запрос POST с простой строкой в ​​блоке HTTP с помощью Alamofire в моем приложении iOS?Запрос POST с простой строкой в ​​теле с Alamofire

По умолчанию Alamofire нужны параметры для запроса:

Alamofire.request(.POST, "http://mywebsite.com/post-request", parameters: ["foo": "bar"]) 

Эти параметры содержат ключевые ценностные пары. Но я не хочу отправлять запрос с помощью строки ключа в тело HTTP.

Я имею в виду что-то вроде этого:

Alamofire.request(.POST, "http://mywebsite.com/post-request", body: "myBodyString") 

ответ

65

Ваш пример Alamofire.request(.POST, "http://mywebsite.com/post-request", parameters: ["foo": "bar"]) уже содержит «Foo =» бар строку в качестве тела. Но если вы действительно хотите строку с пользовательским форматом. Вы можете сделать это:

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) 
     })) 

Примечание: parameters не должно быть nil

UPDATE (Alamofire 4,0, Swift 3,0):

В Alamofire 4,0 API изменился. Поэтому для пользовательской кодировки нам нужен значение/объект, который соответствует протоколу 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: [:]) 
+0

Это отлично работает, не только простые, но все виды строк типа отображаются в формате JSON. –

+0

спас мой день :) Спасибо (y) – ishhhh

+0

@silmaril в моей ситуации Я могу получить необработанный запрос из бэкэнда только в том случае, если я использую метод PUT, не могли бы вы помочь мне, почему запрос POST ничего не видит –

4

Если вы хотите разместить строку в качестве исходного тела в запросе

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) 
     })) 
+0

Hi JITHINRAJ Я разместил вопрос здесь http://stackoverflow.com/questions/40385992/how-to-send-a-xml-object-with-alamofire Я хочу отправить тело xml –

7

Я изменил @ ответ Сильмариля на продление срока действия диспетчера Alamofire в. Это решение использует EVReflection сериализовать объект непосредственно:

//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) 
      }) 
     ) 
    } 
} 

Затем вы можете использовать его как это:

Alamofire.Manager.request(.POST, endpointUrlString, bodyObject: myObjectToPost) 
3
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) 
-2

Xcode 8.X, Swift 3.X

Легкое использование;

let params:NSMutableDictionary? = ["foo": "bar"]; 
      let ulr = NSURL(string:"http://mywebsite.com/post-request" as String) 
      let request = NSMutableURLRequest(url: ulr! as URL) 
      request.httpMethod = "POST" 
      request.setValue("application/json", forHTTPHeaderField: "Content-Type") 
      let data = try! JSONSerialization.data(withJSONObject: params!, options: JSONSerialization.WritingOptions.prettyPrinted) 

      let json = NSString(data: data, encoding: String.Encoding.utf8.rawValue) 
      if let json = json { 
       print(json) 
      } 
      request.httpBody = json!.data(using: String.Encoding.utf8.rawValue); 


      Alamofire.request(request as! URLRequestConvertible) 
       .responseJSON { response in 
        // do whatever you want here 
        print(response.request) 
        print(response.response) 
        print(response.data) 
        print(response.result) 

      } 
5

Если вы используете Alamofire, достаточно типа кодирования в «URLEncoding.httpBody»

При этом, вы можете отправить свои данные в виде строки в httpbody Allthough вы определили его JSON в коде ,

Он работал для меня ..

ОБНОВЛЕНО для

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"]!) 

     } 

    }) 
+0

Можете ли вы привести пример с помощью код? –

+1

Я обновляю свой ответ и напишу код, который использовался, потому что я не мог найти, как писать код в качестве комментария отсюда. Прошу прощения за последнее время. @ Badr Filali –

+0

Спасибо большое –

23

Вы можете сделать это:

  1. Я создал отделенный запрос Alamofire объекта.
  2. Преобразовать строку данных
  3. Пут в httpBody данные

    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) 
    
    } 
    
+1

Это должен быть принятый ответ. Это просто, делает именно то, что нужно, и без лишних расширений или преобразований. Спасибо чувак. –

+1

P.S. Я «заимствовал» ваш ответ на другой вопрос - http://stackoverflow.com/a/42411188/362305 –

2

Я сделал это для массива из строк. Это решение настраивается для струны в теле.

«родной» путь от 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! 
}} 

А затем сделайте свой запрос с:

Alamofire.request("your url string", method: .post, parameters: [:], encoding: JSONStringArrayEncoding.init(string: "My string for body"), headers: [:])