如何从iPhone访问SOAP服务

225

我计划为iPhone开发一个应用程序,该应用程序需要访问一些SOAP服务。在iPhone SDK中进行基本检查时,我没有找到任何支持访问SOAP服务的功能,通过谷歌搜索得出结论:iPhone SDK不支持SOAP。

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

(由于我需要访问的服务由另一方公开并且只公开为SOAP,所以不能选择切换到另一种类型的接口(例如基于REST的API)。

Gero


9
你好 Gero,你的应用程序使用了哪种SOAP服务?因为你没有提到任何答案。 - Ameya
3
使用此服务后,请发布教程,以供他人将来参考。 - Vineesh TP
7个回答

52

一个词:不要。

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

你可以尝试使用CSOAP,它是一个依赖于libxml2的SOAP库(包含在iPhone SDK中)。

我为OSX编写了自己的SOAP框架。但它已经不再维护,并且需要花费一些时间来移植到iPhone上(你需要首先用TouchXML替换NSXML)。


11
你能详细说明一下这个声明吗:“但仍应尽量避免使用SOAP”? - WillF
10
仅仅因为肥皂不一定合适并不意味着在他的应用中就不正确,往往有超越最佳实践的需求。 - Anthony Main
11
因为@schwa发表了一篇潜在有用但没有任何支持证据或辩护的答案,所以被负评了。 - DougW
12
这相当于技术上的说法是“不要使用它,因为它不是默认提供的” - 实际上并没有什么技术上的理由阻止你使用SOAP或任何其他由服务提供的机制。 - Anya Shenanigans
9
至少有一个答案——SOAP协议与REST相比是一种非常高开销的协议。所有的命名空间和有效性检查等都会给你的消息添加大量的额外字符,而这正是你想在高延迟、潜在缓慢的网络(如3G)上避免的。如果你能保证你的应用程序只在4G环境下使用,并且信号良好,或者只在Wifi中使用,那么可能更合适。但总的来说,在移动网络中,越少越好。 - Vineel Shah
显示剩余4条评论

7

我的解决方案是使用PHP编写一个代理服务器,接收REST请求并发出SOAP请求,然后返回结果。

实现时间:15-30分钟。

虽然不太优雅,但很可靠。


4
你是怎么做到的?有任何文件吗?谢谢。 - Spring
3
我喜欢神秘的不回答。这个为什么会得到赞成票? - gdbj
@gdbj 因为REST和SOAP之间的1:1转换应该是不言自明的... - Magic Octopus Urn
1
这是“什么”,但并没有回答“如何”的问题,这就是人们来到这里的原因。我仍然很好奇在这里实现的答案是什么,特别是如果它是如此简单的话。 - gdbj

4

我过去经常使用低级别的方法(生成和解析XML)来处理从Objective-C进行SOAP样式请求的偶然需要。尽管如此,有一个叫做SOAPClient(soapclient)的库可用,它是开源的(BSD许可证),并且在Google Code上可用(mac-soapclient),这可能会引起您的兴趣。

我不确定它的能力或效果,因为我从未使用过它或必须使用它的API,但它可用,根据您的需要可能会提供快速解决方案。

Apple曾经有一个非常糟糕的实用程序叫做WS-MakeStubs。我认为它在iPhone上不可用,但您可能还对开源库感兴趣,该库旨在替代它-为与SOAP客户端交互而生成Objective-C代码。同样,我没有使用过它-但我已在我的笔记中标记了它:wsdl2objc


谢谢,我尝试使用wsdl2objc。从WSDL生成ObjectiveC代码是可以的,但(如预期)它不能直接编译iPhone SDK。我尝试微调源码,但最终遇到了许多无法解决的错误。 - Gero

2

这里是一个使用SOAP服务格式执行API调用的 Swift 4 示例代码。

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

2

我发现了一个工具,您可以使用它进行连接:http://www.wsdl2code.com

SampleServiceProxy *proxy = [[SampleServiceProxy alloc]initWithUrl:@"YOUR
        URL" AndDelegate:self];

[proxy GetDouble];
[proxy GetEnum];
[proxy getEnum:kTestEnumTestEnum2];
[proxy GetInt16];
[proxy GetInt32];
[proxy GetInt64];
[proxy GetString];
[proxy getListStrings];

0

请查看gsoap,下载包中包含两个iOS示例,位于ios_plugin下。该工具可将WSDL转换为SOAP和XML REST的代码。


0

请查看这个链接和他们的路线图。他们正在开发RO|C,它可以连接到他们的Web服务,其中可能包括SOAP(我使用的VCL版本肯定包括它)。


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