zoukankan      html  css  js  c++  java
  • [ios] 数据持久化(加密等)

    从数据保存的方式上讲可以分为三大部分:属性列表、对象归档、嵌入式数据库(SQLite3)、CoreData等

    这里主要解释 属性列表,对象归档

    1.属性列表

    首先要知道获取应用程序中能保存数据的路径, http://www.cnblogs.com/jinjiantong/archive/2013/02/23/2923717.html 这里提过

    1)一种简单的方法是,获取目录路径后直接写下去

    -(IBAction) save {
        
        NSArray * myPaths = NSSearchPathForDirectoriesInDomains (NSDocumentDirectory, NSUserDomainMask, YES);
        NSString * myDocPath = [myPaths objectAtIndex:0];
        NSString *filename = [myDocPath
                              stringByAppendingPathComponent:@"properties.plist"];
        
        NSMutableArray *data = [[NSMutableArray alloc]init];
        [data addObject:studentId.text];
        [data addObject:studentName.text];
        [data addObject:studentClass.text];
        [data writeToFile:filename atomically:YES];

        [data release];
        
    }

    读取

        NSArray * myPaths = NSSearchPathForDirectoriesInDomains (NSDocumentDirectory, NSUserDomainMask, YES);
        NSString * myDocPath = [myPaths objectAtIndex:0];
        NSString *filename = [myDocPath
                              stringByAppendingPathComponent:@"properties.plist"];
        
        if ([[NSFileManager defaultManager] fileExistsAtPath:filename]) {
            NSArray *data = [[NSArray alloc] initWithContentsOfFile:filename];
            studentId.text = [data objectAtIndex:0];
            studentName.text = [data objectAtIndex:1];
            studentClass.text = [data objectAtIndex:2];    
            [data release];
        }
    }

    2)用NSUserdefault

    用NSUserdefault存储的数据在ios应用程序目录中/Library/Prefereces,里面有个plist文件,存储的就是你的userDefaults

    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
      [defaults setObject:@"mytest" forKey:@"mytest"];
      [defaults synchronize];  //同步化,更新你的数据 (我理解为把内存中的数据写入到文件)
      NSString *testStr = [defaults objectForKey:@"myTest"];
      NSLog(@"testStr is: %@",testStr);

    3)keychain 的使用(加密)

    来至:http://blog.csdn.net/weiqubo/article/details/7691278

    需要导入Security.framework 

    [cpp] view plaincopy
     
    1. @implementation WQKeyChain  
    2. + (NSMutableDictionary *)getKeychainQuery:(NSString *)service {  
    3. return [NSMutableDictionary dictionaryWithObjectsAndKeys:  
    4.         (__bridge_transfer id)kSecClassGenericPassword,(__bridge_transfer id)kSecClass,  
    5.         service, (__bridge_transfer id)kSecAttrService,  
    6.         service, (__bridge_transfer id)kSecAttrAccount,  
    7.         (__bridge_transfer id)kSecAttrAccessibleAfterFirstUnlock,(__bridge_transfer id)kSecAttrAccessible,  
    8.         nil];  
    9. }  
    10.   
    11. + (void)save:(NSString *)service data:(id)data {  
    12.     //Get search dictionary  
    13.     NSMutableDictionary *keychainQuery = [self getKeychainQuery:service];  
    14.     //Delete old item before add new item  
    15.     SecItemDelete((__bridge_retained CFDictionaryRef)keychainQuery);  
    16.     //Add new object to search dictionary(Attention:the data format)  
    17.     [keychainQuery setObject:[NSKeyedArchiver archivedDataWithRootObject:data] forKey:(__bridge_transfer id)kSecValueData];  
    18.     //Add item to keychain with the search dictionary  
    19.     SecItemAdd((__bridge_retained CFDictionaryRef)keychainQuery, NULL);  
    20. }  
    21.   
    22. + (id)load:(NSString *)service {  
    23.     id ret = nil;  
    24.     NSMutableDictionary *keychainQuery = [self getKeychainQuery:service];  
    25.     //Configure the search setting  
    26.     [keychainQuery setObject:(id)kCFBooleanTrue forKey:(__bridge_transfer id)kSecReturnData];  
    27.     [keychainQuery setObject:(__bridge_transfer id)kSecMatchLimitOne forKey:(__bridge_transfer id)kSecMatchLimit];  
    28.     CFDataRef keyData = NULL;  
    29.     if (SecItemCopyMatching((__bridge_retained CFDictionaryRef)keychainQuery, (CFTypeRef *)&keyData) == noErr) {  
    30.         @try {  
    31.             ret = [NSKeyedUnarchiver unarchiveObjectWithData:(__bridge_transfer NSData *)keyData];  
    32.         } @catch (NSException *e) {  
    33.             NSLog(@"Unarchive of %@ failed: %@", service, e);  
    34.         } @finally {  
    35.         }  
    36.     }  
    37.     return ret;  
    38. }  
    39.   
    40. + (void)delete:(NSString *)service {  
    41.     NSMutableDictionary *keychainQuery = [self getKeychainQuery:service];  
    42.     SecItemDelete((__bridge_retained CFDictionaryRef)keychainQuery);  
    43. }  
    44. @end  
    45. 使用
    46. static NSString * const KEY_IN_KEYCHAIN = @"com.wuqian.app.allinfo";  
    47. static NSString * const KEY_PASSWORD = @"com.wuqian.app.password";  
    48.   
    49. +(void)savePassWord:(NSString *)password  
    50. {  
    51.     NSMutableDictionary *usernamepasswordKVPairs = [NSMutableDictionary dictionary];  
    52.     [usernamepasswordKVPairs setObject:password forKey:KEY_PASSWORD];  
    53.     [WQKeyChain save:KEY_IN_KEYCHAIN data:usernamepasswordKVPairs];  
    54. }  
    55.   
    56. +(id)readPassWord  
    57. {  
    58.     NSMutableDictionary *usernamepasswordKVPair = (NSMutableDictionary *)[WQKeyChain load:KEY_IN_KEYCHAIN];  
    59.     return [usernamepasswordKVPair objectForKey:KEY_PASSWORD];  
    60. }  
    61.   
    62. +(void)deletePassWord  
    63. {  
    64.     [WQKeyChain delete:KEY_IN_KEYCHAIN]; 

    2.对象归档

    归档”是值另一种形式的序列化,对模型对象进 行归档的技术可以轻松将复杂的对象写入文件, 然后再从中读取它们.

      首先看一下简单字符串的归档

      保存

     
        NSArray * paths=NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask,YES);
        
        NSString * myDocumentPath=[paths objectAtIndex:0];
        
        NSString * filename=[myDocumentPath stringByAppendingPathComponent:@"myDefault.txt"];
        NSMutableData *data=[NSMutableData data];
        NSKeyedArchiver * keyarchive=[[NSKeyedArchiver alloc] initForWritingWithMutableData:data];
        if (![self.name isEqualToString:@""] &&![self.number isEqualToString:@""]) {
            
            [keyarchive encodeObject:self.name forKey:@"name"];
            [keyarchive encodeObject:self.number forKey:@"number"];
            [keyarchive finishEncoding];
            [data writeToFile:filename atomically:YES];
            [keyarchive release];
            
        }

       读取

     NSArray * paths=NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask,YES);
        
        NSString * myDocumentPath=[paths objectAtIndex:0];
        
        NSString * filename=[myDocumentPath stringByAppendingPathComponent:@"myDefault.txt"];
        NSMutableData *data=[NSMutableData data];
        data=[NSData dataWithContentsOfFile:filename];
        if (data.length>0) {
            NSKeyedUnarchiver *keyarchive=[[NSKeyedUnarchiver alloc] initForReadingWithData:data];
            self.shoujianren.text=(NSString *)[keyarchive decodeObjectForKey:@"name"];
            self.name=(NSString *)[keyarchive decodeObjectForKey:@"name"];
            self.number=(NSString *)[keyarchive decodeObjectForKey:@"number"];
            [keyarchive finishDecoding];
            [keyarchive release];
        }

    如果这里保存的是一个对象,为了保证对象的独立性不能直接保存,要复制一个保存进去。这时候要用到

    两个协议 NSCopying NSCoding

    把一个学生的的信息保存到文件里

    1.首先要有一类,实现以上两个协议

    #import <Foundation/Foundation.h>

    @interface Student : NSObject<NSCoding,NSCopying>
    {
        NSString *stunumber;
        NSString *stuname;
        NSString *stumyclass;

    }
    @property (nonatomic,copy)NSString *stunumber;
    @property (nonatomic,copy)NSString *stuname;
    @property (nonatomic,copy)NSString *stumyclass;

    @end

    重写协议里的方法

    #import "Student.h"

    @implementation Student
    @synthesize stuname;
    @synthesize stunumber;
    @synthesize stumyclass;

    - (void)encodeWithCoder:(NSCoder *)aCoder{
        [aCoder encodeObject:self.stumyclass forKey:@"stumyclass"];
        [aCoder encodeObject:self.stuname forKey:@"stuname"];
        [aCoder encodeObject:self.stunumber forKey:@"stunumber"];
     

    }
    - (id)initWithCoder:(NSCoder *)aDecoder{
        self.stumyclass=[aDecoder decodeObjectForKey:@"stumyclass"];
        self.stuname=[aDecoder decodeObjectForKey:@"stuname"];
        self.stunumber=[aDecoder decodeObjectForKey:@"stunumber"];
        return  self;

    }
    - (id)copyWithZone:(NSZone *)zone{
        Student * copy=[[[self class] allocWithZone:zone] init];
        copy.stuname=[self.stuname copyWithZone:zone];
        copy.stumyclass=[self.stumyclass copyWithZone:zone];
        copy.stunumber=[self.stunumber copyWithZone: zone];
        return  copy;


    }
    @end

    开始调用

    - (IBAction)savewithencdoing:(id)sender {
        

        NSString *mydocumentPath=[[NSBundle mainBundle] bundlePath];
        NSString  * mydocument=[mydocumentPath stringByAppendingPathComponent:@"student.archive"];
        NSMutableData * data=[NSMutableData  data];
        //文件缓冲
        NSKeyedArchiver *keyarchive=[[NSKeyedArchiver alloc] initForWritingWithMutableData:data];
        Student *stu=[[Student alloc] init];
        stu.stumyclass=self.myClass.text;
        stu.stuname=self.myName.text;
        stu.stunumber=self.myNumber.text;
        Student *mystu=[stu copy];   //这时候会调用协议里的copyWithZone:(NSZone *)zone 方法
        [keyarchive encodeObject:mystu forKey:@"mystu"];//这时候会调用encodeWithCoder:(NSCoder *)aCoder
        [keyarchive finishEncoding];
        [data writeToFile:mydocument atomically:YES];
        [stu release];
        [keyarchive release];
     
        
    }

    读取

    - (IBAction)loadingwithencoding:(id)sender {
     
    //    NSArray *paths=NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    //    NSString *mydocumentPath=[paths objectAtIndex:0];
        //NSString *mydocumentPath=NSTemporaryDirectory();
        NSString *mydocumentPath=[[NSBundle mainBundle] bundlePath];
        NSString  * mydocument=[mydocumentPath stringByAppendingPathComponent:@"student.archive"];
        NSMutableData * data=[NSMutableData  data];
        data=[NSData dataWithContentsOfFile:mydocument];
        if(data.length>0){
            NSKeyedUnarchiver *keyarchive=[[NSKeyedUnarchiver alloc] initForReadingWithData:data];
            Student * stu=[[[Student alloc] init] autorelease];
            stu=(Student*)[keyarchive decodeObjectForKey:@"mystu"];
            self.myNumber.text=stu.stunumber;
            self.myName.text=stu.stuname;
            self.myClass.text=stu.stumyclass;
            [keyarchive finishDecoding];
            [keyarchive release];
            //[stu release];
            
            
        }
    }

  • 相关阅读:
    Zabbix学习
    Ping 不通的原因分析
    【FAQ】P3. 为什么 torch.cuda.is_available() 是 False
    【PyTorch教程】P2. Python编辑器的选择、安装及配置
    PyTorch环境配置及安装
    更改文件夹图标
    卸载OpenIV
    一次写文,多平台直接粘贴&打造最流畅的写作流程
    Python字符串中删除特定字符
    Python字符串中添加、插入特定字符
  • 原文地址:https://www.cnblogs.com/jinjiantong/p/2973030.html
Copyright © 2011-2022 走看看