2015-04-01 69 views
0

我有一個與服務器通信的問題。 Web服務器期望JSON對象中的所有參數都是一個字符串。所以每個容器中的每個數字和每個布爾值都需要是一個字符串。將Container的所有值轉換爲NSString

對於我的例子,我有一個NSDictionary全是關鍵值(值是各種類型 - 數字,數組等)。例如:

{ 
"AnExampleNumber":7e062fa, 
"AnExampleBoolean":0, 
"AnExampleArrayOfNumber":[17,4,8] 
} 

有可能成爲:

{ 
"AnExampleNumber":"7e062fa", 
"AnExampleBoolean":"0", 
"AnExampleArrayOfNumber":["17","4","8"] 
} 

我試過標準NSJSONSerializer,但它並沒有給我任何選擇做什麼,我需要的。然後,我試圖手動將詞典中的所有內容轉換爲字符串,但似乎是開銷。有人有提示嗎?也許是一個序列化器,只是做一個或一個函數來將容器中的任何對象轉換爲字符串?

+2

糟糕的服務器實施。 – picciano 2015-04-01 13:10:50

+0

當然,我完全和你在一起。 – palme 2015-04-01 13:14:29

回答

1

(我假設你的意思是NSJSONSerializer,不NSSerializer。)

我懷疑你會發現一個預軋解決這個。這不是一個普遍的問題。正如你注意到的,這是不正確的JSON,所以JSON序列化程序不應該這樣做。

IMO的最佳解決方案就是編寫代碼,將您的NSDictionary轉換爲您想要的形式的另一個NSDictionary。如果你真的想讓它成爲一個通用的解決方案,我懷疑用isKindOfClass:來定製NSDictionary步行者是你最好的選擇。像這樣的東西應該工作:

NSDictionary *myStringDictForDict(NSDictionary *dict); // forward decl if needed 

NSArray *myStringArrayForArray(NSArray *array) { 
    NSMutableArray *result = [NSMutableArray new]; 
    [array enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { 
     if ([obj isKindOfClass:[NSArray class]]) { 
      [result addObject:myStringArrayForArray(obj)]; 
     } else if ([obj isKindOfClass:[NSDictionary class]]) { 
      [result addObject:myStringDictForDict(obj)]; 
     } else { 
      [result addObject:[obj description]]; 
     } 
    }]; 

    return result; 
} 

NSDictionary *myStringDictForDict(NSDictionary *dict) { 
    NSMutableDictionary *result = [NSMutableDictionary new]; 
    [dict enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) { 
     if ([obj isKindOfClass:[NSArray class]]) { 
      result[key] = myStringArrayForArray(obj); 
     } else if ([obj isKindOfClass:[NSDictionary class]]) { 
      result[key] = myStringDictForDict(obj); 
     } else { 
      result[key] = [obj description]; 
     } 
    }]; 

    return result; 
} 
+0

工作:)謝謝。我仍然會與服務器的人談話;) – palme 2015-04-01 15:26:03

2

這是一種方法,你可以做到這一點。它沒有優化,沒有錯誤處理。它只支持NSJSONSerializer支持的各種對象。

#import <Foundation/Foundation.h> 

@interface NSObject(SPWKStringify) 
- (id)spwk_stringify; 
@end 

@implementation NSObject(SPWKStringify) 
- (id)spwk_stringify 
{ 
    if ([self isKindOfClass:[NSDictionary class]]) { 
     NSDictionary *dict = (NSDictionary *)self; 
     NSMutableDictionary *newDict = [[NSMutableDictionary alloc] init]; 

     for (NSString *key in [dict allKeys]) { 
      newDict[key] = [dict[key] spwk_stringify]; 
     } 

     return newDict; 
    } else if ([self isKindOfClass:[NSArray class]]) { 
     NSMutableArray *newArray = [[NSMutableArray alloc] init]; 

     for (id value in ((NSArray *)self)) { 
      [newArray addObject:[value spwk_stringify]]; 
     } 

     return newArray; 
    } else if (self == [NSNull null]) { 
     return @"null"; // representing null as a string doesn't make much sense 
    } else if ([self isKindOfClass:[NSString class]]) { 
     return self; 
    } else if ([self isKindOfClass:[NSNumber class]]) { 
     return [((NSNumber *)self) stringValue]; 
    } 

    return nil; 
} 
@end 

int main(int argc, char *argv[]) { 
    @autoreleasepool { 
     NSDictionary *dict = @{ 
      @"AnExampleNumber": @1234567, 
      @"AnExampleBoolean": @NO, 
      @"AnExampleNull": [NSNull null], 
      @"AnExampleArrayOfNumber": @[@17, @4, @8], 
      @"AnExampleDictionary": @{@"innerKey": @[@55, @{@"anotherDict": @[@"foo", @[@1, @2, @"three"]]}]} 
     }; 

     NSData *jsonData = [NSJSONSerialization dataWithJSONObject:[dict spwk_stringify] options:NSJSONWritingPrettyPrinted error:NULL]; 
     NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding]; 

     NSLog(@"result: %@", jsonString); 
    } 
} 

輸出將是:

result: { 
    "AnExampleNumber" : "1234567", 
    "AnExampleNull" : "null", 
    "AnExampleDictionary" : { 
    "innerKey" : [ 
     "55", 
     { 
     "anotherDict" : [ 
      "foo", 
      [ 
      "1", 
      "2", 
      "three" 
      ] 
     ] 
     } 
    ] 
    }, 
    "AnExampleBoolean" : "0", 
    "AnExampleArrayOfNumber" : [ 
    "17", 
    "4", 
    "8" 
    ] 
} 

注意:請記住,轉向[NSNull null]成一個字符串沒有任何意義,實際上可能是誤導性的和危險的。

享受。

+0

您的解決方案也工作。試過了。謝謝 :) – palme 2015-04-01 15:26:50