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

수정 : 연결을 정적으로 변경했는데 응답이 다시 나타납니다. 파싱 ​​메서드를 정적으로 변경하려고합니다. –

답변

1

비동기식 NSURLConnection을 시작한 후 즉시 구문 분석 프로세스를 시작하고 있습니다. connectionDidFinishLoading까지 파싱의 시작을 연기해야합니다. 그렇지 않으면 동기식 NSURLConnection을 실행해야합니다 (하지만 분명히 메인 대기열에서가 아님). 따라서 결국 응답을 얻는 동안 구문 분석은 응답을 받기 전에 시작됩니다.

+0

나는 로그를 만들었고 당신이 말한 것과 정확히 똑같은 것을 얻었습니다. 내가 보낸 XML을 기록한 다음 prepareParsingAndGetResponse를 기록한 다음 startParsing을 실행하고 Response : (null)을 입력하고 마지막으로 응답 xml을 기록하십시오. –

+0

어떤 아이디어가 더 좋은 방법일까요? –

+0

@IdanMoshe 빠른 전술적 수정을 원한다면, XML 구문 분석을 'connectionDidFinishLoading'으로 초기화하거나 ['sendSynchronousRequest'] (http://developer.apple.com/)를 사용할 수 있습니다./background/queue/background/NSURLConnection_Class/Reference/Reference.html # // apple_ref/doc/uid/20001697-BAJHAHGI) (배경 대기열에서 시작). 어쩌면 당신이 "더 나은 접근"을 의미하는지 이해하지 못할 수도 있습니다. – Rob

관련 문제