I am having a coding problem that is slowly driving me insane, and I would appreciate some help off you lovely people.
Basically, I have implemented an NSXMLParser (in a class MeetingXMLParser.m). I am now trying to run this parser in my MeetingsViewController class, so that when I go to that view it will start parsing automatically.
The project compiles, but it compiles with the following warning, which occurs underneath "[MeetingXMLParser parseXMLFileAtURL: path];" in MeetingsViewController.m:
Furthermore, if I launch the simulator and click on a button which links to MeetingsViewController.m, then the whole application crashes and I am presented with the following in console:
Code:
2009-12-28 18:39:50.547 MyApp[27899:20b] *** +[MeetingXMLParser parseXMLFileAtURL:]: unrecognized selector sent to class 0x6580
2009-12-28 18:39:50.549 MyApp[27899:20b] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** +[MeetingXMLParser parseXMLFileAtURL:]: unrecognized selector sent to class 0x6580'
2009-12-28 18:39:50.551 MyApp[27899:20b] Stack: (
807902715,
2441211451,
808284347,
807854166,
807706786,
13644,
815263300,
815243017,
815265053,
815242666,
12556,
815018240,
815005661,
810768858,
807687328,
807683624,
839142449,
839142646,
814752238
)
It looks like I did accidentally define the method as an instance method, rather than a class method.
Having rectified that, the app does not crash in the simulator. However, the original warning message still remains, the XML file does not parse... and I am presented with 7 new identical warning messages stating "warning: instance variable 'parser' accessed in class method".
Here is the code snipped you asked for:
Code:
+ (void)parseXMLFileAtURL:(NSString *)URL //URL is the file path (i.e. /Applications/MyExample.app/MyFile.xml)
{
// My NSString defined in the viewDidLoad method is converted into a proper NSURL
// which allows the parser to read it.
NSURL *xmlURL = [[NSURL alloc] initWithString:@"http://www.url.com/meetings.xml"];
parser = [[NSClassFromString(@"NSXMLParser") alloc] initWithContentsOfURL:xmlURL];
[parser setDelegate:self];
// Functions of the parser which I can change depending on the format of the XML
// file I wish to parse.
[parser setShouldProcessNamespaces:NO];
[parser setShouldReportNamespacePrefixes:NO];
[parser setShouldResolveExternalEntities:NO];
[parser parse];
[parser release];
}
Well, the next question is are you sure you really want this to be a class method?
It looks like you have an instance variable called parser. That variable will only exist within an actual instance of MeetingXMLParser. So you can't really use that variable in the context of a class method.
And the next problem you will have is that you need an actual object (instance) to pass to this instance of NSXMLParser as its delegate.
So maybe what you really want to do is create an instance of MeetingXMLParser and make parseXMLFileAtURL an instance method.
Basically, all I want to do is to have my XML file parsed when I enter the MeetingsViewController.m file. I don't understand why that is not happening at the moment
As for an object. I have my MeetingObject, which stores all the parsed elements?
Well, when you first said that parseXMLFileAtUrl was a class method, I sort of assumed you had some reason for that in your design.
But I think maybe there wasn't a reason for that. Now that I've seen the implementation, it don't understand why you made that a class method at all. It looks to me like that should have been an instance method. But then again, I don't know your design. I only know what you've told us so far.
I can tell you this much: to parse XML with NSXMLParser, you have to create an instance (an object) of type NSXMLParser. And then you need to give that NSXMLParser object another object to use as its delegate.
So you can't give the NSXMLParser your MeetingXMLParser class. You have to give it an instance of that class. In other words, you have to give it a MeetingXMLParser object.
So you can do it like this:
1.) Create an instance of MeetingXMLParser (alloc/init)
2.) Call the instance method parseXMLFileAtUrl on that new instance.
3.) That instance method will create an NSXMLParser (your code does this already, except I don't know why you used NSClassFromString?)
4.) that instance method should set the delegate of the new NSXMLParser object to be your instance of MeetingXMLParser. (again your code sort of does this, but what you did doesn't make sense in a class method)
5.) Your instance of MeetingXMLParser will get all the delegate callbacks that NSXMLParser needs to parse the document.