Я хочу сохранить объект класса 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;
}
я получил аварию encodeWithCoder unrecognized selector sent to instance
при выполнении NSKeyedArchiver archivedDataWithRootObject:imapSession
Затем я добавил следующие методы 3-го класса партии 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 .. Пожалуйста, дайте мне знать, как я могу добавить недвижимость сейчас?
Но, я вижу, все тот же крах. Может ли кто-то исправить меня, что я делаю неправильно здесь, когда храня пользовательский класс MCOIMAPSession
объект в базе данных sqlite?
Я не собираюсь хранить в NSUserDefaults, поэтому у меня нет свойства, чтобы установить там. Я пытаюсь сохранить MCOIMAPSession в Sqlite DB. Как я могу использовать encodeWithCoder в этом случае? – user1953977
NSUserDefaults и Sqlite очень похожи. Они оба принимают только данные конкретных типов. Пользовательские классы, такие как 'MCOIMAPSession', должны быть закодированы для двоичных данных. Вот что делает NSKeyedArchiver. Метод encodeWithCoder используется для кодирования таких свойств, как 'host',' port' 'username'. Дополнительный метод 'initWithCoder' является своего рода' initWithArguments' и создает новый объект MCOIMAPSession, присваивающий значения соответствующим свойствам. Если 'MCOIMAPSession' не соответствует протоколу NSCoding, вы должны добавить категорию, предоставляющую методы NSCoding. – vadian
Я не могу использовать NSUserDefaults, так как в моем приложении динамически создаются несколько объектов MCOIMAPSession. Ключ NSUserDefaults является статическим. – user1953977