2011-11-27 191 views
10

我定義了一些自定義類,例如Teacher,Student ... 現在我從遠程服務器收到教師信息(JSON字符串)。如何將JSON轉換爲對象

如何將JSON字符串轉換爲Teacher對象。

在Java中,很容易爲所有類(Teacher,Student ...)和reflect實現通用方法。

但是在iOS的Objective-C中,我能找到的最好方法是使用核心數據實體,它具有setValue:forKey方法。首先,我將JSON字符串轉換爲NSDictionary,將分配中的鍵值對設置爲Entry

有沒有更好的方法?

(我來自中國,所以也許我的英語很差,對不起!)

+0

你的問題是可以理解的,沒有後顧之憂:) – tekknolagi

+1

哈哈,謝謝:) –

+0

看一看這個鏈接[JSON反對] [1] [1]:HTTP://計算器。 com/questions/5645703/how-to-convert-json-data-to-objects-in-iphone – mH16

回答

5

這些都是JSON解析字典或其他原語的良好框架,但如果您希望避免做大量重複性工作,請查看http://restkit.org。具體而言,請查看https://github.com/RestKit/RestKit/blob/master/Docs/Object%20Mapping.md這是對象映射的示例,您可以爲Teacher類定義映射,並使用KVC將json自動轉換爲Teacher對象。如果你使用RestKit的網絡調用,這個過程是透明和簡單的,但我已經有了我的網絡調用,我需要的是將我的JSON響應文本轉換爲一個用戶對象(在你的情況下,教師),我終於想通了怎麼樣。如果這是您需要的,請發表評論,我將分享如何使用RestKit進行操作。

注意:我將假定json是使用映射約定{"teacher": { "id" : 45, "name" : "Teacher McTeacher"}}輸出的。如果不是這樣,而是像這樣{"id" : 45, "name" : "Teacher McTeacher"},那麼不要擔心...鏈接中的對象映射設計文檔會告訴您如何執行此操作......只需幾個額外的步驟,但不是太糟糕。

這是ASIHTTPRequest

- (void)requestFinished:(ASIHTTPRequest *)request { 
    id<RKParser> parser = [[RKParserRegistry sharedRegistry] parserForMIMEType:[request.responseHeaders valueForKey:@"Content-Type"]]; // i'm assuming your response Content-Type is application/json 
    NSError *error; 
    NSDictionary *parsedData = [parser objectFromString:apiResponse error:&error]; 
    if (parsedData == nil) { 
     NSLog(@"ERROR parsing api response with RestKit...%@", error); 
     return; 
    } 

    [RKObjectMapping addDefaultDateFormatterForString:@"yyyy-MM-dd'T'HH:mm:ssZ" inTimeZone:[NSTimeZone timeZoneWithAbbreviation:@"UTC"]]; // This is handy in case you return dates with different formats that aren't understood by the date parser 

    RKObjectMappingProvider *provider = [RKObjectMappingProvider new]; 

    // This is the error mapping provider that RestKit understands natively (I copied this verbatim from the RestKit internals ... so just go with it 
    // This also shows how to map without blocks 
    RKObjectMapping* errorMapping = [RKObjectMapping mappingForClass:[RKErrorMessage class]]; 
    [errorMapping mapKeyPath:@"" toAttribute:@"errorMessage"]; 
    [provider setMapping:errorMapping forKeyPath:@"error"]; 
    [provider setMapping:errorMapping forKeyPath:@"errors"]; 

    // This shows you how to map with blocks 
    RKObjectMapping *teacherMapping = [RKObjectMapping mappingForClass:[Teacher class] block:^(RKObjectMapping *mapping) { 
     [mapping mapKeyPath:@"id" toAttribute:@"objectId"]; 
     [mapping mapKeyPath:@"name" toAttribute:@"name"]; 
    }]; 

    [provider setMapping:teacherMapping forKeyPath:@"teacher"]; 

    RKObjectMapper *mapper = [RKObjectMapper mapperWithObject:parsedData mappingProvider:provider]; 
    Teacher *teacher = nil; 
    RKObjectMappingResult *mappingResult = [mapper performMapping]; 
    teacher = [mappingResult asObject]; 

    NSLog(@"Teacher is %@ with id %lld and name %@", teacher, teacher.objectId, teacher.name); 
} 

我的回調可以很明顯的重構這使它更清潔的,但現在解決了我所有的問題..沒有更多的解析......只是響應 - >魔法 - >對象

+0

非常感謝。這正是我正在尋找的。請繼續 –

+0

我已經使用了ASIHttp。 –

+0

好吧,我更新了我的答案......這應該讓你去。只要確保按照說明將RestKit放入項目中,就像您在RestKit github頁面上看到的一樣。我花了大約30分鐘的時間纔將它寫入我的項目所需的所有步驟中,但現在我所有的API調用都快速寫入 –

6

首先,你使用JSON解析器? (如果沒有,我會推薦使用SBJson)。

其次,爲什麼不在自定義類中創建一個initWithDictionary初始化方法來返回自我對象?

+0

是的,我使用SBJson來解析json字符串到NSDictionary。我認爲這是創建initWithDictionary方法的有效方法。但是我必須從所有類中創建方法。 –

+3

如果您使用的是iOS 5,則使用NSJSONSerialization類中的構建,如果不使用JSONKit,則其速度超過SBJSON。 – Abizern