将UISwitch状态保存到sqlite数据库并访问它以进行显示

时间:2012-03-06 12:14:22

标签: iphone sqlite save state uiswitch

我有一个包含文本字段,textView和2个开关的表单。现在我使用sqlite数据库将数据保存到数据库中。文本字段,文本视图保存,检索甚至显示已保存的东西都很好。我们知道我们没有任何称为复选框的功能,我们需要使用行为/作为复选框功能的开关。现在将开关状态保存到数据库中。我将其保存为字符串/仅限文本格式,即检查开关的状态,为ON指定值为'1',为OFF指定为'0'整数。现在你可能会有点困惑如何将整数保存为字符串格式,是的你是对的!我正在转换int值到number,最后是number到string。然后我形成了查询并将值插入到sqlite数据库表中。 以下是清晰理解的代码片段:

int smsValue = 0;

    if ([smsSwitch isOn])
    {
        smsValue = 1;
    }

    else
    {
        smsValue = 0;
    }

    NSNumber *smsNum = [NSNumber numberWithInt:smsValue];
    NSString *selectedVal = [smsNum stringValue];

selectedVal是我们在形成查询时将作为字符串传递的内容,我也发现状态正在被正确保存,即。价值是正确的。

现在我有了一个要求,在我的表单中我切换了短信,最初该开关的状态为Off,在关闭状态期间,最后2个字段即textField和textView被隐藏。如果用户选择它(即状态)是ON),然后两个字段都打开以输入值。

我总共保存了3个提醒,其中我已经保存了2个短信和1个短信以及两个字段(最后一个)填充。现在可以传递数据,或者在填写表格后跟踪保存的记录我使用了一个模型类,请看下面的代码片段以便清楚地了解...我如何传递其他字段的值(textFields):

-(void)viewDidLoad
{
    textField.text = reminderInstance.Name;
    textField1.text = reminderInstance.Event;
    textField2.text = reminderInstance.Date;
    textField3.text = reminderInstance.numDays;
    textField4.text = reminderInstance.remGroup;

    [super viewDidLoad];
}

这里的reminderInstance是模型类的对象,包含名称,事件,日期等值...现在最后2个字段即textField5和textView被绑定或链接到sms switch的状态。如果选中它我们需要考虑这两个字段值并传递给用户进行编辑/更改。如果不是我们不需要打扰最后两个字段。

以下是切换操作:

-(IBAction)toggleEnabledForswitch:(id)sender
{
    if(smsSwitch.on)
    {
        textField5.hidden = NO;
        textView.hidden = NO;
    }

    else 
    {
        textField5.hidden = YES;
        textView.hidden = YES;
    }
}

现在在保存操作中,我正在检查交换机的状态并相应地保存值,以下代码片段将显示清晰的图片:

