Since that webservice is a hot topik on the forum, I decided to write a guideline to understand what you can do when you need to use webservice from iOS (so iphone or ipad or ipod, etc...)
In the first Section we will see some basic things about webservice, in Section 2 and 3 we will see 2 important architectures of webservice and how we can use these. In section 4 we will see some example to communicate with webservice, and in section 5 and 6 we will see how we can use what the webservice return.
Basically is a server that expose methods, you can call these methods with an input and you will receive an output. A webservice can be written in any language (php, C#, VB.Net, Java, Python, etc...).
Really webservices are much more than that, but this is not the place to study the argument in dept.
In iOS SDK there isn't a framework for consume webservice, so you need to create something from scratch, this can be "easily" done because webservice generally support HTTP + XML or JSON (in some case HTTP is not enabled for default, you need to enable manually yourself).
SOAP and REST are 2 architectures of webservice. The first use SOAP messages (subset of XML) to communicate with webservice, so you will use http requests to send\receive SOAP messages to communicate with the webservice. With REST you can use http requests using GET (or POST, PUT, DELETE) to call a method of webservice, and XML or JSON as input and output.
There are many other things to know about webservices, start reading from the link posted above if you want have a good explanation of the topik.
NOTE1: This tutorial is not intended to be a perfect explanation of webservice (so some term and phrase can be not 100% exact), it is just a guideline to consume webservice with iOS SDK.
NOTE2: My english is not so good, so if you find some error, tell me privately, i will fix it.
NOTE3: Feel free to add some usefull informations (links, approaches, utility, etc...), I will try to keep updated the thread with all options possible.
Section 2: REST webservice
REST is the easier to consume, it generally have a link, where you can specify a method and parameter directly with GET (GET mean inserting parameters directly on the link) Example: http://www.server.net/rest/?method=myMethod&par1=ok
So what you need to use a REST webservice is just to know the link with the right method and right input for that and then you will call it using an http request. [Look Section 4: HTTP Request]
It is a great tool that generate objective-c code ready to use, starting from WSDL (WSDL is a complete description of webservice, so in it you can read input\ouput of all webservice methods)
Recently was not updated often but the developer said that he will update soon his project adding new features and fixing bugs.
it can work, or can produce something that not fully work. Try it and see if you have some problems. In this case, you can try search on the forum to find some thread about sudzc.
2) Create "manually" xml to send with HTTP request and parse XML that you receive
With this solution, you should create the classes that represent the objects that your method(s) need (you can also start from the classes generated by sudzc). and then you will create a http request to your webservice, it will reply with an xml to parse.
What you want try to do is call some method of your webservice, so you need to understand what webservice expect to have when you call that method and what the webservice will return as output (so that you can parse it). You can read this information looking at the WSDL, but sometime when webservice is not easy\little, can be hard to fully understand what you need directly from WSDL.
So, you can use soapUI, it can help you a lot.
1)download soapUI
2)file\new soap project, and insert link to your wsdl
3)expand method that you want launch, double click "Request", you will see the xml that you should produce to call method.
4)recreate it manually on your iphone (concatenating strings and variables)
5)Send in post to your webservice link asynchronously (you can use ASIHTTPRequest or NSURLConnection). [Look Section 4: HTTP Request]
6)The server will reply with another xml that you can parse. [Look Section 5: Parse XML]
Another way to know what you need to send in xml, is too use a sniffer (wireshark? fiddler? tcpmon?) and see the xml that your "standard client" send\receive (assuming that you have a working client), and then use it as described in points 4,5,6.
Section 4: HTTP Request
How you can do a HTTP request? Easy, using NSURLConnection or ASIHTTPRequest.
For REST webservice generally you need just to do a request to the link (generally using just GET to specify input).
For SOAP webservice generally you need to do a request to the link of your webservice and add your SOAP Message in POST (that contain the method to call and the input for that method)
You would do the request asynchronously, seen that you want to do the request in background without block User Interface, so now we will see how to do asynchronous http requests with NSURLConnection and with ASIHTTPRequest.
NOTE:
NSURLConnection is built in with iOS SDK so you don't need to include nothing to use it, ASIHTTPRequest is a third party library that allow you to easily use http request and more stuff related. In order to use it in your project you must follow this ASIHTTPRequest Setup Instructions
Using ASIHTTPRequest for WebService (when you don't need to specify an input in POST)
Code:
-(void)callWebService{
//this is a typical url for REST webservice, where you can specify the method that you want to call and the parameters directly with GET
NSURL *url = [NSURL URLWithString:@"http://www.yourserver.net/webservice/rest/?method=myMethod&par1=ok"];
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
[request setDidFinishSelector:@selector(requestCompleted:)];
[request setDidFailSelector:@selector(requestError:)];
[request setDelegate:self];
[request startAsynchronous];
}
- (void)requestCompleted:(ASIHTTPRequest *)request
{
NSString *responseString = [request responseString];
}
- (void)requestError:(ASIHTTPRequest *)request
{
NSError *error = [request error];
}
How you can know the name of the methods and their parameters?
Check if your webservice have a WSDL or WADL, or check the documentation (generally who offer a webservice create also a documentation)
Using ASIHTTPRequest for Webservice (when you need to specify an input using POST)
What you need to insert in yourPOSTstring? A SOAP Message o a JSON string that contain your input (depend on what expect your webservice)
Now that you are able to call your webservice and retrieve its response, you just need to parse it, [Look Section 5: Parse XML] or [Look Section 6: Parse JSON]
Then in connectionDidFinishLoading, we have responseString, the output of our webservice, you just need to parse it, [Look Section 5: Parse XML] or [Look Section 6: Parse JSON]
Now that we have a response from the server, generally we want to parse it to create an object of the class that represent the object(s) returned.
We will see how to do that with an example.
Suppose that we have a webservice method getUser(id) that return the information about a user giving an id.
So the responseString from webservice when we call that method will be something like this:
This example cover various situations (when you need to parse an int\boolean, or an array of value (like friends, an array of strings) or a value that is on an attribute (like username)
Nice, so now we should just call this
We should have our user in myUser, now starting from that you should be able to make a parser for your objects.
NOTE:
When a WebService return an error, return a particular object: SoapFault, so you should create a SoapFault object and a SoapFaultParser that parse your responseString searching for a SoapFault, and when you are sure that responseString is not a fault, you should call ParserUser to parse the string as a WS_User.
I haven't done it in this tutorial just to keep it simple, you can see some code to do it from sudzc generated code, or you can just create it starting from my example.
In the same manner of xml section, we will se an example for JSON parsing.
But first we need to see how to setup project to use it, because there is any JSON framework included with iOS SDK,
1) you need to download here SBJson
2) add all the files on folder "Classes" with Drag&Drop on your project, (select the "Copy items into destination group’s folder" option)
Now you should only import SBJson.h in your class.
Code:
#import "SBJson.h"
Suppose that we have a webservice method getUser(id) that return the information about a user giving an id.
So the responseString from webservice when we call that method will be something like this:
Explanation:
responseString contain our json output returned by server, to parse it, we just need to call the method JSONValue, this return a NSDictionary with all the values.
dictionary is a NSDictionary, in our case it have 1 element, that element is in "return" key and is another NSDictionary. We assigned that to dictionaryReturn.
dictionaryReturn contain 5 objects (4 string: username, password_md5, banned, numPost and 1 NSArray). The array contain 3 NSDictionary each with 1 String on it (with key friendName), so we need to loop on the array, take the NSDictionary and then take the NSString from that.
NOTE:
Since that our webservice return only info about 1 user, we have a NSDictionary returned, if webservice return more than a user, it would returned a NSArray, so we would used
Code:
NSArray *arrUsers = [responseString JSONValue];
and so we would looped on the array that contain X NSDictionary, each representing a single user.
Finally you can fill your classes that represent the user (WS_User), or you can use directly what JSON Framework returned, as you prefer!.
Cool tutorial, thanks very much. I just came up with another related question bit more to PHP. Let's say I have index.php which loads me data from DB, creates JSON and does ECHO (something like here: http://app.vapa.cz/). But then...every user can easily see those data from DB. How would you protect it from others???
My idea is that iOS creates a HTTP request which will include some kind of parameter like user name and password. Then my index.php page will check this name + pass whether user is allow to dig data and if so, index.php will make him JSON. Is that good way or is there something better???
Thank you so much dany_dev, very helpful. Is there any way you could post the file source code or send them via email? I'm still confused about how these files should be set up in xcode. For example, where would the "envelope" script be located?
Thank you so much dany_dev, very helpful. Is there any way you could post the file source code or send them via email? I'm still confused about how these files should be set up in xcode. For example, where would the "envelope" script be located?
Thanks again!
For now i haven't an example ready, also if i'm planning to do it one soon (within May).
The xml to send to webservice (soap message that contain envelop, etc...), can be for example on a file, so that you can retrieve it, and add information on it.
I have a website with java as the back end and jsp as the front end , and mysql as the database. I am trying to follow youe tutorial which looks great but can anyone tell me can this tutorial be used if I do not use SOAP or REST.
Can I make the resquest the same way to the http to my jsp page that accesses the jsp and intefaces with the database adn send out a request?
If you already have a SOAP setup, then use SOAP; otherwise, RESTful http is much easier to go. Make sure you return a JSON data set (or XML) and the "Content-Type" header in your return is "application/json".
Also, make sure you put proper authentication on who can call request which data.
Quote:
Originally Posted by famictech2000
Hello
I have a website with java as the back end and jsp as the front end , and mysql as the database. I am trying to follow youe tutorial which looks great but can anyone tell me can this tutorial be used if I do not use SOAP or REST.
Can I make the resquest the same way to the http to my jsp page that accesses the jsp and intefaces with the database adn send out a request?
I have a website with java as the back end and jsp as the front end , and mysql as the database. I am trying to follow youe tutorial which looks great but can anyone tell me can this tutorial be used if I do not use SOAP or REST.
Can I make the resquest the same way to the http to my jsp page that accesses the jsp and intefaces with the database adn send out a request?
thanks in advance.
Yes, you can do the same exact thing, you just need a php or equivalent (so jsp is ok) script that give result in xml or json. Then you can follow "Section 4: HTTP Request" to call it and obtain the response. and then follow Section 5-6 to parse it.