Question

I am successfully connecting to a .NET web service from iOS and print the response xml document to the console via NSLog. This I am doing via the AFNetworking Library. I am now able to connect to this same web service via NSURLConnection, however, I am having trouble extracting the xml document that is being held inside my NSMutableData object. The AFNetworking library is able to do this automatically which makes things a whole lot easier, but I want to know how to do this using native iOS libraries. Here is the code that I am working with:

//This is the code I am using to make the connection to the web service
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];

    [request setHTTPBody:[soapBody dataUsingEncoding:NSUTF8StringEncoding]];

    [request setHTTPMethod:@"POST"];

    [request addValue:@"http://tempuri.org/Customers" forHTTPHeaderField:@"SOAPAction"];
    [request addValue:@"text/xml; charset=utf-8" forHTTPHeaderField:@"Content-Type"];

    // Convert your data and set your request's HTTPBody property
    NSString *stringData = @"some data";
    NSData *requestBodyData = [stringData dataUsingEncoding:NSUTF8StringEncoding];
    request.HTTPBody = requestBodyData;

    // Create url connection and fire request
    NSURLConnection *conn = [[NSURLConnection alloc] initWithRequest:request delegate:self];
    [conn start];

Here is the code that I have to receive the data from the web service:

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {

    _responseData = [[NSMutableData alloc] init];
}

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {

    [_responseData appendData:data];
}

- (NSCachedURLResponse *)connection:(NSURLConnection *)connection
                  willCacheResponse:(NSCachedURLResponse*)cachedResponse {
    return nil;
}

- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
    // The request is complete and data has been received
    NSString *strData = [[NSString alloc]initWithData:_responseData encoding:NSUTF8StringEncoding];

    NSLog(@"%@", strData);

}

- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
    // The request has failed for some reason!

}


/*
    AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];

    [operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {

        NSLog(@"%@", [operation responseString]);

    } failure:^(AFHTTPRequestOperation *operation, NSError *error) {

        NSLog(@"failed");

    }];

    [operation start];
    */

I simply want to print out the entire xml document that I am receiving, and not necessarily parse through the document for now.

Thanks in advance to all who reply.

Was it helpful?

Solution

Looking at the help document on your server, it suggested an example request:

<?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>
    <Customers xmlns="http://tempuri.org/" />
  </soap:Body>
</soap:Envelope>

So, I put that example request in a text file, and initiated the request via NSURLConnection like so:

NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];

NSString *filename = [[NSBundle mainBundle] pathForResource:@"soap1-1example" ofType:@"xml"];
NSData *requestBodyData = [NSData dataWithContentsOfFile:filename];
request.HTTPBody = requestBodyData;

[request setHTTPMethod:@"POST"];

[request addValue:@"http://tempuri.org/Customers" forHTTPHeaderField:@"SOAPAction"];
[request addValue:@"text/xml; charset=utf-8" forHTTPHeaderField:@"Content-Type"];

[NSURLConnection connectionWithRequest:request delegate:self];

Note, I'm not calling start, because as the documentation says unless you use "initWithRequest:delegate:startImmediately: method and provide NO for the startImmediately parameter," it will start for you automatically. Your original code is, in effect, starting the connection twice, which could be problematic.

Anyway, using my revised code with the above request, it worked fine, using both NSURLConnection as well as with AFNetworking. The response I got (prettified) was:

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body>
    <CustomersResponse xmlns="http://tempuri.org/">
    <CustomersResult>
        <Customer>
            <FirstName>Mohammad</FirstName>
            <LastName>Azam</LastName>
        </Customer>
        <Customer>
            <FirstName>John</FirstName>
            <LastName>Doe</LastName>
        </Customer>
    </CustomersResult>
</CustomersResponse>
</soap:Body>
</soap:Envelope>

If it's still not working for you, perhaps you can share the particulars of the request you're submitting.


By the way, since nothing here necessitates the delegate methods (e.g. you're not streaming, you're not doing any authentication, etc.), in you can eliminate all of the NSURLConnectionDataDelegate methods (didReceiveResponse, didReceiveData, etc.), and just use NSURLConnection class method, sendAsynchronousRequest (in iOS 5 and later):

NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];

NSString *filename = [[NSBundle mainBundle] pathForResource:@"soap1-1example" ofType:@"xml"];
NSData *requestBodyData = [NSData dataWithContentsOfFile:filename];
NSAssert(requestBodyData, @"requestBodyData is nil!");
request.HTTPBody = requestBodyData;

[request setHTTPMethod:@"POST"];

[request addValue:@"http://tempuri.org/Customers" forHTTPHeaderField:@"SOAPAction"];
[request addValue:@"text/xml; charset=utf-8" forHTTPHeaderField:@"Content-Type"];

if (!self.networkQueue)
{
    self.networkQueue = [[NSOperationQueue alloc] init];
    self.networkQueue.name = @"com.yourdomain.yourapp.networkQueue";
}

[NSURLConnection sendAsynchronousRequest:request
                                   queue:self.networkQueue
                       completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {

                           if (!error)
                           {
                               NSString *string = [[NSString alloc] initWithData:data
                                                                        encoding:NSUTF8StringEncoding];

                               NSLog(@"%s: data=%@", __FUNCTION__, string);
                           }
                           else
                           {
                               NSLog(@"%s: error=%@", __FUNCTION__, error);
                           }
                       }];
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top