15

Web サービスからの応答を処理する必要がある iOS アプリがあります。応答は、シリアライズされた JSON オブジェクトを含むシリアライズされた JSON 文字列で、次のようになります。

"{ \"name\" : \"Bob\", \"age\" : 21 }"

このレスポンスは、JSON オブジェクトではなく、 JSON文字列であることに注意してください。私がする必要があるのは、文字列を逆シリアル化することです。これにより、次のようになります。

{ "name" : "Bob", "age" : 21 }

そして、それを.+[NSJSONSerialization JSONObjectWithData:options:error:]に逆シリアル化するために使用できますNSDictionary

しかし、どうすればその最初のステップを行うことができますか? つまり、シリアル化された JSON オブジェクトを取得するために、文字列を "エスケープ解除" する方法を教えてください。 +[NSJSONSerialization JSONObjectWithData:options:error:]最上位オブジェクトが配列または辞書である場合にのみ機能します。文字列では機能しません。

最終的に、RFC 4627 のセクション 2.5 に準拠した独自の JSON 文字列パーサーを作成しました。しかし、これを行う簡単な方法または他の利用可能な方法を見落としていると思います。NSJSONSerialization

4

4 に答える 4

-1

最初に、なぜサーバーがサブ構造として JSON を含めないのかを尋ねる必要があります。

とにかく。取得した文字列は、エスケープされたJSON のようです。それが実際に何を意味するかは、完全に Web サービス開発者次第です。二重引用符とエスケープ自体だけがエスケープされているのではないかと思い\ます。結果の文字列は「シリアル化」されていません。JSON は既にシリアル化されていますが、エンコードされています。元に戻すには、「エスケープ解除」または再度デコードする必要があります。

ちょっとした C++ のスニペットは、その方法を示しています (Objective-C を要求したことは知っていますが、これは簡単すぎます)。

編集:コードはUTF-16およびUTF-32でも機能するはずです-任意のエンディアンで-エンコーダーが機械的に私が疑うことをしただけなら、エスケープされたUnicode文字、たとえば\ u1234などでも機能するはずです.

編集 - いいえ、UTF-16 と UTF-32 では機能しません。そのためには、サンプルを修正する必要があります (これは簡単です)。ただし、ほとんどの場合 UTF-8 であることを確認してください。

#include <iostream>

char input[] = u8R"___({ \"name\" : \"Bob\", \"age\" : 21 })___";

// Unescapes the character sequence "in-situ".
// Returns a pointer to "past-the-end" of the unescaped string.
static char* unescape(char* first, char* last) {
    char* dest = first;
    while (first != last) {
        if (*first == '\\') {
            ++first;
        }
        *dest++ = *first++;
    }
    return dest;
}

int main(int argc, const char * argv[])
{
    char* first = input;
    char* last = first + strlen(input);
    std::string s(input, unescape(first, last));

    std::cout << s << std::endl;

    return 0;
}

版画:

{「名前」:「ボブ」、「年齢」:21}

于 2013-06-05T21:44:23.383 に答える