iPhone
SOAP services
mobile development
iOS programming
web services

How to access SOAP services from iPhone

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

SOAP services are older than most modern iOS networking stacks, but they still show up in enterprise systems, payment gateways, and internal business APIs. Accessing them from an iPhone is completely possible, but you usually have to assemble the XML envelope yourself and handle the response as raw XML.

On iOS, the usual approach is to send an HTTP POST request with a SOAP envelope in the body, then parse the response with XMLParser. The hardest part is rarely networking itself; it is matching the exact XML structure and headers expected by the service.

Build the SOAP Request

Most SOAP endpoints expect:

  • 'Content-Type: text/xml; charset=utf-8'
  • an optional SOAPAction header
  • an XML document containing the SOAP envelope and body

Here is a minimal Swift example using URLSession:

swift
1import Foundation
2
3let soapBody = """
4<?xml version="1.0" encoding="utf-8"?>
5<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
6               xmlns:xsd="http://www.w3.org/2001/XMLSchema"
7               xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
8  <soap:Body>
9    <GetWeather xmlns="http://example.com/weather">
10      <city>Toronto</city>
11    </GetWeather>
12  </soap:Body>
13</soap:Envelope>
14"""
15
16let url = URL(string: "https://example.com/weather.asmx")!
17var request = URLRequest(url: url)
18request.httpMethod = "POST"
19request.setValue("text/xml; charset=utf-8", forHTTPHeaderField: "Content-Type")
20request.setValue("http://example.com/weather/GetWeather", forHTTPHeaderField: "SOAPAction")
21request.httpBody = soapBody.data(using: .utf8)
22
23let task = URLSession.shared.dataTask(with: request) { data, response, error in
24    if let error = error {
25        print("Request failed:", error)
26        return
27    }
28
29    guard let httpResponse = response as? HTTPURLResponse else {
30        print("Missing HTTP response")
31        return
32    }
33
34    print("Status:", httpResponse.statusCode)
35
36    guard let data = data else {
37        print("No response body")
38        return
39    }
40
41    let parser = SOAPResponseParser()
42    parser.parse(data: data)
43}
44
45task.resume()

The endpoint URL, namespace, method name, and action header must match the service definition. If even one of those pieces is wrong, the server may return a fault or a plain HTTP error.

Parse the SOAP Response

SOAP responses are XML documents with wrapper elements around the data you actually want. A lightweight option on iOS is XMLParser.

swift
1import Foundation
2
3final class SOAPResponseParser: NSObject, XMLParserDelegate {
4    private var currentText = ""
5
6    func parse(data: Data) {
7        let parser = XMLParser(data: data)
8        parser.delegate = self
9        parser.parse()
10    }
11
12    func parser(_ parser: XMLParser, didStartElement elementName: String,
13                namespaceURI: String?, qualifiedName qName: String?,
14                attributes attributeDict: [String : String] = [:]) {
15        currentText = ""
16    }
17
18    func parser(_ parser: XMLParser, foundCharacters string: String) {
19        currentText += string
20    }
21
22    func parser(_ parser: XMLParser, didEndElement elementName: String,
23                namespaceURI: String?, qualifiedName qName: String?) {
24        if elementName == "Temperature" {
25            print("Temperature:", currentText.trimmingCharacters(in: .whitespacesAndNewlines))
26        }
27    }
28}

This approach works well when you only need a few fields. If the service has complex nested objects, you may want a more structured XML mapping layer, but the underlying flow is still just HTTP plus XML parsing.

Use the WSDL as a Contract

Many SOAP services publish a WSDL file that describes available operations, namespaces, and message shapes. On iOS, you normally do not consume the WSDL directly at runtime the way some desktop frameworks do. Instead, you read it once, figure out the required XML and headers, and encode those in your app.

That is why SOAP integrations on iPhone projects feel more manual than REST integrations. There is no built-in high-level client generator in standard iOS APIs, so correctness depends on matching the contract exactly.

Handle Authentication and Faults

Some SOAP services use HTTP basic authentication, custom headers, or tokens inside the SOAP header section. Others return application errors as SOAP faults even when the HTTP status code is 200.

That means you should inspect both the transport layer and the XML body. A request can succeed at the HTTP level but still contain a fault element explaining that authentication failed or that the operation name was wrong.

Common Pitfalls

  • Sending the right XML to the wrong namespace. SOAP servers are often strict about namespaces and action names.
  • Forgetting the SOAPAction header when the service requires it.
  • Assuming the response payload is the first child element you see. SOAP wrappers and namespaces add extra structure.
  • Treating a 200 response as a guaranteed success. The real error may be inside a SOAP fault element.
  • Trying to call the WSDL URL as if it were the service endpoint. The WSDL describes the service; it is not usually the operation endpoint itself.

Summary

  • iPhone apps can access SOAP services with URLSession and XML parsing.
  • Build a correct SOAP envelope and set the required HTTP headers.
  • Parse the XML response carefully, including the SOAP wrapper elements.
  • Use the WSDL to learn the contract, then encode that contract in Swift.
  • Check for SOAP faults even when the HTTP request itself appears successful.

Course illustration
Course illustration

All Rights Reserved.