私はTVHクライアントのATVバージョンを使用しています - これを見ていなければ、顔の狂気をちらっと見てみる価値があります。これには、電子プログラムガイドを含むデータを返すJSON APIがあります。チャネルによっては、アクセント付きの文字がデータに挿入されることがあります。ここに例がありますが、これはPostmanの結果です。説明のchar: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."
},
このデータはNSJSONSerialization
に供給される場合は、エラーを返します。だから、これを回避するために、データが最初にこの機能に供給された:コントロールデータ内の文字はなく、上記の場合と同様にアクセントがある場合に
+ (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を返しました」というエラーが表示されます。
1つの問題は、ユーザーが限られた数の選択肢の中から文字セットを変更でき、サーバーがクライアントにその内容を知らせないことです。したがって、1つのチャネルでUTF8と別のISO-8891-1を使用する可能性があり、クライアント側でどちらを使用するかを知る方法がありません。
だから誰もこのデータを処理する方法を提案して、きれいな文字列をNSJSONSerialization
に入力することはできますか?
*クライアント側で使用する方法を知る方法がありません。* ['Content-Type'](https://www.w3.org/Protocols/rfc1341/4_Content-Type.html)をチェックしましたか? ? 'charset'パラメータが設定されている場合、クライアントはそれを使用します。 –
ヘッダーには "ext/x-json; charset = UTF-8"と表示されていますが、これは既定値であり、各チャネルは独自のエンコーディングを持つことができます。実際には、デフォルトを変更しても常にUTF8と言います。 –
それを聞いて申し訳ありません。 [ICU](http://site.icu-project.org/)にはエンコーディング[自動検出](http://userguide.icu-project.org/conversion/detection)機能があります。 iOS用のICUのポートがありますが、自動検出だけでそのすべてを引き出すことは厄介です。 –