Home > iPhone, Programming > Using .NET web services and dataset objects in your iphone app

Using .NET web services and dataset objects in your iphone app

October 19, 2009

iPhone XML SOAP or .NET Web Services

can seem overwhelming at first but its actually not too hard to do, you can even download a .NET dataset and query it on the iPhone!

Being a complete n00b to iphone’s cocoa touch api / objective C and then jumping in feet first to iphone programming is like being swallowed by an enormous whale. Its very dark, you can see the blow hole, but you know the only way of reaching it is to be blown out by a mucous-infused geisure of  hot and sticky whale snot. (if you have ever tried to obtain help on irc or various forums you know what I am talking about) not to mention the endless sea of apple docs that may or may not contain any information that you actually need depending on your luck.

That being said after much hair pulling reading docs forums and some examples from everywhere I have put together a simple solution to connect to a .NET web service over https and return a dataset object back to the iphone that can be queried and used accordingly.

Please Note this article is now deprecated you should use the new framework here
I Can not support this version any more if you ask for help with this version you will not be answered.

Download This: iPhone .NET Dataset Framework.zip

In the attached file you will find 6 documents:

DataSet.h
DataSet.m
XMLDataSetParser.h
XMLDataSetParser.m
WebServiceHelper.h
WebServiceHelper.m

These files are pretty much self explanatory. DataSet.h/.m contain code for creating your DataSet Object and contain methods for querying the dataset.

WebServiceHelper contains the code to connect to the appropriate web service with the appropriate methods and parameters

XMLDataSetParser will take the data received from the webservice and pipe it into your DataSet Object.

To use an XML .NET Web service all you need to do is include these files in your project and then call the following procedures.

//First import the relevant files to your viewcontroller class (XMLDataSetParser is
//included by the DataSet class so there is no need to import it here)

#import "WebServiceHelper.h"
#import "DataSet.h"

// Create a connection to the web service
WebServiceHelper *DataCon = [[WebServiceHelper alloc] init];
//set up service method and urls please visit the webservice address in a browser to
//get the exact strings the service expects

DataCon.XMLNameSpace = @"https://myurl.com/WebService";
DataCon.XMLURLAddress = @"https://myurl.com/WebService/service.asmx";
DataCon.MethodName = @"getDataSetFromServer";

//add parameters **PARAMETERS ARE CASE SENSITIVE MAKE SURE THEY ARE TYPED CORRECTLY
//AS THE SERVICE EXPECTS THEM**

DataCon.MethodParameters = [[NSMutableDictionary alloc] init];
[DataCon.MethodParameters setObject:@"Parameter1" forKey:@"P1"];
[DataCon.MethodParameters setObject:@"Parameter2" forKey:@"P2"];

//Connect to the service and retrieve the xml raw data into a NSMutableDataObject
//be sure to include a NSMutableData object called "data" or whatever you wish in
//your viewcontroller

self.data = [DataCon initiateConnection];

//Create a dataset object using the new raw data we received from the service
DataSet *dsMyDataSet = [[DataSet alloc] initWithXMLData:self.data];

//Now we have a dataset filled with data from the initWithXMLData command lets
//query some data from it!
//Set up a dictionary object to hold our query data from the dataset

NSMutableDictionary *mydata= [[NSMutableDictionary alloc] init];

//retrieve all rows from the selected table and column
mydata = [dsMyDataSet getRowsForTableAndColumn:@"Table1" col:@"Username" ];
//mydata should contain all rows from column "Username"

//retrieve all rows from the selected table and column where the CURRENT column
//matches a string

mydata = [dsMyDataSet
getRowsForTableAndColumnWhereEqualsString:@"Table1" col:@"username" where:@"bob"];
//mydata should contain all rows from column username containing the exact match "bob"

//retrieve all rows from the selected table and column where a DIFFERENT column
//matches a string

mydata = [dsMyDataSet
getRowsForTableAndColumnWhereColumnEqualsString:@"Table1"
col:@"username" whereColumn:@"email" whereValue:@"bob@microsoft.com"];
//mydata should contain all rows from column "username" where the column "email"
//contains the exact match "bob@microsoft.com"

//you can do what you want with the data at this point like a simple iteration
NSEnumerator *userIterator= [mydata objectEnumerator];

NSString *username;

while(username =  [userIterator nextObject])
{
NSLog(@"Username: %@", username);
}
[mydata release];

Thats it!!! Hope this helps someone else save as much time as it is now saving me!