-(IBAction)save:(id)sender
{
int smsValue = 0;

    if ([smsSwitch isOn])
    {
        smsValue = 1;
    }

    else
    {
        smsValue = 0;
    }

    NSNumber *smsNum = [NSNumber numberWithInt:smsValue];
    NSString *selectedVal = [smsNum stringValue];

    reminderInstance.smsString = selectedVal;
sqlite3_stmt *statement = nil;
    const char *dbpath = [databasePath UTF8String];

    if (sqlite3_open(dbpath, &remindersDB) == SQLITE_OK && textField.text != nil)
    {
      if (self.navigationItem.rightBarButtonItem.title == @"Save" && [textField.text length] !=0 && [textField1.text length] !=0 && [textField2.text length] !=0 && [textField3.text length] !=0 && [textField4.text length] !=0)
       {
            NSLog(@"am in the save loop");

            if (smsValue == 0)
            {
                NSString *insertSQL = [NSString stringWithFormat:@"INSERT INTO reminders(name,event,date,bfr,grp,val,sms) VALUES (\"%@\", \"%@\", \"%@\", \"%@\", \"%@\", \"%@\", \"%@\")", textField.text, textField1.text,textField2.text,textField3.text,textField4.text,isSelected,selectedVal]; 
                const char *insert_stmt = [insertSQL UTF8String];
                sqlite3_prepare_v2(remindersDB, insert_stmt, -1, &statement, NULL);
            }

            else if (smsValue == 1)
            {
                NSString *insertSQL = [NSString stringWithFormat:@"INSERT INTO reminders(name,event,date,bfr,grp,val,sms,num,bod) VALUES (\"%@\", \"%@\", \"%@\", \"%@\", \"%@\", \"%@\", \"%@\", \"%@\", \"%@\")", textField.text, textField1.text,textField2.text,textField3.text,textField4.text,isSelected,selectedVal,textField5.text,textView.text]; 
                textField5.text = reminderInstance.number;
                textView.text = reminderInstance.msgBody;
                const char *insert_stmt = [insertSQL UTF8String];
                sqlite3_prepare_v2(remindersDB, insert_stmt, -1, &statement, NULL);
            }

            if (sqlite3_step(statement) == SQLITE_DONE)
            {
                UIAlertView *alert = [[UIAlertView alloc]initWithTitle:@"\nReminder Saved" message:nil delegate:nil cancelButtonTitle:nil otherButtonTitles:nil,nil];
                [alert show];
                [alert dismissWithClickedButtonIndex:0 animated:YES];
                [alert release];
            }

            else 
            {
                UIAlertView *alert = [[UIAlertView alloc]initWithTitle:@"Alert" message:@"Reminder not saved" delegate:self cancelButtonTitle:@"Ok" otherButtonTitles:nil];
                [alert show];
                [alert release];
            }

        }
    }
 }

我带了另一个带有表视图的视图控制器,我已经填充了一个表视图来查看正在保存的所有记录,在选择后我们将他/她带到包含表单的控制器页面,即填充了所有值。所以我使用以下方法成功传递了所有值:

1.表格控制器页面中的以下代码:

-(id) initWithReminder:(ReminderClass *)aReminder 
{
    if ( (self=[super init]) ) 
    {
        self.reminderInstance = aReminder;
    }

    return self;
}

2.显示控制器中的以下代码部分:

-(void)loadReminders
{

    // setup the reminders array
    self.array = [[NSMutableArray alloc] init];

    //Retrieve the values of database
    const char *dbpath = [self.databasePath UTF8String];
    sqlite3_stmt *statement;
    if (sqlite3_open(dbpath, &remindersDB) == SQLITE_OK)
    {
        NSString *querySQL = [NSString stringWithFormat:@"SELECT * FROM reminders"];

        const char *query_stmt = [querySQL UTF8String];

        if (sqlite3_prepare_v2(self.remindersDB ,query_stmt , -1, &statement, NULL) == SQLITE_OK)
        {
            while (sqlite3_step(statement) == SQLITE_ROW)
            {
                ReminderClass *loadedReminder = [[ReminderClass alloc] init];

                loadedReminder.reminderID = sqlite3_column_int(statement, 0);

                loadedReminder.Name = [[[NSString alloc]initWithUTF8String:(const char *) sqlite3_column_text(statement, 1)]autorelease];                    

                loadedReminder.Event = [[[NSString alloc]initWithUTF8String:(const char *) sqlite3_column_text(statement, 2)]autorelease];

                loadedReminder.Date = [[[NSString alloc]initWithUTF8String:(const char *) sqlite3_column_text(statement, 3)]autorelease];

                loadedReminder.numDays = [[[NSString alloc]initWithUTF8String:(const char *) sqlite3_column_text(statement, 4)]autorelease];

                loadedReminder.remGroup = [[[NSString alloc]initWithUTF8String:(const char *) sqlite3_column_text(statement, 5)]autorelease];

                loadedReminder.selString = [[[NSString alloc]initWithUTF8String:(const char *) sqlite3_column_text(statement, 6)]autorelease];

                loadedReminder.smsString = [[[NSString alloc]initWithUTF8String:(const char *) sqlite3_column_text(statement, 7)]autorelease];

                NSLog(@"selected value = %@",loadedReminder.smsString);


                 loadedReminder.number = [[[NSString alloc]initWithUTF8String:(const char *) sqlite3_column_text(statement, 8)]autorelease];

                 loadedReminder.msgBody = [[[NSString alloc]initWithUTF8String:(const char *) sqlite3_column_text(statement, 9)]autorelease];


                NSDateFormatter *dateFormat = [[[NSDateFormatter alloc]init]autorelease]; 
                [dateFormat setDateFormat:@"yyyy-MM-dd HH:mm:ss"]; 
                NSDate *theDate = [dateFormat dateFromString:loadedReminder.Date];
                NSString *stringDate = [dateFormat stringFromDate:theDate];
                loadedReminder.Date = stringDate; 

                NSLog(@"Date = %@",loadedReminder.Date);

                [self.array addObject:loadedReminder];
                [loadedReminder release];
            } 

            sqlite3_finalize(statement);
        }
        sqlite3_close(self.remindersDB);
    }

}

