ios - empty tableview rows when parsing with NSXMLPaerser using ASIHTTPRequest -
i'm pretty new iphone development , have problem. after several hours of searching , digging in code understand source of problem (hope) not know how solve it. problem tableview cells loads before parser finish "[array count]" nil. when set 'number of rows in section' manually, table appear, after few sec , scrolling , down.
i have 2 classes, 1 xmlparser , 1 show tableview. according read before opened question need reload tavleview data becuase have 2 various classes dont know how that. ideas?
thanks in davance!
here xmlparser code:
- (void)parserdidstartdocument:(nsxmlparser *)parser { self.titles = [[nsmutablearray alloc]init]; self.descriptions = [[nsmutablearray alloc]init]; self.links = [[nsmutablearray alloc]init]; self.pubdate = [[nsmutablearray alloc]init]; } - (void)parserdidenddocument:(nsxmlparser *)parser { } bool isitem = no; bool istitle = no; bool isdesription = no; bool isimg = no; bool ispubdate = no; - (void)parser:(nsxmlparser *)parser didstartelement:(nsstring *)elementname namespaceuri:(nsstring *)namespaceuri qualifiedname:(nsstring *)qname attributes:(nsdictionary *)attributedict { if ([elementname isequaltostring:@"item"]) { isitem = yes; } if ([elementname isequaltostring:@"title"]) { istitle=yes; self.titlesstring = [[nsmutablestring alloc]init]; } if ([elementname isequaltostring:@"description"]) { isdesription = yes; self.descriptionstring = [[nsmutablestring alloc]init];; self.data = [nsmutabledata data]; } if ([elementname isequaltostring:@"pubdate"]) { ispubdate = yes; self.pubdatestring = [[nsmutablestring alloc]init]; } } - (void)parser:(nsxmlparser *)parser foundcharacters:(nsstring *)string{ if(isitem && istitle){ [self.titlesstring appendstring:string]; } if (isitem && isdesription) { [self.descriptionstring appendstring:string]; } if (isitem && ispubdate) { [self.pubdatestring appendstring:string]; } } - (void)parser:(nsxmlparser *)parser foundcdata:(nsdata *)cdatablock { if (self.data) [self.data appenddata:cdatablock]; } - (void)parser:(nsxmlparser *)parser didendelement:(nsstring *)elementname namespaceuri:(nsstring *)namespaceuri qualifiedname:(nsstring *)qname { if ([elementname isequaltostring:@"item"]) { isitem = no; [self.titles addobject:self.titlesstring]; [self.descriptions addobject:self.descriptionstring]; [self.pubdate addobject:self.pubdatestring]; nslog(@"%@,%@,%@,",self.titlesstring,self.descriptionstring,self.pubdate); } if ([elementname isequaltostring:@"title"]) { istitle=no; } if ([elementname isequaltostring:@"description"]) { isdesription = no; if ([self.data length] > 0) { nsstring *htmlsnippet = [[nsstring alloc] initwithdata:self.data encoding:nsutf8stringencoding]; nsstring *imagesrc = [self firstimgurlstring:htmlsnippet]; [self.links addobject:imagesrc]; } self.data = nil; } if([elementname isequaltostring:@"pubdate"]) ispubdate = no; } - (nsstring *)firstimgurlstring:(nsstring *)string { nserror *error = null; nsregularexpression *regex = [nsregularexpression regularexpressionwithpattern:@"(<img\\s[\\s\\s]*?src\\s*?=\\s*?['\"](.*?)['\"][\\s\\s]*?>)+?" options:nsregularexpressioncaseinsensitive error:&error]; nstextcheckingresult *result = [regex firstmatchinstring:string options:0 range:nsmakerange(0, [string length])]; if (result) return [string substringwithrange:[result rangeatindex:2]]; return nil; }
and here's show tableview code:
- (void)viewdidload { [super viewdidload]; self.navigationitem.leftbarbuttonitem = [[uibarbuttonitem alloc] initwithimage:[uiimage imagenamed:@"menubutton.png"] style:uibarbuttonitemstylebordered target:self.viewdeckcontroller action:@selector(toggleleftview)]; nsurl *url; if (!self.isgetlink) url = [nsurl urlwithstring:@"http://www.ynet.co.il/integration/storyrss2.xml"]; else url = [nsurl urlwithstring:self.linkforparsingstring]; if (!self.xmlparser) { self.xmlparser = [[xmlparser alloc]init]; [self.xmlparser loadxmlwithurl:url]; } self.isgetlink = no; } - (void)didreceivememorywarning { [super didreceivememorywarning]; // dispose of resources can recreated. } #pragma mark - table view data source - (nsinteger)numberofsectionsintableview:(uitableview *)tableview { // return number of sections. return 1; } - (void)registernib:(uinib *)nib forcellreuseidentifier:(nsstring *)identifier { } - (nsinteger)tableview:(uitableview *)tableview numberofrowsinsection:(nsinteger)section { // return number of rows in section. return [self.xmlparser.titles count]; } - (uitableviewcell *)tableview:(uitableview *)tableview cellforrowatindexpath:(nsindexpath *)indexpath { static nsstring *cellidentifier = @"customcell"; customcell *cell = (customcell*) [tableview dequeuereusablecellwithidentifier:cellidentifier]; if (cell == nil) { nsarray *nib = [[nsbundle mainbundle] loadnibnamed:@"customcell" owner:self options:nil]; cell = [nib objectatindex:0]; } cell.lbltitle.text = [self.xmlparser.titles objectatindex:indexpath.row]; cell.lbltitle.font = [uifont boldsystemfontofsize:[uifont systemfontsize]]; nsdata *data = [nsdata datawithcontentsofurl:[nsurl urlwithstring:[self.xmlparser.links objectatindex:indexpath.row]]]; cell.imgview.image = [uiimage imagewithdata:data]; return cell; } - (cgfloat)tableview:(uitableview *)tableview heightforrowatindexpath:(nsindexpath *)indexpath { return 82; } #pragma mark - table view delegate nsstring *curnentdes; nsstring *currenttitle; nsstring *currentpubdate; - (void)tableview:(uitableview *)tableview didselectrowatindexpath:(nsindexpath *)indexpath { readviewcontroller *rvc = [[readviewcontroller alloc]initwithnibname:@"readviewcontroller" bundle:nil]; curnentdes = [self.xmlparser.descriptions objectatindex:indexpath.row]; currenttitle = [self.xmlparser.titles objectatindex:indexpath.row]; currentpubdate = [self.xmlparser.pubdate objectatindex:indexpath.row]; nsdateformatter *inputformatter = [[nsdateformatter alloc]init]; [inputformatter setdateformat:@"eee, dd mmm yyyy hh:mm:ss z"]; nsdate *inputdate = [inputformatter datefromstring:currentpubdate]; nsdateformatter *outputformatter = [[nsdateformatter alloc]init]; [outputformatter setdateformat:@"dd/mm/yyyy hh:mm"]; nsstring *outputdate = [outputformatter stringfromdate:inputdate]; rvc.description = curnentdes; rvc.stitle = currenttitle; rvc.pubdate = outputdate; [self.navigationcontroller pushviewcontroller:rvc animated:yes]; }
pretty simple reload table after parsing done, go. reason data comes after scrolling array updated @ later point , cellforrowatindex called , array has content see rows.
note: cellforrow called every row (hope know that).
using notification:
in parser class
- (void)parserdidenddocument:(nsxmlparser *)parser { [[nsnotificationcenter defaultcenter ]postnotificationname:@"parsingcomplete" object:nil]; }
in viewdidload of table view class add code , add other functions anywhere in ur class:
your viewdidload(edited)
- (void)viewdidload { [super viewdidload]; [[nsnotificationcenter defaultcenter] addobserver:self selector:@selector(parsingcomplete) name:@"parsingcomplete" object:nil]; self.navigationitem.leftbarbuttonitem = [[uibarbuttonitem alloc] initwithimage:[uiimage imagenamed:@"menubutton.png"] style:uibarbuttonitemstylebordered target:self.viewdeckcontroller action:@selector(toggleleftview)]; nsurl *url; if (!self.isgetlink) url = [nsurl urlwithstring:@"http://www.ynet.co.il/integration/storyrss2.xml"]; else url = [nsurl urlwithstring:self.linkforparsingstring]; if (!self.xmlparser) { self.xmlparser = [[xmlparser alloc]init]; [self.xmlparser loadxmlwithurl:url]; } self.isgetlink = no; }
//function handle notification:
-(void)parsingcomplete { nslog(@"parsing results: %@",self.xmlparser.titles); //change tableviewname [yourtableview reloaddata]; }
//removing notification:
-(void)dealloc { [[nsnotificationcenter defaultcenter] removeobserver:self]; }
Comments
Post a Comment