2013-09-03 4 views
3

이 문제에 대해 많은 Q/A를 읽었지만 내 상황에 맞는 대답을 찾을 수 없습니다.NSJSONSerialization을 사용하여 JSON 구문 분석하기 : 오류 3840 - 데이터가 손상 되었습니까?

PHP에서 작성한 REST 서비스에서 JSON 응답을 검색합니다. 이건 내 코드입니다 : 내가 브라우저에서 REST 호출을 호출 할 때, 나는 동일 다음과 같은 반응을 보인다 참조

NSURLResponse *response = nil; 
NSError *theError1 = nil; 
NSError *theError2 = nil; 

NSURL *webServiceUrl = [NSURL URLWithString:@"http://..."]; 
NSURLRequest *request = [NSURLRequest requestWithURL:webServiceUrl cachePolicy:NSURLRequestReturnCacheDataElseLoad timeoutInterval:30]; 
NSData *theData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&theError1]; 

NSString *dataString = [[NSString alloc] initWithData:theData encoding:NSUTF8StringEncoding]; 
NSLog(@"%@", dataString); 

id json = [NSJSONSerialization JSONObjectWithData:theData options:NSJSONReadingAllowFragments | NSJSONReadingMutableContainers error:&theError2]; 
if (theError2 != nil) 
    NSLog(@"%@", theError2); 

어떻게 엑스 코드 로그 :

{ 
    "Name": "REST Service", 
    "Product": "REST Test", 
    "Version": "1.0.0.0", 
    "Copyright": "2013 Test Company" 
} 

나는 위의 코드를 실행하지만 다음 오류가 만들어지고 기록됩니다.

오류 도메인 = NSCocoaErrorDomain 코드 = 3840 "손상 되었기 때문에 데이터를 읽을 수 없습니다." (문자 3의 값이 잘못되었습니다.) UserInfo = 0x100547430 {NSDebugDescription = 문자 3의 값이 잘못되었습니다.}}

내가 뭘 잘못하고 있니?

+0

대신'dataString'을 로깅하는 대신'theData'를 로깅하십시오. 그것은 당신에게 문제를 디버깅하는 데 더 유용해야 바이트 순서를 보여줍니다. 또한 오류를 올바르게 검사하지 않는다는 것을 알아 두십시오. 오류를 검사하기 전에 반환 값이'nil'인지 테스트해야합니다. –

+0

디버깅 할 때'json'의 주소가'0x0000 ... '인 것을 보았 기 때문에 실제로 그 부분을 남겼습니다. 집에서 일할 때 더 자세한 바이트 시퀀스를 분석하겠습니다. –

+1

오케이. 난 그냥 JSON 문자열을 테스트하고 거기에'NSLog()'또는 NSString' 변환이 숨어있는 재미있는 문자가 없다면 작동합니다. –

답변

1

OK, 항상 그렇듯이 문자열 표현 대신 실제 데이터를 확인합니다. pay - thanks @Bavarious.

JSON 작성을 담당하는 PHP 스크립트는 모두 "BOM이있는 UTF8"이었으므로 PHP는 관련된 모든 스크립트에 대해 BOM을 반환했습니다.

일단 모든 PHP 파일을 "BOM없이 UTF8"으로 변경하면 모든 것이 잘된 것처럼 보입니다 - MAC에서 이것을 테스트해야합니다.

방해해서 죄송합니다. 좋은 결과를 얻으십시오.

(@Bavarious : 답을 쓰고 싶다면 해결책을 지적하면서 답변을 전합니다.)


예상대로 JSON을 구문 분석 할 수 있었습니까? 항상 텍스트 파일 인코딩을 다시 확인하도록 정신적으로 메모하십시오.

+0

당신의 대답은 괜찮습니다, 당신은 그것을 받아 들여야합니다. BOM 문자는 JSON 사양 (RFC 4627)에 따라 유효하지 않으므로 이론적으로 웹 서비스에는 BOM 문자가 포함되어서는 안됩니다. –

+0

알아.것은 PHP가 PHP 소스 파일의 인코딩을 기반으로 자동 생성 한 것입니다. –

+0

NSJSONSerialization은 텍스트 시작 부분에 _one_ BOM을 허용한다고 생각합니다. 하지만 다음은 JSON 문서에서 불법이되는 일반적인 "제로 너비 결합 자"(정확히 무엇이 호출되는지 기억할 수 없음) 일 것입니다. 파서가 "문자 3 주위에 유효하지 않은 값"이 있다고 말하면 문자 3 주위에 유효하지 않은 값이 있기 때문에 그 문자가 보이는지 여부에 관계없이 교훈이라고 생각합니다. – gnasher729

0
NSURL *theURL = [NSURL URLWithString:@"http://yourdataurl"]; 

    NSMutableURLRequest *storeRequest = [NSMutableURLRequest requestWithURL:theURL cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:10]; 

    NSOperationQueue *queue = [[NSOperationQueue alloc] init]; 
    [NSURLConnection sendAsynchronousRequest:storeRequest queue:queue 
         completionHandler:^(NSURLResponse *response,  NSData *data, NSError *connectionError) { 
           if (!connectionError) { 
            NSError *error; 

            NSString *dataStr = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; 

            NSData *theData = [dataStr dataUsingEncoding:NSUTF8StringEncoding]; 

            NSDictionary *jsonResponse = [NSJSONSerialization JSONObjectWithData:theData options:0 error:&error]; 


            if (!jsonResponse || error) 
            { 
             NSLog(@"Error"); 
            } 
            else 
            { 
             // Everything is ok.. 
            } 
           } 
          }];