Wykorzystanie usług SOAP w iOS

soap_32

W systemie iOS nie ma gotowych mechanizmów wspierających obsługę usług SOAP. Chcąc wykorzystać je w swoim projekcie, programista może użyć jednej z dwóch nastepujących metod:

  • ręczne przygotowanie zapytania wysyłanego do serwera oraz analiza odpowiedzi;
  • wykorzystanie generatorów projektów Objective-C na podstawie pliku WSDL.

W tym artykule omówię pierwszy sposób, obok narzędzi generujących projekty wspomagające obsługę SOAP.

Wstęp

Aby zaprezentować obsługę usług SOAP w systemie iOS, wykorzystałem usługę zwracającą informację o kursie wymiany walut:

Przykładowe żądanie:

1
2
3
4
5
6
7
8
9
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:web="http://www.webserviceX.NET/">
   <soap:Header/>
   <soap:Body>
      <web:ConversionRate>
         <web:FromCurrency>EUR</web:FromCurrency>
         <web:ToCurrency>PLN</web:ToCurrency>
      </web:ConversionRate>
   </soap:Body>
</soap:Envelope>

Odpowiedź:

1
2
3
4
5
6
7
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
   <soap:Body>
      <ConversionRateResponse xmlns="http://www.webserviceX.NET/">
         <ConversionRateResult>4.1142</ConversionRateResult>
      </ConversionRateResponse>
   </soap:Body>
</soap:Envelope>

Ręczne przygotowanie zapytania

Jednym ze sposobów obsługi usług SOAP w iOS jest ręczne przygotowanie wysyłanego żądania oraz analiza uzyskanej odpowiedzi.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
    NSString *fromCurrency = @"EUR";
    NSString *toCurrency = @"PLN";
   
    NSString *soapFormat = [NSString stringWithFormat:@"<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
                            "<soap:Envelope xmlns:soap=\"http://www.w3.org/2003/05/soap-envelope\" xmlns:web=\"http://www.webserviceX.NET/\">\n"
                            "<soap:Body>"
                            "<web:ConversionRate>"
                            "<web:FromCurrency>"];
    soapFormat = [soapFormat stringByAppendingString:fromCurrency];
    soapFormat = [soapFormat stringByAppendingString:@"</web:FromCurrency>"];
    soapFormat = [soapFormat stringByAppendingString:@"<web:ToCurrency>"];
    soapFormat = [soapFormat stringByAppendingString:toCurrency];
    soapFormat = [soapFormat stringByAppendingString:@"</web:ToCurrency>"];
    soapFormat = [soapFormat stringByAppendingString:@"</web:ConversionRate>\n"
                  "</soap:Body>\n"
                  "</soap:Envelope>\n"];
   
    NSURL *locationService = [NSURL URLWithString:@"http://www.webservicex.net/CurrencyConvertor.asmx"];
    NSMutableURLRequest *request = [[NSMutableURLRequest alloc]initWithURL:locationService];
   
    NSString *requestLength = [NSString stringWithFormat:@"%d",[soapFormat length]];
   
   
    [request addValue:@"text/xml" forHTTPHeaderField:@"Content-Type"];
    [request addValue:@"http://www.webserviceX.NET/ConversionRate" forHTTPHeaderField:@"SOAPAction"];
    [request addValue:requestLength forHTTPHeaderField:@"Content-Length"];
    [request setHTTPMethod:@"POST"];
    [request setHTTPBody:[soapFormat dataUsingEncoding:NSUTF8StringEncoding]];
   
    [NSURLConnection sendAsynchronousRequest:request
                                       queue:[NSOperationQueue mainQueue]
                           completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
                                NSString *responseXML = [[NSString alloc] initWithBytes: [data bytes] length:[data length] encoding:NSUTF8StringEncoding];
                                NSLog(@"%@",responseXML);
                           }
     ];

Powyższy kod wysyła asynchronicznie żądanie do serwera. W odpowiedzi otrzymujemy XML z oczekiwaną wartością kursu waluty.

1
2
3
4
5
6
7
8
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body>
<ConversionRateResponse xmlns="http://www.webserviceX.NET/">
<ConversionRateResult>4.1268</ConversionRateResult>
</ConversionRateResponse>
</soap:Body>
</soap:Envelope>

Jeżeli dostęp do serwera usług wymaga autoryzacji, możemy wykorzystać delegaty NSURLConnection tak jak podczas wszystkich pozostałych połączeń.

Metoda ręcznego przygotowywania zapytania jest bardzo pracochłonna, ale pozwala na obsługę nawet bardzo zaawansowanych usług, z którymi nie radzą sobie automatyczne generatory kodu. Programista, oprócz przygotowania zapytania, musi zaimplementować metody analizujące odpowiedź z serwera.

Wykorzystanie generatorów kodu na podstawie WSDL

Innym sposobem obsługi usług SOAP w systemie iOS jest wykorzystanie automatycznych generatorów kodu Objective C na podstawie pliku WSDL. Wszystkie generatory kodu mają ten sam schemat działania:

  1. analiza pliku WSDL usługi;
  2. wytworzenie klas oraz metod dostarczanych przez usługę.

SUDZC

Ciekawym narzędziem generującym kod Objective C na podstawie pliku WSDL jest SUDZC. Do stycznia 2013 roku było ono dostępne za darmo na stronie http://sudzc.com/. Obecnie korzystanie z niego wymaga rejestracji oraz opłaty 30$ na rok.

Wygląd interfejsu użytkownika:

Użytkownik może zdefiniować:

  • ścieżkę pliku WSDL lub załadować go z dysku;
  • nazwę klasy, jaka ma być użyta w wygenerowanym projekcie;
  • typ generowanego kodu.

Wraz z wygenerowanym projektem dostarczana jest jego dokumentacja oraz przykłady wykorzystania.

Przykład wygenerowanej definicji metody pobierającej dane o aktualnym kursie walut:

1
2
3
    - (SoapRequest*) ConversionRate: (id) target action: (SEL) action
                         FromCurrency: (NSString*) FromCurrency
                         ToCurrency: (NSString*) ToCurrency;

Narzędzie jest cały czas rozwijane, a wszelkie wykryte błędy – poprawiane. Wraz z zakupem rocznego abonamentu otrzymujemy wsparcie w przypadku nietypowych plików WSDL.

WSDL2OBJC

Kolejnym, darmowym narzędziem generującym projekt Objective C na podstawie WSDL jest WSDL2OBJC.

Wygląd interfejsu użytkownika:

Po wykonaniu parsowania otrzymujemy wygenerowany projekt Objective C.
Ostatnia aktualizacja wersji projektu miała miejsce w 2009 roku. To stosunkowo dawno, więc wygenerowany przez nią kod często wymaga ręcznych poprawek.

Wnioski

Brak w iOS sposobu obsługi SOAP (jak np. w języku Java) wymusza konieczność korzystania z metod alternatywnych. Są nimi np. generatory kodu na podstawie pliku WSDL. Ręczny sposób generacji zapytań jest skuteczny, ale trzeba mu poświęcić wiele czasu. Najlepszym spośród rozpoznanych metod obsługi SOAP w iOS jest generator kodu ciągle rozwijany SUDZC, który od stycznia 2013 r. stał się narzędziem płatnym (wcześniej dostępny był jako open-source). Narzędzie to zaoszczędzi na pewno dużo czasu wszystkim programistom iOS w obsłudze usług SOAP.

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *