iPhone アプリとの単純なクライアント/サーバー通信が必要です。XML プロパティ リストは、XML パーサー デリゲートを処理してこれらの構造を自分で構築する手間を省く、非常に簡単で単純なソリューションのように思えます。
外部データで NSPropertyListSerialization クラスを使用するのが賢明でしょうか? 悪用される可能性のあるあいまいな plist 機能はありますか?
はい、信頼できないデータで NSPropertyListSerialization を使用しても安全ですが、バイトのバッグを plist 型の階層に変換した後、それらの型を検証して、期待されるデータ形式と一致することを確認する必要があります。
たとえば、文字列キーと NSNumbers を値として持つ辞書が必要な場合は、次のようなもので検証する必要があります。
NSString *errorDescription = nil;
NSPropertyListFormat format = 0;
id topObject = [NSPropertyListSerialization propertyListFromData:plistData mutabilityOption:NSPropertyListImmutable format:&format errorDescription:&errorDescription];
NSDictionary *validDictionary = nil;
if ([topObject isKindOfClass:[NSDictionary class]]) {
BOOL allNumbers = YES;
for(id value in [topObject allValues]) {
allNumbers = allNumbers && [value isKindOfClass:[NSNumber class]];
}
if (allNumbers) {
validDictionary = topObject;
}
}
return validDictionary;
そうしないと、データのソースが plist 値をアーカイブに入れ、タイプが一致しないか、不正な値がクライアントの誤動作を引き起こし、最終的にセキュリティの脆弱性になる可能性があります。
@ジョン・ヘス:ありがとう。必要なesNSDictionary
の数を減らすためにカテゴリを作成しました。isKindOfClass
@interface NSDictionary (TypedDictionary)
-(NSArray *)arrayForKey:(NSString*)key;
-(NSString *)stringForKey:(NSString*)key;
-(NSDictionary *)dictionaryForKey:(NSString*)key;
@end
@implementation NSDictionary (TypedDictionary)
-(NSArray *)arrayForKey:(NSString*)key {
NSArray *obj = [self objectForKey:key];
return [obj isKindOfClass:[NSArray class]] ? obj : nil;
}
-(NSString *)stringForKey:(NSString*)key {
NSString *obj = [self objectForKey:key];
return [obj isKindOfClass:[NSString class]] ? obj : nil;
}
-(NSDictionary *)dictionaryForKey:(NSString*)key {
NSDictionary *obj = [self objectForKey:key];
return [obj isKindOfClass:[NSDictionary class]] ? obj : nil;
}
@end