关于ios:带有Alamofire正文的简单字符串的POST请求

POST request with a simple string in body with Alamofire

在iOS应用中,如何使用Alamofire在HTTP正文中使用简单字符串发送POST请求?

默认情况下,Alamofire需要用于请求的参数:

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

这些参数包含键值对。 但是我不想在HTTP正文中发送带有键值字符串的请求。

我的意思是这样的:

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

您的示例Alamofire.request(.POST,"http://mywebsite.com/post-request", parameters: ["foo":"bar"])已经包含" foo = bar"字符串作为其主体。
但是,如果您真的要使用自定义格式的字符串。你可以这样做:

1
2
3
4
5
6
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

更新(Alamofire 4.0,Swift 3.0):

在Alamofire 4.0中,API已更改。因此,对于自定义编码,我们需要符合ParameterEncoding协议的值/对象。

1
2
3
4
5
6
7
8
9
10
11
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: [:])


你可以这样做:

  • 我创建了一个单独的请求Alamofire对象。
  • 将字符串转换为数据
  • 放入httpBody数据

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    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)

    }

  • 如果您使用Alamofire,将类型编码为" URLEncoding.httpBody"就足够了

    这样,尽管您在代码中将其定义为json,也可以将数据作为字符串在httpbody中发送。

    它对我有用。

    更新于

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
      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"]!)

            }

        })


    我修改了@Silmaril的答案以扩展Alamofire的Manager。
    此解决方案使用EVReflection直接序列化对象:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    //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)
                })
            )
        }
    }

    然后,您可以像这样使用它:

    1
    Alamofire.Manager.request(.POST, endpointUrlString, bodyObject: myObjectToPost)

    如果要在请求中将字符串作为原始正文发布

    1
    2
    3
    4
    5
    6
    7
    8
    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)
            }))


    我已经完成了从字符串数组。调整此解决方案以适应琴弦。

    来自Alamofire 4的"本地"方式:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    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!
        }
    }

    然后通过以下方式提出您的请求:

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


    我已经使用@afrodev的答案作为参考。就我而言,我将函数参数作为必须在请求中发布的字符串。因此,这是代码:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    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)
        }
    }


    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    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)


    基于Illya Krit的答案

    细节

    • Xcode版本10.2.1(10E1001)
    • 迅捷5
    • Alamofire 4.8.2

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    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"
            }
        }
    }

    用法

    1
    2
    3
    Alamofire.request(url, method: .post, parameters: nil, encoding: BodyStringEncoding(body: text), headers: headers).responseJSON { response in
         print(response)
    }

    Xcode 8.X,Swift 3.X

    易于使用;

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
     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)

                }