Hello :
I used the code posted in this thread. It helped me a lot.
But now I am facing an issue please help me.
I want to send data to web service in the form of xml like
<son>
<child name="XYZ">
</son>
and get back some information related to child.
But 0 byte response is received please help me in fixing this issue
Thanks in advance
Hello :
I used the code posted in this thread. It helped me a lot.
But now I am facing an issue please help me.
I want to send data to web service in the form of xml like
<son>
<child name="XYZ">
</son>
and get back some information related to child.
But 0 byte response is received please help me in fixing this issue
Thanks in advance
Use http post method here in IPhone to send data and add one aspx page in ur webservice and save that post data in to a xml file in page load of aspx page like this.
protected void Page_Load(object sender, EventArgs e)
{
StringBuilder sb = new StringBuilder();
int streamLength;
int streamRead;
Stream s = Request.InputStream;
streamLength = Convert.ToInt32(s.Length);
Byte[] streamArray = new Byte[streamLength];
streamRead = s.Read(streamArray, 0, streamLength);
for (int i = 0; i < streamLength; i++)
{
sb.Append(Convert.ToChar(streamArray[i]));
}
Use http post method here in IPhone to send data and add one aspx page in ur webservice and save that post data in to a xml file in page load of aspx page like this.
protected void Page_Load(object sender, EventArgs e)
{
StringBuilder sb = new StringBuilder();
int streamLength;
int streamRead;
Stream s = Request.InputStream;
streamLength = Convert.ToInt32(s.Length);
Byte[] streamArray = new Byte[streamLength];
streamRead = s.Read(streamArray, 0, streamLength);
for (int i = 0; i < streamLength; i++)
{
sb.Append(Convert.ToChar(streamArray[i]));
}
Like many others I wrote an app that was heavily dependent on asp.net SOAP web services that worked great in the simulator and then got hit with the surprise that the CoreServices library that contained all the web service functionality wasn't actually available on the iPhone. I'm still holding out hope this functionality will be added eventually.
All my code was dependant on receiving back the NSDictionary and NSArray object tree, and I didn't want to rewrite it all, so I created a wrapper to emulate the missing SOAP functionality by passing the request over REST. This allowed me to just swap out the method I was using for the webservice calls and keep the rest of the code the same. I thought I'd share it for anyone else in the same boat.
Fortunately asp.net already supports REST style requests (I didn't realize this before today), so no changes were needed on the web server side.
To demonstrate here the call to a simple method called "SayHello". You pass in name and it returns a single item called "string" that contains "Hello [yourname]". The code will work with more complex objects with child properties as well, and return them as NSDictionary and NSArray objects, but for simplicity I'm using "SayHello".
callRestService is a helper method I created in a class called Webservices. This code was exactly the same before except the helper method was called callSoapService.
WebServices.m contains two methods. getRestUrl just appends all the method parameters into a url to make the REST request. callRestService uses the build-in NSXMLParser class to retrieve the xml and sends it to a custom class called XmlParser to handle the callbacks and create the NSDictionary result,
The final step is to create the XmlParser handler. This class keeps track of each open and close tag to build an object tree containing NSMutableArray NSMutableDictionary and NSString objects.
#import "XmlParser.h"
@implementation XmlParser
@synthesize result;
@synthesize currentElementName;
@synthesize currentElementValue;
@synthesize parentArray;
- (void)parserDidStartDocument:(NSXMLParser *)parser
{
result=[[NSMutableDictionary alloc] init];
parentArray=[[NSMutableArray alloc] init];
[parentArray addObject:result];
currentElementName=@"";
}
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
{
if (qName) {
elementName = qName;
}
currentElementValue=@"";
if (currentElementName!=@"")
{
id newParent=NULL;
if ([currentElementName isLike:@"*Array*"])
{
newParent=[[NSMutableArray alloc] init];
} else {
newParent=[[NSMutableDictionary alloc] init];
}
[parentArray addObject:newParent];
}
currentElementName=elementName;
}
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
if (qName) {
elementName = qName;
}
if (currentElementName==@"")
{
//We're adding a container with children. Add it to the parent and remove this item fromt he parentArray
int currentIndex=[parentArray count]-1;
int parentIndex=currentIndex - 1;
id currentChild=[parentArray objectAtIndex:currentIndex];
id currentParent=[parentArray objectAtIndex:parentIndex];
if ([currentParent isKindOfClass:[NSMutableArray class]])
{
[currentParent addObject:currentChild];
} else {
[currentParent setObject:currentChild forKey:elementName];
}
[parentArray removeObjectAtIndex:currentIndex];
} else {
//We're adding a simple type element
int currentIndex=[parentArray count]-1;
id currentParent=[parentArray objectAtIndex:currentIndex];
if ([currentParent isKindOfClass:[NSMutableArray class]])
{
[currentParent addObject:currentElementValue];
} else {
[currentParent setObject:currentElementValue forKey:currentElementName];
}
}
currentElementName=@"";
}
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
currentElementValue=string;
}
@end
That's it. I'm sure it's not the cleanest code (This is my very first XCode app) and there may be a better way of doing this, but it saved me from having to rewrite all my code that was retrieving data from SOAP services. I've seen tons of other people with the same problem and no solutions so far. I hope this helps.
Hello:
I followed your approach. I am able to call the web service. But I am having an issue please help me in that.
I have an application which when starts first time on the device, then it calls a web service which gives some data and stores it in a xml file for future use. After this call, I am reading the xml file and showing the data in table view. But for the first time, the file is not created before the view load, so no data is displayed. But if I run the application next time, as the file has been created , the table view displays the data.
My problem is that even in the first time also the data should be created before the view load and the data is displayed in the table view.
I noticed one person mentioned using RESTful web services instead of SOAP. This is my plan as well. My question is...are you still streaming XML or are you using something more lightweight like JSON?
For my iphone application I need to request data about an object through a webservice.
I've used the code provided in this thread to do basic GET Request.
In fact, for now on, it just request an XML file located on a webserver (http://.../lait.xml).
Here's the XML i'm supposed to parse :
Code:
<?xml version="1.0" encoding="UTF-8"?>
<object>
<id>126</id> <!-- The object desserved has the id 126 in this kwys instance -->
<name>Milk</name> <!-- It is codenamed Milk -->
<information lang="fr"> <!-- We asked for french information -->
<title>Le lait</title> <!-- The title is the localized object's name -->
<!-- Here be the 3 types of content (for now): text, media, and link. -->
<!-- Each one may appear as many time as possible, in any order. -->
<text> <!-- A text entry is a caption followed by contents -->
<caption>Introduction</caption>
<!-- There must be at least one content Element. -->
<content>
Le lait est une boisson de couleur généralement blanchâtre
produite par
les mammifères femelles (y compris les monotrèmes).
Cette capacité
des femelles est une des caractéristiques définissant
les mammifères.
Le lait est produit par les cellules sécrétrices des
glandes
contenues dans les mamelles. Le lait sécrété dans les
premiers jours
après la parturition s'appelle le colostrum.
</content>
<content>
La fonction première du lait est de nourrir la progéniture
jusqu'à ce
qu'elle soit sevrée, c'est-à-dire capable de digérer
d'autres
aliments. Dans la plupart des civilisations humaines, le
lait des
animaux (eux-mêmes mammifères) domestiques (vache, brebis,
chèvre,
jument, dri, chamelle, dromadaire, bufflonne) est couramment
consommé.
</content>
<content>
Par analogie, on utilise également le terme de lait pour
désigner plusieurs boissons de consistance et/ou d'apparence
similaires et produites à base de végétaux, comme le lait de soja,
de coco, de riz, d'amande, d'avoine ou encore de pistache.
</content>
</text>
<media> <!-- Media refers to static media (picture) or dynamic/rich (video, ...). -->
<caption>Une fille pas douée en train de tout foutre à coté.</caption>
<href>http://upload.wikimedia.org/wikipedia/commons/5/59/MilkMaid.JPG</href>
</media>
<link> <!-- A link may refer to an external source, like this french wikipedia article. -->
<caption>Le lait sur wikipedia.</caption>
<href>http://fr.wikipedia.org/wiki/Lait</href>
</link>
<link> <!-- A link may also refer to another internal object, like this milk box. -->
<caption>La brique de lait.</caption>
<id>956</id>
</link>
</information>
</object>
The webrequest seems ok and here's the result from the NSDictionnary after going through server:
Code:
Response : {
object = {
id = 126;
information = {
link = {
caption = "La brique de lait.";
id = 956;
};
media = {
caption = "\U00e9e en train de tout foutre \U00e0 cot\U00e9.";
href = "http://upload.wikimedia.org/wikipedia/commons/5/59/MilkMaid.JPG";
};
text = {
caption = Introduction;
content = "\U00e9galement le terme de lait pour\n\t\t\t\td\U00e9signer plusieurs boissons de consistance et/ou d'apparence\n\t\t\t\tsimilaires et produites \U00e0 base de v\U00e9g\U00e9taux, comme le lait de soja,\n\t\t\t\tde coco, de riz, d'amande, d'avoine ou encore de pistache.\n\t\t\t";
};
title = "Le lait";
};
name = Milk;
};
}
The only thing is that the XMLParser seems to skip every node type he has already been going through (like <content> for example).
Could anyone tell me if there's a modification to do in the parser to correct that issue ?
I repost the parser .m file:
Code:
- (void)parserDidStartDocument:(NSXMLParser *)parser
{
result=[[NSMutableDictionary alloc] init];
parentArray=[[NSMutableArray alloc] init];
[parentArray addObject:result];
currentElementName=@"";
}
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
{
if (qName) {
elementName = qName;
}
currentElementValue=@"";
if (currentElementName!=@"")
{
id newParent=NULL;
if ([currentElementName isEqualToString:@"*Array*"])
{
newParent=[[NSMutableArray alloc] init];
} else {
newParent=[[NSMutableDictionary alloc] init];
}
[parentArray addObject:newParent];
}
currentElementName=elementName;
NSLog(@"Name %@", currentElementName); //to check the parser is really going through every node received from the web and it does. It just doesn't store 2 similar type of node.
}
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
if (qName) {
elementName = qName;
}
if (currentElementName==@"")
{
//We're adding a container with children. Add it to the parent and remove this item fromt he parentArray
int currentIndex=[parentArray count]-1;
int parentIndex=currentIndex - 1;
id currentChild=[parentArray objectAtIndex:currentIndex];
id currentParent=[parentArray objectAtIndex:parentIndex];
if ([currentParent isKindOfClass:[NSMutableArray class]])
{
[currentParent addObject:currentChild];
} else {
[currentParent setObject:currentChild forKey:elementName];
}
[parentArray removeObjectAtIndex:currentIndex];
} else {
//We're adding a simple type element
int currentIndex=[parentArray count]-1;
id currentParent=[parentArray objectAtIndex:currentIndex];
if ([currentParent isKindOfClass:[NSMutableArray class]])
{
[currentParent addObject:currentElementValue];
} else {
[currentParent setObject:currentElementValue forKey:currentElementName];
}
}
currentElementName=@"";
}
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
currentElementValue=string;
}
Hope someone can help. I just want a generic xml parser which gives me back a big NSDictionnary i can go through and get data.
Mmmh after reading what i just wrote i suppose it's just the way i try to access the data that cause problems.
Could anyone tell me how i'm supposed to access the "caption" field of a link ?
I think i have to get a NSMutableArray from "information" with the key "link" then every row should be a NSDictionary and i should be able to query it by a simple objectForKey:@"caption" right ?
How is everyone securing their per-user access to the web service and managing a server-side session for that user?
i.e. assuming encryption is handled by SSL -- how do you set the user session context on the web server? By http authentication, or actually passing a username/password pair into a 'logon' operation on the web-service and a token afterwards? the userid/pw pair every operation call?
Any examples appreciated.
Last edited by nwhiteside; 04-30-2009 at 01:52 PM.
Does anyone know how to obtain the attributes of an xml tag invoquing a SOAP webservice?
I'm able to get the NSDictionary, but the attributes are missing.
Example:
XML returned by the service:
<son>
<child name="XYZ">
</son>
If I use the WSMethodInvocationInvoke method to invoque it, I will get the NSDictionary whith a "son" object but I wont get the "child" name attribute so it will be nil
but if the webservice returns
<son>
<child>XYZ</son>
</son>
I am trying to read a double value returned by a webservice using NSXMLParser. In the event parser didEndElement, I am getting the correct value. But in the final output, the value gets reset to zero.
Could you please help me in this regard.....
Ramesh.
Quote:
Originally Posted by realberen
Thanks for the post. Just wondering, if you're interacting more, like sending data like you would normally do in the SOAP envelope, how do you do that in this scenario?
As they say: "That's what discussion boards are for...."
Glad I can help....
Im looking to access a webservice to pull data into a tableview on my iphone app for the user to scroll through. Then when they find a title they like, they can select the title in the tableview and be taken to the image that is also being stored on the webserver.
Would you know where i can get some sample code for this?
this seems to be the thread for this stuff so any help would be greatly appreciated!
Thanks
Paul
Last edited by pmvinuelas; 06-27-2009 at 07:07 PM.
Handling of an authentication key that somes back from a SOAP Login Method?
Hi, Thanks very much for posting these examples. These and the threads of replies have been very useful in getting a successful connection to a webservice I am trying to use. I did manage to call a Login method on my
service which sends back a session key. I assume that somehow I need to be sure to include this key in future requests to various methods (so it will know which session to use) What I am not sure is how to send the key. Does it get wrapped into a SOAP header? or does it somehow get associated with the NSURLRequest object? any thoughts, advice, examples appreciated.
Fortunately asp.net already supports REST style requests (I didn't realize this before today), so no changes were needed on the web server side.
Well maybe one change...
This was not working for me. Then I realized it WAS working only from the same development machine that was running the service. You can see this feature in action on the test web service pages that ASP.NET builds automatically.
In order to make this feature of ASP.NET accessible to remote machines I had to add this to my web.config file in ASP.NET.
Like many others I wrote an app that was heavily dependent on asp.net SOAP web services that worked great in the simulator and then got hit with the surprise that the CoreServices library that contained all the web service functionality wasn't actually available on the iPhone. I'm still holding out hope this functionality will be added eventually.
All my code was dependant on receiving back the NSDictionary and NSArray object tree, and I didn't want to rewrite it all, so I created a wrapper to emulate the missing SOAP functionality by passing the request over REST. This allowed me to just swap out the method I was using for the webservice calls and keep the rest of the code the same. I thought I'd share it for anyone else in the same boat.
Fortunately asp.net already supports REST style requests (I didn't realize this before today), so no changes were needed on the web server side.
To demonstrate here the call to a simple method called "SayHello". You pass in name and it returns a single item called "string" that contains "Hello [yourname]". The code will work with more complex objects with child properties as well, and return them as NSDictionary and NSArray objects, but for simplicity I'm using "SayHello".
callRestService is a helper method I created in a class called Webservices. This code was exactly the same before except the helper method was called callSoapService.
WebServices.m contains two methods. getRestUrl just appends all the method parameters into a url to make the REST request. callRestService uses the build-in NSXMLParser class to retrieve the xml and sends it to a custom class called XmlParser to handle the callbacks and create the NSDictionary result,
The final step is to create the XmlParser handler. This class keeps track of each open and close tag to build an object tree containing NSMutableArray NSMutableDictionary and NSString objects.
#import "XmlParser.h"
@implementation XmlParser
@synthesize result;
@synthesize currentElementName;
@synthesize currentElementValue;
@synthesize parentArray;
- (void)parserDidStartDocument:(NSXMLParser *)parser
{
result=[[NSMutableDictionary alloc] init];
parentArray=[[NSMutableArray alloc] init];
[parentArray addObject:result];
currentElementName=@"";
}
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
{
if (qName) {
elementName = qName;
}
currentElementValue=@"";
if (currentElementName!=@"")
{
id newParent=NULL;
if ([currentElementName isLike:@"*Array*"])
{
newParent=[[NSMutableArray alloc] init];
} else {
newParent=[[NSMutableDictionary alloc] init];
}
[parentArray addObject:newParent];
}
currentElementName=elementName;
}
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
if (qName) {
elementName = qName;
}
if (currentElementName==@"")
{
//We're adding a container with children. Add it to the parent and remove this item fromt he parentArray
int currentIndex=[parentArray count]-1;
int parentIndex=currentIndex - 1;
id currentChild=[parentArray objectAtIndex:currentIndex];
id currentParent=[parentArray objectAtIndex:parentIndex];
if ([currentParent isKindOfClass:[NSMutableArray class]])
{
[currentParent addObject:currentChild];
} else {
[currentParent setObject:currentChild forKey:elementName];
}
[parentArray removeObjectAtIndex:currentIndex];
} else {
//We're adding a simple type element
int currentIndex=[parentArray count]-1;
id currentParent=[parentArray objectAtIndex:currentIndex];
if ([currentParent isKindOfClass:[NSMutableArray class]])
{
[currentParent addObject:currentElementValue];
} else {
[currentParent setObject:currentElementValue forKey:currentElementName];
}
}
currentElementName=@"";
}
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
currentElementValue=string;
}
@end
That's it. I'm sure it's not the cleanest code (This is my very first XCode app) and there may be a better way of doing this, but it saved me from having to rewrite all my code that was retrieving data from SOAP services. I've seen tons of other people with the same problem and no solutions so far. I hope this helps.
Hi,can u give me the code..i have gone through ur code,but not getting anything as output.please i m new toi iphone world..help me!!!