【问题标题】:Read plist stored in memory to NSDictionary读取存储在内存中的 plist 到 NSDictionary
【发布时间】:2012-03-25 04:55:31
【问题描述】:

根据post,我可以使用加密/解密方法安全地存储/检索 plist 文件。

但问题是:

问:我解密plist文件后,如何将plist文件解析并存储为NSDitrionary对象

【问题讨论】:

    标签: iphone objective-c ios xcode plist


    【解决方案1】:

    NSPropertyListSerialization 可能就是您要查找的内容。

    正如在这篇文章中看到的: Plist Array to NSDictionary

    【解决方案2】:

    您可以在这里使用核心基础方法与方法CFPropertyListCreateFromXMLData

    如果 plist 代表 NSDictionary 内容,则应通过以下检查:

    if ([(id)plist isKindOfClass:[NSDictionary class]])
    

    并且 plist 对象可能被安全地转换为 NSDictionary。如果不是,则数据或解密过程有问题。

    【讨论】:

      【解决方案3】:

      最简单的方法是像这样为 NSDictionary 创建一个类别:

      NSDictionaryWithData.h:

      @interface NSDictionary (NSDictionaryWithData)
      + (id)dictionaryWithData:(NSData *)data;
      - (id)initWithData:(NSData *)data;
      @end
      

      NSDictionaryWithData.m:

      @implementation NSDictionary (NSDictionaryWithData)
      
      + (id)dictionaryWithData:(NSData *)data
      {
        return [[[NSDictionary alloc] initWithData:data] autorelease];
      }
      
      - (id)initWithData:(NSData *)data
      {
        self = (NSDictionary *)[NSPropertyListSerialization propertyListFromData:data
                                                                mutabilityOption:NSPropertyListImmutable
                                                                          format:NULL
                                                                errorDescription:nil];
        return [self retain];
      }
      
      @end
      

      用法:

      NSDictionary* myDict = [[NSDictionary alloc] initWithData:decryptedData];
      

      【讨论】:

        【解决方案4】:

        dictionaryWithData 不存在的一个可能原因是属性列表不一定是根级别的字典。它同样可以是一个 NSArray。

        这是我对解决方案的看法:使用 NSPropertyListSerialization 的类别

        特点

        • 静默丢弃包含根级别数组的数据。
        • 检查要使用的方法(propertyListFromData:mutabilityOption:format:errorDescription: is depreciated)

        • 也支持 NSMutableDictionary

        注意 - 这采用了一种非正统的方法,即用 init 方法包装类工厂方法。这是为了提高效率 - 大多数时候您将使用工厂方法,它只是包装 NSPropertyListSerialization,它在内部调用 alloc/init/autorelease 以返回适当的对象。

        NSDictionary+DictionaryWithData.h

        #import <Foundation/Foundation.h>
        
        @interface NSDictionary (DictionaryWithData)
        + (id)dictionaryWithData:(NSData *)data;
        - (id)initWithData:(NSData *)data;
        @end
        

        NSDictionary+DictionaryWithData.m

        #import "NSDictionary+DictionaryWithData.h"
        
        
        
        @implementation NSDictionary (DictionaryWithData)
        +(NSPropertyListMutabilityOptions) mutabilityOption {
            return NSPropertyListImmutable;
        }
        
        + (id)dictionaryWithData:(NSData *)data
        {
            static BOOL methodChecked = NO;
            static BOOL use_propertyListWithData = NO;
            if (!methodChecked) {
                SEL sel = @selector(propertyListWithData:options:format:error:);
                use_propertyListWithData = [[NSPropertyListSerialization class]
                                            respondsToSelector:sel];
                methodChecked = YES;
            }
        
            id result;
        
            if (use_propertyListWithData) {
        
                 result =  [NSPropertyListSerialization propertyListWithData:data
                                                                 options:[self mutabilityOption]
                                                                  format:nil
                                                                   error:nil];
        
            } else {
        
                 result =  [NSPropertyListSerialization propertyListFromData:data
                                                        mutabilityOption:[self mutabilityOption]
                                                                  format:NULL
                                                        errorDescription:nil];
            }
        
            return  [result isKindOfClass:[NSDictionary class]] ? result : nil;
        }
        
        - (id)initWithData:(NSData *)data
        {
            id result = [[self class] dictionaryWithData:data];
            self = result ? [self initWithDictionary:result ] : nil;
            return  self;
        }
        @end
        
        @implementation NSMutableDictionary (DictionaryWithData)
        +(NSPropertyListMutabilityOptions) mutabilityOption {
            return NSPropertyListMutableContainersAndLeaves;
        }
        @end
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2011-02-22
          • 1970-01-01
          • 2014-11-13
          • 1970-01-01
          • 2017-03-19
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多