使用NSXMLParser设置NSString变量

时间:2012-04-26 20:13:28

标签: objective-c cocoa nsstring nsxmlparser

我正在使用NSXMLParser从在线XML文件中获取信息。我的目标是让一个类进行XML解析,使用另一个类来实现变量。以下是我项目的代码:

Current.h& Current.m

#import <Foundation/Foundation.h>

@interface Current : NSObject {
    NSString *curTempF;
    IBOutlet NSTextField *textField;
}

@property (nonatomic, copy) NSString *curTempF;

- (void)displayOutlets:(id)sender;

@end

#import "Current.h"

@implementation Current

@synthesize curTempF;

- (void)awakeFromNib {
    [self displayOutlets:self];
}

- (void)displayOutlets:(id)sender {
    [textField setStringValue:curTempF];
}

@end

XmlParser.h&amp; XmlParser.m

#import <Foundation/Foundation.h>

@interface XmlParser : NSObject <NSXMLParserDelegate> {
    NSString *urlString;
    NSURL *url;
    NSMutableString *xmlString;
}

- (IBAction)fetchXML:(id)sender;

@end

#import "XmlParser.h"
#import "Current.h"

@implementation XmlParser

- (void)awakeFromNib {
    [self fetchXML:self];
}

- (IBAction)fetchXML:(id)sender {
    urlString = @"http://api.wunderground.com/api/***/conditions/q/28173.xml";
    url = [NSURL URLWithString:urlString];

    NSXMLParser *parser = [[NSXMLParser alloc] initWithContentsOfURL:url];
    [parser setDelegate:self];
    [parser parse];
}

- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict {

    if ([elementName isEqual:@"temp_f"]) {
        xmlString = [[NSMutableString alloc] init];
    }
}

- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {

    if ([elementName isEqual:@"temp_f"]) {        
        Current *cTempF = [[Current alloc] init];
        [cTempF setCurTempF:xmlString];
    }
}

- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string {
    [xmlString appendString:string];
}

@end

当我运行程序时,我收到有关“无效参数不满足:aString”的错误。看起来IBOutlet的setStringValue不起作用。有什么建议吗?

2 个答案:

答案 0 :(得分:0)

我怀疑使用[[Current alloc] init]初始化Current类时,它会尝试使用curTempF字符串填充textField。但是,在您调用[cTempF setCurTempF:xmlString]之前,curTempF字符串尚未初始化。

一种方法是不在Current类中显示出口:

- (void)awakeFromNib {
    //[self displayOutlets:self];
}

然后,在解析器中调用displayOutlets函数:

if ([elementName isEqual:@"temp_f"]) {        
    Current *cTempF = [[Current alloc] init];
    [cTempF setCurTempF:xmlString];
    [cTempF displayOutlets:cTempF]; 
}

或者,您可以保持awakeFromNib代码相同,但在Current类中创建一个initWith方法,这可能更干净:

- (id) initWithCurTemp:(NSString *)curTemp {
    self = [super init]; 

    if (self) { 
        self.curTempF = curTemp; 
    }

    return self; 
}

- (void)awakeFromNib {
    [self displayOutlets:self];
}

然后,您的解析器代码如下所示:

if ([elementName isEqual:@"temp_f"]) {        
    Current *cTempF = [[Current alloc] initWithCurTemp:xmlString];
}

答案 1 :(得分:0)

你应该像你一样在nib中创建Current,而不是在代码中创建。

至于让解析器(我假设在同一个nib中)与Current交谈,在解析器中创建一个指向Current的插座,并在nib中连接该插座。