码迷,mamicode.com
首页 > 移动开发 > 详细

iOS中的SQLitte

时间:2015-09-13 21:25:23      阅读:181      评论:0      收藏:0      [点我收藏+]

标签:

ContactListController.m

 


#import "ContactListController.h" #import "FMDatabase.h" // 第三方数据库操作类 #import "ContactCell.h" #import "DetailViewController.h" #import "AddViewController.h" @interface ContactListController () <DetailViewControllerDelegate,AddViewControllerDelegate> @property (nonatomic, retain) FMDatabase *db; // 存储数据库操作类对象 @property (nonatomic, retain) NSMutableArray *dataSource; // 存储所有联系人信息 @end @implementation ContactListController // 懒加载, 给数组开辟空间 - (NSMutableArray *)dataSource { if (!_dataSource) { self.dataSource = [NSMutableArray arrayWithCapacity:1]; } return [[_dataSource retain] autorelease]; } - (void)viewDidLoad { [super viewDidLoad]; // 1.创建数据库 -- 找到数据库文件 [self createDataBase]; // 2. 创建表 -- 存储数据 [self createTableInDataBase]; // 3. 读取数据 [self selectDataFromDataBase]; // Edit 按钮 // self.navigationItem.rightBarButtonItem // Uncomment the following line to preserve selection between presentations. // self.clearsSelectionOnViewWillAppear = NO; // Uncomment the following line to display an Edit button in the navigation bar for this view controller. // self.navigationItem.rightBarButtonItem = self.editButtonItem; } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. } #pragma mark - Table view data source - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { #warning Incomplete method implementation. // Return the number of rows in the section. return self.dataSource.count; } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { ContactCell *cell = [tableView dequeueReusableCellWithIdentifier:@"reuse" forIndexPath:indexPath]; // 从数组中取出Model对象 Person *per = self.dataSource[indexPath.row]; // 给cell 赋值 [cell setValueForCellWithPerson:per]; return cell; } /* // Override to support conditional editing of the table view. - (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath { // Return NO if you do not want the specified item to be editable. return YES; } */ // 提交编辑操作 // Override to support editing the table view. - (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath { // 1. 修改数据源 // 移除数据库的数据 Person *per = self.dataSource[indexPath.row]; [self deleteDataFromDataBase:per.cID]; // 从数组中移除 [self.dataSource removeObjectAtIndex:indexPath.row]; // 2. 修改界面 [tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationLeft]; } #pragma mark -- Navigation // 当通过storyboard 完成界面跳转时, 触发, 通过该方法传值 - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { if ([segue.identifier isEqualToString:@"add"]) { // 添加联系人界面 AddViewController *addVC = [segue.destinationViewController viewControllers][0]; addVC.delegate = self; }else { // 列表界面进入详情界面 NSIndexPath *indexPath = [self.tableView indexPathForCell:sender]; // sender 为选中的cell DetailViewController *detailVC = segue.destinationViewController; detailVC.valuePer = self.dataSource[indexPath.row]; detailVC.delegate = self; } } #pragma mark -- delegate method // 详情界面 代理方法 -- 修改联系人 - (void)updatePerson:(Person *)per { [self updateDataBaseWithPerson:per]; } // 添加联系人界面 - (void)addPerson:(Person *)per { // 1. 添加到数组 [self.dataSource addObject:per]; // 2. 将数据插入到数据库 [self insertDataInDataBase:per]; [self.tableView reloadData]; } // view 将要展示时, 刷新界面 - (void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; [self.tableView reloadData]; } #pragma mark -- handle DataBase // 创建数据库 - (void)createDataBase { // db -- 数据库操作类对象 -- 指向本地的数据库 self.db = [FMDatabase databaseWithPath:[self getDataBasePath]]; } // 创建表 -- 表用来存储数据 -- 一条数据就是一个完整的联系人信息 - (void)createTableInDataBase { // 1. 打开数据库 BOOL isOpen = [self.db open]; if (!isOpen) { return; } // 2. 通过SQL语句操作数据库 -- 创建表 // executeUpdate : 除了查询指令, 其他都用这个方法 BOOL isSuccess = [self.db executeUpdate:@"create table if not exists Person(per_cID integer primary key autoincrement, per_name text, per_gender text, per_age text, per_phone text, per_image blob)"]; // blob 二进制数据 NSLog(@"%@", isSuccess ? @"winner" : @"loser"); // 3. 关闭数据库 [self.db close]; } // 往数据库中插入一条新的数据 - (void)insertDataInDataBase:(Person *)per { // 1. 打开数据库 BOOL isOpen = [self.db open]; if (!isOpen) { return; } // 2. 通过SQL语句操作数据库 -- 插入一条新的数据 // executeUpdate : 除了查询指令, 其他都用这个方法 BOOL isSuccess = [self.db executeUpdate:@"insert into Person(per_name, per_gender, per_age, per_phone, per_image) values(?, ?, ?, ?, ?)", per.name, per.gender, per.age, per.phone, per.image]; NSLog(@"%@", isSuccess ? @"insertDataInDataBase winner" : @"insertDataInDataBase loser"); // 3. 关闭数据库 [self.db close]; } // 更新一条数据 - (void)updateDataBaseWithPerson:(Person *)per { // 1. 打开数据库 BOOL isOpen = [self.db open]; if (!isOpen) { return; } // 2. 通过SQL语句操作数据库 -- 更新数据 BOOL isSuccess = [self.db executeUpdate:@"update Person set per_name = ?, per_gender = ?, per_age = ?, per_phone = ?, per_image = ?,where per_cID = ?", per.name, per.age, per.phone, per.image, @(per.cID)]; NSLog(@"%@", isSuccess ? @"update winner" : @" update loser"); // 3. 关闭数据库 [self.db close]; } /** 更新的思路: 点击cell时, 将对应的联系人对象, 传到(属性传值) 详情界面, 当详情界面修改完信息之后, 通过代理回调, 将修改后的 Person对象传到列表中, 进行数据的更新. */ // 读取数据 -- 查询数据库 - (void)selectDataFromDataBase { // 1. 打开数据库 BOOL isOpen = [self.db open]; if (!isOpen) { return; } // 2. 通过SQL语句操作数据库 -- 查询所有的数据 FMResultSet *result = [self.db executeQuery:@"select * from Person"]; while ([result next]) { // 读取一条数据的每个字段的值 NSInteger ID = [result intForColumn:@"per_cID"]; NSString *name = [result stringForColumn:@"per_name"]; NSString *gender = [result stringForColumn:@"per_gender"]; NSString *phone = [result stringForColumn:@"per_phone"]; NSString *age = [result stringForColumn:@"per_age"]; NSData *data = [result dataForColumn:@"per_image"]; UIImage *image = [UIImage imageWithData:data]; // 将读取到的数据封装成Person对象, 存储到数组中 Person *per = [Person personWithName:name gender:gender phone:phone age:age image:image cID:ID]; [self.dataSource addObject:per]; } // 3. 关闭数据库 [self.db close]; } // 获取数据库文件路径 - (NSString *)getDataBasePath { // 1. 获取Documents 文件夹 NSString *documentsPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject]; // 2. 拼接上数据库文件路径 return [documentsPath stringByAppendingPathComponent:@"LO.sqlite"]; } // 从数据库中移除一条数据 - (void)deleteDataFromDataBase:(NSInteger)cID { // 1. 打开数据库 BOOL isOpen = [self.db open]; if (!isOpen) { return; } // 2. 通过SQL语句操作数据库 -- 删除一条数据 BOOL isSuccess = [self.db executeUpdate:@"delete from Person where per_cID = ?", cID]; NSLog(@"%@", isSuccess ? @"success" : @"failure"); // 3. 关闭 [self.db close]; } - (void)dealloc { self.dataSource = nil; self.db = nil; [super dealloc]; } @end
DetailViewController.h
#import <UIKit/UIKit.h>
#import "Person.h"

