在objective-c中归档对象内的对象

时间:2014-01-25 05:30:26

标签: objective-c object save nscoding nsarchiving

谢谢你的阅读,

PS:我是初学者,所以我不太擅长这个不幸,但任何帮助都会非常感激

所以基本上我想归档一个包含Account对象的大数组,它们自己包含:

  • 1.一个NSString形式的用户名,

  • 2.an加密密码数组,填充NSNumbers,

  • 3. 填充服务数据对象的数据数组。

服务数据对象具有以下内容:

    1. 加密的serviceType(NSArray填充NSNumbers)(用户名和密码用于的任何服务)
    1. 加密的用户名(NSArray填充NSNumbers)
    1. 加密密码(NSArray填充NSNumbers)

现在奇怪的是,在尝试存档并保存时,我收到两个错误。有一次它不会让我再将服务数据对象添加到Account类中的数据数组中,并显示以下错误消息(或者至少它们不会显示在我所拥有的NSTableView中,但它确实说它们是exsist):< / p>

[<ServiceData 0x60000023bfa0> valueForUndefinedKey:]: this class is not key value
coding-compliant for the key service.

和两个,当我尝试从Account类登录用户名和密码时,它会正确检索用户名和第一对以及最后一对NSNumbers的密码,但密码的其余NSNumbers是数万亿美元,所以我想知道出了什么问题,任何帮助都会非常感激。

这是我的实例变量的代码,我如何使用NSKeyedArchiver和unarchiver,以及我如何保存和加载文件。再次,请帮助我,我已经坚持了一段时间,这是我的最后一招。我不知道发生了什么!


帐户类:

H档:

@interface Account : NSObject <NSCoding>
{
@private
    NSString *username;
    NSMutableArray *password;
    NSMutableArray *accData;
}

@property NSString *username;
@property NSArray *password;

FULL M文件:

-(id)initWithCoder:(NSCoder *)aDecoder
{
    self = [super init];
    if(self)
    {
        username = [aDecoder decodeObjectForKey:@"username"];
        password = [aDecoder decodeObjectForKey:@"password"];
        accData = [aDecoder decodeObjectForKey:@"data"];
    }
    return self;
}

-(void)encodeWithCoder:(NSCoder *)aCoder
{
    [aCoder encodeObject:username forKey:@"username"];
    [aCoder encodeObject:password forKey:@"password"];
    [aCoder encodeObject:accData forKey:@"data"];
}

SERVICEDATA CLASS:

H档:

@interface ServiceData : NSObject <NSCoding>
{
@private
    NSArray* serviceData;
    NSArray* usernameData;
    NSArray* passwordData;
}

@property NSArray* serviceData; 
@property NSArray* usernameData;
@property NSArray* passwordData;

M档案:

#import "Account.h"
#import "Crypt.h"

NSMutableArray *accounts;
NSInteger accountNumber = -1;


@implementation Account

@synthesize username;
@synthesize password;

- (id)initWithUsername:(NSString *)name withPassword:(NSMutableArray *)key
{
    self = [super init];
    if (self)
    {
        username = name;
        password = key;
        accData = [[NSMutableArray alloc]init];
    }
    return self;
}


/*
setters and getters
*/

-(NSString*)getUsername;
{
    return username;
}
-(NSArray*)getPassword;
{
    return password;
}
-(void)changePassword:(NSMutableArray*)newPassword;
{
    NSInteger sizeOldPass = [password count];
    NSInteger sizeNewPass = [newPassword count];
    int changeXObjects = (int)(sizeNewPass - sizeOldPass);
    int changeSize = abs(changeXObjects);
    //adjusts size differences
    if (changeXObjects < 0)
    {
        for(int i = 0; i < changeSize; i++)
        {
            [password removeLastObject];
        }
    }
    else if (changeXObjects > 0)
    {
        for(int i = 0; i < changeSize; i++)
        {
            NSNumber *value = [NSNumber numberWithInt:0];
            [password addObject:value];
        }
    }

    //change password
    NSInteger sizePass = [password count];
    for (int k = 0; k < sizePass; k++)
    {
        [password replaceObjectAtIndex:k withObject:newPassword[k]];
    }
}

-(NSMutableArray*)getAccData;
{
    return accData;
}
-(void)setAccData:(NSMutableArray*)input
{
    [input setArray: accData];
}

+(NSMutableArray*)getAccounts
{
    return accounts;
}

+(NSInteger)getAccountNumber
{
    return accountNumber;
}

+(void)setAccounts:(id)accs
{
    accounts = accs;
}

+(void)setAccountNumber:(NSInteger)number
{
    accountNumber = number;
}


/*
other methods
*/

+(void)addAccount:(id)acc
{
    [accounts addObject:acc];
}
+(void)deleteAccount:(NSInteger)index
{
    [accounts removeObjectAtIndex:index];
}


-(void)addAccData:(id)input
{
    [accData addObject:input];
}

-(void)deleteAccDataAt:(NSInteger)index
{
    [accData removeObjectAtIndex:index];
}

+(bool)checkPassword:(NSString*)passwordIn accountNumber:(NSInteger)index
{
    NSMutableArray *passwordInputCrypt = [Crypt encrypt:passwordIn];
    NSMutableArray *passwordCrypt = [accounts[index] getPassword];

    NSInteger lengthPassword = [passwordInputCrypt count];

    bool correctPassword = true;
    if([passwordCrypt count] == [passwordInputCrypt count])
    {
        for(int i = 0; i < lengthPassword; i++)
        {
            if(passwordCrypt[i]!=passwordInputCrypt[i])
                correctPassword = false;
        }
    }
    else
    {
        correctPassword = false;
    }

    if(correctPassword == true)
    {
        return true;
    }
    return false;
}


-(id)initWithCoder:(NSCoder *)aDecoder
{
    self = [super init];
    if(self)
    {
        username = [aDecoder decodeObjectForKey:@"username"];
        password = [aDecoder decodeObjectForKey:@"password"];
        accData = [aDecoder decodeObjectForKey:@"data"];
    }
    return self;
}

-(void)encodeWithCoder:(NSCoder *)aCoder
{
    [aCoder encodeObject:username forKey:@"username"];
    [aCoder encodeObject:password forKey:@"password"];
    [aCoder encodeObject:accData forKey:@"data"];
}
@end

加载文件(给出filePath):

NSData *data = [[NSFileManager defaultManager] contentsAtPath:filePath];

if(data != nil)
{
    NSArray *arrayFromData = [NSKeyedUnarchiver unarchiveObjectWithData:data];
    NSMutableArray *initArray = [NSMutableArray arrayWithArray:arrayFromData];
    [Account setAccounts:initArray];
}
else
{
    NSMutableArray *accountsInit = [[NSMutableArray alloc] init];
    [Account setAccounts:accountsInit];
}

保存文件:

NSArray *accounts = [Account getAccounts];
NSString *filePath = [AppController getFilePath];
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:accounts];

[data writeToFile:filePath atomically:YES];

1 个答案:

答案 0 :(得分:0)

一些事情:

  1. 您不应将密码数据存档到磁盘(即使您正在加密它)。这就是钥匙链的用途。看看SSKeychain是否有一个好的包装类。
  2. 您获得的键值编码错误表明您尝试将serviceData数组引用为某个地方的“服务”。检查你的valueForKey和setValueForKey语句。
  3. 您可以发布帐户类的其余部分吗?该方法setAccounts看起来可能是相关的。

    还有一个原因是您使用密钥存档而不是核心数据吗?