我想將自定義類MCOIMAPSession
對象存儲到sqlite3數據庫中。我閱讀了大約NSKeyedArchiver
並嘗試使用下面的內容。在Sqlite3數據庫中存儲自定義類對象失敗
- (void) updateImapSessionForAccount :(NSString *) emailAddress :(MCOIMAPSession *)imapSession {
const char *dbpath = [databasePath UTF8String];
//SQLIte Statement
NSString *selettablequery = [NSString stringWithFormat:@"select * from MailBoxInfoDBTable"];
if (sqlite3_open(dbpath, &database) == SQLITE_OK)
{
//if(sqlite3_prepare_v2(database, [selettablequery UTF8String], -1, &statement, NULL) == SQLITE_OK)
if (sqlite3_prepare(database, [selettablequery UTF8String], -1, &statement, NULL) ==SQLITE_OK)
{
// Take an array to store all string.
//NSMutableArray *allRows = [[NSMutableArray alloc] init];
while(sqlite3_step(statement) == SQLITE_ROW)
{
char *emailfield = (char *) sqlite3_column_text(statement,0);
NSString *emailStr = [[NSString alloc] initWithUTF8String: emailfield];
NSLog(@"updateMailMessagesPerAccount: %@", emailStr);
if([emailStr isEqualToString:emailAddress])
{
sqlite3_reset(statement);
NSData *messagesData = [NSKeyedArchiver archivedDataWithRootObject:imapSession];
NSString* stringFromData = [messagesData base64EncodedStringWithOptions:0];
NSString *sqlStr = [NSString stringWithFormat:@"update MailBoxInfoDBTable set imapsession='%@' where emailid='%@'", stringFromData, emailAddress];
const char *updateStatement = [sqlStr UTF8String];
if (sqlite3_prepare(database, updateStatement, -1, &statement, NULL) == SQLITE_OK)
{
if(SQLITE_DONE != sqlite3_step(statement))
NSLog(@"Error while updating. %s", sqlite3_errmsg(database));
sqlite3_finalize(statement);
sqlite3_close(database);
return;
}
else
{
NSLog(@"Error in statement: %s", sqlite3_errmsg(database));
}
}
}
}
sqlite3_finalize(statement);
sqlite3_close(database);
}
}
- (MCOIMAPSession *) retrieveImapSessionForAccount :(NSString *) emailAddress {
MCOIMAPSession *imapsessionObj = nil;
const char *dbpath = [databasePath UTF8String];
//SQLIte Statement
NSString *selettablequery = [NSString stringWithFormat:@"select * from MailBoxInfoDBTable"];
if (sqlite3_open(dbpath, &database) == SQLITE_OK)
{
//if(sqlite3_prepare_v2(database, [selettablequery UTF8String], -1, &statement, NULL) == SQLITE_OK)
if (sqlite3_prepare(database, [selettablequery UTF8String], -1, &statement, NULL) ==SQLITE_OK)
{
// Take an array to store all string.
//NSMutableArray *allRows = [[NSMutableArray alloc] init];
while(sqlite3_step(statement) == SQLITE_ROW)
{
char *emailfield = (char *) sqlite3_column_text(statement, 0);
NSString *emailStr = [[NSString alloc] initWithUTF8String: emailfield];
NSLog(@"retrieveImapSessionForAccount: Email: %@", emailStr);
if([emailStr isEqualToString:emailAddress])
{
//const void *bytes = sqlite3_column_blob(statement, 3);
char *emailstring = (char *) sqlite3_column_text(statement, 3);
if (emailstring) {
NSString *messageStr = [[NSString alloc] initWithUTF8String: emailstring];
NSData *data = [[NSData alloc] initWithBase64EncodedString:messageStr options:NSDataBase64DecodingIgnoreUnknownCharacters];
imapsessionObj = [NSKeyedUnarchiver unarchiveObjectWithData:data];
}
}
}
}
sqlite3_finalize(statement);
sqlite3_close(database);
}
return imapsessionObj;
}
我做NSKeyedArchiver archivedDataWithRootObject:imapSession
然後當了崩潰encodeWithCoder unrecognized selector sent to instance
,我加入了第三方類MCOIMAPSession.mm
文件
- (void)encodeWithCoder:(NSCoder *)aCoder{
[aCoder encodeObject:self forKey:@"PROPERTY_KEY"];
}
-(id)initWithCoder:(NSCoder *)aDecoder{
if(self = [super init]){
self = [aDecoder decodeObjectForKey:@"PROPERTY_KEY"];
}
return self;
}
更新了以下方法:我嘗試了以下爲好。
@interface MCOIMAPSession : NSObject
....
@end
@interface NSObject (NSCoding)
-(id)initWithCoder:(NSCoder*)decoder;
-(void)encodeWithCoder:(NSCoder*)encoder;
@end
#endif
@implementation MCOIMAPSession
-(id)initWithCoder:(NSCoder *)decoder {
if ((self=[super initWithCoder:decoder])) {
}
return self;
}
@end
@implementation NSObject (NSCoding)
-(id)initWithCoder:(NSCoder*)decoder {
return [self init];
}
-(void)encodeWithCoder:(NSCoder*)encoder {}
@end
這裏是MCOIMAPSESSION MCOIMAPSESSION link的文件。請讓我知道我怎麼可以現在添加屬性?
但是,我看到仍然一樣的崩潰。在sqlite數據庫中存儲自定義類MCOIMAPSession
對象時,有人能糾正我在這裏做錯了什麼嗎?
我不打算存儲在NSUserDefaults中,所以我沒有設置屬性。我試圖在Sqlite數據庫中存儲MCOIMAPSession。我如何在這種情況下使用encodeWithCoder? – user1953977
NSUserDefaults和Sqlite非常相似。他們都只接受特定類型的數據。像'MCOIMAPSession'這樣的自定義類必須被編碼爲二進制數據。這就是'NSKeyedArchiver'所做的。 'encodeWithCoder'方法用於編碼諸如'host','port''用戶名之類的屬性。互補方法'initWithCoder'是一種'initWithArguments',並創建一個新的'MCOIMAPSession'對象,將這些值分配給相應的屬性。如果'MCOIMAPSession'不符合NSCoding協議,則必須添加一個提供NSCoding方法的類別 – vadian
我無法使用NSUserDefaults,因爲在我的應用程序中動態創建了多個MCOIMAPSession對象。 NSUserDefaults鍵是靜態的。 – user1953977