2012-11-06 166 views
0

當前我正在爲我的iOS應用程序編寫一個在線登錄,我做了一些關於應該使用什麼庫來處理HTTP請求和XML解析的研究。我結束了AFNetworking和KissXML。我還使用KissXML添加AFNetworking。對網站的請求是成功的,但我有點卡在解析收到的XML。從網站解析XML響應

的迴應是這樣的:

<login> 
    <response status="success" result="correct"/> 
    <data> 
     <username>testusername</username> 
     <country>Germany</country> 
    </data> 
</login> 

在我的代碼做一個HTTPRequest,該網站收到的XML,然後嘗試檢查userdatas是有效還是無效。如果他們是有效的,我想收到像用戶名和國家元素。但是如果發生錯誤,我想把它還給你。我的代碼sofar:

{ 
__block BOOL success = NO; 
__block NSError *localerror = nil; 
__block NSString *domain = @"de.FranzBusch.Searchlight.ErrorDomain"; 

//HTTP Request 
NSURL *url = [NSURL URLWithString:@"http://www.example.de/login.php"]; 
AFHTTPClient *client = [[AFHTTPClient alloc] initWithBaseURL:url]; 

NSDictionary *params = [NSDictionary dictionaryWithObjectsAndKeys: 
         email, @"email", 
         password, @"password", nil]; 

NSMutableURLRequest *request = [client requestWithMethod:@"POST" path:@"" parameters:params]; 

//Parse XML-Response 
AFKissXMLRequestOperation *operation = [AFKissXMLRequestOperation XMLDocumentRequestOperationWithRequest:request success:^(NSURLRequest *request, NSHTTPURLResponse *response, DDXMLDocument *XMLDocument) 
{ 
    NSArray *resultNodes = nil; 
    NSError *responseError = nil; 
    resultNodes = [XMLDocument nodesForXPath:@"//response" error:&responseError]; 

    if (responseError || ([resultNodes count] != 1)) 
    { 
     localerror = [NSError errorWithDomain:domain code:-101 userInfo:[self generateErrorDictionary:@"XMLError"]]; 
     success = NO; 
    } 
    else 
    { 
     for (DDXMLElement *element in resultNodes) 
     { 
      DDXMLNode *node = [element attributeForName:@"status"]; 
      NSString *status = [node stringValue]; 

      if ([status isEqualToString:@"fail"]) 
      { 
       success = NO; 
       localerror = [NSError errorWithDomain:domain code:-101 userInfo:[self generateErrorDictionary:[[element attributeForName:@"result"] stringValue]]]; 
      } 
      else 
      { 
       NSError *usernameError = nil; 
       NSArray *dataNodes = [XMLDocument nodesForXPath:@"//data//username" error:&usernameError]; 

       if (usernameError || ([dataNodes count] != 1)) 
       { 
        localerror = [NSError errorWithDomain:domain code:-101 userInfo:[self generateErrorDictionary:@"XMLError"]]; 
        success = NO; 
       } 
       else 
       { 
        for (DDXMLELement *dataElement in dataNodes) 
        { 

        } 
       } 
      } 
     } 
    } 

    }failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error, DDXMLDocument *XMLDocument) 
    { 
     NSLog(@"failure"); 
    }]; 
[operation start]; 
return success; 
} 

任何人都可以告訴我如何改善代碼,以及如何做到這一點。因爲如果我想將localerror分配給錯誤,我總是會得到一個錯誤:(

+0

您是否曾經使用AFNetwork和KissXML找到您的解決方案,或者您是否回答了下面的問題?如果可以,請與KissXML/AFNetwork分享您的結論 –

回答

2

如果我正確理解你,你在解析XML響應時遇到了問題,我通常只使用Apple的流XML解析器NSXMLParser 。這是簡單,快速和易於使用的

我做了一個小例子項目爲您(使用ARC),解析你所描述的XML響應,的NSXMLParser:https://github.com/erikt/ETXMLParseSOExample

你可以用它播放和運行項目,但重要的部分是NSXMLParser代表:

@interface ETLoginInfoXMLParser() 
@property (strong,nonatomic) NSMutableString *currentElementValue; 
@property (strong,nonatomic) ETLoginInfo *loginInfo; 
@end 

@implementation ETLoginInfoXMLParser 

#pragma mark - NSXMLParserDelegate 
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict 
{ 
    if ([elementName isEqualToString:@"login"]) { 
     if (!self.loginInfo) { 
      self.loginInfo = [[ETLoginInfo alloc] init]; 
     } 
     return; 
    } 

    if ([elementName isEqualToString:@"response"]) { 
     self.loginInfo.responseStatus = [attributeDict objectForKey:@"status"]; 
     self.loginInfo.responseResult = [attributeDict objectForKey:@"result"]; 
    } 
} 

- (void) parser:(NSXMLParser *)parser foundCharacters:(NSString *)string { 
    if (!self.currentElementValue) { 
     self.currentElementValue = [[NSMutableString alloc] initWithString:string]; 
    } else { 
     [self.currentElementValue appendString:string]; 
    } 
} 

- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName 
{ 
    if ([elementName isEqualToString:@"username"]) { 
     NSString *trimmedValue = [self.currentElementValue stringByTrimmingCharactersInSet: 
            [NSCharacterSet whitespaceAndNewlineCharacterSet]]; 
     self.loginInfo.username = trimmedValue; 
    } 

    if ([elementName isEqualToString:@"country"]) { 
     NSString *trimmedValue = [self.currentElementValue stringByTrimmingCharactersInSet: 
            [NSCharacterSet whitespaceAndNewlineCharacterSet]]; 
     self.loginInfo.country = trimmedValue; 
    } 

    self.currentElementValue = nil; 
} 


/** Parse XML login response */ 
+(ETLoginInfo *)parseXMLLoginResponse:(NSString *)xml { 
    ETLoginInfoXMLParser *loginInfoParser = [[ETLoginInfoXMLParser alloc] init]; 
    NSXMLParser *xmlParser = [[NSXMLParser alloc] initWithData:[xml dataUsingEncoding:NSUTF8StringEncoding]]; 
    [xmlParser setDelegate:loginInfoParser]; 
    BOOL success = [xmlParser parse]; 

    if (success) { 
     return loginInfoParser.loginInfo; 
    } else { 
     NSLog(@"Error parsing login information"); 
     return nil; 
    } 
} 

@end 

我有線它到一個愚蠢的iOS應用程序,以顯示該XML響應的解析:

<login> 
    <response status="success" result="correct"/> 
    <data> 
    <username>Willy Wonka</username> 
    <country>Germany</country> 
    </data> 
</login> 

enter image description hereenter image description here

你會希望有一個更有趣的模型的層次結構,I-爲了簡單起見,只把所有東西都放在同一個實體中

+0

感謝您的評論。但我想使用KissXML,因爲AFNetworking的擴展非常好。描述我的問題更詳細。我正在努力解決錯誤的問題。我正在使用本地__block NSError,但我不能將它分配給方法調用給出的錯誤。它說不能分配NSError __block給NSError。我也不知道for循環是否正確。 – digga