美文网首页
SQLite 存储

SQLite 存储

作者: 小苗晓雪 | 来源:发表于2017-07-10 14:39 被阅读9次
效果图 Gif.gif

Contact.h

#import <Foundation/Foundation.h>
@interface Contact : NSObject

@property (nonatomic,assign)    int64_t     serialId;
@property (nonatomic,copy)      NSString    *name;
@property (nonatomic,copy)      NSString    *mobile;

@end

Contact.m

#import "Contact.h"

@implementation Contact

@end

AddContactViewController.h

#import <UIKit/UIKit.h>
#import "Contact.h"

@protocol AddContactDelegate <NSObject>

- (void)onAddContact:(Contact *)contact;

- (void)onCancel;

@end


@interface AddContactViewController : UIViewController

@property (nonatomic,weak)  id<AddContactDelegate>  delegate;

@end

AddContactViewController.m

#import "AddContactViewController.h"

@interface AddContactViewController ()

@property (weak, nonatomic) IBOutlet UITextField *nameTextfield;

@property (weak, nonatomic) IBOutlet UITextField *mobileTextfield;

@end

@implementation AddContactViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    self.title = @"添加联系人页面";
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}
- (IBAction)onCancel:(id)sender {
    if (_delegate && [_delegate respondsToSelector:@selector(onCancel)])
    {
        [_delegate onCancel];
    }
}

- (IBAction)onSave:(id)sender {
    NSString *name = _nameTextfield.text;
    NSString *mobile = _mobileTextfield.text;
    if ([name length] && [mobile length])
    {
        Contact *contact = [[Contact alloc] init];
        contact.name = name;
        contact.mobile = mobile;
        if (_delegate && [_delegate respondsToSelector:@selector(onAddContact:)])
        {
            [_delegate onAddContact:contact];
        }
    }
}

@end

ContactListTableViewController.h

#import <UIKit/UIKit.h>

@interface ContactListTableViewController : UITableViewController

@end

ContactListTableViewController.m

#import "ContactListTableViewController.h"
#import "AddContactViewController.h"
#import <sqlite3.h>


static NSString *contactReuseIdentifier = @"contactReuseIdentifier";


@interface ContactListTableViewController ()<AddContactDelegate,UISearchBarDelegate,UISearchResultsUpdating>

@property (nonatomic,strong)    UISearchController *searchViewController;
@property (nonatomic,copy)      NSMutableArray *contacts;
@property (nonatomic,copy)      NSArray *filteredContacts;
@property (nonatomic,assign)    BOOL shouldShowSearchResult;

@property (nonatomic, assign) sqlite3 *db;

@end

@implementation ContactListTableViewController

- (instancetype)init
{
    if (self = [super init])
    {
        _contacts = [NSMutableArray array];
    }
    return self;
}

- (void)viewDidLoad {
    [super viewDidLoad];
    [self setup];
    
    [self openDatabase];
    
    [self read];
    
}


- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
}


#pragma mark - <UITableViewDelegate>
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    [tableView deselectRowAtIndexPath:indexPath animated:YES];
}

#pragma mark - Table view data source

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    return self.shouldShowSearchResult ? [self.filteredContacts count] : [self.contacts count];
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:contactReuseIdentifier];
    if (cell == nil)
    {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle
                                      reuseIdentifier:contactReuseIdentifier];
    }
    Contact *contact = self.shouldShowSearchResult ? self.filteredContacts[indexPath.row] : self.contacts[indexPath.row];
    cell.textLabel.text = contact.name;
    cell.detailTextLabel.text = contact.mobile;
    
    return cell;
}

- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
    return self.shouldShowSearchResult == NO;   //搜索结果不做删除处理
}

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
    if (editingStyle == UITableViewCellEditingStyleDelete)
    {
        int64_t serialId = [self.contacts[indexPath.row] serialId];
        NSString *sql = @"delete from contacts where id = ?";
        sqlite3_stmt *stmt = NULL;
        if (sqlite3_prepare(_db, [sql UTF8String], -1, &stmt, NULL) == SQLITE_OK)
        {
            //绑定ID从1开始:
            sqlite3_bind_int64(stmt, 1, serialId);
            //执行:
            if (sqlite3_step(stmt) == SQLITE_DONE)
            {
                [self.contacts removeObjectAtIndex:indexPath.row];
                [self.tableView reloadData];
            }
            sqlite3_finalize(stmt);
        }
    }
}

#pragma mark - misc
- (void)setup
{
    self.title = @"联系人列表";
    self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"添加"
                                                                              style:UIBarButtonItemStylePlain
                                                                             target:self
                                                                             action:@selector(add:)];
    

    self.searchViewController = [[UISearchController alloc] initWithSearchResultsController:nil];
    self.searchViewController.searchBar.delegate = self;
    self.searchViewController.searchResultsUpdater = self;
    self.tableView.tableHeaderView = self.searchViewController.searchBar;
    
}

- (void)add:(id)sender
{
    AddContactViewController *vc = [[AddContactViewController alloc] init];
    vc.delegate = self;
    [self.navigationController pushViewController:vc animated:YES];
}

#pragma mark - store

/**
 *  获取一个 documents 文件夹下的文件名;
 
 */
- (NSString *)filepath
{
    NSString *documents = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
    return  [documents stringByAppendingPathComponent:@"contacts.db"];
}

#pragma mark - AddContactDelegate
- (void)onCancel
{
    [self.navigationController popViewControllerAnimated:YES];
}



- (void)onAddContact:(Contact *)contact
{
    //声明结构体指针:
    sqlite3_stmt *stmt = NULL;
    NSString *sql = @"insert into contacts(name , mobile) values(?,?)";
    //1.准备:
    if (sqlite3_prepare(_db, [sql UTF8String], -1, &stmt, NULL) == SQLITE_OK)
    {
        //2.绑定后续传入的参数
        //sqlite的 index 是从1开始的!!!
        sqlite3_bind_text(stmt, 1, [contact.name UTF8String], -1, NULL);
        sqlite3_bind_text(stmt, 2, [contact.mobile UTF8String], -1, NULL);
        
        //3.是否执行成功:
        if (sqlite3_step(stmt) == SQLITE_DONE)
        {
            contact.serialId = sqlite3_last_insert_rowid(_db);
            [self.contacts addObject:contact];
            [self.tableView reloadData];
        }
        //4.清理sql语句:
        sqlite3_finalize(stmt);
    }
    
    
    [self.navigationController popViewControllerAnimated:YES];
    

    //插入数据:
//    NSString *sql = [NSString stringWithFormat:@"insert into contacts(name , mobile) values('%@' , '%@')",contact.name , contact.mobile];
//    sqlite3_exec(_db, [sql UTF8String], NULL, NULL, NULL);
    
}

#pragma mark - search
- (void)searchBarTextDidBeginEditing:(UISearchBar *)searchBar
{
    self.shouldShowSearchResult = YES;
    self.filteredContacts = nil;
    [self.tableView reloadData];
}

- (void)searchBarTextDidEndEditing:(UISearchBar *)searchBar
{
    self.shouldShowSearchResult = NO;
    self.filteredContacts = nil;
    [self.tableView reloadData];
}