// 代理 一
@protocol DetailViewControllerDelegate <NSObject>

- (void)updatePerson:(Person *)per;

@end



@interface DetailViewController : UIViewController

// 代理 二
@property (nonatomic, assign)id<DetailViewControllerDelegate> delegate;
@property (nonatomic, retain)Person *valuePer; // 属性传值

@end
DetailViewController.m
#import "DetailViewController.h"

@interface DetailViewController () <UIActionSheetDelegate, UINavigationControllerDelegate, UIImagePickerControllerDelegate>
@property (retain, nonatomic) IBOutlet UITextField *nameText;
@property (retain, nonatomic) IBOutlet UITextField *genderText;
@property (retain, nonatomic) IBOutlet UITextField *ageText;
@property (retain, nonatomic) IBOutlet UITextField *phoneNumber;
@property (retain, nonatomic) IBOutlet UIImageView *iconView;

@end

@implementation DetailViewController

// 轻拍手势
- (IBAction)handleTap:(UITapGestureRecognizer *)sender {UIActionSheet *sheet = [[UIActionSheet alloc] initWithTitle:@"选择图像" delegate:self cancelButtonTitle:@"取消" destructiveButtonTitle:@"拍照" otherButtonTitles:@"从相册选择", nil];
    
    [sheet showInView:self.view];
    
    [sheet release];
    
}

