zoukankan      html  css  js  c++  java
  • iOS 学习

    主要是用sqlite3来存储聊天记录

    先导入sqlite3.dylib, 点 Add Other, 同时按住 shift + command + G , 在弹出的 Go to the folder 中输入 /usr/lib/libsqlite3.dylib, 就 OK 了. 还需要#import<sqlite3.h>

    1.new file 一个 Text 类用来存储, .m 无需操作

    1 #import <Foundation/Foundation.h>
    2 
    3 @interface Text : NSObject
    4 //聊天内容
    5 @property(nonatomic,copy)NSString *userText;
    6 //聊天内容发送的时间
    7 @property(nonatomic,copy)NSString *currentTime;
    8 @end

    2.另封装一个 TextModel 类用来操作数据

     1 #import <Foundation/Foundation.h>
     2 #import <sqlite3.h>
     3 @class Text;
     4 @interface TextModel : NSObject
     5 //建表
     6 -(BOOL)createList:(sqlite3 *)db;
     7 //插入
     8 -(BOOL)insertList:(Text *)insertList;
     9 //获取数据
    10 -(NSMutableArray *)getList;
    11 @end

    .m

    //
    //  TextModel.m
    //  保存聊天记录
    //
    //  Copyright © 2016年 736376103@qq.com. All rights reserved.
    //
    
    #import "TextModel.h"
    #import "Text.h"
    @implementation TextModel
    //定义一个变量
    static sqlite3 *_database;
    
    -(NSString *)filename{
        NSString *path = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)lastObject];
        //这里打印,是方便用MesaSQLite打开sqlite3文件,可以增删改查,非常方便,主要是免费(有时间限制)~~~
        NSLog(@"%@",path);
        return [path stringByAppendingPathComponent:@"LIKE.sqlite"];
    }
    
    -(BOOL)openDB{
        //获取路径
        NSString *path = [self filename];
        NSFileManager *fileManager = [NSFileManager defaultManager];
        //判断数据库是否存在
        BOOL find = [fileManager fileExistsAtPath:path];
        //如果为真,就打开数据库,不存在,自动创建
        if (find) {
            NSLog(@"database存在");
            
            if (sqlite3_open([path UTF8String], &_database)!=SQLITE_OK) {
                //failed关闭,据说这个习惯好,不明觉厉
                sqlite3_close(_database);
                NSLog(@"打开database失败");
                return NO;
            }
            //建表
            [self createList:_database];
            return YES;
        }
        //同上
        if (sqlite3_open(path.UTF8String, &_database) == SQLITE_OK) {
            [self createList:_database];
            return YES;
        }else{
            sqlite3_close(_database);
            NSLog(@"打开database失败");
            return NO;
        }
            return NO;
        
    }
    #pragma mark -- 建表
    -(BOOL)createList:(sqlite3 *)db{
        //我这里缺少一个主键,自己加上即可--ID INTEGER PRIMARY KEY AUTOINCREMENT
        NSString *sql = [NSString stringWithFormat:@"CREATE TABLE IF NOT EXISTS DRINK(userText TEXT,currentTime TEXT)"];
        sqlite3_stmt *stmt;
        //sqlite3_prepare_v2 接口把一条SQL语句解析到statement结构里去. 使用该接口访问数据库是当前比较好的的一种方法
        NSInteger sqlReturn = sqlite3_prepare_v2(_database, sql.UTF8String, -1, &stmt, NULL);
        //-1是sql语句的长度,<0会自动计算
        if (sqlReturn != SQLITE_OK) {
            NSLog(@"创建表失败");
            return NO;
        }
        int success = sqlite3_step(stmt);
        //释放stmt
        sqlite3_finalize(stmt);
        if (success != SQLITE_DONE) {
            NSLog(@"创建表失败");
            return NO;
        }
        NSLog(@"创建表成功");
        return YES;
    }
    #pragma mark -- 插入 -(BOOL)insertList:(Text *)insertList{ if ([self openDB]) { sqlite3_stmt *stmt; // ? 表示待会儿插入 NSString *sql = [NSString stringWithFormat:@"INSERT INTO DRINK(userText,currentTime)VALUES(?,?)"]; //int success = sqlite3_exec(_database, sql.UTF8String, NULL, NULL, &error); int success = sqlite3_prepare_v2(_database, sql.UTF8String, -1, &stmt, NULL); if (success != SQLITE_OK) { NSLog(@"insert failed"); sqlite3_close(_database); return NO; } sqlite3_bind_text(stmt, 1, [insertList.userText UTF8String], -1, SQLITE_TRANSIENT); sqlite3_bind_text(stmt, 2, [insertList.currentTime UTF8String], -1, SQLITE_TRANSIENT); //执行插入语句 success = sqlite3_step(stmt); //释放stmt sqlite3_finalize(stmt); NSLog(@"%@",insertList.userText); NSLog(@"%@",insertList.currentTime); //如果failed if (success == SQLITE_ERROR) { NSLog(@"failed insert into database"); sqlite3_close(_database); return NO; } sqlite3_close(_database); return YES; } return NO; }
    #pragma mark -- 获取 -(NSMutableArray *)getList{ NSMutableArray *array = nil; //判断是否打开,这里可以用 dispatch_once 只执行一次 if ([self openDB]) { sqlite3_stmt *stmt; NSString *sql = [NSString stringWithFormat:@"SELECT userText,currentTime FROM DRINK"]; if (sqlite3_prepare_v2(_database, sql.UTF8String, -1, &stmt, NULL) != SQLITE_OK) { NSLog(@"failed to get list"); }else{ array = [NSMutableArray array]; //遍历记录,这里是从0开始,别写错了 while (sqlite3_step(stmt) == SQLITE_ROW) { Text *p = [[Text alloc]init]; char *strText = (char *)sqlite3_column_text(stmt, 0); //做个判断,如果记录为nil,不执行,这里自己要想一下,为什么要判断 if (strText != NULL) { p.userText = [NSString stringWithUTF8String:strText]; } char *strTime = (char *)sqlite3_column_text(stmt, 1); //时间为Null,不执行 if (strTime != NULL) { p.currentTime = [NSString stringWithUTF8String:strTime]; } //加进可变数组 [array addObject:p]; } } //释放stmt sqlite3_finalize(stmt); sqlite3_close(_database); } return array; } @end

    3.ViewController.h, 在 storyboard 拖一个 tableView 和一个 textField

    #import <UIKit/UIKit.h>
    @interface ViewController : UIViewController
    @property (weak, nonatomic) IBOutlet UITableView
    *tableview; @property (weak, nonatomic) IBOutlet UITextField *textField; @end

    .m

    //
    //  ViewController.m
    //  保存聊天记录
    //
    //  Created by 736376103@qq.com on 16/4/4.
    //  Copyright © 2016年 736376103@qq.com. All rights reserved.
    //
    
    #import "ViewController.h"
    #import "TableViewCell.h"
    #import "Text.h"
    #import "TextModel.h"
    //实现 UITablevView 和 UITextField 的代理
    @interface ViewController ()<UITableViewDataSource,UITableViewDelegate,UITextFieldDelegate>
    //数据源
    @property(nonatomic,strong)NSMutableArray *dataSource;
    //处理数据的类
    @property(nonatomic,strong)TextModel *textModel;
    
    @end
    
    @implementation ViewController
    //加载数据
    -(void)reloadDataSource{
        if (_textModel == nil) {
            _textModel = [[TextModel alloc]init];
        }
        //获取数据
        _dataSource = [_textModel getList];
    }
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        //设置代理
        _textField.delegate = self;
        //调用加载数据方法
        [self reloadDataSource];
    
    }
    
    - (void)didReceiveMemoryWarning {
        [super didReceiveMemoryWarning];
    }
    
    -(void)sendMessageContent:(NSString *)text {
        //获取时间
        NSDate *date = [NSDate date];
        NSDateFormatter *dateForMatter = [[NSDateFormatter alloc]init];
        //hh:mm 是 09:54 这样的格式,可以自由发挥
        dateForMatter.dateFormat = @"hh:mm";
        NSString *timeString = [dateForMatter stringFromDate:date];
        
        Text *t = [[Text alloc]init];
        //把时间存到 Text 的属性
        t.currentTime = timeString;
        //输入的内容
        t.userText = text;
        //插入到数据库
        [_textModel insertList:t];
    }
    #pragma mark -- UITextField代理
    -(BOOL)textFieldShouldReturn:(UITextField *)textField{
        //自定义方法,把输入的内容存到 Text
        [self sendMessageContent:textField.text];
        //取消第一响应
        [textField resignFirstResponder];
        //清空键盘
        textField.text = @"";
        //插入之后,加载一次数据,相当于往数据源里加数据
        [self reloadDataSource];
        //刷新界面,显示刚插入的数据
        [_tableview reloadData];
        return YES;
    }
    
    #pragma mark - TableView 数据源
    -(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
        return _dataSource.count;
    }
    
    -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
        
        Text *p = _dataSource[indexPath.row];
        //自定义 cell
        TableViewCell *cell = [TableViewCell tableView:tableView];
        //cell 不可点击
        cell.selectionStyle = UITableViewCellSelectionStyleNone;
        cell.timeLabel.text = p.currentTime;
        cell.OtherLabel.text = p.userText;
        return cell;
    }
    #pragma mark - 代理方法
    -(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
        return 80;
    }
    @end

    4.自定义 cell

    #import <UIKit/UIKit.h>
    
    @interface TableViewCell : UITableViewCell
    //聊天内容
    @property (strong, nonatomic)UILabel *OtherLabel;
    //时间
    @property (strong, nonatomic)UILabel *timeLabel;
    //头像,这个自己随便找个图
    @property(strong,nonatomic)UIImageView *meImageView;
    
    +(instancetype)tableView:(UITableView *)tableView;
    
    @end

    .m

    //
    //  TableViewCell.m
    //  保存聊天记录
    //
    //  Created by 736376103@qq.com on 16/4/4.
    //  Copyright © 2016年 736376103@qq.com. All rights reserved.
    //
    
    #import "TableViewCell.h"
    
    @implementation TableViewCell
    //初始化的时候,创建控件
    -(id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier{
        if (self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]) {
            
            CGFloat width = [UIScreen mainScreen].bounds.size.width;
            
            _OtherLabel = [[UILabel alloc]initWithFrame:CGRectMake(0, 40, width-40, 30)];
            _OtherLabel.font = [UIFont systemFontOfSize:16];
            _OtherLabel.numberOfLines = 0;
            _OtherLabel.lineBreakMode = NSLineBreakByTruncatingTail;
            _OtherLabel.textAlignment = NSTextAlignmentRight;
            [self.contentView addSubview:_OtherLabel];
            
            _timeLabel = [[UILabel alloc]initWithFrame:CGRectMake(width/2-20, 0, 40, 20)];
            _timeLabel.font = [UIFont systemFontOfSize:12];
            [self.contentView addSubview:_timeLabel];
            
            _meImageView = [[UIImageView alloc]initWithFrame:CGRectMake(width-40, 10, 30, 30)];
            _meImageView.image = [UIImage imageNamed:@"003"];
            [self.contentView addSubview:_meImageView];
        }
        return self;
    }
    
    
    +(instancetype)tableView:(UITableView *)tableView{
        TableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"ChatTableViewCell"];
        //cell 复用
        if (cell == nil) {
            cell = [[TableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"ChatTableViewCell"];
        }
        return cell;
    }
    
    
    @end

     

  • 相关阅读:
    Vscode 隐藏 工作区中的目录
    java 中 静态泛型方法书写
    Vscode 配置 maven debug
    vscode 配置 java utf-8 编码
    node.js 设置 淘宝 镜像
    vscode 注册表
    ESET Smart Security 6 – 免费60天(SG)
    WIN-8“内置管理员无法激活此应用”问题
    怎样更新PE内的工具
    使用Setup安装Windows8 RTM方法
  • 原文地址:https://www.cnblogs.com/asamu/p/5361473.html
Copyright © 2011-2022 走看看