如何使用Alamofire发送带有XML Body的请求

3
我在我的项目中安装了Alamofire,现在我所做的是这样的。
我安装了postman并放入了我的url和一个xml对象到body中,然后得到了结果。
以下是我使用postman进行操作的图片: enter image description here 现在我该如何使用Alamofire或SWXMLHash来发送与使用postman相同的内容?
提前致谢!
编辑
我尝试了另一个问题中的解决方法:
 Alamofire.request(.POST, "https://something.com" , parameters: Dictionary(), encoding: .Custom({
            (convertible, params) in
            let mutableRequest = convertible.URLRequest.copy() as! NSMutableURLRequest

            let data = (self.testString as NSString).dataUsingEncoding(NSUTF8StringEncoding)
            mutableRequest.HTTPBody = data
            return (mutableRequest, nil)
        }))


    .responseJSON { response in


    print(response.response) 

    print(response.result)   


    }
}

但它没有发送任何内容

这是日志:

可选( { URL: https://something.com } { 状态码: 200, headers { 连接 = "保持连接"; "Content-Length" = 349; "Content-Type" = "application/xml"; 日期 = "Wed, 02 Nov 2016 21:13:32 GMT"; 服务器 = nginx; "Strict-Transport-Security" = "max-age=31536000; includeSubDomains"; } })

失败

编辑

如果您没有简单的添加,永远不要忘记传递参数,参数:字典()


从第一眼看,您的代码看起来是有效的。我建议您将请求与Postman中的有效请求进行比较。也许服务器期望特殊的“Content-Type”或其他内容。您应该找到请求之间的差异。响应可能无法给出答案。 - Silmaril
嗨@Silmaril,感谢您的评论。我在Postman和我的项目中使用相同的URL,但是在Postman中,我得到了应该得到的结果,但是在我的应用程序中,我遇到了问题。我不明白您的意思,我应该尝试什么内容类型? - mike vorisis
同一个URL可能不足以满足需求。请求还包括HTTP标头(其中之一是“Content-Type”)。 “Alamofire.request”方法返回您的应用程序实际执行的请求。 您可以“print”它并将其与postman的请求数据进行比较(在右侧按“code”按钮,您还可以将类型更改为“cURL”,使其看起来类似于“print”结果)。 - Silmaril
我可能在这里找到了答案https://dev59.com/-V8d5IYBdhLWcg3w21Om#32631261,但我无法获取任何日志以查看是否正确。您知道如何打印nsurlconnection的响应吗? - mike vorisis
你的意思是说像这样使用 NSURLConnection 对你有效吗?你使用哪个 API 没有区别,区别在于你实际的请求。例如,在你链接中的示例中,有一行 request.setValue...。它实际上更改了我所说的 HTTP 标头。你也可以使用 Alamofire 或其他工具来更改它们。NSURLConnectionCustom 编码中与 Alamofire 使用相同的请求。 - Silmaril
你能否写一个类似于我的Alamofire示例的答案?请提供翻译后的文本。 - mike vorisis
3个回答

8

使用Swift 3 和Alamofire 4

    let stringParams : String = "<msg id=\"123123\" reqTime=\"123123\">" +
        "<params class=\"API\">" + 
        "<param name=\"param1\">123213</param>" + 
        "<param name=\"param2\">1232131</param>" +
        "</params>" +
    "</msg>"

    let url = URL(string:"<#URL#>")
    var xmlRequest = URLRequest(url: url!)
    xmlRequest.httpBody = stringParams.data(using: String.Encoding.utf8, allowLossyConversion: true)
    xmlRequest.httpMethod = "POST"
    xmlRequest.addValue("application/xml", forHTTPHeaderField: "Content-Type")


    Alamofire.request(xmlRequest)
            .responseData { (response) in
                let stringResponse: String = String(data: response.data!, encoding: String.Encoding.utf8) as String!
                debugPrint(stringResponse)
    }

你好。和.authenticate(user: "user", password: "password")?? - Andres Marin

6

使用Swift 3和Alamofire 4,您可以创建自定义ParameterEncoding。与任何其他XML编码的主体一样,SOAP消息可以使用此参数编码,如以下示例所示。其他XML主体编码可以类似地创建(请检查urlRequest.httpBody = ...所在的行):

struct SOAPEncoding: ParameterEncoding {
    let service: String
    let action: String

    func encode(_ urlRequest: URLRequestConvertible, with parameters: Parameters?) throws -> URLRequest {
        var urlRequest = try urlRequest.asURLRequest()

        guard let parameters = parameters else { return urlRequest }

        if urlRequest.value(forHTTPHeaderField: "Content-Type") == nil {
            urlRequest.setValue("text/xml", forHTTPHeaderField: "Content-Type")
        }

        if urlRequest.value(forHTTPHeaderField: "SOAPACTION") == nil {
            urlRequest.setValue("\(service)#\(action)", forHTTPHeaderField: "SOAPACTION")
        }

        let soapArguments = parameters.map({key, value in "<\(key)>\(value)</\(key)>"}).joined(separator: "")

        let soapMessage =
            "<s:Envelope xmlns:s='http://schemas.xmlsoap.org/soap/envelope/' s:encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'>" +
            "<s:Body>" +
            "<u:\(action) xmlns:u='\(service)'>" +
            soapArguments +
            "</u:\(action)>" +
            "</s:Body>" +
            "</s:Envelope>"

        urlRequest.httpBody = soapMessage.data(using: String.Encoding.utf8)

        return urlRequest
    }
}

然后就可以像这样使用它:

Alamofire.request(url, method: .post, parameters: ["parameter" : "value"], encoding: SOAPEncoding(service: "service", action: "action"))

非常感谢,创建自定义编码确实是一个非常合适的解决方案! - Alessandro Francucci

3

假设您的请求缺少有效的HTTP头,更新后的请求可能如下:

Alamofire.request(.POST, "https://something.com", parameters: Dictionary() , encoding: .Custom({
            (convertible, params) in
            let mutableRequest = convertible.URLRequest.copy() as! NSMutableURLRequest

            let data = (self.testString as NSString).dataUsingEncoding(NSUTF8StringEncoding)
            mutableRequest.HTTPBody = data
            mutableRequest.setValue("application/x-www-form-urlencoded; charset=utf-8", forHTTPHeaderField: "Content-Type")
            return (mutableRequest, nil)
        }))
    .responseJSON { response in
    print(response.response) 
    print(response.result)   
    }
}

基本上,你应该添加一行代码。

mutableRequest.setValue("application/x-www-form-urlencoded; charset=utf-8", forHTTPHeaderField: "Content-Type")

更新:
尝试使用responseDataresponseString而不是responseJSON,因为你的响应可能不是JSON


尝试使用 responseDataresponseString 替换 responseJSON,因为你的响应可能不是 JSON - Silmaril
是的,那就是我的回复,它也是一个XML,但我认为responseJson是获取响应的标准。 - mike vorisis

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接