现在发生了什么,因为我在显示控制器中有表视图,其中包含2个包含字段,除了链接到短信状态和填充所有字段的字段。当我选择视图控制器时它崩溃在“ loadedReminder.number “:

*由于未捕获的异常'NSInvalidArgumentException'而终止应用程序,原因:'* - [NSPlaceholderString initWithUTF8String:]:NULL cString'

当我删除 loadedReminder.number loadedReminder.msgBody 时,我们可以查看表(控制器页面)没有崩溃问题,所以有什么...选择表查看单元格我正在执行以下操作:

-(void)tableView:(UITableView *)atableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{

    ReminderClass *rem = [self.array objectAtIndex:indexPath.section];

    // Instantiate your detail/editor view controller,
    // and pass in the ReminderClass object to be edited.
    ERAddReminderViewController *rdvc = [[[ERAddReminderViewController alloc]initWithReminder:rem]autorelease];

    [self.navigationController pushViewController:rdvc animated:YES];
    rdvc.navigationItem.rightBarButtonItem.title = @"Edit";
}

现在我可以看到字段中正确填充的所有值,除了switch的问题。因为它正确保存,但是开关始终处于关闭状态,状态设置为默认,正如我在填写表单时已经说过的那样并保存它(如果用户选择它并填充最后两个字段)以保存它(记录)。

很抱歉这个巨大的描述,只是想详细说明,以便任何人都可以理解我的问题,我已经做了几个searches。但无法完成任务

任何人都可以建议我如何在数据库中保存交换机状态,然后在从数据库sqlite加载记录时填充相同的内容。

提前感谢每一位:)

1 个答案:

答案 0 :(得分:0)

我找到了解决方案,即。使用NSString并分配字符串值,即添加到数组中的检索状态值。让我详细解释一下:

在Add Reminder页面中,取一个NSString,比如说currentState,现在回到查看保存的提醒的位置,取一个名为“stateValues”的数组,并将状态值添加到该数组,即:。

loadedReminder.smsState = [[[NSString alloc]initWithUTF8String:(const char *) sqlite3_column_text(statement, 7)]autorelease];

[stateValues addObject:loadedReminder.smsState];

现在在索引路径中选择行,我们在其中导航以添加提醒页面以进行编辑或修改提醒的现有值,请执行以下操作:

-(void)tableView:(UITableView *)atableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    ReminderClass *rem = [self.array objectAtIndex:indexPath.section];
    NSLog(@" switch state in did : %@",[stateValues objectAtIndex:indexPath.section]);
 ERAddReminderViewController *rdvc = [[[ERAddReminderViewController alloc]initWithReminder:rem]autorelease];
    rdvc.currentState = [stateValues objectAtIndex:indexPath.section];
}

我们已成功将值设置为当前状态,现在返回添加提醒页面以设置切换状态,即。在viewDidLoad方法中执行以下操作:

-(void)viewDidLoad
{

    if ([currentState isEqualToString:@"0"]) 
    {
        [smsSwitch setOn:NO animated:NO];
    }
    else if([currentState isEqualToString:@"1"])
    {
        [smsSwitch setOn:YES animated:YES];
    }
}

就是这样,我们现在通过适当访问为所有连续提醒保存的值来正确设置开关状态。

希望它有所帮助。谢谢!