Tips to consume .net webservice in IOS applications
Creating an iOS Client:
Our iOS client will consist of a button which when clicked will make a request to the HelloWorld web method of the NotificationService. The button click event is shown below:
-(IBAction)submitButtonClicked:(id)sender
{
NSURL *url = [NSURL URLWithString:@"http://127.0.0.1:8080/NotificationService.asmx/HelloWorld?"];
ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:url];
[request setRequestMethod:@"POST"];
[request addRequestHeader:@"Content-Type" value:@"text/xml; charset=utf-8"];
[request setDelegate:self];
[request startAsynchronous];
}
The URL points to the “HelloWorld” web method which will be invoked when the button is clicked. The requestFinished and requestFailed methods are implemented below which are called depending on the result of invocation.
- (void)requestFinished:(ASIHTTPRequest *)request
{
NSLog(@"status code %d",request.responseStatusCode);
if(request.responseStatusCode == 200)
{
NSLog(@"success");
NSString *responseString = [request responseString];
NSLog(@"%@",responseString);
}
NSLog(@"request finished");
}
- (void)requestFailed:(ASIHTTPRequest *)request
{
NSError *error = [request error];
NSLog(@"%@",error.localizedDescription);
}
When you run the iOS application you will get the following in your console.
<?xml version=”1.0″ encoding=”utf-8″?>
<string xmlns=”http://tempuri.org/”>Hello World</string>
Invoking Web Service with Parameters:
Calling parameter less web method is quite easy. In this section we are going to call a web service which accepts multiple parameters. The web service implementation is shown below:
The above web method “Greet” takes two parameters namely deviceToken and userName and returns a concatenation between the two parameters. In order to call this web method from an iOS we will need to construct a SOAP envelope. The implementation is shown below:
-(IBAction)submitButtonClicked:(id)sender
{
NSURL *url = [NSURL URLWithString:@”http://127.0.0.1:8080/NotificationService.asmx”];
ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:url];
[request setRequestMethod:@”POST”];
[request addRequestHeader:@”Content-Type” value:@”text/xml; charset=utf-8″];
[request addRequestHeader:@”SOAPAction” value:@”http://tempuri.org/HelloWorld”];NSString *soapMessage = [NSString stringWithFormat:
@”<?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>”
“<Greet xmlns=\”http://tempuri.org/\”>”
“<deviceToken>some device token</deviceToken>”
“<userName>azamsharp</userName>”
“</Greet>”
“</soap:Body>”
“</soap:Envelope>”];NSString *messageLength = [NSString stringWithFormat:@”%d”,[soapMessage length]];
[request addRequestHeader:@”Content-Length” value:messageLength];
[request appendPostData:[soapMessage dataUsingEncoding:NSUTF8StringEncoding]];
[request setDelegate:self];
[request startAsynchronous];
}
A good way to find out what header values are required is to use browser or a .NET client to invoke the service and then view the contents of the request header. The result is shown below:
<?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><GreetResponse
xmlns=”http://tempuri.org/”><GreetResult>device
token:azamsharp</GreetResult></GreetResponse></soap:Body></soap:Envelope>
The code above shows the response returned from the web method “Greet”. As you can see the response is quite big and hard to parse. You can specify what kind of response you are interested in and the web service will adhere to it. The following implementation asks for the JSON response, although it returns XML response but the response is greatly reduced.
-(IBAction)submitButtonClicked:(id)sender
{
NSURL *url = [NSURL URLWithString:@"http://127.0.0.1:8080/NotificationService.asmx/Greet"];
ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:url];
[request setRequestMethod:@"POST"];
[request addRequestHeader:@"Content-Type" value:@"application/json"];
NSString *messageLength = [NSString stringWithFormat:@"%d",[soapMessage length]];
[request setPostValue:@"device token" forKey:@"deviceToken"];
[request setPostValue:@"azamsharp" forKey:@"userName"];
[request setDelegate:self];
[request startAsynchronous];
}
In the next section we are going to create a generic handler will will return pure JSON response.
Creating Generic Handler:
Our simple generic handler will return plain JSON. Here is the implementation of the generic handler.
public class HighHandler : System.Web.IHttpHandler
{
public virtual bool IsReusable
{
get
{
return false;
}
}
public virtual void ProcessRequest(HttpContext context)
{
var zombie = new Zombie() {Name = “John Doe”};
var json = new JavaScriptSerializer();
context.Response.Write(json.Serialize(zombie));
}
}
The handler is available on HighOnCoding at the following URL:
http://highoncoding.com/HighHandler.ashx
The HighHandler.ashx returns the following result:
{“Name”:”John Doe”}
Since, it is returning JSON format we can easily consume it using iOS application as shown below:
-(IBAction)submitButtonClicked:(id)sender
{
NSURL *url = [NSURL URLWithString:@"http://www.highoncoding.com/highhandler.ashx"];
ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:url];
[request setRequestMethod:@"GET"];
[request addRequestHeader:@"Content-Type" value:@"application/json"];
NSString *messageLength = [NSString stringWithFormat:@"%d",[soapMessage length]];
[request setDelegate:self];
[request startAsynchronous];
}
- (void)requestFinished:(ASIHTTPRequest *)request
{
NSLog(@"status code %d",request.responseStatusCode);
if(request.responseStatusCode == 200)
{
NSLog(@"success");
NSString *responseString = [request responseString];
NSDictionary *dict = [responseString JSONValue];
NSLog(@"%@",[dict valueForKey:@"Name"]);
}
NSLog(@"request finished");
}
The above code will display “John Doe” in the console. In the next section we will return a list of objects from the web service which will be consumed by the iOS application.
Consuming List of JSON Objects:
In this section we are going to return a list of objects from the web service instead of a single object. The list of objects will be returned in the JSON format. The ASHX HttpHandler is implemented below:
public void ProcessRequest(HttpContext context)
{
var zombies = new List<Zombie>()
{
new Zombie() { Name = “John Doe”,NoOfKills = 5},
new Zombie() { Name = “Mary Kate”, NoOfKills = 10},
new Zombie() { Name = “Alex Lowe”, NoOfKills = 2}
};
var zombie = new Zombie() {Name = “John Doe”};
var json = new JavaScriptSerializer();
context.Response.Write(json.Serialize(zombies));
}
In the above code we just created a list of zombie objects and then returned them in the JSON string format using the JavaScriptSerializer class. If you visit the URL you will get the following result:
[{“Name”:”John Doe”,”NoOfKills”:5},{“Name”:”Mary Kate”,”NoOfKills”:10},{“Name”:”Alex Lowe”,”NoOfKills”:2}]
Now, we need to consume this JSON string from inside our iOS application and populate a UITableView will the JSON object. The following code initiates a GET request which returns the JSON string representing Zombie objects.
-(IBAction)submitButtonClicked:(id)sender
{
NSURL *url = [NSURL URLWithString:@"http://www.highoncoding.com/highhandler.ashx"];
ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:url];
[request setRequestMethod:@"GET"];
[request addRequestHeader:@"Content-Type" value:@"application/json"];
NSString *messageLength = [NSString stringWithFormat:@"%d",[soapMessage length]];
[request setDelegate:self];
[request startAsynchronous];
}
The requestFinished is fired when the response is returned. If the response code is 200 then we proceed to extract the JSON object from the JSON string and add it to the NSMutableArray called “zombies”.
– (void)requestFinished:(ASIHTTPRequest *)request
{
NSLog(@”status code %d”,request.responseStatusCode);
if(request.responseStatusCode == 200)
{
NSLog(@”success”);
NSString *responseString = [request responseString];
NSArray *list = [responseString JSONValue];
// iterate through the dict and populate the model
for(NSDictionary *item in list)
{
Zombie *zombie = [[Zombie alloc] init];
zombie.name = [item valueForKey:@”Name”];
[self.zombies addObject:zombie];
}
}
[zombieTableView reloadData];
[zombieTableView setNeedsDisplay];
NSLog(@”request finished”);
}
Discover more from CODE t!ps
Subscribe to get the latest posts sent to your email.