2013-06-05 5 views
11

मेरे पास एक आईओएस ऐप है जिसे वेब सेवा से प्रतिक्रिया को संसाधित करने की आवश्यकता है।NSJSONSerialization के साथ एक बच निकले JSON स्ट्रिंग को आप कैसे deserialize कर सकते हैं?

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

ध्यान दें कि यह प्रतिक्रिया एक JSON स्ट्रिंग, नहीं एक JSON ऑब्जेक्ट है: प्रतिक्रिया एक धारावाहिक JSON ऑब्जेक्ट युक्त, कुछ इस तरह की तलाश में एक धारावाहिक JSON स्ट्रिंग है।

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

और फिर मैं +[NSJSONSerialization JSONObjectWithData:options:error:] उपयोग कर सकते हैं deserialize करने के लिए है कि एक NSDictionary में: क्या मैं क्या करने की जरूरत स्ट्रिंग deserialize, ताकि मैं इस मिलता है।

लेकिन, मैं यह पहला कदम कैसे करूं? यही है, मैं स्ट्रिंग को "अनदेखा" कैसे करूं ताकि मेरे पास एक क्रमबद्ध JSON ऑब्जेक्ट हो? +[NSJSONSerialization JSONObjectWithData:options:error:] केवल तभी काम करता है जब शीर्ष-स्तरीय ऑब्जेक्ट एक सरणी या शब्दकोश है; यह तारों पर काम नहीं करता है।

मैंने my own JSON string parser लिखना समाप्त कर दिया, जो मुझे उम्मीद है कि section 2.5 of RFC 4627 पर अनुरूप है। लेकिन मुझे संदेह है कि मैंने NSJSONSerialization या कुछ अन्य उपलब्ध विधि का उपयोग करके ऐसा करने के कुछ आसान तरीके को अनदेखा कर दिया है।

+0

बस बंद प्रमुख और अनुगामी quoteß कटौती और फिर सभी '\" 'रों की जगह '' 'के साथ। –

+0

फिर आप प्रत्येक संभावित भागने अनुक्रम के लिए अनजान प्रक्रिया को दोहराते हैं (बहुत सारे हैं)। –

+0

'\ uXXXX' एस्केप अनुक्रम सरल खोज-और-प्रतिस्थापन को आसान बनाता है। –

उत्तर

24

आप नेस्ट है JSON, बस उसके बाद JSONObjectWithData दो बार फोन:

NSString *string = @"\"{ \\\"name\\\" : \\\"Bob\\\", \\\"age\\\" : 21 }\""; 
// --> the string 
// "{ \"name\" : \"Bob\", \"age\" : 21 }" 

NSError *error; 
NSString *outerJson = [NSJSONSerialization JSONObjectWithData:[string dataUsingEncoding:NSUTF8StringEncoding] 
           options:NSJSONReadingAllowFragments error:&error]; 
// --> the string 
// { "name" : "Bob", "age" : 21 } 
NSDictionary *innerJson = [NSJSONSerialization JSONObjectWithData:[outerJson dataUsingEncoding:NSUTF8StringEncoding] 
           options:0 error:&error]; 
// --> the dictionary 
// { age = 21; name = Bob; } 
+0

जब मैंने कोशिश की, तो मुझे एक त्रुटि संदेश मिला। ऐसा लगता है कि शीर्ष-स्तरीय ऑब्जेक्ट एक सरणी या शब्दकोश है। –

+0

@ क्रिस्टोफर जॉनसन: मैंने बिल्कुल इस कोड की कोशिश की और यह मेरे लिए काम किया। आपको पहले चरण में NSJSONReadingAllowFragments विकल्प की आवश्यकता है। –

+0

मैं कसम खाता हूं कि मैंने पहले 'NSJSONReadingAllowFragments' की कोशिश की, और यह काम नहीं किया, लेकिन अब यह करता है। मुझे फिर से कोशिश करने के लिए धन्यवाद। –

0

आंकड़ों के स्ट्रिंग में कनवर्ट करें:

NSString *string = @"{ \"name\" : \"Bob\", \"age\" : 21 }"; 
NSData *data = [string dataUsingEncoding:NSUTF8StringEncoding]; 
NSError *error; 
id json = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error]; 
+0

