I am using NSXMLParsing and UIPickerView in my application but i am not able to display
data in uipicker view after parsing. can anyone help me out about this problem.
I just want to know that how to store data in array and display it in uipickerview.
thnx frnds
Thanks mahboudz... I have done that what u said but its not working.. actually i have parsed some data and stored it in nsmutablearray using dictionary... and want to display it in uipicker view but its not working.. my code is:-
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict {
if ( [elementName isEqualToString:#"news"] ) {
//msgAdded = [[attributeDict objectForKey:#"added"] retain];//fetch session from message tag.
//msgId = [[attributeDict objectForKey:#"id"] intValue];//fetch id from message tag.
newId = [[NSMutableString alloc] init];
newsTitle =[[NSMutableString alloc]init];
newsOverview = [[NSMutableString alloc]init];
newsOfDay = [[NSMutableString alloc] init];
createdOn = [[NSMutableString alloc]init];
newsDescription = [[NSMutableString alloc]init];
idNews = NO;
ttlNews = NO;
overvwNews = NO;
dyNews = NO;
onCreated = NO;
desNews = NO;
//inFromUserName = NO;
}
if ( [elementName isEqualToString:#"news_id"] ) {
idNews = YES;
}
if ( [elementName isEqualToString:#"news_title"] ) {
ttlNews = YES;
}
if ( [elementName isEqualToString:#"news_overview"] ) {
overvwNews = YES;
}
if ( [elementName isEqualToString:#"is_news_of_the_day"] ) {
dyNews = YES;
}
if ( [elementName isEqualToString:#"created_on"] ) {
onCreated = YES;
}
if ( [elementName isEqualToString:#"news_description"] ) {
desNews = YES;
}
}
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string {
if ( idNews ) {
[newId appendString:string];
}
if (ttlNews) {
[newsTitle appendString:string];
}
if ( overvwNews ) {
[newsOverview appendString:string];
//NSLog(#"USER_NAME ===== %d",fromUserName);
}
if (dyNews) {
[newsOfDay appendString:string];
}
if (onCreated) {
[createdOn appendString:string];
}
if (desNews) {
[newsDescription appendString:string];
// NSLog(#"MESSAGE ==== %#",chatComment);
}
}
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {
if ( [elementName isEqualToString:#"news"] ) {
//[news addObject:[NSDictionary dictionaryWithObjectsAndKeys:chatSession,#"chatSession",fromUserName,#"fromUserName",chatComment,#"chatComment",nil]];
[messages addObject:[NSDictionary dictionaryWithObjectsAndKeys:newsTitle,#"title",newId,#"id",nil]];
}
if ( [elementName isEqualToString:#"news_id"] ) {
idNews = NO;
}
if ( [elementName isEqualToString:#"news_title"] ) {
ttlNews = NO;
}
if ( [elementName isEqualToString:#"news_overview"] ) {
overvwNews = NO;
}
if ( [elementName isEqualToString:#"is_news_of_the_day"] ) {
dyNews = NO;
}
if ( [elementName isEqualToString:#"created_on"] ) {
onCreated = NO;
}
if ( [elementName isEqualToString:#"news_description"] ) {
desNews = NO;
}
}
and now i want to display the contents of array in uipicker view. that is objectForKey:#"newstitle"
i have tried it display through following code:-
- (UIView *)pickerView:(UIPickerView *)pickerView viewForRow:(NSInteger)row forComponent:(NSInteger)component reusingView:(UIView *)view
{
UILabel *partyLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 300, 37)];
partyLabel.text= [[messages objectAtIndex:row]objectForKey:#"title"];
partyLabel.font = [UIFont boldSystemFontOfSize:13];
partyLabel.textAlignment = UITextAlignmentCenter;
partyLabel.backgroundColor = [UIColor clearColor];
return partyLabel;
}
but its not working ...please can any one help me out..
Thnx
Kunal
You are free to store the parsed data in whatever format you wish, such as an NSArray or a C array. When the UIPicker needs to display each row, it will call one of the following, depending on how you are managing the Picker:
– pickerView:titleForRow:forComponent:
– pickerView:viewForRow:forComponent:reusingView:
You need to implement only one of the two. The first one is easiest. When you get called for each row, then just return the NSString that you would like to have displayed in that row. The second one is more complex, but allows you to have more flexibility such as formatting the row or adding images.
If you are changing the display data after the UIPicker is on screen, you will need to call reloadComponent: or reloadAllComponents to update the display.
I think that at first you have to parse the xml and store data into an nsmutable array, then you have to display data in picker view from your array
Related
I am using XML parser to get my data.
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
currentNodeContent = (NSMutableString *) [string stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
}
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
if ( [elementName isEqualToString:#"country"] )
{
x++;
[messages addObject:[NSDictionary dictionaryWithObjectsAndKeys:Id,#"ID",Name,#"NAME",Image,#"IMAGE",nil]];
//**111**
NSLog(#"Data in Message : %#", [messages objectAtIndex:(x-1)]);
[Id setString:#""];
[Name setString:#""];
[Image setString:#""];
}
if ( [elementName isEqualToString:#"id"] )
{
[Id appendString:currentNodeContent];
}
if ( [elementName isEqualToString:#"name"] )
{
[Name appendString:currentNodeContent];
}
if ( [elementName isEqualToString:#"im"] )
{
[Image appendString:currentNodeContent];
}
}
//At //*111* the message is printed but when I do this after calling the xml parser, it doesn't print:
chatParser = [[NSXMLParser alloc] initWithData:receivedData];
[chatParser setDelegate:self];
[chatParser parse];
NSLog(#"\n\nMessages...\n\n%#", messages); //here there is no data printing
at this point it is printing empty..
Messages.
(
{
ID = "";
IMAGE = "";
NAME = "";
},
{
ID = "";
IMAGE = "";
NAME = "";
},
{
ID = "";
IMAGE = "";
NAME = "";
},
{
ID = "";
IMAGE = "";
NAME = "";
},
{
ID = "";
IMAGE = "";
NAME = "";
},
)
I have define message properties and also sythesize it.
In viewDidLoad I have did this
messages=[[NSMutableArray alloc] init];
Thank you for help..
Your problem is that you use same objects Id, Name, Image all the time and with the lines
[Id setString:#""];
[Name setString:#""];
[Image setString:#""];
set their values to "" at the end of each country element.
It better should look like this (not tested, maybe some typos):
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
currentNodeContent = (NSMutableString *) [string stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
}
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
if ([elementName isEqualToString:#"id"] )
{
[lastMessage setObject:currentNodeContent forKey:"ID"];
}
else if ( [elementName isEqualToString:#"name"] )
{
[lastMessage setObject:currentNodeContent forKey:"NAME"];
}
else if ( [elementName isEqualToString:#"im"] )
{
[lastMessage setObject:currentNodeContent forKey:"IMAGE"];
}
else if ( [elementName isEqualToString:#"country"] )
{
NSLog(#"Data in Message : %#", lastObject);
[messages addObject:lastMessage];
[lastMessage release];
}
}
-(void) parser:(NSXMLParser *)parser didStartElement:(NSString *)elName namespaceURI:(NSString *)uri
{
if ( [elementName isEqualToString:#"country"] )
{
lastMessage = [[NSMutableDictionary alloc]init];
}
}
Use the Below Code.Where Table is NSObject Class with the CaseId,PartyId,CartId as a properties in this class.If you have the xml url just called loadXMLByURL method with URl.After parsing you will get Each Object in TableArray which have the Table object with above properties.
NSMutableString *currentNodeContent;
NSXMLParser *parser;
Tweet *currentTweet;
bool isStatus;
-(id) loadXMLByURL:(NSString *)urlString
{
_tweets = [[NSMutableArray alloc] init];
NSURL *url = [NSURL URLWithString:urlString];
NSData *data = [[NSData alloc] initWithContentsOfURL:url];
parser = [[NSXMLParser alloc] initWithData:data];
parser.delegate = self;
[parser parse];
return self;
}
- (void) parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
currentNodeContent = (NSMutableString *) [string stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
}
- (void) parser:(NSXMLParser *)parser didStartElement:(NSString *)elementname namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
{
if ([elementname isEqualToString:#"Table"])
{
currentTable = [Table alloc];
isStatus = YES;
}
}
- (void) parser:(NSXMLParser *)parser didEndElement:(NSString *)elementname namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
if (isStatus)
{
if ([elementname isEqualToString:#"CaseId"])
{
currentTable.CaseId = currentNodeContent;
}
if ([elementname isEqualToString:#"PartyId"])
{
currentTable.PartyId = currentNodeContent;
}
if ([elementname isEqualToString:#"CartId"])
{
currentTable.CartId = currentNodeContent;
}
}
if ([elementname isEqualToString:#"Table"])
{
[self.tableArray addObject:currentTable];
currentTable = nil;
currentNodeContent = nil;
}
}
Let me know if you have any doubt.
I'm getting some data from a XML file on my server,here's the parse of the file:
-(void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict {
if ( [elementName isEqualToString:#"ipayregs"] ) {
msgAdded = [[attributeDict objectForKey:#"added"] retain];
msgId = [[attributeDict objectForKey:#"id"] intValue];
msgNome = [[NSMutableString alloc] init];
msgName = [[NSMutableString alloc] init];
msgMatricula = [[NSMutableString alloc] init];
msgSenderCode = [[NSMutableString alloc] init];
inNome = NO;
inName = NO;
inMatricula = NO;
inSenderCode = NO;
}
if ( [elementName isEqualToString:#"nome"] ) { inNome = YES; }
if ( [elementName isEqualToString:#"nome"] ) { inName = YES; }
if ( [elementName isEqualToString:#"matricula"] ) { inMatricula = YES; }
if ( [elementName isEqualToString:#"sendercode"] ) { inSenderCode = YES; }
}
-(void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string {
if ( inNome ) { [msgNome appendString:string]; }
if ( inName ) { [msgName appendString:string]; }
if ( inMatricula ) { [msgMatricula appendString:string]; }
if ( inSenderCode ) { [msgSenderCode appendString:string]; }
}
-(void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {
if ( [elementName isEqualToString:#"ipayregs"] ) {
[messages addObject:[NSDictionary dictionaryWithObjectsAndKeys:msgAdded,#"added",msgNome,#"nome",msgMatricula,#"matricula",msgSenderCode,#"sendercode",msgName,#"name",nil]];
[[messages reverseObjectEnumerator] allObjects];
lastId = msgId;
[msgAdded release];
[msgNome release];
[msgName release];
[msgMatricula release];
[msgSenderCode release];
}
if ( [elementName isEqualToString:#"nome"] ) { inNome = NO;}
if ( [elementName isEqualToString:#"name"] ) { inName = NO;}
if ( [elementName isEqualToString:#"matricula"] ) { inMatricula = NO;}
if ( [elementName isEqualToString:#"sendercode"] ) { inSenderCode = NO;}
}
As you can notice,the data downloaded is stored in vars(#"nome",#"matricula"..).But how can i display the values in UILabels,like | label.text = #"nome" |?
it looks like the data is actually being stored in msgNome. #"nome" is a string expression, not an instance variable. So, you would set label.text = msgNome;
also, you should just have:
inNome = [elementName isEqualToString:#"nome"];
instead of all the extra if statements.
I parsing some elements from a xml file located on my server to my app.This is the code to parse all elements:
-(void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict {
if ( [elementName isEqualToString:#"ipayregs"] ) {
msgAdded = [[attributeDict objectForKey:#"added"] retain];
msgId = [[attributeDict objectForKey:#"id"] intValue];
msgNome = [[NSMutableString alloc] init];
msgName = [[NSMutableString alloc] init];
msgMatricula = [[NSMutableString alloc] init];
msgSenderCode = [[NSMutableString alloc] init];
inNome = NO;
inName = NO;
inMatricula = NO;
inSenderCode = NO;
}
if ( [elementName isEqualToString:#"nome"] ) { inNome = YES; }
if ( [elementName isEqualToString:#"nome"] ) { inName = YES; }
if ( [elementName isEqualToString:#"matricula"] ) { inMatricula = YES; }
if ( [elementName isEqualToString:#"sendercode"] ) { inSenderCode = YES; }
}
-(void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string {
if ( inNome ) { [msgNome appendString:string]; }
if ( inName ) { [msgName appendString:string]; }
if ( inMatricula ) { [msgMatricula appendString:string]; }
if ( inSenderCode ) { [msgSenderCode appendString:string]; }
}
-(void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {
if ( [elementName isEqualToString:#"ipayregs"] ) {
[messages addObject:[NSDictionary dictionaryWithObjectsAndKeys:msgAdded,#"added",msgNome,#"nome",msgMatricula,#"matricula",msgSenderCode,#"sendercode",msgName,#"name",nil]];
[[messages reverseObjectEnumerator] allObjects];
lastId = msgId;
[msgAdded release];
[msgNome release];
[msgName release];
[msgMatricula release];
[msgSenderCode release];
}
if ( [elementName isEqualToString:#"nome"] ) { inNome = NO;}
if ( [elementName isEqualToString:#"name"] ) { inName = NO;}
if ( [elementName isEqualToString:#"matricula"] ) { inMatricula = NO;}
if ( [elementName isEqualToString:#"sendercode"] ) { inSenderCode = NO;}
}
As you can see all data is placed in a array to be displayed after on a UITableView,using this code:
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
-(NSInteger)tableView:(UITableView *)myTableView numberOfRowsInSection:(NSInteger)section {
return ( messages == nil ) ? 0 : [messages count];
}
-(UITableViewCell *)tableView:(UITableView *)myTableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = (UITableViewCell *)[self.messageList dequeueReusableCellWithIdentifier:#"newsCustomCell"];
if (cell == nil) {
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"newsCustomCell" owner:self options:nil];
cell = (UITableViewCell *)[nib objectAtIndex:0];
}
NSDictionary *itemAtIndex = (NSDictionary *)[messages objectAtIndex:indexPath.row];
UILabel *timeDate = (UILabel *)[cell viewWithTag:1];
timeDate.text = [itemAtIndex objectForKey:#"added"];
UILabel *userL = (UILabel *)[cell viewWithTag:2];
userL.text = [itemAtIndex objectForKey:#"nome"];
UILabel *textL2 = (UILabel *)[cell viewWithTag:3];
textL2.text = [itemAtIndex objectForKey:#"matricula"];
UILabel *textL3 = (UILabel *)[cell viewWithTag:4];
textL3.text = [itemAtIndex objectForKey:#"sendercode"];
return cell;
}
Ok,now is my problem,how can i make a UILabel display the value of the strings,per example the #"nome",be displayed in a UILabel when the view loads.It's related to this piece of code:
NSDictionary *itemAtIndex = (NSDictionary *)[messages objectAtIndex:indexPath.row];
But i don't know how i can set it up.
I'm a newbie to Objective-C & iPhone development, hence please bear with me.
I'm working on an app which loads with UITableView and upon selecting one particular cell called "Address Book" it should load with another UITableView containing all the addresses retrieved from a web request. Using NSXMLParser's delegate methods I'm storing those addresses into a NSMutableArray defined in the loaded view's header file. But the problem occurs when those addresses are being displayed onto the UITableView cells (yes, I have got the count for the number of cells). Can anybody please help me with this problem? I'm stuck on this for days now !!! Following is my code:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
AddressEntry *entry = (AddressEntry *)[self.addresses objectAtIndex:indexPath.row];
#try
{
NSLog(#"%#", entry.firstName);
}
#catch (NSException * e)
{
#try
{
NSLog(#"%#", entry.lastName);
}
#catch (NSException * e)
{
NSLog(#"%#", entry.lastName);
}
}
[entry release];
return cell;
}
- (void)parserDidStartDocument:(NSXMLParser *)parser
{
self.currentElement = nil;
self.f_Name = nil;
self.l_Name = nil;
self.phone = nil;
self.email = nil;
count = 0;
self.addresses = [[NSMutableArray alloc] init];
}
- (void) parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName
namespaceURI:(NSString *)namespaceURI
qualifiedName:(NSString *)qName
attributes:(NSDictionary *)attributeDict
{
if([elementName isEqualToString:#"Entries"])
{
count = [[attributeDict valueForKey:#"total"] intValue];
}
else if([elementName isEqualToString:#"FirstName"])
{
[self.f_Name release];
self.f_Name = [[NSString alloc] init];
}
else if([elementName isEqualToString:#"LastName"])
{
[self.l_Name release];
self.l_Name = [[NSString alloc] init];
}
else if([elementName isEqualToString:#"PhoneNumber"])
{
[self.phone release];
self.phone = [[NSString alloc] init];
}
else if([elementName isEqualToString:#"EmailAddress"])
{
[self.email release];
self.email = [[NSString alloc] init];
}
else if([elementName isEqualToString:#"Record"])
{
[self.addrEntry release];
self.addrEntry = [[[AddressEntry alloc] init] retain];
}
[self.currentElement release];
self.currentElement = nil;
self.currentElement = [elementName copy];
}
- (void) parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName
namespaceURI:(NSString *)namespaceURI
qualifiedName:(NSString *)qName
{
//
if([elementName isEqualToString:#"FirstName"])
self.addrEntry.firstName = self.f_Name;
else if ([elementName isEqualToString:#"LastName"])
self.addrEntry.lastName = self.l_Name;
else if([elementName isEqualToString:#"PhoneNumber"])
self.addrEntry.mobile = self.phone;
else if([elementName isEqualToString:#"EmailAddress"])
self.addrEntry.emailAddress = self.email;
else if([elementName isEqualToString:#"Record"])
{
[self.addresses addObject:self.addrEntry];
[self.addrEntry release];
self.addrEntry = nil;
/*AddressEntry *e = (AddressEntry *)[self.addresses lastObject];
NSLog(#"%# %# %# %#", e.firstName, e.lastName, e.mobile, e.emailAddress);
[e release];*/
}
}
- (void) parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
if([currentElement isEqualToString:#"FirstName"])
self.f_Name = string;
else if([currentElement isEqualToString:#"LastName"])
self.l_Name = string;
else if([currentElement isEqualToString:#"PhoneNumber"])
self.phone = string;
else if([currentElement isEqualToString:#"EmailAddress"])
{
self.email = string;
}
}
The most likely reason for the app crashing is this line in cellForRowAtIndexPath:
[entry release];
You did not alloc/init the variable entry there so don't call release on it. Remove that line.
In that method, entry is only holding a reference to an already-allocated object in the address array. It doesn't "own" the object so it shouldn't release it.
This page in the Apple docs shows a nice flow diagram and some simple rules for memory management that might help in understanding this better.
As a separate issue unrelated to the crashing, the use of #try/#catch in your example seems unnecessary. See this answer for an explanation.
Finally, also unrelated to the crashing, in foundCharacters, you should really be appending the string parameter to your data instead of just assigning because it's possible for that method to be called multiple times within the same value. See Handling XML Elements and Attributes for an example.
I am trying to extract the title from this xml:
<entry>
...
<title type="html">Some title</title>
<published>2011-02-07T00:04:16Z</published>
<updated>2011-02-07T00:04:16Z</updated>
...
</entry>
in the NSXMLParsing's didStartElement code:
if ([elementName isEqualToString:#"entry"])
{
item = [[NSMutableDictionary alloc] init];
}
if([elementName isEqualToString:#"title"])
{
currentElement = [elementName copy];
currentTitle = [[NSMutableString alloc] init];
}
in foundCharacters:
if ([currentElement isEqualToString:#"title"])
{
[currentTitle appendString:string];
}
in didEndElement:
if ([elementName isEqualToString:#"entry"])
{
[item setObject:currentTitle forKey:#"title"];
[currentElement release];
currentElement = nil;
[item release];
item = nil;
}
The problem is that for some reason when it gets to the didEndElement the currentTitle has got the three node's content, so its:
Some
title2011-02-07T00:04:16Z2011-02-07T00:04:16Z
I don't get why its picking up the published and updated node and appending them to the title string.
You set currentElement to #"title" in didStartElement: but you never unset it. The first element in this particular XML file is title, so you set currentElement and for every foundCharacters: thereafter you append them. Change didStartElement: to:
currentElement = [elementName copy];
if ([elementName isEqualToString:#"entry"])
{
item = [[NSMutableDictionary alloc] init];
}
if([elementName isEqualToString:#"title"])
{
currentTitle = [[NSMutableString alloc] init];
}
You have to add to didEndElement:
if ([elementName isEqualToString:#"title"])
{
[currentElement release];
currentElement = nil;
}
define
NSMutableString *strFoundCharacters; in class method set property and synthesize it.
then in
- (void) parser:(NSXMLParser *)parser foundCharacters:(NSString *) string {
NSString *strAppend = [string stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
if ([strAppend length] > 0) {
[self.strFoundCharacters appendString:string];
}
}
make nil to strfoundcharacter in
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName{
if ([elementName isEqualToString:#"title"] ) {
self.currentTitle = self.strFoundCharacters;
}
[self.strFoundCharacters setString:#""];
}
i think it will work