SOAP Webservice (wsdl) call mit IOS

Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

  • SOAP Webservice (wsdl) call mit IOS

    Hi zusammen,

    wie der Titel schon beschreibt, versuche ich einen SOAP-Webservice, den ich mal in Java geschrieben habe, in einer iPad-App zu callen. Da ich selber mehr aus der AS3 Ecke stamme, tue ich mich da son bissle schwer... Ich habe jetzt die komplette Doku im DevCenter durchgelesen und sonst wie viele Posts, aber irgendwie scheint das im IOS nicht ganz so einfach zu sein. Ich hatte auch schonmal in einem anderen Forum requestet, aber die konnten mir leider auch nicht helfen. Sitze hier also schon ein paar Tage dran. Am liebsten wäre mir ein SampleCode in dem so ein URL-Request bereits funktioniert oder ein Link zu einem wirkllich hilfreichen tutorial.

    Also der Service an sich Funktioniert definitiv, da ich dieses via SOAP-Client und auch schon in einer AS3-App getestet habe.


    Freu mich schon auf eure Antworten. Besten Gruß, Ole!
    Das Leben ist kein Ponyhof!

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von Mole23 ()

  • Da ist Handarbeit angesagt, ums mal kurz zu machen.

    Es gibt kein SOAP, was noch am schnellsten gemacht ist. Und es gibt noch weniger WSDL.

    Auf dem iPhone schickst du eine entsprechende XML Datei als POST Request und parst die Antwort absolut generisch mit dem NSXMLParser.

    Es gibt WSDL Ansätze von "Drittanbietern" (Google Code), das steht aber immer eine Versionsnummer 0.0.0.0.0.1 dran und das wird so lange weiterentwickelt, wie jemand Lust hat.

    Gruß
    Manfred
    Seminare, Artikel, Code. ObjectiveCeeds - alles für die Apfelzucht.
  • Ui, das hatte ich mir etwas einfacher vorgestellt.

    Mal zum Verständniss etwas einfacher ausgedrückt: Ich muss um den Call zu erstellen meine Parameter etc. in eine XML Datei schreiben und als POST Request versenden. Dann bekomme ich eine Art Result, welches ich mit dem NSXMLParser auslesen und z.B. in Variablen speichern kann.

    Stimmt das so?
    Das Leben ist kein Ponyhof!
  • Beispielcode

    Hier ist der Beispielcode aus ner Inhouse Schulung. War jetzt zu faul die ganzen build Ordener aus den Unterverzeichnissen zu löschen, daher etwas größer ;)

    Einmal hast du das XML Handling, dann die Posterei und zum Schluss die Kombination.

    Der Beispiel SOAP Service läuft auf meiner lokalen Kiste, von daher geht das bei dir dann natürlich in die Hose, aber das sollte wohl das kleinste Problem sein.
    Seminare, Artikel, Code. ObjectiveCeeds - alles für die Apfelzucht.
  • Wow! Vielen Dank dafür! Jetzt wird auch einiges klarer. Damit kann ich was anfangen. Ich muss das erstmal ein bissle verarbeiten, evtl. kommt dann noch eine etwas detaillierte Frage...

    Ich bin begeistert! Das hebt die Stimmung! :thumbsup: Beste Grüße!
    Das Leben ist kein Ponyhof!
  • Hi,

    erstmal noch einmal vielen Dank für das Codebeispiel. Ich habe das jetzt mal etwas genauer unter die Lupe genommen, allerdings ist mir eine Sache noch nicht ganz klar. In der OCSOAPAdd.m wird ja, wenn ich das richtig verstanden habe, die Anzahl an Parameter für die request.xml festgelegt. Aber an welcher Stelle hast du diese denn definiert?

    Kannst du mir da evtl. noch einmal auf die Sprünge helfen?
    Das Leben ist kein Ponyhof!
  • XML-Quellcode

    1. <?xml version="1.0" encoding="UTF-8"?>
    2. <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="urn:xmethodsTestServer" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
    3. <SOAP-ENV:Body>
    4. <ns1:add>
    5. <sum1 xsi:type="xsd:int">###value1@@@</sum1>
    6. <sum2 xsi:type="xsd:int">###value2@@@</sum2>
    7. </ns1:add>
    8. </SOAP-ENV:Body>
    9. </SOAP-ENV:Envelope>


    Im Initializer werden die Platzhalter des Request dann durch die entsprechenden Werte ersetzt. Oder was meinst du? Definition der Funktion via WSDL?

    Das kann man natürlich auch etwas schöner machen, ist aber die übliche Mogelpackung.
    Seminare, Artikel, Code. ObjectiveCeeds - alles für die Apfelzucht.
  • Achso, die Werte hast du dementsprechend in der PostAppDelegate.m definiert oder?

    Quasi hier:

    Quellcode

    1. - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    2. [_OCLabel setText: @"Loading..."];
    3. dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    4. int a = 900;
    5. int b = 100;
    6. dispatch_async(queue, ^{
    7. OCSOAPAdd *add = [[OCSOAPAdd alloc] initWithInt: a andInt: b];
    8. if (add != nil)
    9. {
    10. _OCResult = [add result];
    11. }
    12. [self updateGUI];
    13. });
    14. NSLog(@"async dispatch done, loading proceeds in background");
    15. dispatch_release(queue);
    16. [window makeKeyAndVisible];
    17. return YES;
    18. }
    Alles anzeigen
    Das Leben ist kein Ponyhof!

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von Mole23 ()

  • Hi, bis jetzt hat alles super hingehauen. Allerdings scheine ich noch einen Fehler in meiner XML-Datei zu haben. Um das noch genauer einzugrenzen, wollte ich noch einmal auf Nummer sicher gehen und folgende Frage stellen:

    Es geht um folgende Stelle im Code:

    Quellcode

    1. OCPostRequest *request = [[OCPostRequest alloc] init];
    2. [request setPostBody: [replace2 dataUsingEncoding: NSUTF8StringEncoding]];
    3. //[request setURLString: @"http://management.users.webservices.nexmo.eu"];
    4. [request setURLString: @"http://www.smartexpertise.de:9180/axis2/services/UsersSessionsManager?wsdl"];
    5. NSData *result = [request sendSynchronous];
    6. NSLog(@"request %@", replace2);
    7. if (result == nil)
    8. {
    9. NSLog(@"Panic, strange things goin on");
    10. return NO;
    11. }
    12. NSString *res = [[NSString alloc] initWithData: result encoding: NSUTF8StringEncoding];
    13. NSLog(@"result %@", res);
    14. [res release];
    Alles anzeigen



    An dieser Stelle wird doch der XML-Request und das Result in das Log kopiert, oder? Also bei NSLog(@"request %@", replace2); und NSLog(@"result %@", res); ...

    Bzw. wenn ich mir im Log, nachdem NSLog(@"request %@", replace2); ausgeführt wurde, die XML-Struktur anschaue, ist diese doch identisch mit der Struktur die der Server erhält, oder?


    Besten Gruß, Ole!
    Das Leben ist kein Ponyhof!
  • Hallo noch einmal,

    zum Teil scheint der Request jetzt zu laufen, zumindest bekomme ich eine XML-Datei als Result. Leider enthält diese folgende Fehlermeldung:


    The endpoint reference (EPR) for the Operation not found is /.../ and the WSA Action = null



    Diese "endpoint reference" finde ich auch in meiner wsdl Datei, bei den URL-Links wieder... Sieht dort in etwa so aus:

    <wsdl:port name="UsersSessionsManagerHttpSoap11Endpoint" binding="ns:UsersSessionsManagerSoap11Binding">
    <wsdl:port name="UsersSessionsManagerHttpSoap12Endpoint" binding="ns:UsersSessionsManagerSoap12Binding">
    <wsdl:port name="UsersSessionsManagerHttpEndpoint" binding="ns:UsersSessionsManagerHttpBinding">

    Muss ich jetzt einen davon an die URL mit ranhängen? Außerdem ist da noch die Geschichte mit der WSA-Action. Ich habe mittlerweile herrausgefunden, dass diese WSA-Action im Header definiert wird. Wenn ich das versuche, erhalte ich derzeit allerdings immer einen Error als Antwort. Das Problem habe ich mit allen Header-Befehlen...

    Ich weiß auch garnicht wo ich am besten anfangen soll. An sich bräuchte ich Hilfe bei der Erstellung von der XML-Datei.

    Meine XML-Datei schaut derzeit wie folgt aus:


    XML-Quellcode

    1. <?xml version="1.0" encoding="utf-8"?>
    2. <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:getSession="urn:getSession" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
    3. <SOAP-ENV:Body>
    4. <getSession xmlns="http://management.users.webservices.nexmo.eu">
    5. <username xsi:type="xsd:string">pw</username>
    6. <password xsi:type="xsd:string">pw</password>
    7. <mainLanguage xsi:type="xsd:string">original</mainLanguage>
    8. </getSession>
    9. </SOAP-ENV:Body>
    10. </SOAP-ENV:Envelope>
    Alles anzeigen



    Ich bin mir auch nicht ganz sicher, wie ich jetzt vorgehen musss. Ich denke ich muss den Header definieren. Aber wie? Wenn da noch jemand ein Tip oder so hätte, wäre das super! Besten Gruß, Ole!
    Das Leben ist kein Ponyhof!

    Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von Mole23 ()

  • Endlich! Nach gerade mal drei Tagen, habe ich das Ding zum laufen gebracht. Da soll mal einer von "Simple"... Object Access Protocol sprechen...

    Hier ist noch mein Code, falls jemand mal Ähnliches plant... Ich habe den Parser weggelassen, dann ist das einfacher zu verstehen...

    Vielen Dank noch einmal an Manfred! Letztendlich habe ich zwar den Request neu geschrieben, allerdings hätte ich das ohne den SampleCode wohl kaum hinbekommen. Auch noch einmal Danke für den schnellen Support!

    Quellcode

    1. //
    2. // Hello_SOAPAppDelegate.h
    3. // Hello_SOAP
    4. //
    5. // Created by Ole Bruens on 27/07/2010.
    6. // Copyright by Ole Bruens 2010. All rights reserved.
    7. //
    8. #import "Hello_SOAPViewController.h"
    9. @implementation Hello_SOAPViewController
    10. @synthesize greeting, webData, soapResults, xmlParser;
    11. -(IBAction)buttonClick:(id)sender
    12. {
    13. NSString *soapMessage = [NSString stringWithFormat:
    14. @"<?xml version=\"1.0\" encoding=\"utf-8\"?>"
    15. "<SOAP-ENV:Envelope xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:SOAP-ENC=\"http://schemas.xmlsoap.org/soap/encoding/\" SOAP-ENV:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\" xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\">"
    16. "<SOAP-ENV:Body>"
    17. "<getSession xmlns=\"http://management.users.webservices.olebruens.com\">"
    18. "<username xsi:type=\"xsd:string\">pw</username>"
    19. "<password xsi:type=\"xsd:string\">pw</password>"
    20. "<mainLanguage xsi:type=\"xsd:string\">languageType</mainLanguage>"
    21. "</getSession>"
    22. "</SOAP-ENV:Body>"
    23. "</SOAP-ENV:Envelope>"
    24. ];
    25. NSLog(@"soapMessage: %@", soapMessage);
    26. NSURL *url = [NSURL URLWithString:@"http://0.100.90.0:0000/axis2/services/UsersSessionsManager/"];
    27. NSMutableURLRequest *theRequest = [NSMutableURLRequest requestWithURL:url];
    28. NSString *msgLength = [NSString stringWithFormat:@"%d", [soapMessage length]];
    29. [theRequest addValue: @"Mac OS X; WebServicesCore (357)" forHTTPHeaderField:@"User-Agent"];
    30. [theRequest addValue: @"text/xml" forHTTPHeaderField:@"Content-Type"];
    31. [theRequest addValue: @"0.100.90.0" forHTTPHeaderField:@"Host"];
    32. [theRequest addValue: @"urn:getSession" forHTTPHeaderField:@"SOAPAction"];
    33. [theRequest addValue: msgLength forHTTPHeaderField:@"Content-Length"];
    34. [theRequest setHTTPMethod:@"POST"];
    35. [theRequest setHTTPBody: [soapMessage dataUsingEncoding:NSUTF8StringEncoding]];
    36. NSURLConnection *theConnection = [[NSURLConnection alloc] initWithRequest:theRequest delegate:self];
    37. if ( theConnection )
    38. {
    39. webData = [[NSMutableData data] retain];
    40. }
    41. else
    42. {
    43. NSLog(@"theConnection is NULL");
    44. }
    45. }
    46. -(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
    47. {
    48. [webData setLength: 0];
    49. }
    50. -(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
    51. {
    52. [webData appendData:data];
    53. }
    54. -(void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
    55. {
    56. NSLog(@"ERROR with theConenction");
    57. [connection release];
    58. [webData release];
    59. }
    60. -(void)connectionDidFinishLoading:(NSURLConnection *)connection
    61. {
    62. NSLog(@"DONE. Received Bytes: %d", [webData length]);
    63. NSString *theXML = [[NSString alloc] initWithBytes: [webData mutableBytes] length:[webData length] encoding:NSUTF8StringEncoding];
    64. NSLog(@"theXML: %@", theXML);
    65. UIAlertView *resultAlert = [[UIAlertView alloc]
    66. initWithTitle:@"ACHTUNG:"
    67. message: (@"Result %@", theXML)
    68. delegate:self
    69. cancelButtonTitle:nil
    70. otherButtonTitles:@"OK", nil];
    71. [resultAlert show];
    72. [theXML release];
    73. }
    74. - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
    75. {
    76. // Return YES for supported orientations
    77. return (interfaceOrientation == UIInterfaceOrientationPortrait);
    78. }
    79. - (void)didReceiveMemoryWarning
    80. {
    81. [super didReceiveMemoryWarning]; // Releases the view if it doesn't have a superview
    82. // Release anything that's not essential, such as cached data
    83. }
    84. - (void)dealloc
    85. {
    86. [xmlParser release];
    87. [super dealloc];
    88. }
    89. @end
    Alles anzeigen
    Das Leben ist kein Ponyhof!

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von Mole23 ()

  • moin alle zusammen!
    Ich bin grade dabei ein Soapclient fürs iPad zu schreiben(bin noch eher am Anfang). Deswegen freuts mich den Beitrag hier gefunden zu haben. :thumbup:
    Bin leider noch kein erfahrener Programmierer, trotzdem wollt ich mal fragen wie das mit der wsdl funktioniert. Wie übersetze ich sie?
    Muss ich für jeden soap request meine xml separat anpassen?
  • Rico schrieb:

    Wie oben schon erwähnt gibt es bei code.google.com so einen wsdl2objC-generator. Der baut mir aus meinem wsdl-file ein paar .m (und .h) files.

    Wie Manfred aber auch geschrieben hat, sind das allenfalls Ansätze, keine fertigen Out-Of-The-Box-Lösungen. Es ist die Frage, ob Du mit den Dingern wirklich Entwicklungszeit sparst oder eher auf ein totes Pferd wettest. Ich würde mir eher Manfreds Lösung anschauen...

    Rico schrieb:

    Muss ich die verwenden um meinen Request zu bauen??

    Du kannst sie verwenden. Einen eigenen SAX-Content-Handler zu bauen ist aber auch keine Hexerei.
    „Meine Komplikation hatte eine Komplikation.“
  • Hallo,

    habe gerade neu angefangen mich mit diesem Thema zu beschäftigen.
    Allerdings habe erstmal ein paar Verständnisfragen.

    Also ich habe einen Webservice der funktioniert, um den muss ich mich nicht kümmern, dazu habe ich eine URL zu einer WSDL File.
    Dann habe ich ein XML File das z.b. den Input Parameter für den Webservice enthält.
    Wie geh ich da jetzt am besten vor.

    Muss ich zuerst das WSDL File parsen? (Wie mach das?) und ( Da mein WSDL File nur mit User+Passwort geöffnet werden kann, muss ich ja bestimmt irgendwie eine Autorisierung einbauen?)
    Danach mein XML an den Service posten? (Wie und wohin?)
    Und das Antwort XML mit dem Outputparametern wieder parsen um die Werte auszugeben?

    In dem o.g. Codebeispiel wurde aber nichts mit WSDL gemacht, oder überseh da was?
  • TobiasWachtel schrieb:

    In dem o.g. Codebeispiel wurde aber nichts mit WSDL gemacht, oder überseh da was?

    Du brauchst die WSDL nur, um SOAP-Requests zu generieren und die Antworten auszuwerten. Da es für iOS aber keine WebService-Implementierung (wie CXF oder AXIS2) gibt, die das kann, musst Du die Requests selber bauen und die Responses selber parsen. Die WSDL ist also nur so eine Art Doku für Dich.
    „Meine Komplikation hatte eine Komplikation.“