2012-04-26 44 views
0

我使用NSXMLParser從聯機XML文件中獲取信息。我的目標是讓一個類執行XML解析,另一個類執行變量。下面是我的項目代碼:使用NSXMLParser設置NSString變量

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 & 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不起作用。有什麼建議麼?

回答

0

我懷疑,當你與[[Current alloc] init]初始化當前類,它試圖來用字符串curTempF文本字段。但是,curTempF字符串尚未初始化,直到您撥打[cTempF setCurTempF:xmlString]

一種辦法是在當前類不顯示網點:

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

然後,調用displayOutlets功能在您的解析器:

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

或者,你可以讓你的awakeFromNib代碼相同,但在當前類中創建一個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]; 
} 
+0

嗯,我試了兩種方法,但都沒有奏效。項目運行時我沒有收到任何錯誤,但IBOutlet沒有使用字符串值進行更新。 – wigging 2012-04-26 22:17:14

+0

當前類如何連接到您的視圖?在界面生成器中,您是否有一個視圖上有一個Current?我問的原因是你需要專門更新視圖上的Current。簡單地做Current * cTempF = [[Current alloc] init];如果Current的這個實例不在視圖上,它將不會執行任何操作。 – 2012-04-26 22:21:52

+0

我像往常一樣設置了IBOutlet。在IB中,我將它的類設置爲「當前」,並將插座連接到窗口中的「標籤」。 – wigging 2012-04-26 22:51:05

0

您應該創建在筆尖當前,你在做什麼,而不是代碼。

至於讓語法分析器(我認爲是在同一個筆尖)與當前對話,在分析器中創建一個指向Current的出口,並將該出口連接到筆尖。

+0

對不起,但我仍然困惑。我可以在xmlparser類中獲得一個IBOutlet來工作,但我的目標是不這樣做。我希望所有網點都在其他課堂文件中。您能否提供一些代碼或指向適用的在線示例項目? – wigging 2012-04-27 01:29:33

+0

@Gavin:你是什麼意思「我希望所有網點都在其他課堂文件中」?如果你不想讓XmlParser知道Currents(這是合理的),你可以將它設置爲一個委託協議,但XmlParser的委託屬性仍然是一個委託。如果您不希望XmlParser直接與Current交談,那麼您必須通過第三個對象間接實現它。 – 2012-04-27 01:31:35

+0

所以我用另一個更簡單的代碼示例發佈了另一個與此相關的問題。隨時檢查問題並添加您的答案。 – wigging 2012-04-27 19:41:49