मेरे पास 'NSData' ऑब्जेक्ट है जब मैं' NSJSONSerialization'। तो ऐसा लगता है जैसे आपका कोड 'स्ट्रिंग = @ "\" {\\ "नाम \\": \\ "बॉब \\", \\ "आयु \\": 21} \ ""; ' –

+0

कैसे हैं आपको वह स्ट्रिंग मिल रही है? यह पाइपलाइन के साथ कहीं और लगता है कि यह डबल-एस्केप किया जा रहा है, और यही आपको डीबग करने की ज़रूरत है। –

+1

वेब सेवा डबल-एस्केपिंग है। आप और मैं सहमत हो सकता हूं कि यह नहीं होना चाहिए, लेकिन ऐसा करता है, और मुझे इससे निपटना होगा। –

0

बस अग्रणी और अनुगामी उद्धरण काट और फिर सभी \ "के साथ" की जगह:

NSString *sub = [original substringWithRange:(NSRange){ 1, original.length - 2 }]; 
NSString *unescaped = [sub stringByReplacingOccurrencesOfString:@"\\\" withString:@"\"]; 
+0

यह मेरा प्रारंभिक हैकी वर्कअराउंड था, लेकिन यह केवल तभी काम करता है जब स्ट्रिंग में कोई अन्य विशेष वर्ण नहीं है ('\ n',' \ t', '\ u1234', आदि)। लेकिन मैं इसे नहीं मान सकता। –

+0

इन वर्णों से बचने के लिए एक JSON स्ट्रिंग की आवश्यकता होगी। इसलिए, जब एक एन्कोडर लागू होता है, तो यह केवल भागने से बच जाएगा: "(\\ n)" – CouchDeveloper

0

एक पहले से पूछना चाहिए क्यों सर्वर अभी शामिल नहीं हैं एक उप संरचना के रूप में JSON।

लेकिन वैसे भी। आपको मिली स्ट्रिंग JSON से बच गई। वास्तव में का अर्थ है, पूरी तरह से वेब सेवा डेवलपर तक है। मुझे संदेह है कि केवल दोहरे उद्धरण और एक भागने से बचने के लिए \ से बच निकला है। जिसके परिणामस्वरूप स्ट्रिंग "धारावाहिक" नहीं है - JSON पहले से ही धारावाहिक है - लेकिन इनकोडिंग

: -

एक छोटी सी सी ++ टुकड़ा दिखाता है कि (लेकिन यह अभी भी आसान है मुझे पता है तुम ऑब्जेक्टिव-सी के लिए कहा): - क्रम उसे पूर्ववत् करने के लिए आप के लिए "unescape" या डिकोड इसे फिर से की जरूरत है

संपादित करें: कोड भी UTF-16 और UTF-32 के लिए काम करना चाहिए - किसी भी endianness साथ - और अगर एनकोडर बस यंत्रवत् मैं क्या संदेह किया था, यह भी बच गए यूनिकोड वर्ण, जैसे के लिए काम करना चाहिए \ 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}

+1

आपका उदाहरण इनपुट में {{\ "नाम \": \ "बॉब \", \ "आयु \": 21} 'पर चल रहा है। लेकिन वास्तविक सर्वर प्रतिक्रिया थी (जैसा कि मैं इसे समझता हूं) '" {\ "नाम \": \ "बॉब \", \ "आयु \": 21} "' (प्रमुख और पिछला उद्धरण चिह्न नोट करें)। यही कारण है कि NSJSONReadingAllowFragments काम करता है। –

+0

ठीक है, इसका मतलब है, NSJSONSerialization इसे JSON स्ट्रिंग के रूप में व्याख्या करता है, और फिर यह शीर्ष स्तर ऑब्जेक्ट देता है - जो एक एनएसएसटींग है। इसलिए, प्रभावी रूप से यह दिए गए स्ट्रिंग में "JSON स्ट्रिंग डिकोडर" लागू होता है। यह काम कर सकता है - लेकिन मैं वैसे भी स्पष्ट करता हूं कि वेब सेवा द्वारा दिए गए स्ट्रिंग को कैसे डीकोड किया गया है। – CouchDeveloper

संबंधित मुद्दे