- (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar
{
    self.shouldShowSearchResult = NO;
    self.filteredContacts = nil;
    [self.tableView reloadData];
}

#pragma mark - 🔍🔍🔍🔍🔍
- (void)updateSearchResultsForSearchController:(UISearchController *)searchController
{
    NSString *text = searchController.searchBar.text;
    //将搜索的结果放到一个可变数组中保存:
    NSMutableArray *contacts = nil;
    if ([text length]) {
        //转换字符串:
        NSString *searchText = [NSString stringWithFormat:@"%%%@%%", text];
        contacts = [NSMutableArray array];
        sqlite3_stmt *stmt = NULL;
        //sql语句:
        NSString *sql = @"select * from contacts where name like ? or mobile like ?";
        
        if (sqlite3_prepare(_db, [sql UTF8String], -1, &stmt, NULL) == SQLITE_OK)
        {
            sqlite3_bind_text(stmt, 1, [searchText UTF8String], -1, NULL);
            sqlite3_bind_text(stmt, 2, [searchText UTF8String], -1, NULL);
            while (sqlite3_step(stmt) == SQLITE_ROW)
            {
                int64_t serialId = sqlite3_column_int64(stmt, 0);
                const char *name = (const char *)sqlite3_column_text(stmt, 1);
                const char *mobile = (const char *)sqlite3_column_text(stmt, 2);
                if (name && mobile) {
                    Contact *contact = [[Contact alloc] init];
                    contact.serialId = serialId;
                    contact.name = [NSString stringWithUTF8String:name];
                    contact.mobile = [NSString stringWithUTF8String:mobile];
                    [contacts addObject:contact];
                }
            }
            sqlite3_finalize(stmt);
        }
    }
    
    self.filteredContacts = contacts;
    [self.tableView reloadData];
}


#pragma mark - 打开数据库
- (void)openDatabase
{
    NSString *filePath = [self filepath];
    
    //创建sqlite表格:
    //所有的sql语句返回的是一个int值:
    //#define SQLITE_OK           0   /* Successful result */
    if ((sqlite3_open([filePath UTF8String], &_db)) == SQLITE_OK)
    {
        //建表:
        //CREATE TABLE member (id integer primary key autoincrement , name text , gender integer , mobile text)
        if (sqlite3_exec(_db, "create table if not exists contacts(id integer primary key autoincrement , name text , mobile text)", NULL, NULL, NULL) != SQLITE_OK)
        {
            NSLog(@"create table failed");
        }
    }
    else
    {
        NSLog(@"open database failed");
    }
    
    sqlite3_open([filePath UTF8String], &_db);
}


#pragma mark - 析构函数
- (void)dealloc
{
    [self closeDatabase];
}

#pragma mark - 关闭数据库
- (void)closeDatabase
{
    sqlite3_close(_db);
}


#pragma mark - 读取数据库信息
- (void)read
{
    sqlite3_stmt *stmt = NULL;
    //sql语句:
    NSString *sql = @"select * from contacts";
    //第三个参数�一定要写 -1 才行 , 不能瞎逼写...
    if (sqlite3_prepare(_db, [sql UTF8String], -1, &stmt, NULL) == SQLITE_OK) {
        //SQLITE_ROW:如果执行SQLITE_ROW后面还有其他数据可以再次执行......
        while (sqlite3_step(stmt) == SQLITE_ROW) {
            int64_t serialId = sqlite3_column_int64(stmt, 0);
            const char *name = (const char *)sqlite3_column_text(stmt, 1);
            const char *mobile = (const char *)sqlite3_column_text(stmt, 2);
            if (name && mobile) {
                Contact *contact = [[Contact alloc] init];
                contact.serialId = serialId;
                contact.name = [NSString stringWithUTF8String:name];
                contact.mobile = [NSString stringWithUTF8String:mobile];
                [self.contacts addObject:contact];
            }
        }
        //清理回收sql:
        sqlite3_finalize(stmt);
    }
    [self.tableView reloadData];
}

@end

AppDelegate.m

#import "AppDelegate.h"
#import "ContactListTableViewController.h"

@interface AppDelegate ()

@end

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    
    ContactListTableViewController *vc = [[ContactListTableViewController alloc] init];
    UINavigationController *nav =[[UINavigationController alloc] initWithRootViewController:vc];
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    self.window.rootViewController = nav;
    [self.window makeKeyAndVisible];
    return YES;
}

愿编程让这个世界更美好

相关文章

网友评论

      本文标题:SQLite 存储

      本文链接:https://www.haomeiwen.com/subject/rinyhxtx.html