J'ai lu des articles à ce sujet, et il semble assez simple. Je suis assez nouveau pour Obj-C et iPhone dev en général, donc je pourrais facilement négliger quelque chose. Je ne peux pas sembler retourner le NSMutableArray
avec les objets article. Je ne reçois aucune erreur, mais quand j'essaie de NSLog()
certaines choses, je reçois des erreurs EXEC_BAD_ACCESS
(je suppose un problème d'accès à la mémoire?). J'ai une ArticlesParser
classe qui l'analyse syntaxique ... Voici à quoi il ressemble:Aide! Comment partager la classe NSXMLParser entre les contrôleurs?
// ArticlesParser.h
#import <Foundation/Foundation.h>
#import "Article.h"
@class Article;
@interface ArticlesParser : NSObject <NSXMLParserDelegate> {
NSMutableString *currentCharaters;
Article *currentArticle;
NSMutableArray *articlesCollection;
NSMutableData *xmlData;
NSURLConnection *connectionInProgress;
BOOL connectionHasCompleted;
}
@property (nonatomic, assign) BOOL connectionHasCompleted;
- (void)parseUrl:(NSString *)url;
- (void)beginParsing:(NSURL *)xmlUrl;
- (NSMutableArray *)arrayOfArticles;
@end
est ici la mise en œuvre ...
// ArticlesParser.m
#import "ArticlesParser.h"
@implementation ArticlesParser
@synthesize connectionHasCompleted;
#pragma mark -
#pragma mark Parsing methods
- (void)parseUrl:(NSString *)url
{
[self setConnectionHasCompleted:NO];
NSURL *xmlUrl = [NSURL URLWithString:url];
[self beginParsing:xmlUrl];
}
- (void)beginParsing:(NSURL *)xmlUrl
{
[articlesCollection removeAllObjects];
articlesCollection = [[NSMutableArray alloc] init];
NSURLRequest *request = [NSURLRequest requestWithURL:xmlUrl cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:30];
// clear existing connection if there is one
if (connectionInProgress) {
[connectionInProgress cancel];
[connectionInProgress release];
}
[xmlData release];
xmlData = [[NSMutableData alloc] init];
// asynchronous connection
connectionInProgress = [[NSURLConnection alloc] initWithRequest:request delegate:self startImmediately:YES];
}
- (NSMutableArray *)arrayOfArticles
{
// NOT RETURNING ANYTHING
return articlesCollection;
}
#pragma mark -
#pragma mark NSXMLParserDelegate methods
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
[xmlData appendData:data];
}
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
{
if ([elementName isEqual:@"article"]) {
currentArticle = [[Article alloc] init];
return;
}
if ([elementName isEqual:@"title"]) {
currentCharaters = [[NSMutableString alloc] init];
return;
}
if ([elementName isEqual:@"last_updated"]) {
currentCharaters = [[NSMutableString alloc] init];
return;
}
}
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
[currentCharaters appendString:string];
}
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
if ([elementName isEqual:@"article"]) {
[articlesCollection addObject:currentArticle];
[currentArticle release], currentArticle = nil;
return;
}
if ([elementName isEqual:@"title"]) {
[currentArticle setTitle:currentCharaters];
[currentCharaters release], currentCharaters = nil;
return;
}
if ([elementName isEqual:@"last_updated"]) {
[currentArticle setLastModified:currentCharaters];
[currentCharaters release], currentCharaters = nil;
return;
}
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
NSXMLParser *parser = [[NSXMLParser alloc] initWithData:xmlData];
[parser setDelegate:self];
[parser parse];
[parser release];
[self setConnectionHasCompleted:YES];
}
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
[currentArticle release];
currentArticle = nil;
[currentCharaters release];
currentCharaters = nil;
[articlesCollection release];
articlesCollection = nil;
[connectionInProgress release];
connectionInProgress = nil;
[xmlData release];
xmlData = nil;
NSLog(@"connection failed: %@", [error localizedDescription]);
}
@end
Je sais que l'analyse réelle fonctionne parce que j'ai eu ce directement dans mon contrôleur de vue et tout a bien fonctionné. Mais maintenant, je veux accéder à la même chose à partir d'un autre contrôleur, seule l'URL est différente (renvoie le même format XML).
Voilà comment je suis en train de faire usage de cette classe dans mon contrôleur:
// instance method called within an articles controller
// that is to load the results in a table view
- (void)loadArticles
{
// (leaving off the URL because it's not important)
NSString *urlToRequest = [NSString stringWithFormat:@"...", [self letterToList]];
ArticlesParser *aParser = [[ArticlesParser alloc] init];
// initiate the parsing
[aParser parseUrl:urlToRequest];
// load up the articles ivar so the tableview can
// make use of it to load its cells
articles = [aParser arrayOfArticles];
}
Y at-il quelque chose d'évident que je suis absent? Est-ce encore un bon moyen de partager le code NSXMLParser
? Je tire mes cheveux sur celui-ci ... merci d'avance!
Dans cette situation, l'appel synchrone serait bien. Je ne suis pas sûr de savoir comment faire l'appel asynchrone, synchrone cependant. – rpheath