iOS: App crashing, likely due to instantiation of class - ios

I'm trying to debug a crash I'm experiencing...
I'm getting some data from a web server, so I've set up three classes:
Child
ChildConnection
ChildParser
ChildConnection contacts the web service and gets the data and starts the ChildParser, which then parse the xml and saves it as a Child object...
I've got it working in a project, where instead of having the ChildConnection, I set up the connection in the AppDelegate, and the issue I'm having in my current project is to do with delegates(at least that's what I think)... since I'm getting the error:
-[AppDelegate children]: unrecognized selector sent to instance 0x6b07e80
I'm fairly certain that the error is caused by: (NOTE: I'm pretty new to this)
- (ChildParser *) initChildParser {
self = [super init];
if(self)
{
childConnection = (ChildConnection *)[[UIApplication sharedApplication] delegate];
NSLog(#"Init");
}
return self;
}
ChildConnection.h:
#interface ChildConnection : NSObject
{
NSMutableArray *children;
NSMutableData *webData;
}
#property (nonatomic, retain) NSMutableArray *children;
-(void)connectionSetUp;
#end
ChildConnection.m:
#import "ChildConnection.h"
#import "ChildParser.h"
#implementation ChildConnection
#synthesize children;
- (void)connectionSetUp
{
NSString *soapMsg =
[NSString stringWithFormat:
Soap message left out due to sensitive data
];
NSURL *url = [NSURL URLWithString:#"Private"];
NSMutableURLRequest *req = [NSMutableURLRequest requestWithURL:url];
// Calculate the length of the post
NSString *postLength = [NSString stringWithFormat:#"%d", [soapMsg length]];
// Set the headers
[req addValue:postLength forHTTPHeaderField:#"Content-Length"];
[req addValue:#"text/xml; charset=utf-8" forHTTPHeaderField:#"Content-Type"];
[req addValue:#"PRIVATE" forHTTPHeaderField:#"SOAPAction"];
// Set the HTTP method and body
[req setHTTPMethod:#"POST"];
[req setHTTPBody:[soapMsg dataUsingEncoding:NSUTF8StringEncoding]];
NSURLConnection *myConnection = [[NSURLConnection alloc] initWithRequest:req delegate:self];
if(myConnection)
{
NSLog(#"Connection established");
webData = [NSMutableData data];
} else
{
NSLog(#"Connection failed");
}
}
-(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
NSLog(#"didReceiveResponse");
[webData setLength:0];
}
-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
//NSLog(#"didReceiveData");
[webData appendData:data];
}
-(void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
NSLog(#"didFailWithError: %#", [error localizedDescription]);
}
-(void)connectionDidFinishLoading:(NSURLConnection *)connection
{
NSLog(#"Finished loading");
NSXMLParser *xmlParser = [[NSXMLParser alloc] initWithData:webData];
//Initialize the delegate.
ChildParser *parser = [[ChildParser alloc] initXMLParser];
//Set delegate
[xmlParser setDelegate:parser];
//Start parsing the XML file.
BOOL success = [xmlParser parse];
/*
if(success)
NSLog(#"No Errors");
else
NSLog(#"Error Error Error!!!");
*/
//NSLog(#"Count: %#", [ count]);
}
#end
ChildParser.h:
#class Child;
#class ChildConnection;
#interface ChildParser : NSObject <NSXMLParserDelegate>
{
NSMutableString *currentElementValue;
Child *aChild;
ChildConnection *childConnection;
}
- (ChildParser *) initChildParser;
#end
.m:
#import "ChildParser.h"
#import "Child.h"
#import "ChildConnection.h"
#implementation ChildParser
- (ChildParser *) initChildParser {
self = [super init];
if(self)
{
childConnection = (ChildConnection *)[[UIApplication sharedApplication] delegate];
NSLog(#"Init");
}
return self;
}
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName
namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qualifiedName
attributes:(NSDictionary *)attributeDict
{
NSLog(#"didstart");
if([elementName isEqualToString:#"GetKidsResult"])
{
// initialize the array
if(!childConnection.children)
{
childConnection.children = [[NSMutableArray alloc] init];
}
}
else if([elementName isEqualToString:#"a:KeyValueOfintKidf4KEWLbb"])
{
if(!aChild)
{
//Initialize the child.
aChild = [[Child alloc] init];
}
}
//NSLog(#"Processing Element: %#", elementName);
}
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string {
NSLog(#"foundcharacters");
/*
if(!currentElementValue)
{
currentElementValue = [[NSMutableString alloc] initWithString:string];
}
else
{
[currentElementValue appendString:string];
}*/
}
-(void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
//NSLog(#"El name: %#", elementName);
if([elementName isEqualToString:#"GetKidsResult"])
{
NSLog(#"end of xml");
return;
}
if([elementName isEqualToString:#"a:KeyValueOfintKidf4KEWLbb"])
{
//NSLog(#"Found end of child");
//[childConnection.children addObject:aChild];
//NSLog(#"added");
//int i = [childConnection.children count];
//NSLog(#"Count: %d", i);
//aChild = nil;
}
else if([elementName isEqualToString:#"a:Key"])
{
//NSLog(#"Found key: %#", currentElementValue);
//aChild.key = [currentElementValue intValue];
//NSLog(#"key: %#", aChild.key);
}
else if([elementName isEqualToString:#"b:CPR"])
{
//NSLog(#"Found cpr");
//aChild.cpr = [currentElementValue intValue];
}
else if([elementName isEqualToString:#"b:CheckedIn"])
{
//NSLog(#"Found checkedIn");
//aChild.checkedIn = [currentElementValue boolValue];
}
else if([elementName isEqualToString:#"b:FirstName"])
{
//NSLog(#"Found firstname: %#", currentElementValue);
//[aChild setValue:currentElementValue forKey:#"firstName"];
//aChild.firstName = currentElementValue;
}
else if([elementName isEqualToString:#"b:Gender"])
{
//NSLog(#"found gender");
//aChild.gender = currentElementValue;
}
else if([elementName isEqualToString:#"b:Id"])
{
//NSLog(#"found id");
aChild.idChild = [currentElementValue intValue];
}
else if([elementName isEqualToString:#"b:IsOnTour"])
{
//NSLog(#"found isontour");
//aChild.isOnTour = [currentElementValue boolValue];
}
else if([elementName isEqualToString:#"b:LastName"])
{
//NSLog(#"found lastname: %#", currentElementValue);
//aChild.lastName = currentElementValue;
}
else if([elementName isEqualToString:#"b:GroupName"])
{
//NSLog(#"found groupname");
//aChild.groupName = currentElementValue;
}
currentElementValue = nil;
}
- (void)parserDidEndDocument:(NSXMLParser *)parser
{
NSLog(#"didEndDocument");
//NSLog(#"Number of objects: %d", [childConnection.children count]);
[[NSNotificationCenter defaultCenter] postNotificationName:#"finishedParsing" object:nil];
}
#end
UPDATE
Okay, so got a bit further... I'm now getting a SIGABRT in the class where I use the data:
#import "AllView.h"
#import "CustomCellNoSubtitle.h"
#import "DTCustomColoredAccessory.h"
#import "Child.h"
#import "ChildConnection.h"
#implementation AllView
#synthesize allChildrenTable, childView, whichGroupLabel, charIndex;
-(void)receivedData
{
NSLog(#"data update gotten");
charIndex = [[NSMutableArray alloc] init];
listOfNames = [[NSMutableArray alloc] init];
for(int i=0; i<[childConnection.children count]-1; i++)
{
// get the person
Child *aChild = [childConnection.children objectAtIndex:i];
// get both first and last name and join them
NSString *joinName = [NSString stringWithFormat:#"%# %#", aChild.firstName, aChild.lastName];
// save the full name to an array of all the names
[listOfNames addObject:joinName];
// get the first letter of the first name
NSString *firstLetter = [aChild.firstName substringToIndex:1];
NSLog(#"first letter: %#", firstLetter);
// if the index doesn't contain the letter
if(![charIndex containsObject:firstLetter])
{
// then add it to the index
NSLog(#"adding: %#", firstLetter);
[charIndex addObject:firstLetter];
}
}
[allChildrenTable reloadData];
}
}
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
// Deselect the row, so it's clear when the user returns
[allChildrenTable deselectRowAtIndexPath:indexPath animated:YES];
if(self.childView == nil)
{
ChildView *cView = [[ChildView alloc] initWithNibName:#"ChildView" bundle:[NSBundle mainBundle]];
self.childView = cView;
}
[self.navigationController pushViewController:childView animated:YES];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
// set the number of sections in the table to match the number of first letters
return [charIndex count];
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
// set the section title to the matching letter
return [charIndex objectAtIndex:section];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// get the letter in each section
NSString *alphabet = [charIndex objectAtIndex:section];
// get the names beginning with the letter
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"SELF beginswith[c] %#", alphabet];
NSArray *names = [listOfNames filteredArrayUsingPredicate:predicate];
return [names count];
}
// set up an index
- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView
{
return charIndex;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
CustomCellNoSubtitle *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
//cell = [[CustomCell alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier];
//cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
cell = [[CustomCellNoSubtitle alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
//cell.frame = CGRectZero;
}
/*
//---get the letter in the current section---
NSString *alphabet = [charIndex objectAtIndex:[indexPath section]];
//---get all states beginning with the letter---
NSPredicate *predicate =
[NSPredicate predicateWithFormat:#"SELF beginswith[c] %#", alphabet];
NSArray *names = [listOfNames filteredArrayUsingPredicate:predicate];
if ([names count]>0) {
//---extract the relevant state from the states object---
NSString *cellValue = [names objectAtIndex:indexPath.row];
cell.primaryLabel.text = cellValue;
}
cell.myImageView.image = [UIImage imageNamed:#"kidblank.png"];*/
return cell;
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
//childConnection = (ChildConnection *)[[UIApplication sharedApplication] delegate];
childConnection =[[ChildConnection alloc] init];
[allChildrenTable reloadData];
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Set up a connection to the server to fetch the list of children
ChildConnection *childConnection = [[ChildConnection alloc] init];
[childConnection connectionSetUp];
// Set up a listener to receive notice when the parser is done
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(receivedData) name:#"finishedParsing" object:nil];
}

The problem looks pretty simple.
In your very first pasted function, you are assigning your app delegate to the variable childConnection.
childConnection = (ChildConnection *)[[UIApplication sharedApplication] delegate];
Surely you actually want to assign a new instance of the ChildConnection class to that property instead. Like this:
childConnection = [[ChildConnection alloc] init];
I know that Objective-C errors can sometimes be hard to make sense of, but the one you are getting is actually pretty clear:
[AppDelegate children]: unrecognised selector
So it's complaining that you are calling a method/property "children" on the app delegate. But why would you be calling anything on the app delegate if you aren't using it any more? And why would you call a method called "children" on it, when that's actually defined as a property of the ChildConnection class, not the app delegate?
Answer: because an object you thought was a ChildConnection is actually the app delegate.
UPDATE: It looks like you need to use the ChildConnection in more than one place. The easiest way to do this is to make a shared instance. Add this method to your ChildConnection class:
+ (ChildConnection *)sharedConnection
{
static ChildConnection *sharedConnection = nil;
if (sharedConnection == nil)
{
sharedConnection = [[self alloc] init];
}
return sharedConnection;
}
Now in your other classes, wherever you've used [[ChildConnection alloc] init] use [ChildConnection sharedInstance] instead.

Your right the offending piece of code is :
if(self)
{
childConnection = (ChildConnection *)[[UIApplication sharedApplication] delegate];
NSLog(#"Init");
}
And the reason why is your casting your AppDelegate to a ChildConnection Object, you can't do this because well it isn't a ChildConnection.
If you want to reference your childConnection in your AppDelegate i recommend the following:
+ (AppDelegate*)sharedDelegate;
//Implementation
+ (AppDelegate*)sharedDelegate {
return (AppDelegate*)[[UIApplication sharedApplication] delegate];
}
So this way you reference your childConnection like so:
[AppDelegate sharedDelegate].childConnection;
If you need data the moment the App starts initialise the childConnection in:
application:didFinishLaunchingWithOptions:

Related

NSArray of dictionaries and copy

i have a huge huge problem, i feel like i will never get rid of it. i got a xml file coming from my server, parsing it well. but i got duplicates in that xml file. The thing is i need to get rid of the duplicates in my NSMutableArray, in order to know what i have in my NSMutable array and display a little menu with wich section is avaible and wich is not. But i can't manage to copy only the good stuff into another array since the NSMutableArray is as a matter of fact a Array of dictionaries. And i don't know how to manage them, i tried sevral things the past two days with no results, so please if someone can help me it would very appreciated.
here is my entire code (hope it doesn't burn you eyes :3) :
#include <CommonCrypto/CommonDigest.h>
#include <CommonCrypto/CommonHMAC.h>
#import "SizingDataViewController.h"
#import "LCYDataBackedTableView.h"
#implementation SizingDataViewController
- (void)viewDidLoad {
//Add the following line if you want the list to be editable
self.title = #"Last choice";
}
-(BOOL)ifStringExists:(NSString *)stringSentToCheck{
for (int i = 0; i < ([stories count]); i++) {
NSLog(#"i = %i", i);
NSMutableString *stringToCheck = (NSMutableString *)[[stories objectAtIndex: i] objectForKey: #"type"];
if ([stringToCheck isEqualToString:stringSentToCheck] == YES) {
NSLog(#"%#", #"okay its OKAY ");
return YES;
}
}
return NO;
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *MyIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:MyIdentifier];
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:MyIdentifier] autorelease];
CGRect frame = CGRectMake(0, 0, 160, 50);
UILabel *lbl1 = [[UILabel alloc] initWithFrame:frame];
lbl1.textAlignment = NSTextAlignmentRight;
[lbl1 setFont:[UIFont fontWithName:#"Helvetica" size:12.0]];
[lbl1 setTextColor:[UIColor grayColor]];
int storyIndex = [indexPath indexAtPosition: [indexPath length] - 1];
lbl1.text = [[stories objectAtIndex: storyIndex] objectForKey: #"creation_date"];//Modifier pour changer le texte affiché
[cell.contentView addSubview:lbl1];
[lbl1 release];
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [stories count];
}
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
}
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
}
- (void)parseXMLFileAtURL:(NSString *)URL
{
stories = [[NSMutableArray alloc] init];
NSData *xmlData = [URL dataUsingEncoding:NSUTF8StringEncoding];
rssParser = [[[NSXMLParser alloc] initWithData:xmlData]autorelease];
[rssParser setDelegate:self];
[rssParser setShouldProcessNamespaces:NO];
[rssParser setShouldReportNamespacePrefixes:NO];
[rssParser setShouldResolveExternalEntities:NO];
[rssParser parse];
}
- (void)parser:(NSXMLParser *)parser parseErrorOccurred:(NSError *)parseError {
NSString * errorString = [NSString stringWithFormat:#"Unable to download story feed from web site (Error code %i )", [parseError code]];
NSLog(#"error parsing XML: %#", errorString);
UIAlertView * errorAlert = [[UIAlertView alloc] initWithTitle:#"Error loading content" message:errorString delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil];
[errorAlert show];
}
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict{
currentElement = [elementName copy];
if ([elementName isEqualToString:#"data"]) {
item = [[NSMutableDictionary alloc] init];
currentData_id = [[NSMutableString alloc] init];
currentSizing_id = [[NSMutableString alloc] init];
currentName = [[NSMutableString alloc] init];
currentSize = [[NSMutableString alloc] init];
currentType = [[NSMutableString alloc]init];
}
}
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName{
if ([elementName isEqualToString:#"data"]) {
[item setObject:currentData_id forKey:#"data_id"];
[item setObject:currentSizing_id forKey:#"sizing_id"];
[item setObject:currentName forKey:#"name"];
[item setObject:currentSize forKey:#"size"];
[item setObject:currentType forKey:#"type"]
// here is where the magic happens
--> if (([self ifStringExists:currentType] == NO)){
[stories addObject:[item copy]];
}
}
}
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string{
NSLog(#"found characters in found characters: %#", string);
if ([currentElement isEqualToString:#"data_id"]) {
[currentData_id appendString:string];
} else if ([currentElement isEqualToString:#"sizing_id"]) {
[currentSizing_id appendString:string];
} else if ([currentElement isEqualToString:#"name"]) {
[currentName appendString:string];
} else if ([currentElement isEqualToString:#"size"]) {
[currentSize appendString:string];
}else if ([currentElement isEqualToString:#"type"]) {
[currentType appendString:string];
}
}
- (void)parserDidEndDocument:(NSXMLParser *)parser {
[activityIndicator stopAnimating];
[activityIndicator removeFromSuperview];
NSLog(#"all done!");
NSLog(#"stories array has %d items", [stories count]);
[newsTable reloadData];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}
- (void)dealloc {
[currentElement release];
[rssParser release];
[stories release];
[item release];
[currentData_id release];
[currentSize release];
[currentSizing_id release];
[currentName release];
[currentType release];
[super dealloc];
}
#end
my .h
#import <UIKit/UIKit.h>
#import <Foundation/Foundation.h>
#import "LCYDataBackedTableView.h"
#interface SizingDataViewController : LCYDataBackedTableView {
IBOutlet UITableView * newsTable;
UIActivityIndicatorView * activityIndicator;
CGSize cellSize;
NSXMLParser * rssParser;
NSMutableArray * stories;
NSMutableArray * newStories;
NSMutableArray *filteredStories;
NSString *l_uri;
NSString *myId;
NSString *idName;
BOOL *uploaded;
BOOL isFiltered;
NSIndexPath *indexPaath;
NSMutableDictionary * item;
NSString * currentElement;
NSMutableString * currentData_id, * currentSizing_id, * currentType, * currentName, * currentSize;
NSDictionary *data, *data1, *data2, *data3, *data4;
}
- (void)parseXMLFileAtURL:(NSString *)URL;
-(void)lastChance;
-(BOOL)ifStringExists:(NSString *)stringSentToCheck;
-(void)lastChance;
#end
Where you have the code [stories addObject:[item copy]]; in your parser delegate callback, don't just blindly add the new item - check if it exists already:
if (![stories containsObject:item]) {
[stories addObject:item copy];
}
Then you won't have duplicates at all.
You don't strictly need to copy item because you're creating a new one each time you start a new element. Also, if you don't define 'duplicate' as a full match to the entire dictionary then you will need to write your own contains type method which iterates the array and check the parts of each dictionary that you're interested in.

How to set badge value in Tab bar?

i have to read datas from xml and have to display values in view controller. am using tab barcontroller . where i have to read xml data and have to display it in tab bar as badge. here is my controller code.
-(void) parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qualifiedName attributes:(NSDictionary *)attributeDict
{
if([elementName isEqualToString:#"Event"]) {
//Initialize the array.
rssOutputData = [[NSMutableArray alloc] init];
mycount = [attributeDict objectForKey:#"count"];
NSLog(#"Reading count value :%#",mycount);
}
else if([elementName isEqualToString:#"eventdashboard"]) {
//Initialize the book.
aEvent = [[Eventlist alloc] init];
//Extract the attribute here.
aEvent.id = [[attributeDict objectForKey:#"userid"] integerValue];
NSLog(#"Reading id value :%d", aEvent.id);
}
NSLog(#"Processing Element: %#", elementName);
}
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string {
if(!nodecontent)
nodecontent = [[NSMutableString alloc] initWithString:string];else
[nodecontent appendString:string];
NSLog(#"Processing Value: %#", nodecontent);
}
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName
namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {
if([elementName isEqualToString:#"Event"])
return;
if([elementName isEqualToString:#"eventdashboard"]) {
[rssOutputData addObject:aEvent];
[aEvent release];
aEvent= nil;
}
else
[aEvent setValue:nodecontent forKey:elementName];
[nodecontent release];
nodecontent = nil;
}
- (void)viewDidLoad
{
[super viewDidLoad];
self.view.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:#"bg2.jpeg"]];
NSLog(#"%d",memberid);
myid = [SingleTonClass sinlgeTon].memberIdOne;
NSString *post =[[NSString alloc] initWithFormat:#"userid=%d",myid];
NSData *postData = [post dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
NSString *postLength = [NSString stringWithFormat:#"%d", [postData length]];
NSURL *url = [NSURL URLWithString:#"http://journalonline.in/cfts/dashboards/dashboard?"];
NSMutableURLRequest *theRequest = [NSMutableURLRequest requestWithURL:url];
// [theRequest addRequestHeader:#"Content-Type" value:#"application/xml"];
[theRequest setHTTPMethod:#"POST"];
[theRequest setValue:#"application/xml" forHTTPHeaderField:#"Accept"];
[theRequest setValue:#"application/x-www-form-urlencoded" forHTTPHeaderField:#"Content-Type"];
[theRequest setValue:postLength forHTTPHeaderField:#"Content-Length"];
[theRequest setHTTPBody:postData];
NSURLConnection *theConnection = [[NSURLConnection alloc] initWithRequest:theRequest delegate:self];
if( theConnection )
{
webData = [[NSMutableData data] retain];
NSLog(#"%#",webData);
}
}
-(void)viewWillAppear:(BOOL)animated{
[tblView reloadData];
}
-(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
[webData setLength: 0];
}
-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
[webData appendData:data];
}
-(void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
[connection release];
[webData release];
}
-(void)connectionDidFinishLoading:(NSURLConnection *)connection {
eventarray = [[NSMutableArray alloc]init];
xmlParserObject = [[NSXMLParser alloc] initWithData:webData];
[xmlParserObject setDelegate:self];
[xmlParserObject parse];
for (int i =0; i<[rssOutputData count]; i++) {
Eventlist *log = [rssOutputData objectAtIndex:i];
eventid = log.id;
NSLog(#"%d",eventid);
Invit = log.invitationdet;
NSLog(#"%#",Invit);
[eventarray addObject:log];
}
[connection release];
[tblView reloadData];
}
-(void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
NSString * segueIdentifier = [segue identifier];
if([segueIdentifier isEqualToString:#"MainEventList"]){
UINavigationController *nav = [segue destinationViewController];
MaineventListController *MVC = (MaineventListController *)nav.topViewController;
MVC.memberid1 = [SingleTonClass sinlgeTon].memberIdOne;
NSLog(#"%d",MVC.memberid1);
}
if ([segue.identifier isEqualToString:#"EventListDetail"])
{
NSIndexPath *indexPath = [tblView indexPathForSelectedRow];
[[SingleTonClass sinlgeTon] addObjectsColorArray:[NSString stringWithFormat:#"%d",indexPath.row]];
MainEventDetailController *destViewController = segue.destinationViewController;
MainEvent *aEvent1 = [eventarray objectAtIndex:indexPath.row];
destViewController.eveID = aEvent1.id;
destViewController.usrid = [SingleTonClass sinlgeTon].memberIdOne;
}
}
-(void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return [eventarray count];
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
if (section == 0)
return [eventarray count];
if (section == 1)
return 1;
return 0;
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"eventCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
if(indexPath.section == 0)
{
Eventlist *msglist = [eventarray objectAtIndex:indexPath.row];
cell.textLabel.text = msglist.invitationdet;
NSLog(#"Array %#",[SingleTonClass sinlgeTon].colorArray);
NSInteger stat=msglist.readflag;
if([[SingleTonClass sinlgeTon].colorArray containsObject:[NSString stringWithFormat:#"%d",indexPath.row]] || stat == 1 ) {
NSInteger stat1 = msglist.responseflag;
if(stat1 == 1){
cell.textLabel.textColor = [UIColor yellowColor];
}
else {
cell.textLabel.textColor = [UIColor redColor];
}
}
else{
cell.textLabel.textColor = [UIColor greenColor];
}
cell.backgroundColor = [UIColor blackColor];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
}
if(indexPath.section == 1)
{
UIButton *viewmoreButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
viewmoreButton.frame = CGRectMake(200.0f, 5.0f, 80.0f, 30.0f);
[viewmoreButton setTitle:#"View More" forState:UIControlStateNormal];
[cell addSubview:viewmoreButton];
[viewmoreButton addTarget:self
action:#selector(viewMore:)
forControlEvents:UIControlEventTouchUpInside];
cell.backgroundColor = [ UIColor blackColor];
}
return cell;
}
- (void)viewMore:(id)sender
{
[self performSegueWithIdentifier:#"MainEventList" sender:sender];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
-(void) dealloc
{
[xmlParserObject release];
[super dealloc];
}
Here am reading a value from XML
mycount = [attributeDict objectForKey:#"count"];
I dont know to display in tab bar as badge. i tried to display it under ViewdidLoad but didnt worked
pls help me friends
Let me tell you the simplest way to set badge value :
[[self navigationController] tabBarItem].badgeValue = #"YourBadgeValue";
Vineet Singh's answer is good if you want to change the badge for the current tab. If instead you need to change the value for another tab you have in your tab bar, use the following:
Objective-C
[[self.tabBarController.tabBar.items objectAtIndex:0] setBadgeValue:nil];
Swift
tabBarController?.tabBar.items?[0].badgeValue = nil
Remember to replace the index I used with the actual tab you want to edit the value for.
AppDelegate *appDelegate = (AppDelegate*)[[UIApplication sharedApplication] delegate];
UITabBarItem *tbItem = (UITabBarItem *)[appDelegate.tabBarController.tabBar.items objectAtIndex:tabIndex];
tbItem.badgeValue = [NSString stringWithFormat:#"%i", count];
swift 2.0:
self.navigationController!.tabBarItem.badgeValue = "YourBadgeValue"
Try this:
tabBarItem.badgeValue = [NSString stringWithFormat:#"%d",count];
I see some answers about setting this on the TabItem, but if the tab has never been loaded the viewDidLoad function will never get loaded. This is especially important when you are trying to create a background process such as push notification handling set a tab's badge. It's much more likely you will need your TabViewController to handle the badge setting. Tags on the TabItem seem more appropriate and then flip through the tabs until you find the one you want to update.
Cheers!
int indexOfTabbarItem = 0;
NSString *badgeValue = [NSString stringWithFormat:#"%lu", (long)countUnreadMessages];
[[[[self viewControllers] objectAtIndex:indexOfTabbarItem] tabBarItem] setBadgeValue:([badgeValue isEqualToString:#"0"]) ? nil : badgeValue];
This worked for me. Some times you have to find the right controller and then its item to set it. Cheers.
For ionic angular, you just bind the value to tabBadge
<ion-tab [root]="tab3Root" tabIcon="notifications" tabBadgeStyle="red" tabBadge={{totalUnread}}></ion-tab>

parsed feed not visible on UITableView, cellForRowAtIndexPath method not getting accessed

I am trying to show parsed Yahoo RSS feed on the table view. But nothing is getting shown on the screen. When I used breakpoints I came to know that the control is not going to cellForRowAtIndexPath method at all. I don't know why that is happening. The structure of the yahoo feed is as follows:
<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:media="http://search.yahoo.com/mrss/" version="2.0">
<channel>
<title>Yahoo! News - Latest News & Headlines</title>
<link>http://news.yahoo.com/</link>
<description>The latest news and headlines from Yahoo! News. Get breaking news stories and in-depth coverage with videos and photos.</description>
<language>en-US</language>
<copyright>Copyright (c) 2013 Yahoo! Inc. All rights reserved</copyright>
<pubDate>Sun, 21 Apr 2013 17:08:00 -0400</pubDate>
<ttl>5</ttl>
<image>
<title>Yahoo! News - Latest News & Headlines</title>
<link>http://news.yahoo.com/</link>
<url>http://l.yimg.com/a/i/us/nws/th/main_142c.gif</url>
</image>
<item><title>After the bombings, the blame game begins</title><description><p><a href="http://news.yahoo.com/boston-marathon-bombing-blame-game-begins-210800101.html"><img src="http://l3.yimg.com/bt/api/res/1.2/uiv31afw5K_BzPxeYQz44Q--/YXBwaWQ9eW5ld3M7Zmk9ZmlsbDtoPTg2O3E9ODU7dz0xMzA-/http://media.zenfs.com/en_us/News/Reuters/2013-04-22T013026Z_741208741_GM1E94M0Q7101_RTRMADP_3_USA-EXPLOSIONS-BOSTON.JPG" width="130" height="86" alt="A couple embraces at a memorial on Boylston Street to the victims of the Boston Marathon bombings in Boston" align="left" title="A couple embraces at a memorial on Boylston Street to the victims of the Boston Marathon bombings in Boston" border="0" /></a>Some lawmakers fault the FBI for not following up on intelligence about one of the alleged bombers.</p><br clear="all"/></description><link>http://news.yahoo.com/boston-marathon-bombing-blame-game-begins-210800101.html</link><pubDate>Sun, 21 Apr 2013 17:08:00 -0400</pubDate><source url="http://www.csmonitor.com/">Christian Science Monitor</source><guid isPermaLink="false">boston-marathon-bombing-blame-game-begins-210800101</guid><media:content url="http://l3.yimg.com/bt/api/res/1.2/uiv31afw5K_BzPxeYQz44Q--/YXBwaWQ9eW5ld3M7Zmk9ZmlsbDtoPTg2O3E9ODU7dz0xMzA-/http://media.zenfs.com/en_us/News/Reuters/2013-04-22T013026Z_741208741_GM1E94M0Q7101_RTRMADP_3_USA-EXPLOSIONS-BOSTON.JPG" type="image/jpeg" width="130" height="86"></media:content><media:text type="html"><p><a href="http://news.yahoo.com/boston-marathon-bombing-blame-game-begins-210800101.html"><img src="http://l3.yimg.com/bt/api/res/1.2/uiv31afw5K_BzPxeYQz44Q--/YXBwaWQ9eW5ld3M7Zmk9ZmlsbDtoPTg2O3E9ODU7dz0xMzA-/http://media.zenfs.com/en_us/News/Reuters/2013-04-22T013026Z_741208741_GM1E94M0Q7101_RTRMADP_3_USA-EXPLOSIONS-BOSTON.JPG" width="130" height="86" alt="A couple embraces at a memorial on Boylston Street to the victims of the Boston Marathon bombings in Boston" align="left" title="A couple embraces at a memorial on Boylston Street to the victims of the Boston Marathon bombings in Boston" border="0" /></a>Some lawmakers fault the FBI for not following up on intelligence about one of the alleged bombers.</p><br clear="all"/></media:text><media:credit role="publishing company"></media:credit></item></guid></channel>
</rss>
My feedViewController.m is as follows:
#interface feedViewController ()
#end
#implementation feedViewController
#synthesize tableView,showPosts;
//#synthesize feed;
Feed *xmlParseFeed;
//channel *chShow;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
//self.feed = [[Feed alloc] init];
self.showPosts = [[NSMutableArray alloc] init];
NSArray *newPosts = [xmlParseFeed newPosts];
if (newPosts) {
[self.showPosts addObjectsFromArray:newPosts];
//[newPosts release];
}
static NSString *feedURLString = #"http://news.yahoo.com/rss";
NSURL *feedURL = [NSURL URLWithString:feedURLString];
xmlParseFeed = [[Feed alloc] initWithURL:feedURL];
self.showPosts = [[NSMutableArray alloc] init];
[xmlParseFeed refresh];
}
- (void)viewDidUnload
{
[self setTableView:nil];
[super viewDidUnload];
// Release any retained subviews of the main view.
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView
numberOfRowsInSection:(NSInteger)section {
return [showPosts count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] ;
cell.selectionStyle = UITableViewCellSelectionStyleNone;
}
ItemDataCollection *post = [showPosts objectAtIndex:indexPath.row];
Feed *entry = [showPosts objectAtIndex:indexPath.row];
// Set up the cell...
channel *channelRecord = [self.showPosts objectAtIndex:indexPath.row];
cell.textLabel.text = channelRecord.cTitle;
cell.textLabel.text = channelRecord.pubDate;
NSLog(#"channelRecord.title *****************%#",channelRecord.cTitle);
/* cell.textLabel.text = post.title;
cell.textLabel.text = post.itemDescription;
cell.textLabel.text = post.titleImage;
NSLog(#"item title******%#",post.title); */
cell.textLabel.font=[UIFont fontWithName:#"Arial" size:12];
cell.textLabel.numberOfLines = 1;
return cell;
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
#end
Properties in channel class are: cTitle,pubDate and itemCollectionArray. Properties in Post class are: title, itemDescription and titleImage. Feed class is for parsing. the contents of Feed.m is as follows:
#class ItemDataCollection;
#implementation Feed
#synthesize feedURL,feedRequest,currentElement,currentElementData;
//#synthesize feedChannel;
//#synthesize feedPosts;
static ItemDataCollection *itemCollection;
static NSMutableArray *channelCollection;
NSMutableString *mString;
NSMutableString *str;
channel *Channel ;
- (NSArray *)newPosts {
NSMutableArray *posts = [[NSMutableArray alloc] init];
for (NSInteger item = 1; item <= 5; item++) {
//NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
ItemDataCollection *newPost;
newPost = [[ItemDataCollection alloc] init];
// NSString *pubDate = [NSDate dateWithTimeIntervalSinceNow:#"pubDate"];
newPost.title = [NSString stringWithFormat:#"title %#", kTitleElementName];
newPost.itemDescription = [NSString stringWithFormat:#"itemdescription %#", kItemDescription];
newPost.titleImage = [NSString stringWithFormat:#"image %#",kItemImage];
// newPost.itemTitle = [NSString stringWithFormat:#"itemtitle %#", ITEM_TITLE_XML];
[posts addObject:newPost];
//[newPost release];
// [pool drain];
}
return posts;
}
- (Feed *) initXMLParser {
//[super init];
appDelegate = (appAppDelegate *)[[UIApplication sharedApplication] delegate];
return self;
}
-(id)initWithURL:(NSURL *)sourceURL {
if (self = [super init]) {
self.feedURL = sourceURL;
channelCollection=[[NSMutableArray alloc] init];
}
return self;
}
- (void)refresh {
self.feedRequest = [ASIHTTPRequest requestWithURL:feedURL];
// [feedPosts removeAllObjects];
[feedRequest setDelegate:self];
[feedRequest startAsynchronous];
}
- (void)requestFinished:(ASIHTTPRequest *)request {
NSData *responseData = [request responseData];
// NSLog(#"*************response are *********%#",[[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding]);
NSXMLParser *parser = [[NSXMLParser alloc] initWithData:responseData];
[parser setDelegate:self];
if ([parser parse]) {
[[NSNotificationCenter defaultCenter]
postNotificationName:#"myevent"
object:nil];
// [posts ]
}
}
- (void)requestFailed:(ASIHTTPRequest *)request {
NSError *error = [request error];
NSLog(#"requestFailed: %#", [error localizedDescription]);
}
- (void)parser:(NSXMLParser *)parser
didStartElement:(NSString *)elementName
namespaceURI:(NSString *)namespaceURI
qualifiedName:(NSString *)qName
attributes:(NSDictionary *)attributeDict {
if ([elementName isEqualToString:kChannelElementName]) {
Channel = [[channel alloc] init];
dict=[[NSMutableDictionary alloc] init];
[Channel setItemCollectionArray:[[NSMutableArray alloc] init]];
return ;
}
if ([elementName isEqualToString:kItemElementName]) {
itemCollection=[[ItemDataCollection alloc] init];
return ;
}
if ([elementName isEqualToString:kTitleElementName]) {
return ;
}
if([elementName isEqualToString:kItemDescription]){
return ;
}
if ([elementName isEqualToString:kItemImage]) {
NSString *urlString = attributeDict[#"url"];
if(urlString){
[dict setObject:urlString forKey:#"img"];
NSLog(#"%#",urlString);
mString = [NSString stringWithFormat:urlString];
str = [NSString stringWithFormat:mString];
}
return ;
}
}
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string {
if (currentElementData == nil) {
self.currentElementData = [[NSMutableString alloc] init];
}
[currentElementData appendString:string];
}
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName
namespaceURI:(NSString *)namespaceURI
qualifiedName:(NSString *)qName {
if ([elementName isEqualToString:kChannelElementName]) {
[channelCollection addObject:Channel];
NSLog(#"channel are***********%#",channelCollection);
for(ItemDataCollection *mydata in Channel.itemCollectionArray){
NSLog(#"___%# <><><><><> desc \n <><><><><><> img \n %#",mydata.title,/*mydata.itemDescription*/mydata.titleImage);
}
Channel =nil;
}
else if ([elementName isEqualToString:kItemElementName]) {
[[Channel itemCollectionArray] addObject:itemCollection];
itemCollection=nil;
}
else if ([elementName isEqualToString:kTitleElementName]) {
if(itemCollection==nil){
Channel.cTitle=currentElementData;
}
else{
itemCollection.title=currentElementData;
}
}
else if ([elementName isEqualToString:kPubDate]) {
Channel.pubDate=currentElementData;
}
else if ([elementName isEqualToString: kItemDescription]) {
if(itemCollection!=nil){
itemCollection.itemDescription = currentElementData;
}
}
else if([currentElementData rangeOfString:#"media:content"].location){
if(itemCollection!=nil){
if([str isEqualToString:mString]){
// [currentElementData appendString:dict];
itemCollection.titleImage = mString;
} else{
itemCollection.titleImage = #"";
}
}
}
self.currentElementData = nil;
}
- (void)parser:(NSXMLParser *)parser parseErrorOccurred:(NSError *)parseError {
NSString *info = [NSString stringWithFormat:
#"Error %i, Description: %#, Line: %i, Column: %i",
[parseError code],
[[parser parserError] localizedDescription],
[parser lineNumber],
[parser columnNumber]];
NSLog(#"RSS Feed Parse Error: %#", info);
}
#end
The feed is getting parsed and can be seen on the console. But it is not visible on the screen. What can be the reason? As i said earlier, cellForRowAtIndexPath() is not getting accessed at all. What's the reason for that??
I've added this method:
- (void)feedChanged:(NSNotification *)notification {
NSArray *newPosts = [xmlParseFeed newPosts];
NSLog(#"%#",newPosts);
if (newPosts) {
[self.showPosts addObjectsFromArray:newPosts];
[self.tableView reloadData];
// [self updateViewTitle];
// [newPosts release];
}
I don't see where in your code you're calling reloadData from UITableView. You need to call this method after you load newPosts.
If this doesn't work, check a couple of things like:
What is the value returned by tableView:numberOfRowsInSection:? Is it greater than zero? If it's zero, that's why tableView:cellForRowAtIndexPath doesn't get called.
How do you load your feed? Is it in the main thread or different thread? You should be loading it in a different thread, so you won't block your UI while you load the data, but make sure you're calling reloadData after the data is loaded into newPosts.

Youtube thumbnail from channel rss feed?

I am trying to load a youtube channel's feed into a uitableview with an rss feed. I need this to display the thumbnail from the individual videos. I can only find this using the gdata client which does not work. Here is the code I have so far:
Videos.h:
#import <UIKit/UIKit.h>
#interface Videos : UITableViewController<NSXMLParserelegate>{
IBOutlet UITableView * newsTable;
UIActivityIndicatorView * activityIndicator;
CGSize cellSize;
NSXMLParser * rssParser;
NSMutableArray * stories;
// a temporary item; added to the "stories" array one at a time, and cleared for the next one
NSMutableDictionary * item;
// it parses through the document, from top to bottom...
// we collect and cache each sub-element value, and then save each item to our array.
// we use these to track each current item, until it's ready to be added to the "stories" array
NSString * currentElement;
NSMutableString * currentTitle, * currentDate, * currentSummary, * currentLink;
}
- (void)parseXMLFileAtURL:(NSString *)URL;
#end
Videos.m
#import "Videos.h"
#import "AppDelegate.h"
#implementation Videos
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
self.tabBarItem.image = [UIImage imageNamed:#"clapboard#2x.png"];
}
return self;
}
- (void)viewDidLoad {
// Add the following line if you want the list to be editable
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [stories count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *MyIdentifier = #"MyIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:MyIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:MyIdentifier];
}
// Set up the cell
int storyIndex = [indexPath indexAtPosition: [indexPath length] - 1];
cell.textLabel.text=[[stories objectAtIndex: storyIndex] objectForKey: #"title"];
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
// Navigation logic
int storyIndex = [indexPath indexAtPosition: [indexPath length] - 1];
NSString * storyLink = [[stories objectAtIndex: storyIndex] objectForKey: #"link"];
NSLog(#"%#",stories );
// clean up the link - get rid of spaces, returns, and tabs...
storyLink = [storyLink stringByReplacingOccurrencesOfString:#" " withString:#""];
storyLink = [storyLink stringByReplacingOccurrencesOfString:#"\n" withString:#""];
storyLink = [storyLink stringByReplacingOccurrencesOfString:#" " withString:#""];
// open in Safari
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:storyLink]];
}
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
}
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
if ([stories count] == 0) {
NSString * path = #"https://youtube.com/rss/user/TheGruenebergBrother/videos.rss";
[self parseXMLFileAtURL:path];
}
cellSize = CGSizeMake([newsTable bounds].size.width, 60);
}
- (void)viewWillDisappear:(BOOL)animated {
}
- (void)viewDidDisappear:(BOOL)animated {
}
#pragma mark - parseing_Delegate_methods
- (void)parserDidStartDocument:(NSXMLParser *)parser{
NSLog(#"found file and started parsing");
}
- (void)parseXMLFileAtURL:(NSString *)URL
{
stories = [[NSMutableArray alloc] init];
//you must then convert the path to a proper NSURL or it won't work
NSURL *xmlURL = [NSURL URLWithString:URL];
// here, for some reason you have to use NSClassFromString when trying to alloc NSXMLParser, otherwise you will get an object not found error
// this may be necessary only for the toolchain
rssParser = [[NSXMLParser alloc] initWithContentsOfURL:xmlURL];
// Set self as the delegate of the parser so that it will receive the parser delegate methods callbacks.
[rssParser setDelegate:self];
// Depending on the XML document you're parsing, you may want to enable these features of NSXMLParser.
[rssParser setShouldProcessNamespaces:NO];
[rssParser setShouldReportNamespacePrefixes:NO];
[rssParser setShouldResolveExternalEntities:NO];
[rssParser parse];
}
- (void)parser:(NSXMLParser *)parser parseErrorOccurred:(NSError *)parseError {
NSString * errorString = [NSString stringWithFormat:#"Unable to download story feed from web site (Error code %i )", [parseError code]];
NSLog(#"error parsing XML: %#", errorString);
UIAlertView * errorAlert = [[UIAlertView alloc] initWithTitle:#"Error loading content" message:errorString delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil];
[errorAlert show];
}
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict{
//NSLog(#"found this element: %#", elementName);
currentElement = [elementName copy];
if ([elementName isEqualToString:#"item"]) {
// clear out our story item caches...
item = [[NSMutableDictionary alloc] init];
currentTitle = [[NSMutableString alloc] init];
currentDate = [[NSMutableString alloc] init];
currentSummary = [[NSMutableString alloc] init];
currentLink = [[NSMutableString alloc] init];
}
}
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName{
//NSLog(#"ended element: %#", elementName);
if ([elementName isEqualToString:#"item"]) {
// save values to an item, then store that item into the array...
[item setObject:currentTitle forKey:#"title"];
[item setObject:currentLink forKey:#"link"];
[item setObject:currentSummary forKey:#"summary"];
[item setObject:currentDate forKey:#"date"];
[stories addObject:[item copy]];
NSLog(#"adding story: %#", currentTitle);
}
}
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string{
//NSLog(#"found characters: %#", string);
// save the characters for the current item...
if ([currentElement isEqualToString:#"title"]) {
[currentTitle appendString:string];
} else if ([currentElement isEqualToString:#"link"]) {
[currentLink appendString:string];
} else if ([currentElement isEqualToString:#"description"]) {
[currentSummary appendString:string];
} else if ([currentElement isEqualToString:#"pubDate"]) {
[currentDate appendString:string];
}
}
- (void)parserDidEndDocument:(NSXMLParser *)parser {
[activityIndicator stopAnimating];
[activityIndicator removeFromSuperview];
NSLog(#"all done!");
NSLog(#"stories array has %d items", [stories count]);
[newsTable reloadData];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning]; // Releases the view if it doesn't have a superview
// Release anything that's not essential, such as cached data
}
- (void)dealloc {
[currentElement release];
[rssParser release];
[stories release];
[item release];
[currentTitle release];
[currentDate release];
[currentSummary release];
[currentLink release];
[super dealloc];
}
#end
Also where should the code go, and what is the code?
Thanks
there is a thumbnail url,
http://img.youtube.com/vi/VIDEOIDHERE/0.jpg
http://img.youtube.com/vi/VIDEOIDHERE/1.jpg
http://img.youtube.com/vi/VIDEOIDHERE/2.jpg
http://img.youtube.com/vi/VIDEOIDHERE/3.jpg
will fetch you the thumbnail for any video. The number represents the quality, zero being the highest. E.g:
http://img.youtube.com/vi/F2Jko4Ipdrs/0.jpg

NSXMLParser crashes my App on second Call (Leak)

i have a big Problem on XCode 4/Objective C and my NSXMLParser:
I got a Tabbar App with a NSXMLParser on one Tab, so on the first call,
...when the Tab becomes clicked/touched, the NSXMLParser parses me Data
into a tableview. But, if the tab gets clicked/touched a second time,
the Parser/app creates a big Memory leak, and if thats not enough, it
crashes on the iphone (not simulator).
Maybe any of you have any ideas. I heard about a workaround but i have
no idea how to realize that. Any sample code etc. is welcome.
I hope you can help me.
thanks
XMLController.h
#import "XMLController.h"
#import "Tabelle.h"
#implementation XMLController
#synthesize table;
-(id) loadXMLbyURL:(NSString *)urlString{
table = [[NSMutableArray alloc] init];
NSURL *url= [NSURL URLWithString:urlString];
NSData *xmlData = [NSData dataWithContentsOfURL:url];
NSXMLParser *parser = [[NSXMLParser alloc] initWithData:xmlData];
parser.delegate = self;
[parser setShouldProcessNamespaces:NO];
[parser setShouldReportNamespacePrefixes:NO];
[parser setShouldResolveExternalEntities:NO];
[parser parse];
[parser release];
return self;
}
-(void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)
namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
{
if([elementName isEqualToString:#"team"])
{
[currentNodeContent setString:nil];
currentTabelle = [[Tabelle alloc] init];
currentNodeContent = [[NSMutableString alloc]init];
}
}
-(void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)
namespaceURI qualifiedName:(NSString *)qName
{
NSString *theContent = [currentNodeContent stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]; //
[currentNodeContent setString:#""];
if([elementName isEqualToString:#"pos"])
{
currentTabelle.place = theContent;
}
if([elementName isEqualToString:#"name"])
{
currentTabelle.Name = theContent;
}
if([elementName isEqualToString:#"w"])
{
currentTabelle.wins = theContent;
}
if([elementName isEqualToString:#"l"])
{
currentTabelle.losses = theContent;
}
if([elementName isEqualToString:#"pct"])
{
currentTabelle.winpct = theContent;
}
if([elementName isEqualToString:#"gb"])
{
currentTabelle.GamesBehind = theContent;
}
if([elementName isEqualToString:#"team"])
{
[table addObject:currentTabelle];
[currentTabelle release];
currentTabelle = nil;
[currentNodeContent release];
currentNodeContent = nil;
}
}
-(void) parserDidEndDocument:(NSXMLParser *)nparser
{
}
-(void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
//currentNodeContent = [string stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
[currentNodeContent appendString:string];
}
#end
#
And the class where i call it:
#import "TabellenController.h"
#import "Tabelle.h"
#import "Baseball_DeutschlandAppDelegate.h"
#import "CustomCell.h"
#implementation TabellenController
#synthesize xmlcont, ergebnisTabelle;
#pragma mark -
#pragma mark View lifecycle
- (void)viewDidLoad {
//Abfragen nach der Liga (mit Dateiladen)
NSArray *paths = NSSearchPathForDirectoriesInDomains
(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
//make a file name to write the data to using the documents directory:
NSString *fileName = [NSString stringWithFormat:#"%#/CellContent.txt",
documentsDirectory];
NSString *content = [[NSString alloc] initWithContentsOfFile:fileName
usedEncoding:nil
error:nil];
self.xmlcont = [[XMLController alloc] init];
if ([content isEqualToString:#"1. Bundesliga"]){
if(pageNumber == 0){
[self.xmlcont loadXMLbyURL:#"http://results.baseball-softball.de/extern/standing.php?l=12&xml"];
}
if(pageNumber == 1){
[self.xmlcont loadXMLbyURL:#"http://results.baseball-softball.de/extern/standing.php?l=11&xml"];
}
}if ([content isEqualToString:#"2. Bundesliga"]){
if(pageNumber == 0){
[self.xmlcont loadXMLbyURL:#"http://results.baseball-softball.de/extern/standing.php?l=22&xml"];
}
if(pageNumber == 1){
[self.xmlcont loadXMLbyURL:#"http://results.baseball-softball.de/extern/standing.php?l=21&xml"];
}
}if ([content isEqualToString:#"Regionalligen"]){
if(pageNumber == 0){
[self.xmlcont loadXMLbyURL:#"http://results.baseball-softball.de/extern/standing.php?l=31&xml"];
}
if(pageNumber == 1){
[self.xmlcont loadXMLbyURL:#"http://results.baseball-softball.de/extern/standing.php?l=32&xml"];
}
if(pageNumber == 2){
[self.xmlcont loadXMLbyURL:#"http://results.baseball-softball.de/extern/standing.php?l=33&xml"];
}
if(pageNumber == 3){
[self.xmlcont loadXMLbyURL:#"http://results.baseball-softball.de/extern/standing.php?l=34&xml"];
}
}
[content release];
[super viewDidLoad];
}
- (id)initWithPageNumber:(int)page{
pageNumber = page;
return self;
}
#pragma mark -
#pragma mark Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
/*NSMutableArray *ar = [xmlcont table];
NSInteger *sections;
for (int i = 0; i < [ar count]; i++){
for (int j = (i+1); j < [ar count]; j++){
}
}*/
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
// Return the number of rows in the section.
NSMutableArray *ar = [xmlcont table];
return [ar count];
}
- (NSString *)tableview:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
return [NSString stringWithFormat:#"# Team W L AVG GB"];
}
// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"CustomCell";
CustomCell *cell = (CustomCell *) [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:#"CustomCell" owner:self options:nil];
for (id currentObject in topLevelObjects){
if ([currentObject isKindOfClass:[UITableViewCell class]]){
cell = (CustomCell *) currentObject;
break;
}
}
}
// Configure the cell...
NSMutableArray *cont = [xmlcont table];
Tabelle *current = [cont objectAtIndex:indexPath.row];
cell.place.text = [NSString stringWithFormat:#"%#.", [current place]];
cell.team.text = [NSString stringWithFormat:#"%#", [current Name]];
cell.wins.text = [NSString stringWithFormat:#"%#", [current wins]];
cell.losses.text = [NSString stringWithFormat:#"%#", [current losses]];
cell.winpct.text = [NSString stringWithFormat:#"%#", [current winpct]];
cell.gb.text = [NSString stringWithFormat:#"%#", [current GamesBehind]];
return cell;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return 35.0f;
}
#pragma mark -
#pragma mark Table view delegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
// Navigation logic may go here. Create and push another view controller.
/*<#DetailViewController#> *detailViewController = [[<#DetailViewController#> alloc] initWithNibName:#"<#Nib name#>" bundle:nil];
// ...
// Pass the selected object to the new view controller.
[self.navigationController pushViewController:detailViewController animated:YES];
[detailViewController release];*/
}
#pragma mark -
#pragma mark Memory management
- (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Relinquish ownership any cached data, images, etc. that aren't in use.
}
- (void)viewDidUnload {
NSLog(#"View verschwindet1");
}
- (void)dealloc {
[self.xmlcont release];
[super dealloc];
}
#end
I think you are missing a dealloc method in your XMLController.
Also, self.xmlcont = [[XMLController alloc] init]; might be a memory leak if xmlcont is a retain or copy property. In dealloc, you should prefer to do [xmlcont release]; without dot syntax.
There might be more problems, but these bits could make a good start.

Resources