3

I installed Alamofire in my project and now here is what I have done.

I installed postman and I put my url and inside body a xml object and I got my result.

Here is a picture of what I exactly have done with postman

enter image description here

How can I now use Alamofire or SWXMLHash to send it as I send it with postman

Thanks in advance!

EDIT

I tried this from another question:

 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)   


    }
}

But it didn't send anything

This is the log:

Optional( { URL: https://something.com } { status code: 200, headers { Connection = "keep-alive"; "Content-Length" = 349; "Content-Type" = "application/xml"; Date = "Wed, 02 Nov 2016 21:13:32 GMT"; Server = nginx; "Strict-Transport-Security" = "max-age=31536000; includeSubDomains"; } })

FAILURE

EDIT

NEVER FORGET TO PASS parameters if you don't have simple add this , parameters: Dictionary()

mike vorisis
  • 2,786
  • 6
  • 40
  • 74
  • From first look your code looks valid. I suggest you to compare your request with valid one from postman. Maybe server expects special `Content-Type` or something else. You should find the difference between requests. Response may not give you the answer. – Silmaril Nov 03 '16 at 10:50
  • Hi @Silmaril thanks for your comment. I'm using the same url in the postman and in my project but in postman I get the result I should got but in my app I have the error in my question. I didn't understand you what should I try with content-type – mike vorisis Nov 03 '16 at 10:55
  • Same url can be not enough. Request also includes HTTP headers inside (one of which is `Content-Type`). `Alamofire.request` method returns the actual request your app is doing. You can `print` it and compare with request data from postman (press `code` button on the right, you can also change the type to `cURL` to make it look similar to `print` result). – Silmaril Nov 03 '16 at 11:24
  • I might found an answer here http://stackoverflow.com/a/32631261/3704857 but I can't get any log to see if I'm doing it right do you know how to print the response from nsurlconnection – mike vorisis Nov 03 '16 at 11:29
  • Do you mean that using `NSURLConnection` like this works for you? There should be no difference what API you use. Difference is in your actual request. For example in the example from your link there is `request.setValue...` line. It actually changes HTTP headers I'm talking about. You can change them with Alamofire or whatever as well. `NSURLConnection` takes same request as Alamofire in `Custom` encoding. – Silmaril Nov 03 '16 at 11:35
  • can you write an answer with that that follows my example with alamofire please? – mike vorisis Nov 03 '16 at 11:38

3 Answers3

8

Using Swift 3 and 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)
    }
PinkeshGjr
  • 8,460
  • 5
  • 41
  • 56
Zeeshan
  • 4,194
  • 28
  • 32
6

With Swift 3 and Alamofire 4 you would create a custom ParameterEncoding. As with any other XML encoded body, SOAP messages can use this parameter encoding as in the following example. Other XML body encodings can be created similarly (check the line where it says 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
    }
}

And then use it like that:

Alamofire.request(url, method: .post, parameters: ["parameter" : "value"], encoding: SOAPEncoding(service: "service", action: "action"))
Lars Blumberg
  • 19,326
  • 11
  • 90
  • 127
3

Assuming you that you're missing valid HTTP headers in your request, the updated request could look like:

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

So, basically you should add one line

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

Update:
Try same, but use responseData or responseString instead of responseJSON because it is possible that your response is not JSON

mike vorisis
  • 2,786
  • 6
  • 40
  • 74
Silmaril
  • 4,241
  • 20
  • 22
  • try same but use `responseData` or `responseString` instead of `responseJSON` because it is possible that your response is not `JSON` – Silmaril Nov 03 '16 at 12:06
  • YES that was it my response is also an xml but I thought that responseJson is standar to get response – mike vorisis Nov 03 '16 at 12:08