#pragma mark -- imagePickerControllerDelegate

//获取图片后触发

- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
    
    self.iconView.image = [info objectForKey:UIImagePickerControllerOriginalImage];
    
    [picker dismissViewControllerAnimated:YES completion:nil];
    
}



#pragma mark - handle Photo

//action sheet 响应事件

- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex {
    
    //创建对象
    
    UIImagePickerController *imagePicker = [[[UIImagePickerController alloc] init] autorelease];
    
    //相片来源:1.photoAlum 2.camera 3.photoLibrary
    
    //指定相片来源
    
    switch (buttonIndex) {
            
        case 0: //拍照
            
            //判断是否支持相机
            
            if ([UIImagePickerController isSourceTypeAvailable:(UIImagePickerControllerSourceTypeCamera)]) {
                
                imagePicker.sourceType = UIImagePickerControllerSourceTypeCamera;
                
            } else {
                
                UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"提示" message:@"不支持相机拍照,请重新选择" delegate:self cancelButtonTitle:@"取消" otherButtonTitles:nil, nil];
                
                [alert show];
                
                [alert release];
                
                return;
                
            }
            
            break;
            
        case 1:
            
            imagePicker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary; //从相册选择
            
            break;
            
        case 2:
            
            return; //取消
            
        default:
            
            break;
            
    }
    
    //跳转模式
    
    imagePicker.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
    
    //指定代理
    
    imagePicker.delegate = self;
    
    //弹出视图
    
    [self presentViewController:imagePicker animated:YES completion:nil];
    
}


- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    
    // 给自身控件赋值
    self.iconView.image = self.valuePer.image;
    self.nameText.text = self.valuePer.name;
    self.phoneNumber.text = self.valuePer.phone;
    self.genderText.text = self.valuePer.gender;
    self.ageText.text = self.valuePer.age;
    
    // Edit 按钮
    self.navigationItem.rightBarButtonItem = self.editButtonItem;
    
    // 控制 控件的交互
    [self depenedUserInteration:NO];
}

// 点击Edit 触发
- (void)setEditing:(BOOL)editing animated:(BOOL)animated {
    
    [super setEditing:editing animated:animated];
    // 控制自身控件交互的方法 -- 自定义的
    [self depenedUserInteration:editing];
    if (!editing) { // 如果此时点击 done 要保存数据
        [self save];
    }
}

// 控制自身控件交互
- (void)depenedUserInteration:(BOOL)editing {
    self.iconView.userInteractionEnabled = editing;
    self.nameText.enabled = editing;
    self.nameText.enabled = editing;
    self.ageText.enabled = editing;
    self.phoneNumber.enabled = editing;
}

