2013-05-24 2 views
1

Я пытаюсь создать хороший маленький класс с NSXMLParser для моих нужд. Я звоню классу так: ViewController.m:Вызов NSXMLParser из статического метода не анализируется

[IDAN_XML_Parser setXmlString:soapMsg]; 
[IDAN_XML_Parser setStringToFind:@"userID"]; 
[IDAN_XML_Parser setHeader:kAPP_PASSWORD andHeaderValue:kAPP_HEADER]; 
[IDAN_XML_Parser setSetupXml:kWEB_SERVICE_URL]; 
[IDAN_XML_Parser prepareParsingAndGetResponse]; 

NSString *answer = [IDAN_XML_Parser getResponse]; 
NSLog(@"Response: %@", answer); 

И мой класс это:

.h файл:

#import <Foundation/Foundation.h> 

@interface IDAN_XML_Parser : NSObject <NSXMLParserDelegate, NSURLConnectionDelegate> 



+ (void)setXmlString:(NSString *)theXML; 
+ (void)setStringToFind:(NSString *)stringToFind; 
+ (void)setSetupXml:(NSString *)webServicesURL; 
+ (void)setHeader:(NSString *)headerKey andHeaderValue:(NSString *)headerValue; 
+ (BOOL)prepareParsingAndGetResponse; 
- (NSInteger)startParsing; 
+ (BOOL)isParsingOK; 
+ (IDAN_XML_Parser *)sharedXML; 
+ (NSString *)getXMLString; 
+ (NSString *)getResponse; 




@end 

.m файл

#import "IDAN_XML_Parser.h" 



@implementation IDAN_XML_Parser 


NSString *matchingElement; 
NSString *xmlString; 
NSMutableData *webData; 
NSURLConnection *conn; 
NSString *soapHeader_key; 
NSString *soapHeader_value; 
NSURL *url; 
BOOL isHeader = NO; 
NSInteger didGetError = 0; 
BOOL elementFound; 
NSMutableString *soapResults; 
NSString *returnedString; 
NSXMLParser *xmlParser; 
NSString *exceptionReason; 
NSString *resultXML; 


#pragma mark - Setup Parsing 

+ (IDAN_XML_Parser *)sharedXML 
{ 
    static IDAN_XML_Parser *theParser; 
    @synchronized(self) { 
     if (!theParser) 
      theParser = [[self alloc] init]; 
    } 
    return theParser; 
} 

+ (void)setXmlString:(NSString *)theXML 
{ 
    xmlString = theXML; 
    NSLog(@"\n\nXML TO SEND: %@", xmlString); 
} 

+ (void)setStringToFind:(NSString *)stringToFind 
{ 
    matchingElement = stringToFind; 
} 

+ (void)setHeader:(NSString *)headerKey andHeaderValue:(NSString *)headerValue 
{ 
    isHeader = YES; 
    soapHeader_key = headerKey; 
    soapHeader_value = headerValue; 
} 

+ (void)setSetupXml:(NSString *)webServicesURL 
{ 
    url = [NSURL URLWithString:webServicesURL]; 
    NSMutableURLRequest *req = [NSMutableURLRequest requestWithURL:url]; 
    NSString *msgLength = [NSString stringWithFormat:@"%d", [xmlString length]]; 
    [req addValue:@"text/xml; charset=utf-8" forHTTPHeaderField:@"Content-Type"]; 
    [req addValue:msgLength forHTTPHeaderField:@"Content-Length"]; 
    [req setHTTPMethod:@"POST"]; 
    [req setHTTPBody: [xmlString dataUsingEncoding:NSUTF8StringEncoding]]; 

    if (isHeader) { 
     [req setValue:soapHeader_value forHTTPHeaderField:soapHeader_key]; 
    } 

    conn = [[NSURLConnection alloc] initWithRequest:req delegate:self]; 

    if (conn) 
    { 
     webData = [NSMutableData data]; 
    } 
} 

-(void) connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *) response 
{ 
    [webData setLength: 0]; 
} 

-(void) connection:(NSURLConnection *)connection didReceiveData:(NSData *) data 
{ 
    [webData appendData:data]; 
} 

