zoukankan      html  css  js  c++  java
  • iOS中的SQLitte

    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
  • 相关阅读:
    Linux命令大全之关机重启命令
    Linux命令大全之帮助命令及压缩命令
    Linux命令大全之搜索命令
    Linux命令大全之基本命令
    Linux安装界面简介
    Linux 的ftp服务未启用怎么办
    创建分区表
    Linux分区,格式化概念理解
    VMware简介
    Linux简介
  • 原文地址:https://www.cnblogs.com/wohaoxue/p/4805534.html
Copyright © 2011-2022 走看看