无法使用SQLITE3将Xcode数据添加到数据库

时间:2013-08-15 18:24:39

标签: iphone ios xcode sqlite xcode4.6

我对Xcode和Sqlite3有点新,并且已经遵循了许多教程并花费了无数个小时的时间,但仍然坚持使用我正在尝试创建的简单iPhone应用程序添加到数据库。该应用程序有一个表单,其中包含用于文本输入的文本字段,我想将其保存到数据库中。我的故事板包含两个输入字段和一个按钮(“AddEvalFormButton”)。

这就是:

  1. 我确保重置模拟器,然后运行应用程序。一旦我按下前面屏幕中的按钮就会崩溃,以获得评估表单页面(我假设ViewDidLoad出了问题,但不确定)。但是,控制台说:“你能够创建一个数据库”。 (我也有一个CreateOrOpenDB断点(见下面的代码):0x1e4df:movl -12(%ebp),%edx< - 这对我来说完全是胡说八道;任何关于如何使用这些信息的想法都将受到赞赏)。

  2. 我关闭iOS模拟器并再次运行,这一次,它在打开表单屏幕时不会崩溃。我能够将数据输入到文本字段中,但是当我点击AddEvalFormButton按钮时应用程序崩溃了。这次控制台中没有消息。

  3. 问题:

    • app崩溃了,我不知道为什么

    • 没有保存数据:我检查终端,发现没有表格添加到我的数据库中。

    就我而言(如果我错了请纠正我),我有两个目录:

    1)我的Xcode项目

    2)用户/媒体库/应用程序支持/ iPhone模拟器

    我有4个文件:EvaluationFormViewController.h,EvaluationFormViewController.m,EvalForm.h和EvalForm.m。它们如下所示:

    EvaluationFormViewController.h:

    #import <UIKit/UIKit.h>
    #import "sqlite3.h"
    #import "EvalForm.h"
    
    @interface EvaluationViewController : UIViewController <UIActionSheetDelegate, UITableViewDataSource, UITextFieldDelegate, UITextViewDelegate, UITableViewDelegate>
    
    @property (weak, nonatomic) IBOutlet UIScrollView *scrollView;
    @property (weak, nonatomic) IBOutlet UITextField *efq1Field;
    @property (weak, nonatomic) IBOutlet UITextField *efq2Field;
    
    - (IBAction)backgroundTouched:(id)sender;
    - (IBAction)textfieldReturn:(id)sender;
    - (IBAction)addEvalFormButton:(id)sender;
    
    @end
    

    EvaluationFormViewController.m:

    #import "EvaluationViewController.h"
    
    @interface EvaluationViewController ()
    {
        NSMutableArray *arrayOfEvalFormQs;
        sqlite3 *evalFormDB;
        NSString *dbPathString;
    }
    @property (nonatomic, readonly) CGPoint originalOffset;
    @property (nonatomic, readonly) UIView *activeField;
    @end
    
    @implementation EvaluationViewController
    
    @synthesize efq1Field, efq2Field;
    
    
    //FROM TUTORIAL Cocoa W/Love; need the following instance variables
    CGFloat animatedDistance;
    //FROM TUTORIAL Cocoa W/Love; need the following instance constants
    static const CGFloat KEYBOARD_ANIMATION_DURATION = 0.3;
    static const CGFloat MINIMUM_SCROLL_FRACTION = 0.2;
    static const CGFloat MAXIMUM_SCROLL_FRACTION = 0.8;
    static const CGFloat PORTRAIT_KEYBOARD_HEIGHT = 216;
    static const CGFloat LANDSCAPE_KEYBOARD_HEIGHT = 162;
    
    - (IBAction)backgroundTouched:(id)sender {
        [efq1Field resignFirstResponder];
        [efq2Field resignFirstResponder];
    }
    
    //dismisses the keyboard when the return/done button is pressed for TextFields.
    - (BOOL)textFieldShouldReturn:(UITextField *)textField
    {
        [textField resignFirstResponder];
        return YES;
    }
    //dismisses the keyboard when the return/done button is pressed for TextViews.
    - (BOOL)textViewShouldReturn:(UITextView *)textView
    {
        [textView resignFirstResponder];
        return YES;
    }
    
    
    //FROM TUTORIAL: www.cocoawithlove.com/2008/10/sliding-uitextfields-around-to-avoid.html
    
    //Animate upwards when the text field is selected
    //Get the rects of the text field being edited and the view that we're going to scroll. We convert everything to window coordinates, since they're not necessarily in the same coordinate space.
    - (void)textFieldDidBeginEditing:(UITextField *)textField
    {
        CGRect textFieldRect =
        [self.view.window convertRect:textField.bounds fromView:textField];
        CGRect viewRect =
        [self.view.window convertRect:self.view.bounds fromView:self.view];
    
        //So now we have the bounds, we need to calculate the fraction between the top and bottom of the middle section for the text field's midline:
        CGFloat midline = textFieldRect.origin.y + 0.5 * textFieldRect.size.height;
        CGFloat numerator =
        midline - viewRect.origin.y
        - MINIMUM_SCROLL_FRACTION * viewRect.size.height;
        CGFloat denominator =
        (MAXIMUM_SCROLL_FRACTION - MINIMUM_SCROLL_FRACTION)
        * viewRect.size.height;
        CGFloat heightFraction = numerator / denominator;
    
    
        //Clamp this fraction so that the top section is all "0.0" and the bottom section is all "1.0".
        if (heightFraction < 0.0)
        {
            heightFraction = 0.0;
        }
        else if (heightFraction > 1.0)
        {
            heightFraction = 1.0;
        }
    
    
        //Now take this fraction and convert it into an amount to scroll by multiplying by the keyboard height for the current screen orientation. Notice the calls to floor so that we only scroll by whole pixel amounts.
        UIInterfaceOrientation orientation =
        [[UIApplication sharedApplication] statusBarOrientation];
        if (orientation == UIInterfaceOrientationPortrait ||
            orientation == UIInterfaceOrientationPortraitUpsideDown)
        {
            animatedDistance = floor(PORTRAIT_KEYBOARD_HEIGHT * heightFraction);
        }
        else
        {
            animatedDistance = floor(LANDSCAPE_KEYBOARD_HEIGHT * heightFraction);
        }
    
    
        //Finally, apply the animation. Note the use of setAnimationBeginsFromCurrentState: — this will allow a smooth transition to new text field if the user taps on another.
        CGRect viewFrame = self.view.frame;
        viewFrame.origin.y -= animatedDistance;
    
        [UIView beginAnimations:nil context:NULL];
        [UIView setAnimationBeginsFromCurrentState:YES];
        [UIView setAnimationDuration:KEYBOARD_ANIMATION_DURATION];
    
        [self.view setFrame:viewFrame];
    
        [UIView commitAnimations];
    }
    
    
    //ANIMATE BACK AGAIN:  The return animation is far simpler since we've saved the amount to animate.
    - (void)textFieldDidEndEditing:(UITextField *)textField
    {
        CGRect viewFrame = self.view.frame;
        viewFrame.origin.y += animatedDistance;
    
        [UIView beginAnimations:nil context:NULL];
        [UIView setAnimationBeginsFromCurrentState:YES];
        [UIView setAnimationDuration:KEYBOARD_ANIMATION_DURATION];
    
        [self.view setFrame:viewFrame];
    
        [UIView commitAnimations];
    }
    
    //SAME CODE AS ABOVE, BUT FOR TEXTVIEW
    //FROM TUTORIAL: www.cocoawithlove.com/2008/10/sliding-uitextfields-around-to-avoid.html
    
    //Animate upwards when the text field is selected
    //Get the rects of the text field being edited and the view that we're going to scroll. We convert everything to window coordinates, since they're not necessarily in the same coordinate space.
    - (void)textViewDidBeginEditing:(UITextView *)textView
    {
        CGRect textFieldRect =
        [self.view.window convertRect:textView.bounds fromView:textView];
        CGRect viewRect =
        [self.view.window convertRect:self.view.bounds fromView:self.view];
    
        //So now we have the bounds, we need to calculate the fraction between the top and bottom of the middle section for the text field's midline:
        CGFloat midline = textFieldRect.origin.y + 0.5 * textFieldRect.size.height;
        CGFloat numerator =
        midline - viewRect.origin.y
        - MINIMUM_SCROLL_FRACTION * viewRect.size.height;
        CGFloat denominator =
        (MAXIMUM_SCROLL_FRACTION - MINIMUM_SCROLL_FRACTION)
        * viewRect.size.height;
        CGFloat heightFraction = numerator / denominator;
    
    
        //Clamp this fraction so that the top section is all "0.0" and the bottom section is all "1.0".
        if (heightFraction < 0.0)
        {
            heightFraction = 0.0;
        }
        else if (heightFraction > 1.0)
        {
            heightFraction = 1.0;
        }
    
    
        //Now take this fraction and convert it into an amount to scroll by multiplying by the keyboard height for the current screen orientation. Notice the calls to floor so that we only scroll by whole pixel amounts.
        UIInterfaceOrientation orientation =
        [[UIApplication sharedApplication] statusBarOrientation];
        if (orientation == UIInterfaceOrientationPortrait ||
            orientation == UIInterfaceOrientationPortraitUpsideDown)
        {
            animatedDistance = floor(PORTRAIT_KEYBOARD_HEIGHT * heightFraction);
        }
        else
        {
            animatedDistance = floor(LANDSCAPE_KEYBOARD_HEIGHT * heightFraction);
        }
    
        //Finally, apply the animation. Note the use of setAnimationBeginsFromCurrentState: — this will allow a smooth transition to new text field if the user taps on another.
        CGRect viewFrame = self.view.frame;
        viewFrame.origin.y -= animatedDistance;
    
        [UIView beginAnimations:nil context:NULL];
        [UIView setAnimationBeginsFromCurrentState:YES];
        [UIView setAnimationDuration:KEYBOARD_ANIMATION_DURATION];
    
        [self.view setFrame:viewFrame];
    
        [UIView commitAnimations];
    }
    
    
    //ANIMATE BACK AGAIN:  The return animation is far simpler since we've saved the amount to animate.
    - (void)textViewDidEndEditing:(UITextView *)textView
    {
        CGRect viewFrame = self.view.frame;
        viewFrame.origin.y += animatedDistance;
    
        [UIView beginAnimations:nil context:NULL];
        [UIView setAnimationBeginsFromCurrentState:YES];
        [UIView setAnimationDuration:KEYBOARD_ANIMATION_DURATION];
    
        [self.view setFrame:viewFrame];
    
        [UIView commitAnimations];
    }
    
    
    /**Keyboard dismissed when background is clicked or when return is hit**/
    - (IBAction)textfieldReturn:(id)sender{
        [sender resignFirstResponder];
    }
    
    - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
    {
        self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
        if (self) {
            // Custom initialization
        }
        return self;
    }
    
    
    - (void) viewWillDisappear: (BOOL)animated{
    
        [super viewWillDisappear:animated];
    
        NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
        [nc removeObserver:self name: UIKeyboardWillShowNotification object:nil];
        [nc removeObserver:self name: UIKeyboardWillHideNotification object:nil];
    }
    
    - (void)viewWillAppear:(BOOL)animated
    {
        [[self view] setBackgroundColor:[UIColor colorWithPatternImage:[UIImage imageNamed:@"136676912132100.gif"]]];
    
    }
    
    
    //RELEVANT CODE FOR SQLITE ISSUE BELOW:
    - (void)viewDidLoad
    {
        [super viewDidLoad];
    
        //relating to sqlite:
        arrayOfEvalFormQs = [[NSMutableArray alloc]init];
        [self createOrOpenDB];
    
    }
    
    - (void)createOrOpenDB
    {
        NSArray *path = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
        NSString *docPath = [path objectAtIndex:0];
    
        dbPathString = [docPath stringByAppendingPathComponent:@"evalForm.db"];   
        char *error;
    
        NSFileManager *fileManager = [NSFileManager defaultManager];
        if (![fileManager fileExistsAtPath:dbPathString]) {
            const char *dbPath = [dbPathString UTF8String];
    
            //creat db here
            if (sqlite3_open(dbPath, &evalFormDB)==SQLITE_OK) {
                const char *sql_stmt = "CREATE TABLE IF NOT EXISTS EVALFORMDB (ID INTEGER PRIMARY KEY AUTOINCREMENT, EFQ1 TEXT, EFQ2 TEXT)";
                NSLog(@"You were able to create DB");
                sqlite3_exec(evalFormDB, sql_stmt, NULL, NULL, &error);
                sqlite3_close(evalFormDB);
            }
            else {
                NSLog(@"Problem with createopenDB");
            }
        }
    }
    
    - (IBAction)addEvalFormButton:(id)sender {
        char *error;
        if (sqlite3_open([dbPathString UTF8String], &evalFormDB)==SQLITE_OK) {
            NSString *inserStmt = [NSString stringWithFormat:@"INSERT INTO EVALFORM(EFQ1,EFQ2) values ('%s', '%s')",[self.efq1Field.text UTF8String], [self.efq2Field.text UTF8String]];
            NSLog(@"I am in the loop");
    
            const char *insert_stmt = [inserStmt UTF8String];
    
            if (sqlite3_exec(evalFormDB, insert_stmt, NULL, NULL, &error)==SQLITE_OK) {   
                NSLog(@"Answer added");
    
                //not really sure what this does:
                EvalForm *evalForm = [[EvalForm alloc]init];
                [evalForm setEfq1:self.efq1Field.text];
                [evalForm setEfq2:self.efq2Field.text];
                [arrayOfEvalFormQs addObject:evalForm];
            }
            else{
                NSLog(@"Answer not added");
            }
            sqlite3_close(evalFormDB);
        }
    }
    
    @end
    

    EvalForm.h:

    #import <Foundation/Foundation.h>
    
    @interface EvalForm : NSObject
    
    @property(nonatomic, strong)NSString *efq1;
    @property(nonatomic, strong)NSString *efq2;
    
    @end
    

    EvalForm.m:

    #import "EvalForm.h"
    
    @implementation EvalForm
    
    @end
    

    我尝试过尽可能多的信息(可能是矫枉过正,我的道歉)。就像我刚才提到的,我还是Xcode和SQLite的新手,所以我不确定我是否忽略了我的代码中的基本内容。关于我的代码无法正常工作的任何输入都将非常感激。

0 个答案:

没有答案