-(void) connection:(NSURLConnection *)connection didFailWithError:(NSError *) error 
{ 
    didGetError = 1; 
    NSLog(@"\n\nConnection Error: %@", error); 
} 

-(void) connectionDidFinishLoading:(NSURLConnection *) connection 
{ 
    resultXML = [[NSString alloc] initWithBytes:[webData mutableBytes] 
               length:[webData length] 
               encoding:NSUTF8StringEncoding]; 
    didGetError = 0; 
    NSLog(@"\n\nRESPONSE XML: %@", resultXML);  
} 

+ (BOOL)prepareParsingAndGetResponse 
{ 
    NSInteger isParsingOK; 
    isParsingOK = [[self sharedXML] startParsing]; 

    if (isParsingOK == 1) { 
     return YES; 
    } else { 
     return NO; 
    } 
} 

- (NSInteger)startParsing 
{ 
    @try { 
     xmlParser = [[NSXMLParser alloc] initWithData:webData]; 
     [xmlParser setDelegate:self]; 
     [xmlParser setShouldResolveExternalEntities:YES]; 
     [xmlParser parse]; 
    } 
    @catch (NSException *exception) { 
     didGetError = 1; 
     exceptionReason = exception.reason; 
     NSLog(@"Exception Reason: %@", exception.reason); 
    } 

    if (didGetError != 1) { 
     didGetError = 0; 
    } 

    return didGetError; 
} 

+ (NSString *)getXMLString 
{ 
    return resultXML; 
} 

+ (BOOL)isParsingOK 
{ 
    if (didGetError == 1) { // We have error 
     return 1; 
    } else { // We don't have error 
     return 0; 
    } 
} 

+ (NSString *)getResponse 
{ 
    return returnedString; 
} 

#pragma mark - Start Parsing 

- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict 
{ 
    NSLog(@"START PARSING!"); 
    if ([elementName isEqualToString:matchingElement]) { 
     if (!soapResults) { 
      soapResults = [[NSMutableString alloc] init]; 
     } 
     elementFound = YES; 
    } 
} 

- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string 
{ 
    if (elementFound) { 
     [soapResults appendString:string]; 
     NSLog(@"\n\nsoapResults: %@", soapResults); 
    } 
} 

- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName 
{ 
    if ([elementName isEqualToString:matchingElement]) { 
     returnedString = soapResults; // Save the element we found 
     elementFound = NO; 
    } 
} 

@end 

Мне удается отправить и вернуть правильный xml, но на самом деле он не запускает разбор. Любая идея, как я могу ее решить?

+0

Итак, разместите в своем коде несколько сообщений журнала - вы когда-нибудь вызывали prepareParsingAndGetResponse? –

+0

Подготовлен вызов prepareParsingAndGetResponse. –

+0

Отредактировано: I change connection to static, и я возвращаю ответ. Я также попытаюсь изменить методы разбора на статические. –

ответ

1

Вы начинаете асинхронный NSURLConnection, а затем сразу же начинаете процесс синтаксического анализа. Вам нужно отложить инициирование разбора до connectionDidFinishLoading, или вы должны сделать синхронный NSURLConnection (но, очевидно, не из основной очереди). Таким образом, пока вы получаете ответ, разбор, несомненно, инициируется до получения ответа.

+0

Я сделал журнал, и это именно то, что я получаю, как вы сказали: зарегистрируйте xml, который я отправляю, затем заготовьте команду prepareParsingAndGetResponse, затем startParsing, а затем Response: (null) и, наконец, запишите ответ xml. –

+0

Любая идея, какой будет лучший подход? –

+0

@IdanMoshe Если вы ищете быстрое тактическое исправление, вы можете либо переместить инициализацию синтаксического анализа XML на 'connectionDidFinishLoading', либо вы могли бы использовать [' sendSynchronousRequest'] (http://developer.apple.com/ библиотека/ios/documentation/Cocoa/Reference/Foundation/Classes/NSURLConnection_Class/Reference/Reference.html # // apple_ref/doc/uid/20001697-BAJHAHGI) (но инициируйте это из фоновой очереди). Возможно, я не понимаю, что вы подразумеваете под «лучшим подходом». – Rob

Смежные вопросы