如何从iPhone访问SOAP服务

如何从iPhone访问SOAP服务,iphone,ios,web-services,soap,wsdl,Iphone,Ios,Web Services,Soap,Wsdl,我计划为iPhone开发一个应用程序,该应用程序必须访问几个SOAP服务。在对iphonesdk进行一些基本检查时,我无法找到任何对访问SOAP服务的支持,通过谷歌搜索可以得出结论,iphonesdk中不支持SOAP 因此,如果我真的想构建这个应用程序,我需要想出一种从iPhone访问SOAP服务的方法。最好的方法是什么?有什么最佳实践吗?是否有人已经使用iPhone SDK中的功能编写了一个库来访问SOAP服务 (由于我需要访问的服务是由另一方公开的,他们只将其作为SOAP公开,不幸的是,切换

我计划为iPhone开发一个应用程序,该应用程序必须访问几个SOAP服务。在对iphonesdk进行一些基本检查时,我无法找到任何对访问SOAP服务的支持,通过谷歌搜索可以得出结论,iphonesdk中不支持SOAP

因此,如果我真的想构建这个应用程序,我需要想出一种从iPhone访问SOAP服务的方法。最好的方法是什么?有什么最佳实践吗?是否有人已经使用iPhone SDK中的功能编写了一个库来访问SOAP服务

(由于我需要访问的服务是由另一方公开的,他们只将其作为SOAP公开,不幸的是,切换到另一种类型的接口(例如基于REST的API)不是一个选项

Gero和他们的路线图。他们已经有了RO | C,可以连接到他们的web服务,其中可能包括SOAP(我使用的VCL版本肯定包括SOAP)。

一句话:不要

好的,显然这不是一个真正的答案。但是仍然应该不惜一切代价避免使用SOAP;-)有可能在iPhone和web服务之间添加代理服务器吗?也许有什么东西可以为您将REST转换为SOAP

您可以尝试使用一个依赖于libxml2(包含在iphonesdk中)的SOAP库


我已经为OSX写了自己的。但是,它不是主动维护的,需要一段时间才能移植到iPhone上(您首先需要将NSXML替换为)

我一直在低级别(XML生成和解析)使用自己的访问权限,以处理偶尔需要从Objective-C执行SOAP样式的请求。也就是说,有一个名为SOAPClient()的库,它是开源的(BSD许可),可以在Google代码()上找到,这可能会引起人们的兴趣

我不会证明它的能力或有效性,因为我从未使用过它,也没有使用过它的API,但它是可用的,可能会根据您的需要为您提供快速解决方案


苹果曾经有一个非常糟糕的工具,叫做WS-MakeStubs。我认为它在iPhone上不可用,但您可能还对一个开源库感兴趣,该库旨在取代该库—用于与SOAP客户端交互的代码生成Objective-C。同样,我没有使用它,但我在笔记中记下了它:

我的解决方案是让代理服务器接受REST,发出SOAP请求,然后使用PHP返回结果

实施时间:15-30分钟


不是最优雅的,但很坚固。

您可以使用我找到的工具进行连接


看看在iOS_插件下的下载包中包含的两个iOS示例。该工具将WSDL转换为SOAP和XML REST的代码。

这里是一个swift 4示例代码,它使用SOAP服务格式执行API调用

   func callSOAPWSToGetData() {

        let strSOAPMessage =
            "<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
                "<soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">" +
                "<soap:Body>" +
                "<CelsiusToFahrenheit xmlns=\"http://www.yourapi.com/webservices/\">" +
                "<Celsius>50</Celsius>" +
                "</CelsiusToFahrenheit>" +
                "</soap:Body>" +
        "</soap:Envelope>"

        guard let url = URL.init(string: "http://www.example.org") else {
            return
        }
        var request = URLRequest.init(url: url)
        let length = (strSOAPMessage as NSString).length
        request.addValue("application/soap+xml; charset=utf-8", forHTTPHeaderField: "Content-Type")
        request.addValue("http://www.yourapi.com/webservices/CelsiusToFahrenheit", forHTTPHeaderField: "SOAPAction")
        request.addValue(String(length), forHTTPHeaderField: "Content-Length")
        request.httpMethod = "POST"
        request.httpBody = strSOAPMessage.data(using: .utf8)

        let config = URLSessionConfiguration.default
        let session = URLSession(configuration: config)
        let task = session.dataTask(with: request) { (data, response, error) in
            guard let responseData = data else {
                print("Error: did not receive data")
                return
            }
            guard error == nil else {
                print("error calling GET on /todos/1")
                print(error ?? "")
                return
            }
            print(responseData)
            let strData = String.init(data: responseData, encoding: .utf8)
            print(strData ?? "")
        }
        task.resume()
    }
func callSOAPWSToGetData(){
让strSOAPMessage=
"" +
"" +
"" +
"" +
"50" +
"" +
"" +
""
guard let url=url.init(字符串:http://www.example.org)其他{
返回
}
var request=URLRequest.init(url:url)
let length=(strSOAPMessage作为NSString).length
addValue(“应用程序/soap+xml;字符集=utf-8”,用于HttpHeaderField:“内容类型”)
request.addValue(“http://www.yourapi.com/webservices/CelsiusToFahrenheit,forHTTPHeaderField:“SOAPAction”)
request.addValue(字符串(长度),forHTTPHeaderField:“内容长度”)
request.httpMethod=“POST”
request.httpBody=strSOAPMessage.data(使用:.utf8)
让config=URLSessionConfiguration.default
let session=URLSession(配置:config)
让task=session.dataTask(with:request){(data,response,error)在
guard let responseData=其他数据{
打印(“错误:未收到数据”)
返回
}
保护错误==nil else{
打印(“调用GET on/todos/1时出错”)
打印(错误??“”)
返回
}
打印(响应数据)
让strData=String.init(数据:responseData,编码:.utf8)
打印(标准数据??“”)
}
task.resume()
}

谢谢,我尝试使用wsdl2objc。从WSDL生成ObjectiveC代码是可行的,但是(正如预期的那样)不会直接针对iPhone SDK进行编译。我试图对源代码进行一些调整,但最终出现了一系列我无法解决的错误。你能详细说明一下这句话吗“但仍然应该不惜一切代价避免使用SOAP”仅仅因为SOAP不一定合适并不意味着它在他的实现中不正确,有些需求往往超出最佳实践之外not@schwa-在没有任何支持证据或辩护的情况下发布可能有用的答案,遭到否决。这在技术上等同于“不要使用它,因为它不是默认提供的”-不应该使用SOAP或服务提供的任何其他机制,没有真正的技术原因。这里至少有一个答案——与REST相比,SOAP是一个开销非常高的协议。所有的名称空间和有效性检查等都会在消息中添加大量额外字符,这正是您希望在高延迟、可能较慢的网络(如3G)中避免的。如果你能保证你的应用程序只能在信号良好的4g环境中使用,或者只能在Wifi中使用,那么它可能更合适。但一般来说,在移动网络中,少就是多。嗨,Gero,你在应用程序中使用了什么soap服务。因为您没有提到任何正确的答案。在您使用该服务后,请发布教程供其他人参考。您是如何做到这一点的?任何文件。爱的神秘无答案。这个upv怎么样
   func callSOAPWSToGetData() {

        let strSOAPMessage =
            "<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
                "<soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">" +
                "<soap:Body>" +
                "<CelsiusToFahrenheit xmlns=\"http://www.yourapi.com/webservices/\">" +
                "<Celsius>50</Celsius>" +
                "</CelsiusToFahrenheit>" +
                "</soap:Body>" +
        "</soap:Envelope>"

        guard let url = URL.init(string: "http://www.example.org") else {
            return
        }
        var request = URLRequest.init(url: url)
        let length = (strSOAPMessage as NSString).length
        request.addValue("application/soap+xml; charset=utf-8", forHTTPHeaderField: "Content-Type")
        request.addValue("http://www.yourapi.com/webservices/CelsiusToFahrenheit", forHTTPHeaderField: "SOAPAction")
        request.addValue(String(length), forHTTPHeaderField: "Content-Length")
        request.httpMethod = "POST"
        request.httpBody = strSOAPMessage.data(using: .utf8)

        let config = URLSessionConfiguration.default
        let session = URLSession(configuration: config)
        let task = session.dataTask(with: request) { (data, response, error) in
            guard let responseData = data else {
                print("Error: did not receive data")
                return
            }
            guard error == nil else {
                print("error calling GET on /todos/1")
                print(error ?? "")
                return
            }
            print(responseData)
            let strData = String.init(data: responseData, encoding: .utf8)
            print(strData ?? "")
        }
        task.resume()
    }