// 保存更改之后的数据
- (void)save {
    // 1. 将内存中的valuePer 数据进行更改
    self.valuePer.image = self.iconView.image;
    self.valuePer.name = self.nameText.text;
    self.valuePer.phone = self.phoneNumber.text;
    self.valuePer.age = self.ageText.text;
    self.valuePer.gender = self.genderText.text;
    
    // 2. 让前一个界面更改数据库中的数据
    // 代理 六
    if ([self.delegate respondsToSelector:@selector(updatePerson:)]) {
        [self.delegate updatePerson:self.valuePer];
    }
    
    
    
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

/*
#pragma mark - Navigation

// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    // Get the new view controller using [segue destinationViewController].
    // Pass the selected object to the new view controller.
}
*/

- (void)dealloc {
    self.valuePer = nil;
    [_nameText release];
    [_genderText release];
    [_ageText release];
    [_phoneNumber release];
    [_iconView release];
    [super dealloc];
}
@end
AddViewController.h
#import <UIKit/UIKit.h>
#import "Person.h"

// 代理 一
@protocol AddViewControllerDelegate <NSObject>

- (void)addPerson:(Person *)per;

@end

@interface AddViewController : UIViewController

@property (nonatomic, assign)id<AddViewControllerDelegate> delegate; // 定义delegate属性 , 存储代理对象

@end
AddViewController.m
#import "AddViewController.h"

@interface AddViewController () <UINavigationControllerDelegate, UIActionSheetDelegate, UIImagePickerControllerDelegate, AddViewControllerDelegate>
@property (retain, nonatomic) IBOutlet UITextField *nameTextFiled;
@property (retain, nonatomic) IBOutlet UITextField *genderTextFiled;
@property (retain, nonatomic) IBOutlet UITextField *ageTextFiled;
@property (retain, nonatomic) IBOutlet UITextField *phoneNumber;
@property (retain, nonatomic) IBOutlet UIImageView *iconView;

@end

@implementation AddViewController
// 轻拍手势
- (IBAction)handleTap:(UITapGestureRecognizer *)sender {UIActionSheet *sheet = [[UIActionSheet alloc] initWithTitle:@"选择图像" delegate:self cancelButtonTitle:@"取消" destructiveButtonTitle:@"拍照" otherButtonTitles:@"从相册选择", nil];
    
    [sheet showInView:self.view];
    
    [sheet release];
    
}

#pragma mark -- imagePickerControllerDelegate

//获取图片后触发

- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
    
    self.iconView.image = [info objectForKey:UIImagePickerControllerOriginalImage];
    
    [picker dismissViewControllerAnimated:YES completion:nil];
    
}



#pragma mark - handle Photo

//action sheet 响应事件

- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex {
    
    //创建对象
    
    UIImagePickerController *imagePicker = [[[UIImagePickerController alloc] init] autorelease];
    
    //相片来源:1.photoAlum 2.camera 3.photoLibrary
    
    //指定相片来源
    
    switch (buttonIndex) {
            
        case 0: //拍照
            
            //判断是否支持相机
            
            if ([UIImagePickerController isSourceTypeAvailable:(UIImagePickerControllerSourceTypeCamera)]) {
                
                imagePicker.sourceType = UIImagePickerControllerSourceTypeCamera;
                
            } else {
                
                UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"提示" message:@"不支持相机拍照,请重新选择" delegate:self cancelButtonTitle:@"取消" otherButtonTitles:nil, nil];
                
                [alert show];
                
                [alert release];
                
                return;
                
            }
            
            break;
            
        case 1:
            
            imagePicker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary; //从相册选择
            
            break;
            
        case 2:
            
            return; //取消
            
        default:
            
            break;
            
    }
    
    //跳转模式
    
    imagePicker.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
    
    //指定代理
    
    imagePicker.delegate = self;
    
    //弹出视图
    
    [self presentViewController:imagePicker animated:YES completion:nil];
    
}


// 返回按钮
- (IBAction)backBtn:(UIBarButtonItem *)sender {
    // 如果姓名, 联系方式为空, 直接返回上一界面
    if (!self.nameTextFiled.text.length || !self.phoneNumber.text.length) {
        [self dismissViewControllerAnimated:YES completion:nil];
    }
    // 如果不为空, 代理传值
    if ([self.delegate respondsToSelector:@selector(addPerson:)]) {
        Person *per = [Person personWithName:self.nameTextFiled.text gender:self.genderTextFiled.text phone:self.phoneNumber.text age:self.ageTextFiled.text image:self.iconView.image cID:0];
        [self.delegate addPerson:per];
    }
    
}

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

/*
#pragma mark - Navigation

// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    // Get the new view controller using [segue destinationViewController].
    // Pass the selected object to the new view controller.
}
*/

- (void)dealloc {
    [_nameTextFiled release];
    [_genderTextFiled release];
    [_ageTextFiled release];
    [_phoneNumber release];
    [_iconView release];
    [super dealloc];
}
@end

 

iOS中的SQLitte

标签:

原文地址:http://www.cnblogs.com/wohaoxue/p/4805534.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!