About these ads
Categories: iPhone, Programming
  1. November 8, 2009 at 8:54 am | #1

    Hi,

    I was just wondering what self.data is defined as within the interface.

    Regards
    Mick

    • o0joecool0o
      November 8, 2009 at 6:00 pm | #2

      self.data is just an NSMutableData object to hold the raw data returned from the XML service, it can be defined in your function or in the view controller interface, I sometimes access this object from outside the view controller and that is why I chose to declare it inside the interface. Your application may or may not have this requirement.

  2. November 18, 2009 at 12:20 pm | #3

    Nice post & nice blog. I love both.

  3. ekkk
    December 14, 2009 at 10:49 am | #4

    Hi,

    I have a problem to pass the parameters from conn.method (Iphone) to .NET Web Services, using below codes.

    //add parameters **PARAMETERS ARE CASE SENSITIVE MAKE SURE THEY ARE TYPED CORRECTLY
    //AS THE SERVICE EXPECTS THEM**
    DataCon.MethodName = @”getDataSetFromServer”;
    DataCon.MethodParameters = [[NSMutableDictionary alloc] init];
    [DataCon.MethodParameters setObject:@"Parameter1" forKey:@"P1"];
    [DataCon.MethodParameters setObject:@"Parameter2" forKey:@"P2"];

    I created a Web Services Method ,getDataSetFromServer(string P1, string P2)
    to get parameters from Parameter1, Parameter2 ,
    but I receive nothing subsequently.

    What’s the reason why? Wait for your reply!

    Regards,

    Ekkk

    • o0joecool0o
      December 15, 2009 at 4:29 am | #5

      I would need more information if you would like to send me the relevant files you can email them to me and I would be happy to look over the code and see if I can find the error. The above parameter info looks correct so I suspect the error is somewhere else perhaps the connection URL or the receiving NSMutableData array. I will email you at the address you specified for your post so you can reply

  4. jason
    December 21, 2009 at 7:07 pm | #6

    How would I populate a table with this data I am a noobie.

    • o0joecool0o
      December 23, 2009 at 3:49 pm | #7

      You can populate a table using the same code, in a tableview the function “cellForRowAtIndexPath” you would simply add the cell.text as the object at that indexPath.
      NSUInteger row = [indexPath row];

      cell.text = [mydata objectAtIndex:row];

  5. Billy
    December 21, 2009 at 10:50 pm | #8

    Great article, what code changes need to be made in order for this to work with none ssl web service?

    • o0joecool0o
      December 23, 2009 at 3:51 pm | #9

      under WebserviceHelper.m I believe you just need to comment out the line

      [NSURLRequest setAllowsAnyHTTPSCertificate:YES forHost:[myWebserverURL host]];

  6. Shibin
    December 23, 2009 at 5:34 am | #10

    Thanks for the post..

    But i am not using a data-set. i am retrieving a simple XML file. how can i change this to implement my changes.

    Thanks in advance. please help.

    • o0joecool0o
      December 23, 2009 at 3:53 pm | #11

      You can use the “WebServiceHelper.m” object to make your connection and modify the XMLDataSetParser to conform to your own XML structure that you are receiving. Or just use it as an example to create your own XML parser using the Objective C NSXMLParser object.

  7. Steve
    December 24, 2009 at 6:47 am | #12

    Do you know if there is any way to get the details of the webservice if all you have been provided with is the .svc file and not the asmx details? This is fine under .Net where you can connect to the service and then find the underlying functions, but I can’t seem to find anything that describes how to do the same thing for iPhone.

  8. December 29, 2009 at 9:38 am | #14

    Calling a web method (without parameters) its ok, but when I called my web service method passing in parameter, it don’t seems to work.
    Hopefully theres some tutorial on this as well as how the web service method look like in C#.
    Not sure if the parameter is to be passed like the following:

    //add parameters **PARAMETERS ARE CASE SENSITIVE MAKE SURE THEY ARE TYPED CORRECTLY
    //AS THE SERVICE EXPECTS THEM**
    DataCon.MethodParameters = [[NSMutableDictionary alloc] init];
    [DataCon.MethodParameters setObject:@"npalmtest" forKey:@"strUserID"];

    • o0joecool0o
      December 29, 2009 at 3:23 pm | #15

      vb and C should make no difference the web service is still a soap service with standard parameters. Make sure when you connect to the .asmx url you are seeing the .net web method and parameters typed properly and case sensitive.

    • July 27, 2010 at 3:17 pm | #16

      Hi,
      Did you ever find out why calling the service with parameters doesn’t work. I am
      having the same problem, without parameters it work. When I log the web service,
      the parameter aren’t receiving anything. case sensitive and typing is ok.

      Thanks,
      Alan

  9. December 29, 2009 at 9:45 am | #17

    i wonder issue #4 has been resolved, i had the exact same problem.

    • o0joecool0o
      December 29, 2009 at 3:24 pm | #18

      issue #4 turned out to be an issue using special characters in the data that interfered with xml structure.

      • ekkk
        December 31, 2009 at 1:55 am | #19

        How to solve if I using special characters in the data ??

        I haved been implemented into encoding uft-8 in XML structure

        Thanks and Regards,

  10. coco
    December 29, 2009 at 10:27 pm | #20

    I am not sure what I am doing wrong, but … I tried this example … and I am having an issue with the declaration of self.data. I have pasted the code for the use in the ViewController.m page inside the viewDidLoad method. I’ve tried a few different ways but I still see no data coming out.

    Looks like this:


    DataCon.XMLNameSpace = @”http://www.webservicex.net/”;
    DataCon.XMLURLAddress = @”http://www.webservicex.net/uszip.asmx”;
    DataCon.MethodName = @”GetInfoByCity”;

    //add parameters **PARAMETERS ARE CASE SENSITIVE MAKE SURE THEY ARE TYPED CORRECTLY
    //AS THE SERVICE EXPECTS THEM**
    DataCon.MethodParameters = [[NSMutableDictionary alloc] init];
    [DataCon.MethodParameters setObject:@"New York" forKey:@"USCity"];
    //[DataCon.MethodParameters setObject:@"Parameter2" forKey:@"P2"];

    //Connect to the service and retrieve the xml raw data into a NSMutableDataObject
    //be sure to include a NSMutableData object called “data” or whatever you wish in
    //your viewcontroller
    //NSMutableData *data;//=[[NSMutableData alloc] retain];

    //self.data = [NSMutableData data]
    self.data = [DataCon initiateConnection];

    //Create a dataset object using the new raw data we received from the service
    DataSet *dsMyDataSet = [[DataSet alloc] initWithXMLData:data];

    what I get is that data is something not a union or structure. Thank you in advance.

    • Luis Enrique Ortiz
      December 30, 2009 at 1:18 am | #21

      you have to declare self.data in the header
      example:

      @interface TestWSViewController : UITableViewController{
      NSMutableData *data;
      }

      @property(nonatomic, retain) NSMutableData *data;

      @end

      and then in the implementation

      @implementation TestWSViewController

      @synthesize data;

  11. Luis Enrique Ortiz
    December 29, 2009 at 10:28 pm | #22

    i have the same error in the parameters, i get “” in the reveiving parameters in the web service

    i have
    _
    Public Function obtenerVentas(ByVal fecha As String) As DataSet

    and in the iphone app i have

    WebServiceHelper *DataCon = [[WebServiceHelper alloc] init];
    DataCon.XMLNameSpace = @”http://leortiz-imac/irrab”;
    DataCon.XMLURLAddress = @”http://leortiz-imac/irrab/ventas.asmx”;
    DataCon.MethodName = @”obtenerVentas”;

    DataCon.MethodParameters = [[NSMutableDictionary alloc] init];
    [DataCon.MethodParameters setObject:@"12/01/2009" forKey:@"fecha"];
    self.data = [DataCon initiateConnection];

    • coco
      December 29, 2009 at 10:42 pm | #23

      How do you initialize the self.data variable?

    • December 30, 2009 at 2:45 am | #24

      My problem is exactly similar to this. The following is a snippet code:

      self.data = [[NSMutableData alloc] init];
      WebServiceHelper *DataCon = [[WebServiceHelper alloc] init];
      DataCon.XMLNameSpace = @”http://tempuri.org”;
      DataCon.XMLURLAddress = @”http://192.168.0.20/uploadlinkservice/service1.asmx”;
      DataCon.MethodName = @”GetUsers”;
      DataCon.MethodParameters = [[NSMutableDictionary alloc] init];
      [DataCon.MethodParameters setObject:@"npalmtest" forKey:@"strUserID"];
      self.data = [DataCon initiateConnection];

      while the C# web service method looks like this:

      [WebMethod(Description = "Returns NPalmDB users", EnableSession = true)]
      public DataSet GetUsers(String strUserUD)
      {
      SqlConnection con = new SqlConnection(con);
      if (strUser == “npalmtest”) {
      SqlDataAdapter DA = new SqlAdapter(“Select * from Users, con);
      DataSet DS = new DataSet();
      DA.Fill(DS,”Users”);
      return DS;
      }
      else
      return null;
      }

      Problem is nothing gets passed into the webservice parameters..

      • MayurNilwant
        June 14, 2010 at 10:20 am | #25

        This code has really helped me…….n its working for me thanks to who so ever posted this soln

    • December 30, 2009 at 2:55 am | #26

      And after printing the sRequest, all seems correct, only the parameter “npalmtest” does not parse into the strUserID param.

      Printing description of sRequest:
      npalmtest

    • December 30, 2009 at 2:56 am | #27

      Printing description of sRequest:
      npalmtest

    • December 30, 2009 at 2:58 am | #28

      Printing description of sRequest:
      //npalmtest

    • o0joecool0o
      December 30, 2009 at 3:27 pm | #29

      the functions I wrote utilize the windows .NET service methods. I see you are connecting to an imac so I am not sure what you are using for a web service. My dataset methods parse .NET specific tags and attributes to determine where the tables and rows start in the xml structure.

    • July 27, 2010 at 3:19 pm | #30

      Did you find out why passing parameters to web service doesn’t work. I am having the same problem. Web service receives nothing.
      Thanks, Alan

  12. Luis Enrique Ortiz
    December 30, 2009 at 1:15 am | #31

    when i want to populate a TableView with

    NSUInteger row = [indexPath row];

    cell.text = [mydata objectAtIndex:row];

    i get this error

    2009-12-29 18:07:52.687 TestWS[6018:207] *** -[NSCFDictionary objectAtIndex:]: unrecognized selector sent to instance 0x3c03bb0
    2009-12-29 18:07:52.688 TestWS[6018:207] *** Terminating app due to uncaught exception ‘NSInvalidArgumentException’, reason: ‘*** -[NSCFDictionary objectAtIndex:]: unrecognized selector sent to instance 0x3c03bb0′

    i can get the count of rows in mydata but not the value for the cell

    what can i do???

    • o0joecool0o
      December 30, 2009 at 3:31 pm | #32

      the raw data sent back from your service is not returned as a string in the mutable array it is returned as binary data. you need to use NSXMLParser to iterate through your data and you need to turn the data into a string first.

      NSString *theXml = [[NSString alloc]initWithBytes:[mydata mutableBytes] length:[mydata length] encoding:NSUTF8StringEncoding];
      NSLog(@”response:%@”, theXml, nil);

      that should print the xml as text to the console.

  13. coco
    December 30, 2009 at 6:05 am | #33

    Ok, I finally figured it out … so in case this helps someone else here is what you need to do:

    This will only work with a dataset coming from a webservice. So anything else you try that provides standard XML will not work out of the box. So make a .asmx page with a webmethod that returns a Dataset first. I made the mistake of trying to use some generic online XML webservices to test it.

    Set the DataCon.XMLNameSpace=@”http://tempuri.org”;

    When you run this go to your output window in Xcode and see what name your table has. Mine ended up with “RequestType” … then put that in the mydata = … @”Table1″ … I changed mine to @”RequestType” in there …

    Then it magically worked!

    … if I can only put a spinner now to let the user know that the webservice is downloading … its a tad on the slow side with large tables. What I might do instead is provide a comma delimited string and parse that … it’ll be faster than the XML service and parsing but not sure if I might need something more generic later on.

    btw Great job to the gentleman that put this together … for .net folks working in Objective C feels like driving on the wrong side of the road.

  14. coco
    December 30, 2009 at 6:11 am | #34

    I would be interested in anyone knows how to return all the columns for a specific row … ie: all the fields for a record matching a specific column or key value … thoughts?

    • o0joecool0o
      December 30, 2009 at 5:20 pm | #35

      I will eventually add this when i get some down time. You could write your own in the Dataset.m class

  15. December 30, 2009 at 6:54 am | #36

    Seems like still cant get answer to the problem with the parameters in the web service method discussed earlier on. Anybody encountered this problem and has a solution to it.

    • coco
      December 30, 2009 at 6:59 am | #37

      You have a spelling error … in the C# code the param is called strUserUD and in the iPhone code you have strUserID

    • December 30, 2009 at 8:46 am | #38

      OK, i have figured out why,.. the problem with the parameters not being fed… If i inspect my asmx request and response, in the request soap message i have the following tags:

      ^GetUsers xmlns=http://tempuri.org/”^
      ^strUserID^ string ^/strUserID^
      ^/GetUsers^

      Now, after i check the request msg in the console, i spotted the difference

      ^GetUsers xmlns=http://tempuri.org”^
      ^strUserID^ string ^/strUserID^
      ^/GetUsers^

      The “/” really make a big difference! make sure you type in that XMLNameSpace correctly!

      This comes another issue, since the framework will default

      self.SOAPActionURL = [NSString stringWithFormat:@"%@/%@",self.XMLNameSpace, self.MethodName];

      this will cause my SOAPActionURL to become http://tempuri.org//GetUsers
      which the now extra “/” will cause problem. So to solve this i changed into:

      self.SOAPActionURL = [NSString stringWithFormat:@"%@%@",self.XMLNameSpace, self.MethodName];

      Also i have updated the following:

      [request addValue:SOAPActionURL forHTTPHeaderField:@"SOAPAction"];
      to
      [request addValue:self.SOAPActionURL forHTTPHeaderField:@"SOAPAction"];

      • o0joecool0o
        December 30, 2009 at 3:38 pm | #39

        hmm this is strange when I looked at my webservice.asmx the xml names space does not contain the “/” at the end like yours did. I wonder why this is.

      • Nik
        January 25, 2010 at 7:18 pm | #40

        First of all thanks o0joecool0o for sharing the code,
        John thank you as well as these modifications worked for me as well…

  16. December 30, 2009 at 8:50 am | #41

    noted the spelling error, its just my typo error here.

  17. coco
    December 30, 2009 at 5:03 pm | #42

    Does anyone know how to retrieve an entire record with all columns? For example I have a data set with name, phone, and address. When I click on a row using the tableview I would like to see the details …

    thank you in advance

    • o0joecool0o
      December 30, 2009 at 5:29 pm | #43

      for now you have to retrieve one column at a time. I will add this functionality some time later. When I have enough time I want to add SQL syntax so you can query a dataset just like a SQL table by using “SELECT * ” etc

  18. coco
    December 30, 2009 at 8:10 pm | #44

    Does anyone else have the issue where it sometimes fails to load in the simulator?

  19. January 5, 2010 at 8:37 am | #45

    when i try to load all records from my dataset, i encountered NSMallocException in :

    NSMutableDictionary *table = [[NSMutableDictionary alloc] initWithDictionary:[thisDataset.Tables objectForKey:self.currentTable]];

    this in the function (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string

    Wonder any of you experiences this?

    • o0joecool0o
      January 5, 2010 at 6:41 pm | #46

      I have never seen this error, try debugging by NSLogging the xml raw output and see if there are any special characters that could be throwing it off.

      • January 6, 2010 at 2:16 am | #47

        If Small data is ok, but i believe my dataset is Big and the above NSMutableDictionary is blown,

        i uncommented :
        NSLog(@”founddata: %@”, string);
        in
        - (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string

        and run. Initially its running very fast and smoothly and slows down as it progresses.. in debug console traces, i got the error eventually:

        NaPalmNursingAccessment(696,0xa0a4d500) malloc: *** mmap(size=2097152) failed (error code=12)
        *** error: can’t allocate region
        *** set a breakpoint in malloc_error_break to debug
        NaPalmNursingAccessment(696,0xa0a4d500) malloc: *** mmap(size=2097152) failed (error code=12)
        *** error: can’t allocate region
        *** set a breakpoint in malloc_error_break to debug
        2010-01-06 10:15:15.989 NaPalmNursingAccessment[696:207] *** Terminating app due to uncaught exception ‘NSInvalidArgumentException’, reason: ‘(null): attempt to insert nil’
        NaPalmNursingAccessment(696,0xa0a4d500) malloc: *** mmap(size=2097152) failed (error code=12)
        *** error: can’t allocate region
        *** set a breakpoint in malloc_error_break to debug

  20. Luis Enrique Ortiz
    January 6, 2010 at 12:46 am | #48

    How can i catch errors like there is no connection o servertime out???

  21. David R
    January 14, 2010 at 12:57 am | #49

    FANTASTIC work. Thanks for taking the time to post your work. It’s MUCH appreciated.

  22. TF
    January 16, 2010 at 12:00 pm | #50

    Really Fantastic piece of work. Expecting more in future from urside :)

    • o0joecool0o
      January 18, 2010 at 5:26 pm | #51

      Thanks! current project is keeping me super tied up but as soon as its complete (march) I will have time for some new posts, UIPicker POP UP (Like safari) will be my next post.

  23. Victor S
    January 18, 2010 at 10:58 pm | #52

    Hi,

    This tutorial is the best. Thank you so much for this :)

  24. January 19, 2010 at 8:59 am | #53

    Hi,

    I tried the code for my webservices, I got the following errors,

    my parameters are :

    DataCon.XMLNameSpace = @”http://www.mvirtualcity.com/thespacewebservices/TheSpaceWebServices”;
    DataCon.XMLURLAddress = @”http://www.mvirtualcity.com/thespacewebservices/TheSpaceWebServices.asmx”;
    DataCon.MethodName = @”CheckLogin”;

    The webmethod does not return any dataset, it just return an integer that indicate if the logon is successful or not.

    soap:ClientSystem.Web.Services.Protocols.SoapException: Server did not recognize the value of HTTP Header SOAPAction: http://www.mvirtualcity.com/thespacewebservices/TheSpaceWebServices/CheckLogin.
    at System.Web.Services.Protocols.Soap11ServerProtocolHelper.RouteRequest()
    at System.Web.Services.Protocols.SoapServerProtocol.RouteRequest(SoapServerMessage message)
    at System.Web.Services.Protocols.SoapServerProtocol.Initialize()
    at System.Web.Services.Protocols.ServerProtocol.SetContext(Type type, HttpContext context, HttpRequest request, HttpResponse response)
    at System.Web.Services.Protocols.ServerProtocolFactory.Create(Type type, HttpContext context, HttpRequest request, HttpResponse response, Boolean& abortProcessing)

    • o0joecool0o
      January 19, 2010 at 5:57 pm | #54

      If you are following my example above using my classes I have only written support for datasets, if you want to just accept an integer you will have to write your own XMLParser object to handle the returned data.

  25. Luis Enrique Ortiz
    January 19, 2010 at 4:06 pm | #55

    Hi

    I have one problem, in my webservice i have an sql query where i insert the parameters that i received from the iphone to a database

    in my iphone when i call the webservice, in the server its call 3 times, for example if the parameters is one i get 3 rows in my databse with the value one

    why its the iphone calling 3 times the webservice??

    can anyone help

    • o0joecool0o
      January 19, 2010 at 5:58 pm | #56

      Not sure why this would be happening Mine only ever gets called once. Double check that the method is being called 3 times and its not a SQL error thats inserting a record 3 times… If it is being called 3 tiems check your iphone code for any duplicate class instances.

    • January 26, 2010 at 11:14 pm | #57

      I am also getting this issue, when I call a method in the web service that inserts a record into the DB (once) it is inserting the same record three times. Did you figure out what was causing this?

  26. January 25, 2010 at 10:12 am | #58

    great example and thanks for the files! I have tried to get this to work but I do not seem to get a dataset back. Im using a .Net service that takes in a string parameter (RoomID) and sends back a dataset.
    Heres my code, can you see anything wrong?

    - (IBAction)btnRefreshClick:(id)sender
    {

    WebServiceHelper *DataCon = [[WebServiceHelper alloc] init];

    DataCon.XMLNameSpace = @”http://phonefling.com/FlingService”;
    DataCon.XMLURLAddress = @”http://www.phonefling.com/flingservice/flingservice.asmx”;
    DataCon.MethodName = @”GetChatLinesByRoomID”;

    DataCon.MethodParameters = [[NSMutableDictionary alloc] init];
    [DataCon.MethodParameters setObject:@"1" forKey:@"RoomID"];

    self.data = [DataCon initiateConnection];

    DataSet *dsMyDataSet = [[DataSet alloc] initWithXMLData:self.data];

    NSMutableDictionary *mydata = [[NSMutableDictionary alloc] init];
    mydata = [dsMyDataSet getRowsForTableAndColumn:@"Table1" col:@"fromUser"];
    }

    • January 25, 2010 at 10:37 am | #59

      nevermind, i am getting the data back, I just need to figure out how to work with it =)

  27. January 26, 2010 at 10:23 pm | #60

    Wow, great work!
    I’m new in iPhone Developing and work with DataSets every day. It’s quiet hard to come from c# and dive into object-c ;-)
    You saved me a lot of time!
    Thank you

  28. January 27, 2010 at 12:51 am | #61

    Im having a similar problem to the post above. Im building a chat app that currently calls a webservice to get the chat lines, and also posts a single chat line to the service. When I debug and add breakpoints, the program goes through as expected and will add a single chat line until the flow reaches the end bracket of textFieldDoneEditing. As soon as I press continue the same chatline is then posted two more times. here is my code, can you see anything wrong? Thanks!!

    - (IBAction)textFieldDoneEditing:(id)sender //POSTs a new chat line to the chatroom
    {
    [sender resignFirstResponder];
    [txtAddText resignFirstResponder];
    WebServiceHelper *DataCon = [[WebServiceHelper alloc] init];

    DataCon.XMLNameSpace = @”http://phonefling.com/FlingService”;
    DataCon.XMLURLAddress = @”http://www.phonefling.com/flingservice/flingservice.asmx”;
    DataCon.MethodName = @”InsertChatLine”;

    DataCon.MethodParameters = [[NSMutableDictionary alloc] init];
    [DataCon.MethodParameters setObject:@"1" forKey:@"RoomID"];
    [DataCon.MethodParameters setObject:@"121431" forKey:@"UserID"];
    [DataCon.MethodParameters setObject:@"Scotty" forKey:@"UserName"];
    [DataCon.MethodParameters setObject:@"" forKey:@"toUser"];
    [DataCon.MethodParameters setObject:txtAddText.text forKey:@"ChatLine"];

    [DataCon initiateConnection];

    txtAddText.text = @””;

    [DataCon release];

    [self btnRefreshClick:nil];
    }

    - (IBAction)btnRefreshClick:(id)sender //refresh chatlines
    {
    WebServiceHelper *DataCon = [[WebServiceHelper alloc] init];

    DataCon.XMLNameSpace = @”http://phonefling.com/FlingService”;
    DataCon.XMLURLAddress = @”http://www.phonefling.com/flingservice/flingservice.asmx”;
    DataCon.MethodName = @”GetChatLinesByRoomID”;

    DataCon.MethodParameters = [[NSMutableDictionary alloc] init];
    [DataCon.MethodParameters setObject:@"1" forKey:@"RoomID"];

    self.data = [DataCon initiateConnection];
    DataSet *dsMyDataSet = [[DataSet alloc] initWithXMLData:self.data];
    [wvChat loadHTMLString:html baseURL:[NSURL URLWithString:@"http://www.apple.com"]];

    [DataCon release];
    }

    • January 27, 2010 at 12:59 am | #62

      another note, when i invoke the service from the server, it only inserts one record.

  29. Luke
    February 5, 2010 at 8:14 pm | #63

    This code was exactly what I needed to get my iPhone app talking to my company’s .net web service. The only issues I’m having are that this code uses a synchronous request to download the data, which causes my UI to freeze, and that it treats each element in the soap response as a distinct ‘column’ in the table – ignoring how it actually relates to other elements in the xml tree structure that I’m getting back from the server. It would help me tremendously if there was a way to parse each node of the xml into an NSDictionary, or to simply dump the data into a .plist file. Also, if anyone knows how to change this so that it works asynchronously, or can point me in the right direction, I would really appreciate it.

  30. o0joecool0o
    February 5, 2010 at 9:18 pm | #64

    I have a new version of the code that will now store the entire table in NSDictionary format which will allow you to retrieve the records row by row instead of by column. The new structure will be
    DATASET.TABLES(NSDictionary-ofTables)
    TABLE(NSDIctionary)[Key=RowID:Value=NSDictionary-ofcolumns]
    COLUMN(NSDictionary)[Key=ColumnName:Value=String-ofData]

    This will be much more flexible in that you can retrieve an entire table of rows and loop through each single row or column depending on your needs. simply by calling [myRow objectForKey@"Column1"]. This may help you out with what you are trying to accomplish.

    I will create a brand new blog post for this new version with instructions on using it which are far more simplified. My new approach actually is much better performance wise as it does not need to loop so much to create these structures. hopefully I will have the new post done by the end of this weekend.

    • March 26, 2010 at 9:32 am | #65

      i wonder when this update will be release?

    • Todd Banister
      April 7, 2010 at 7:56 pm | #66

      Was a newer version ever released? If so, can someone point me in the right direction. Thanks a ton for the awesome tutorial!

  31. February 9, 2010 at 1:20 am | #67

    Thanks for the great example.

    One word of warning – don’t use this code as-is. As it stands, it is leakier than a sieve. Run it under the static analyser to see the warnings and correct them for yourself.

  32. February 9, 2010 at 2:54 am | #68

    Actually, further to my last comment – this is great as sample code, but you can’t really use it in a commercial product due to the GPL license being attached to this code. Bugger.

  33. Austin
    February 12, 2010 at 10:56 pm | #69

    When I look at the soap envelope I created in the console, everything looks fine. However when I get to [Parser parse] in dataset.m, I look at *theXML and it tells me I didn’t supply the expected parameter. But its clearly there in the envelope (userName):

    Printing description of sRequest:
    austins

    here is the error:
    2010-02-12 16:56:21.519 Ring[4059:207] response:soap:ServerServer was unable to process request. —> Procedure or function ‘sp_SelPastAFEsByUserName’ expects parameter ‘@userName’, which was not supplied.

    • Austin
      February 12, 2010 at 10:58 pm | #70

      It looks like the site cut off my envelope, heres my attempt to re-paste it with the userName parameter in it:

      Printing description of sRequest:
      austins

      • Austin
        February 12, 2010 at 11:01 pm | #71

        Trying one more time:

        austins

      • Austin
        February 13, 2010 at 1:19 pm | #72

        Ok, it turns out it was the same problem John had up above. It sure is misleading tho to see an error about the stored proc not receiving the parameter. It leads one to believe that we’re communicating properly with the web service.

        So if anyone else gets the same error, it has nothing to do with your parameters. Its because you missed a stupid forward slash ‘/’ somewhere in your xmlNameSpace.

  34. gokhan
    February 26, 2010 at 3:56 pm | #73

    hey;

    thanx for great post. But did you find a solution for special characters ? if there is a special character in xml structure unlike XmlDatasetParser class is unable to detect and append to previous string.Is anyone found a solution for this?

    • o0joecool0o
      March 3, 2010 at 1:21 am | #74

      This will be fixed in the next version I came accross this error when tryign to recieive an “&” character The problem is for some reason XMLPArser splits the foundcharacters method and calls it 3 times for example pass in “Me&Him” calls found characters 3 tiems with “Me” “&” “Him”. Expect a much better bersion to be posted soon. Jsut crazy busy tryign to finish a project up!

  35. March 18, 2010 at 7:00 pm | #75

    Thanks John and oOjoecool. I was having the same problem with missing parameters and the extra \ in the method call. It is now working. This seems like a good start to a generalized architecture for dealing with SOAP web services.

  36. Wash
    March 19, 2010 at 2:27 am | #76

    HI… Great work on the code.. I was thinking about doing something like that !! :)

    bu here’s my question… My Response comes back as:

    Success

    I was trying to retrieve the LoginResult.. I got the webservice retrieving the data, jsut need to figure out how to parse it..
    what should the call be??

    mydata = [dsMyDataSet
    getRowsForTableAndColumnWhereEqualsString:@"??"
    col:@"????" where:@"?????"];

    • Wash
      March 19, 2010 at 11:16 am | #77

      Sorry .. I guess the “cat” eat my code.. . anyway.. here’s the xml response (replace with GT & LT)

      LT?xml version=”1.0″ encoding=”utf-8″?GT
      LTsoap:Envelope xmlns:soap=”http://schemas.xmlsoap.org/soap/envelope/” GT xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance” xmlns:xsd=”http://www.w3.org/2001/XMLSchema”
      LTsoap:BodyGT
      LTLoginResponse xmlns=”http://SERVER/ObjectLogin/”GT
      LTLoginResult GT
      Success
      LT/LoginResultGT
      LTLoginResponseGT
      LT/soap:BodyGT
      LT/soap:Envelope

  37. njdoxie
    March 20, 2010 at 4:11 pm | #78

    Hello, I get XML back from service call and it looks fine, no special characters, but when I call the dataset object, it doesn’t create a table or anything, I verified that the XML is being passed to the method DataSet…..it’s as if I’m passing nothing to the dataset object. Any ideas?

  38. Wash
    March 21, 2010 at 5:48 pm | #79

    njdoxie,

    I stopped the code in the DataSet.m method (getRowsForTableAndColumn) and figured out what the code translate as a table & column.. took me a while but it works… in my case (you can see the XML above), getRowsForTableAndColumn:@”LoginResponse” col:@”LoginResult–1″

    not sure if that will help but it worked for me !! :)

  39. Bilal
    March 22, 2010 at 3:11 pm | #80

    Hi,
    I am new to iphone dev. I want to call a web service without passing a complete xml (mean, like remote method invocation). I want to get ref of object (like C# do). thx in advance

  40. Pinal Tripathi
    March 25, 2010 at 3:22 pm | #81

    Thanks for really good post.

    I am new to iPhone apps dev., Now I want put my all data (UserId, Name, Email) in table view. What should I do? How should I iterate the loop?

    Thanks in advance… :)

  41. JB
    March 26, 2010 at 5:35 pm | #82

    Hello, by all accounts this sample is supposed to be wonderful, and I am about to have a play with it. (found the article ages ago, and only just got round to having a go)

    However I would like to use it in a commercial project, are you willing to release it under a different licence?

    Thanks very much
    J

  42. JB
    March 26, 2010 at 6:16 pm | #83

    update – just tried it out, its lovely!

  43. JB
    March 27, 2010 at 5:13 pm | #84

    Me again. I am not sure if I found an issue, I found that it was calling the webservices 3 times.

    It appears to still work (and indeed, only call the webservices once) if I comment out the following lines from WebServiceHelper.m

    //NSURLConnection *conn = [[NSURLConnection alloc] initWithRequest:request delegate:self];
    NSMutableData *myMutableData;
    // Check the connection object
    //if(conn)
    //{
    // myMutableData=[[NSMutableData data] retain];
    //}

    —-AND LATER ON…..

    //[NSURLConnection connectionWithRequest:request delegate:self];

    I think that each one of the commented out sections is kicking off a seperate ASynchronous thread.

    If anyone can reproduce and confirm it would be nice (As I am not an objective c person)

    J.

    • Wash
      April 1, 2010 at 1:08 pm | #85

      JB, I have the code working in an semi completed app and I cannot reproduce what you describing… as a matter of fact, what that shows is that you are making 3 successive calls somewhere else IMHO…

      Hope u got it working !!

  44. March 30, 2010 at 3:15 am | #86

    Hello, I am using Gentoo Linux for my webserver (running apache tomcat). I have written the webservices server in perl using SOAP::Lite module and dropped the code into cgi-bin. Using a simple perl-client I can communicate with the webservice. However, I was wondering if the code you provide might help my iphone app communicate with this linux web service?

  45. Digitaldave
    March 31, 2010 at 6:53 pm | #87

    I tried to declare self.data in the header of the my app:

    @interface Basic_iPhone_AppAppDelegate : NSObject {

    IBOutlet UIWindow *window;
    IBOutlet UITextField *textField;
    IBOutlet UILabel *label;

    }

    @property (nonatomic, retain) IBOutlet UIWindow *window;

    - (IBAction)click:(id)sender;

    @end

    But I am getting a bunch of errors.

    • Wash
      April 1, 2010 at 1:02 pm | #88

      can u show what u were trying to do and the first error??

  46. Wash
    April 1, 2010 at 1:17 pm | #89

    All,

    if you are looking to test your web service before making calls, you can use this really useful tool: http://code.google.com/p/mac-soapclient/ Soap Client uses WSDL files (or call the service with the service.asmx?WSDL) you provide to dynamically creates a graphical user interface for any given SOAP-based web service.

    Then you can use the output into your DataCon.XMLURLAddress, DataCon.XMLNameSpace & DataCon.MethodName…
    :)

  47. Digitaldave
    April 1, 2010 at 3:53 pm | #90

    I figured how to get rid of the error:

    @interface Basic_iPhone_AppAppDelegate : NSObject {

    IBOutlet UIWindow *window;
    IBOutlet UITextField *textField;
    IBOutlet UILabel *label;
    IBOutlet NSMutableData *data;
    IBOutlet NSString *phone;

    }

    @property (nonatomic, retain) IBOutlet UIWindow *window;
    @property(nonatomic, retain) IBOutlet NSMutableData *data;
    @property(nonatomic, retain) IBOutlet NSString *phone;

    - (IBAction)click:(id)sender;

    @end

    Now I am not getting any data back. Here some of the code:

    //add parameters **PARAMETERS ARE CASE SENSITIVE MAKE SURE THEY ARE TYPED CORRECTLY
    //AS THE SERVICE EXPECTS THEM**
    DataCon.MethodParameters = [[NSMutableDictionary alloc] init];
    //[DataCon.MethodParameters setObject:@"strFirst" forKey:[textField text]];
    [DataCon.MethodParameters setObject:@"" forKey:@"strFirst"];
    [DataCon.MethodParameters setObject:@"" forKey:@"strLast"];
    [DataCon.MethodParameters setObject:@"" forKey:@"strEmail"];
    [DataCon.MethodParameters setObject:@"" forKey:@"strPhone"];

    //Connect to the service and retrieve the xml raw data into a NSMutableDataObject
    //be sure to include a NSMutableData object called “data” or whatever you wish in
    //your viewcontroller
    self.data = [DataCon initiateConnection];

    //textField.text = @””;

    //Create a dataset object using the new raw data we received from the service
    DataSet *dsMyDataSet = [[DataSet alloc] initWithXMLData:self.data];

    //Now we have a dataset filled with data from the initWithXMLData command lets
    //query some data from it!
    //Set up a dictionary object to hold our query data from the dataset
    NSMutableDictionary *mydata= [[NSMutableDictionary alloc] init];

    //retrieve all rows from the selected table and column
    //mydata should contain all rows from column “email”
    mydata = [dsMyDataSet getRowsForTableAndColumn:@"Table1" col:@"phone"];

    The output for the service looks this:

    1
    bleh
    bleh
    Bleh
    Bleh
    Bleh
    Bleh
    Bleh
    Bleh
    Bleh

    I don’t get any errors from the service itself and I am able to access the service from the same machine as I am creating the app.

    The debugger console shows:

    [Session started at 2010-04-01 08:42:27 -0700.]
    2010-04-01 08:42:33.800 Basic iPhone App[11925:207] Parameter:strEmail Value: str:
    2010-04-01 08:42:33.801 Basic iPhone App[11925:207] Parameter:strPhone Value: str:
    2010-04-01 08:42:33.801 Basic iPhone App[11925:207] Parameter:strFirst Value: str:
    2010-04-01 08:42:33.802 Basic iPhone App[11925:207] Parameter:strLast Value: str:
    2010-04-01 08:42:33.869 Basic iPhone App[11925:207] Document Started Parsing…
    2010-04-01 08:42:33.869 Basic iPhone App[11925:207] Document Ended Parsing…
    2010-04-01 08:42:40.674 Basic iPhone App[11925:207] Parameter:strEmail Value: str:
    2010-04-01 08:42:40.674 Basic iPhone App[11925:207] Parameter:strPhone Value: str:
    2010-04-01 08:42:40.675 Basic iPhone App[11925:207] Parameter:strFirst Value: str:
    2010-04-01 08:42:40.675 Basic iPhone App[11925:207] Parameter:strLast Value: str:
    2010-04-01 08:42:40.732 Basic iPhone App[11925:207] Document Started Parsing…
    2010-04-01 08:42:40.733 Basic iPhone App[11925:207] Document Ended Parsing…

    The service allows blank parameters.

  48. Digitaldave
    April 1, 2010 at 3:57 pm | #91

    [REVISED]

    The service has the following table/columns:

    Table1
    sid
    department
    program
    lname
    fname
    email
    phone
    position
    site
    room

  49. Wash
    April 2, 2010 at 2:12 pm | #92

    Here’s a new question… if you have an xml that’s very long being processed as well as not consistently formed, how can I parse it (example is below) ??

    I get a table with dissociated elements and very hard to deal with.. I suppose I would like to have a structured table with the elements organized the way it was read… has anyone experienced the problem??

    Success
    Persons read: 25

    TESTA
    BLUE
    TESTA, BLUE
    0858530
    4-711-872-4
    1912-12-12T00:00:00.000-05:00
    947524
    FEMALE

    TESTB
    BARB
    TESTB, BARB
    5-569-322-0
    1945-01-12T01:00:00.000-04:00
    1192834
    FEMALE

  50. Digitaldave
    April 8, 2010 at 4:45 pm | #93

    I finally was able to connect to the web service. I just had to update the namespace. Now I am getting a different error as seen through debugger:

    2010-04-08 09:40:09.773 Basic iPhone App[9450:207] Document Started Parsing…
    Basic iPhone App(9450,0xa03ec4e0) malloc: *** mmap(size=16777216) failed (error code=12)
    *** error: can’t allocate region
    *** set a breakpoint in malloc_error_break to debug
    2010-04-08 09:41:38.498 Basic iPhone App[9450:207] *** Terminating app due to uncaught exception ‘NSMallocException’, reason: ‘Attempt to allocate 65536 bytes for NS/CFDictionary failed’
    2010-04-08 09:41:38.545 Basic iPhone App[9450:207] Stack: (
    29303899,
    2472080649,
    924296,
    29592397,
    28825756,
    29034760,
    29201916,
    29201409,
    14921,
    651860,
    32780906,
    32825095,
    649039,
    9012,
    8301,
    2733145,
    3140514,
    3149251,
    3144463,
    2838067,
    2746396,
    2773173,
    37400273,
    29088640,
    29084744,
    37394317,
    37394514,
    2777091
    )

    This looks like too much information came in, even though I am passing parameters.

  51. hashbang
    April 22, 2010 at 9:02 pm | #94

    Thanks for providing this code, it has helped me immensely. I am having one problem: the database call result from my webservice is returning a result with < instead of , so the XMLparser can’t understand it. I was thinking i would just include something before
    NSXMLParser *parser = [[NSXMLParser alloc] initWithData:data];

    that would turn the data into an NSString, find and replace those characters and turn it back into an NSMutabledata. Am i overlooking something simple here, or do you think this would be a good way to go about it?

  52. hashbang
    April 22, 2010 at 9:05 pm | #95

    hashbang :
    the database call result from my webservice is returning a result with < instead of , so the XMLparser can’t understand it.

    sorry, the HTML got garbled when i replied. it is returning ampersand lt; instead of a less than symbol.

  53. Chuck Condron
    April 26, 2010 at 10:16 pm | #96

    This code looks awesome, but it is a bit over my head as I have only been a mac owner for 4 days lol, and still learning Objective C and Xcode. I am curious if anyone knows if this will work to connect to Microsoft’s CRM Dynamics, CRM 4. I have done it with .NET with ease… I want to port this code over to the Ipad:

    public static CrmService GetCrmService(string orgName, string server)
    {
    CrmAuthenticationToken token = new CrmAuthenticationToken();
    token.AuthenticationType = 0; //AD (On-Premis)
    token.OrganizationName = orgName;

    CrmService service = new CrmService();
    service.UseDefaultCredentials = true;

    service.CrmAuthenticationTokenValue = token;
    service.Url = string.Format(“http://{0}/MSCrmServices/2007/crmservice.asmx”, server);
    return service;
    }

    and then here is what I am grabbing from the CRM webservice

    private void GetGeese()
    {
    GeeseList.Items.Clear();
    int i = 0;
    string boardnumber = “”;
    string MiniGooseIP = “”;

    ColumnSet cols = new ColumnSet();
    cols.Attributes = new string[] { “new_boardnumber”, “new_minigoose”};

    QueryExpression query = new QueryExpression();
    // Set the properties of the QueryExpression object.
    query.EntityName = EntityName.new_digital_billboard_master_data.ToString();
    query.ColumnSet = cols;

    ConditionExpression condition = new ConditionExpression();
    condition.AttributeName = “new_boardnumber”;
    condition.Operator = ConditionOperator.Like;

    condition.Values = new string[] { Boardlist.SelectedItem.ToString() };

    //Build the filter based on the condition.
    FilterExpression filter = new FilterExpression();
    filter.FilterOperator = LogicalOperator.And;
    filter.Conditions = new ConditionExpression[] { condition };

    // Set the Criteria property.
    query.Criteria = filter;

    // Retrieve the contacts.
    BusinessEntityCollection boardinfo = service.RetrieveMultiple(query);

    foreach (new_digital_billboard_master_data obj in boardinfo.BusinessEntities)
    {

    boardnumber = obj.new_boardnumber;
    MiniGooseIP = obj.new_minigoose;
    GeeseList.Items.Add(boardnumber);
    GeeseList.Items[i].UseItemStyleForSubItems = false;
    GeeseList.Items[i].SubItems.Add(MiniGooseIP);
    BoardLabel.Text = boardnumber;
    ipBox.Text = “http://” + MiniGooseIP + “/data.xml”;

    }

    i++;

    }

    So to start, I just want to see if I can talk to it, and pull out some data… I guess what I am not seeing in the code posted here on this site is that in the .net world, you can import the web service directly and call objects as if they were already created. So I think that is what you are doing in the web service helper? For example above the BusinessEntityCollection is already “known” from the web service.

    So using your examples, would I want to start simple and make a tableview and set the datasource to the Dataset? would you by chance have a full blown iphone app example including how to do the IBAction and IBOutlets to connect over to the Tableview? I know im a complete and utter noob but your article said you were one once too lol.

    thank you, please feel free to email me at chuckcondron@clearchannel.com

  54. Geo
    May 3, 2010 at 4:30 pm | #97

    I also would you to start by saying thanks for the work on this. I am attempting to call a web service I wrote and although it appears to be connecting and bring back something, it is never in a format I can get at.

    My question is this: Does the web service have to be returning a certain type of object? Meaning, currently I had it returning a dataset, then changed it to a data table. Should it just be an array or something like that? Can this code read a dataset/data table being returned?

    Thanks in advance for any and all help.

    Geo…

    • o0joecool0o
      May 28, 2010 at 5:59 pm | #98

      The dataset framework will ONLY accept a Dataset from the webservice. The XMLDatasetParser is built only for this datatype.

  55. Geo
    May 4, 2010 at 12:01 am | #99

    To continue with the problem I have, when the web service is returning a Data Table, Data Set or Array, it always only shows:

    2010-05-03 18:55:22.890 webServiceII[636:307] found this element: soap:Envelope
    2010-05-03 18:55:26.755 webServiceII[636:307] found this element: soap:Body
    2010-05-03 18:55:27.817 webServiceII[636:307] found this element: soap:Fault
    2010-05-03 18:55:29.444 webServiceII[636:307] found this element: faultcode
    2010-05-03 18:55:31.261 webServiceII[636:307] found this element: faultstring
    2010-05-03 18:55:33.813 webServiceII[636:307] found this element: detail

    Any help is greatly appreciated.

    • Yoyi
      June 24, 2010 at 3:30 am | #100

      I also have this problem when I’m providing two parameters. Do you get to solve this issue? How?

      Thanks

  56. Yves
    May 4, 2010 at 1:44 pm | #101

    hello
    I am French, beginner in programming for the iPhone and not very good in English ;-)
    I found your very great code, but I have to access other data in the dataset and despite your reply No. 61, I get nowhere! Can you help me please?

    • o0joecool0o
      May 28, 2010 at 5:58 pm | #102

      Please try the new framework in my latest post. A link to the post can be found above.

  57. yom
    May 6, 2010 at 3:45 pm | #103

    Hi,

    I’m interested in using your code, but I would like to make some updates to the code so that it is a bit more configurable.
    I’ve seen the GPLv3 licence in your code, but since there is no mail to contact you, I would like to know if you’d let me modify your code.

    Thanks to let me know by mail at yom@iaelu.net.

    Best regards,

    Guillaume.

    • o0joecool0o
      May 28, 2010 at 5:55 pm | #104

      You are welcome to modify the code as you wish for any purpose you like. I beleive that is what the gplv3 license said. If I am mistaken please let me know as I intended this to be open to everyoen to do with what they liek short of selling my example code or the framework itself for a profit.

  58. MayurNilwant
    June 14, 2010 at 6:17 am | #105

    I have connected to my web service but i am getting response in this format …plz can body help me
    Response :
    20202020 3c746974 6c653e54 68652072 65736f75 72636520 63616e6e 6f742062 6520666f 756e642e 3c2f7469 746c653e 0d0a2020 20202020 20203c73 74796c65 3e0d0a20 20202020 20202020 626f6479 207b666f 6e742d66 616d696c 793a2256 65726461 6e61223b 666f6e74 2d776569 6768743a 6e6f726d 616c3b66 6f6e742d 73697a65 3a202e37 656d3b63 6f6c6f72 3a626c61 636b3b7d 200d0a20 20202020 20202020 70207b66 6f6e742d 66616d69 6c793a22 56657264 616e6122 3b666f6e 742d7765 69676874 3a6e6f72 6d616c3b 636f6c6f 723a626c 61636b3b 6d617267 696e2d74 6f703a20 2d357078 7d0d0a20 20202020 20202020 62207b66 6f6e742d 66616d69 6c793a22 56657264 616e6122 3b666f6e 742d7765 69676874 3a626f6c 643b636f 6c6f723a 626c6163 6b3b6d61 7267696e 2d746f70 3a202d35 70787d0d

    Expected response format should be a xml file

  59. Yoyi
    June 24, 2010 at 4:11 am | #106

    Thanks for this amazing tutorial. It was working fine without parameters. But when I call a method with parameter this is what I get:

    2010-06-24 00:06:36.490 MyCars101[11619:207] Parameter:year Value:2001 str:2001
    2010-06-24 00:06:36.491 MyCars101[11619:207] Parameter:make Value:10 str:10
    2010-06-24 00:06:37.203 MyCars101[11619:207] Document Started Parsing…
    2010-06-24 00:06:37.203 MyCars101[11619:207] found this element: soap:Envelope
    2010-06-24 00:06:37.204 MyCars101[11619:207] found this element: soap:Body
    2010-06-24 00:06:37.204 MyCars101[11619:207] found this element: soap:Fault
    2010-06-24 00:06:37.205 MyCars101[11619:207] found this element: faultcode
    2010-06-24 00:06:37.205 MyCars101[11619:207] found this element: faultstring
    2010-06-24 00:06:37.206 MyCars101[11619:207] found this element: detail
    2010-06-24 00:06:37.207 MyCars101[11619:207] Document Ended Parsing…

    I have created a second method in the web service without params that calls inside this method with hardcoded params and it works fine. Here is my code, I’m completely sure that the params names and order match also the datatypes which are strings.

    WebServiceHelper * helper = [[WebServiceHelper alloc] init];
    helper.XMLNameSpace = @”http://tempuri.org”;
    helper.XMLURLAddress = @”http://localhost/yoyitest/Service.asmx”;
    helper.MethodName = @”GetModels”;
    helper.MethodParameters = [[NSMutableDictionary alloc] init];

    [helper.MethodParameters setObject: carYear forKey:@"year"];
    [helper.MethodParameters setObject: carMake forKey:@"make"];

    NSMutableData * rawData = [helper initiateConnection] ;
    DataSet * dataSet = [[DataSet alloc] initWithXMLData:rawData] ;
    NSMutableDictionary * data = [dataSet getRowsForTableAndColumn:@"t_car_models" col:@"model_name" ];

    NSEnumerator * enumerator = [data objectEnumerator] ;
    NSMutableArray * result = [[NSMutableArray alloc] init] ;
    NSString * model;

    // ITERATE THOUGH THE DICTIONARY
    while (model = [enumerator nextObject] )
    {
    [result addObject:model];
    }

    [helper release] ;
    [rawData release] ;
    [dataSet release] ;
    [data release] ;

    return result;

    I’m also sure that the parameters values are right. I even hardcode them in the code above and the problem persisted. I think is has to do with the soap request but I haven been able to detect the problem.

    Thank you very much. This has really helped me a lot.

    YOYI

  60. Yoyi
    June 24, 2010 at 4:37 am | #107

    I fix my previous problem. It was all about the namespace name which I think is wierd because it worked before for other methods without parameters.

    My namespace was http://tempuri.org after reading carefully the web service request I realize it was expecting this http://tempuri.org/ (with /). I put slash I it did not work because the helper inside add a slash when building the SoapAction value. So, I added a slash in this line of the helper class

    [sRequest appendString:[NSString stringWithFormat:@"",MethodName, XMLNameSpace]];

    now I have to make sure not to write a slash at the end in future namespaces. Hope this can save time to everyone facing this problem.

    Thanks again and good luck in the Apple Store :-)

    YOYI

  61. Yoyi
    June 24, 2010 at 4:40 am | #108

    [sRequest appendString:[NSString stringWithFormat:@"",MethodName, XMLNameSpace]];

    This was the line I modified. I have put some spaces so this blog text analyzer does not remove it.

    • o0joecool0o
      July 4, 2010 at 8:17 pm | #109

      Please update to Revision 2 see the link above. I cannot support this version as there are many bugs that have been fixed and memory issues in the new version.

  62. July 16, 2010 at 4:26 pm | #110

    Hi, I’m new for XCode developer,
    I try the code, from a my test web service,
    that work correcty on C# on Visual Studio.
    The web service on Visual Studio fill a grid and work very well,
    but the code on Xcode not work, the dataset is every nill,
    i dont know i think is ok(?), but not work

    The col: szRagSoc, return the name of user number

    Thank you very much. This has really helped me a lot.

    Nicola F. :)

    self.data = [[NSMutableData alloc] init];
    WebServiceHelper *DataCon = [[WebServiceHelper alloc] init];
    DataCon.XMLNameSpace = @”http://tempuri.org/”;
    DataCon.XMLURLAddress = @”http://www.tercera.biz/TelecomWs.asmx”;
    DataCon.MethodName = @”GetNumber”;
    DataCon.MethodParameters = [[NSMutableDictionary alloc] init];
    [DataCon.MethodParameters setObject:@"0495590318" forKey:@"szNumber"];
    self.data = [DataCon initiateConnection];

    //Create a dataset object using the new raw data we received from the service
    DataSet *dsMyDataSet = [[DataSet alloc] initWithXMLData:self.data];

    //Now we have a dataset filled with data from the initWithXMLData command lets
    //query some data from it!
    //Set up a dictionary object to hold our query data from the dataset
    NSMutableDictionary *mydata= [[NSMutableDictionary alloc] init];

    //retrieve all rows from the selected table and column
    mydata = [dsMyDataSet getRowsForTableAndColumn:@"telecom" col:@"szRagSoc" ];
    //mydata should contain all rows from column “Username”

    //you can do what you want with the data at this point like a simple iteration
    NSEnumerator *userIterator= [mydata objectEnumerator];

    NSString *username;

    while(username = [userIterator nextObject])
    {
    NSLog(@”Username: %@”, username);
    }
    [mydata release];

  63. o0joecool0o
    July 27, 2010 at 9:52 pm | #111

    Please update to Revision 2 see the link above. I cannot support this version as there are many bugs that have been fixed and memory issues in the new version

    • Nicola Fagan
      July 28, 2010 at 6:56 am | #112

      Thank you, i try the revision 2, and work very well :) :) many thanks

  64. August 16, 2010 at 9:34 am | #113

    soap:ClientServer did not recognize the value of HTTP Header SOAPAction: http://192.168.0.105/lws/getReportlist.”>soap:ClientServer did not recognize the value of HTTP Header SOAPAction: http://192.168.0.105/lws/getReportlist.

    When i call my web-service i got response some thing like this can any one help me please.

    thanks

  65. sam
    October 4, 2010 at 11:44 am | #114

    hi friend

    i want to create one form which will contain the colunm ” Name, address , Telephone no, Email and comments ”

    this will be entered by user in iphone app this information entered by the user should be saved in online server database
    i have to create this with webservice please i am new to this completetely i have to sub this with in 2 days please please help me

    Thanks
    Sam

Comments are closed.
Follow

Get every new post delivered to your Inbox.

%d bloggers like this: