2016-11-27 4 views
0

TVH 클라이언트의 ATV 버전을 사용하고 있습니다.이 기능을 보지 못했다면 TVH를보고 얼굴을 보며 광란을 들여다 볼 가치가 있습니다. 전자 프로그램 가이드를 포함하여 데이터를 다시 보내는 JSON API가 있습니다. 때때로 채널은 악센트 부호가있는 문자를 데이터에 넣습니다. 예를 들면, 이것은 Postman의 결과입니다. 설명에 문자 :이 데이터가 NSJSONSerialization에 공급JSON 데이터에 NSJSONSerialization이 죽는 "불량"문자가 있습니다.

{ 
     "eventId": 14277, 
     "episodeId": 14278, 
     "channelName": "49.3 CometTV", 
     "channelUuid": "02fe96403d58d53d71fde60649bf2b9a", 
     "channelNumber": "49.3", 
     "start": 1480266000, 
     "stop": 1480273200, 
     "title": "The Brain That Wouldn't Die", 
     "description": "Dr. Bill Cortner and his fianc�e, Jan Compton , are driving to his lab when they get into a horrible car accident. Compton is decapitated. But Cortner is not fazed by this seemingly insurmountable hurdle. His expertise is in transplants, and he is excited to perform the first head transplant. Keeping Compton's head alive in his lab, Cortner plans the groundbreaking yet unorthodox surgery. First, however, he needs a body." 
    }, 

경우, 오류를 반환합니다. 그래서이를 방지하기 위해, 데이터는 먼저이 함수에 공급된다

+ (NSDictionary*)convertFromJsonToObjectFixUtf8:(NSData*)responseData error:(__autoreleasing NSError**)error { 
    NSMutableData *FileData = [NSMutableData dataWithLength:[responseData length]]; 
    for (int i = 0; i < [responseData length]; ++i) { 
     char *a = &((char*)[responseData bytes])[i]; 
     if ((int)*a >0 && (int)*a < 0x20) { 
      ((char*)[FileData mutableBytes])[i] = 0x20; 
     } else { 
      ((char*)[FileData mutableBytes])[i] = ((char*)[responseData bytes])[i]; 
     } 
    } 
    NSDictionary* json = [NSJSONSerialization JSONObjectWithData:FileData //1 
                 options:kNilOptions 
                  error:error]; 
    if(*error) { 
     NSLog(@"[JSON Error (2nd)] output - %@", [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding]); 
     NSDictionary *userInfo = @{ NSLocalizedDescriptionKey:[NSString stringWithFormat:NSLocalizedString(@"Tvheadend returned malformed JSON - check your Tvheadend's Character Set for each mux and choose the correct one!", nil)] }; 
     *error = [[NSError alloc] initWithDomain:@"Not ready" code:NSURLErrorBadServerResponse userInfo:userInfo]; 
     return nil; 
    } 
    return json; 
} 

가 데이터의 제어 문자이지만, 경우에 케이스를 정리하지 위의 경우처럼 악센트. 해당 데이터를 피드 할 때 "Tvheadend가 잘못된 JSON을 반환했습니다"라는 오류가 발생합니다.

한 가지 문제점은 사용자가 제한된 수의 선택 중에서 문자 세트를 변경할 수 있고 서버가 클라이언트에게 그 문자를 알리지 못한다는 것입니다. 따라서 한 채널에서 UTF8과 다른 ISO-8891-1을 사용할 수 있으며 클라이언트 측에서 사용할 채널을 알 수있는 방법이 없습니다.

그렇다면 누구나이 데이터를 처리하는 방법에 대한 제안을 제공해 깨끗한 문자열을 NSJSONSerialization에 넣을 수 있습니까?

+0

* 클라이언트 측에서 사용할 것을 알 수있는 방법이 없습니다. * ['Content-Type'] (https://www.w3.org/Protocols/rfc1341/4_Content-Type.html)을 확인 했습니까? ? 'charset' 매개 변수가 설정되면 클라이언트는이를 사용합니다. –

+0

헤더에 "ext/x-json; charset = UTF-8"이라고 표시되어 있지만 이것이 기본값 일 뿐이며 각 채널은 자체 인코딩을 가질 수 있습니다. 기본적으로 UTF8을 변경한다고해도 항상 UTF8이 표시됩니다. –

+0

그 점은 유감입니다. [ICU] (http://site.icu-project.org/)에는 인코딩 [자동 탐지] (http://userguide.icu-project.org/conversion/detection) 기능이 있습니다. iOS 용 ICU 포트가 있지만 자동 감지를 위해 모든 것을 끌어 당기는 것은 어설픈 일입니다. –

답변

1

나는 아직도 내가 겪고있는 문제의 근본 원인을 모른다. 서버는 위에서 언급 한 것과 같은 높은 비트 문자를 전송하지 않고 있지만 제어 문자도 포함하고있다. 다른 스레드를 살펴보면 나는이 문제를보고있는 유일한 사람이 아니기 때문에 다른 사람들이 유용하다고 생각할 것입니다. ...

기본 트릭은 서버의 원래 데이터를 UTF8을 사용하여 문자열로 변환하는 것입니다. 이러한 "잘못된"문자가 있으면 변환이 실패합니다. 결과 문자열이 비어 있는지 확인하고 다른 문자셋을 시도하십시오. 결국 당신은 데이터를 다시 얻을 것이다. 이제 해당 문자열을 가져 와서 제어 문자를 제거합니다. 이제 UTF8 "clean"인 결과를 UTF8 NSData로 다시 변환합니다. 그러면 오류없이 JSON 변환을 통과하게됩니다. 휴!

// ... the original data from the URL is in responseData 
NSString *str = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding]; 
if (str == nil) { 
    str = [[NSString alloc] initWithData:responseData encoding:NSISOLatin1StringEncoding]; 
} 
if (str == nil) { 
    str = [[NSString alloc] initWithData:responseData encoding:NSASCIIStringEncoding]; 
} 
NSCharacterSet *controls = [NSCharacterSet controlCharacterSet]; 
NSString *stripped = [[str componentsSeparatedByCharactersInSet:controls] componentsJoinedByString:@""]; 
NSData *data = [stripped dataUsingEncoding:NSUTF8StringEncoding]; 
NSDictionary* json = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&error]; 

나는 사람이이 유용한 발견 희망 : 여기

내가 마지막으로 사용되는 솔루션입니다!

+0

이것은 실행되지만 유니 코드 문자는 나를 위해 쓰레기 ASCII 문자로 끝납니다 ... 아마도 나는 번역에 잘못 생각하고 있습니다. – aehlke

관련 문제