Search

Loading...

Jun 21, 2010

Calling WCF service from iPhone

WCF changes way of communication between application-to-application and intra-application. This post will help you to call WCF from iPhone application. First we will see what we have to do on WCF to let iPhone application call service. And the sample code which call WCF from iPhone.

First let’s create simple WCF service.

[ServiceContract(Namespace = "")]
[DataContractFormat]
public class MultiEndPointsService
{
[OperationContract]
public string GetDictionary()
{
Dictionary<string, string> dict = new Dictionary<string, string>();
dict.Add("IB", "Imran Bhadelia");
dict.Add("DO", "David Oliver");
dict.Add("NA", "Nick Althoff");
dict.Add("JJ", "Jay Joshi");
dict.Add("DL", "Dave Larson");
dict.Add("BA", "Brenda Ayong-Chee");
dict.Add("JP", "Jay Parikh");

StringBuilder sbJson = new StringBuilder();
new JavaScriptSerializer().Serialize(dict, sbJson);
return sbJson.ToString();

}
}

This is simple WCF Service. We need to add some decoration for enabling web script and handle POST method. We are going to send http post form iPhone application and send Json string as response. Doing so we also need to decorate our operation contract to set request and response format.

[ServiceContract(Namespace = "")]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
[ServiceBehaviorAttribute(IncludeExceptionDetailInFaults = true)]
[DataContractFormat(Style = OperationFormatStyle.Document)]
public class MultiEndPointsService
{
[WebInvoke(Method = "POST", BodyStyle = WebMessageBodyStyle.WrappedRequest,
RequestFormat = WebMessageFormat.Xml, ResponseFormat = WebMessageFormat.Json)]
[OperationContract]
public string GetDictionary()
{
Dictionary<string, string> dict = new Dictionary<string, string>();
dict.Add("IB", "Imran Bhadelia");
dict.Add("DO", "David Oliver");
dict.Add("NA", "Nick Althoff");
dict.Add("JJ", "Jay Joshi");
dict.Add("DL", "Dave Larson");
dict.Add("BA", "Brenda Ayong-Chee");
dict.Add("JP", "Jay Parikh");

StringBuilder sbJson = new StringBuilder();
new JavaScriptSerializer().Serialize(dict, sbJson);
return sbJson.ToString();
}
}

And following are the configuration settings

<system.serviceModel>
<services>
<service name="Demo.Service.MultiEndPointsService" behaviorConfiguration="serviceBehaviour">
<endpoint address="basic" binding="basicHttpBinding" bindingConfiguration="basicBinding" contract="Demo.Service.MultiEndPointsService" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="serviceBehaviour">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
</behaviors>
<bindings>
<basicHttpBinding>
<binding name="basicBinding" maxBufferSize="2147483647" maxReceivedMessageSize="2147483647">
<security mode="None"></security>
<readerQuotas maxStringContentLength="2147483647" />
</binding>
</basicHttpBinding>
</bindings>
</system.serviceModel>

We need to create basicHttpBinding so it get called form iPhone application, we haven’t sent security to call this method; and following is the Objective-C code which call WCF from iPhone.

NSString *soapMessage = [NSString stringWithFormat:@"<SOAP-ENV:Envelope xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\"><SOAP-ENV:Body><GetDictionary></GetDictionary></SOAP-ENV:Body></SOAP-ENV:Envelope>"];

NSURL *url = [NSURL URLWithString:@http://localhost/Demo.Service/MultiEndPointsService.svc/basic];
NSMutableURLRequest *theRequest = [NSMutableURLRequest requestWithURL:url];
NSString *msgLength = [NSString stringWithFormat:@"%d", [soapMessage length]];

[theRequest addValue: @"text/xml; charset=utf-8" forHTTPHeaderField:@"Content-Type"];
[theRequest addValue: @"urn:MultiEndPointsService/GetDictionary" forHTTPHeaderField:@"SOAPAction"];
[theRequest addValue: msgLength forHTTPHeaderField:@"Content-Length"];
[theRequest setHTTPMethod:@"POST"];
[theRequest setHTTPBody: [soapMessage dataUsingEncoding:NSUTF8StringEncoding]];

NSURLConnection *theConnection = [[NSURLConnection alloc] initWithRequest:theRequest delegate:self];

Once you parse the response it will look like following.

wsdl

You can also call operation contract having parameters, for that need to create proper message and then add it in SOAP-BODY that will work.

12 comments:

Anonymous said...

What changes are needed in order to call a WCF service using wsHTTP binding instead of basicHTTP binding?

Anonymous said...

Do you have success in using WCF REST POSTing feature when the request format is JSON, not XML and with parameters? How do you call this in an iPhone?

Thanks!

Anonymous said...

thanks, it's a great post. But can you explain a little how to parse the XML response ???

Anonymous said...

I've the same question, how to handle the request when it's in JSON ??? Help Please
Thanks

J said...

Hi,

Could you provide a little more insight on how to parse the response. I've implemented the didReceiveData delegate method but I always received 0 bytes when posting the SOAP call... why?

Anonymous said...

this is really helpful, however i have created secure service using transport level security, so what additional code i have to write on iphone side?
Thanks a lot

Anonymous said...

Hi Imran's can you email me a sample code of "Calling WCF service from iPhone". I read your post. This was so great and great help. This is my email angelkorn04@gmail.com

Anonymous said...

Hi, thanks for this instructions. It works great. But I have a question:
What do I have to change for HTTPS.


I change

NSURL *url = [NSURL URLWithString:@http://localhost/..../IphoneService.svc/basic
to

NSURL *url = [NSURL URLWithString:@https://username:password@localhost/..../IphoneService.svc/basic


I add two methods

canAuthenticateAgainstProtectionSpace

and

didReceiveAuthenticationChallange


in didReceiveAuthenticationChallange I call:

[challange.sender continueWithoutCredentialForAuthenticationChallange:chalange]



When execute all this methods are called as expected, but I get Status code 404 in method didReceiveResponse. Method didReceiveData isn't called.



Any suggestion?

Vivek K Shrivastava said...

HI Thanks for providing wonderfull post.
i am searching lot on net but not find teh exact solution. i hope you will prove me that .

I want to register teh user from iphone using wcf service how i will do that can you provide me code or give some guide line . or mail me on vivekshrivstava51@gmail.com
I appreciate your help

Reagrds
VIvek

Anonymous said...

Hi Imran's can you email me a sample complete code of "Calling WCF service from iPhone". I read your post. This was so great and great help. This is my email: asifeqbal2005@gmail.com

Some thing by Mahmood Memon said...

Thanks Imaran.
Demo is awesome and your way of teaching is so nice. Thanks Again.
But I have one problem I have a parameter in my method ho can I set and get its Value.
Any help please.

Some thing by Mahmood Memon said...

Thanks Imran bhai.
Article is awesome and your way of teaching is so nice.
Thanks Again.
But I have a little issue that I have one string parameter in my method. Can you please tell me that how can I set and get its Value.
Help me please.