iOS学习4.存储聊天记录

主要是用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
//  保存聊天记录
//
//  Created by [email protected] on 16/4/4.
//  Copyright © 2016年 [email protected] 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 [email protected] on 16/4/4.
//  Copyright © 2016年 [email protected] 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 [email protected] on 16/4/4.
//  Copyright © 2016年 [email protected] 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
时间: 2024-10-12 17:08:48

iOS学习4.存储聊天记录的相关文章

iOS 学习笔记——0005(数据存储)

先发一个练手的小demo,自己写的简略通讯录,已上传至github https://github.com/liaoshaolim/addressBook 1.NSKeyedArchiver:(归档) 这里用一个添加联系人的例子来说明: 注意:归档形式保存数据,需要该对象遵守NSCoding协议,而且对应的必须提供encodeWithCoder和initWithCoder方法 因为归档是一次性的,解压也是一次性的,所以小量的ok,如果量大的话,改一个小地方就要归档或解压全部,效率会比较低 //用一

IOS学习笔记 -- Segue、数据存储、UITabBarController

一. Segue1.Storyboard上每一根用来界面跳转的线,都是一个UIStoryboardSegue对象(简称Segue)每一个Segue对象,都有3个属性1>.唯一标识: @property (nonatomic, readonly) NSString *identifier;2>.来源控制器: @property (nonatomic, readonly) id sourceViewController;3>.目标控制器: @property (nonatomic, read

iOS学习笔记之UITableViewController&amp;UITableView

iOS学习笔记之UITableViewController&UITableView 写在前面 上个月末到现在一直都在忙实验室的事情,与导师讨论之后,发现目前在实验室完成的工作还不足以写成毕业论文,因此需要继续思考新的算法.这是一件挺痛苦的事情,特别是在很难找到与自己研究方向相关的文献的时候.也许网格序列水印这个课题本身的研究意义就是有待考证的.尽管如此,还是要努力的思考下去.由于实验室的原因,iOS的学习进度明显受到影响,加之整理文档本身是一件耗费时间和精力的事情,因此才这么久没有写笔记了. M

2015最新iOS学习线路图

iOS是由苹果公司开发的移动操作系统,以xcode为主要开发工具,具有简单易用的界面.令人惊叹的功能,以及超强的稳定性,已经成为iPhone.iPad 和iPod touch 的强大基础:iOS 内置的众多技术和功能让 Apple设备始终保持着遥遥领先的地位. iOS学习路线:http://www.mobiletrain.org/page/ios.html 课程分  类 课程模块 模块介绍 课程内容 Part1C语言 C语言和Objective-C语言 C语言 Mac系统及常用工具.进制:C数据

iOS学习之 plist文件的读写

在做iOS开发时,经经常使用到到plist文件,  那plist文件是什么呢? 它全名是:Property List,属性列表文件,它是一种用来存储串行化后的对象的文件.属性列表文件的扩展名为.plist ,因此通常被称为 plist文件.文件是xml格式的. Plist文件通经常使用于储存用户设置,也能够用于存储捆绑的信息 我们创建一个项目来学习plist文件的读写. 1.创建项目Plistdemo 项目创建之后能够找到项目相应的plist文件,打开例如以下图所看到的: 在编辑器中显示相似与表

iOS学习笔记-精华整理

iOS学习笔记总结整理 一.内存管理情况 1- autorelease,当用户的代码在持续运行时,自动释放池是不会被销毁的,这段时间内用户可以安全地使用自动释放的对象.当用户的代码运行告一段 落,开始等待用户的操作,自动释放池就会被释放掉(调用dealloc),池中的对象都会收到一个release,有可能会因此被销毁. 2-成员属性:     readonly:不指定readonly,默认合成getter和setter方法.外界毫不关心的成员,则不要设置任何属性,这样封装能增加代码的独立性和安全

ios学习笔记---c语言第二天

一.bool布尔类型    c语言没有bool类型,oc里有bool类型 是一种非真即假的数据类型,布尔类型的变量只有yes和no两个值.yes表示表达式是真,no表示表达式是假. 在c语言中认为非0即为真. 分支语句中常用bool值做判断,判断执行if语句还是else语句. 循环结构中,也常使用bool值做判断,判断是否要执行循环. 注意事项: #define yes 1 #define no 0 计算机在识别时,yes就替换成1,no就替换成0. 二.关系运算符 >   >=   <

iOS学习资源收集

https://github.com/Tim9Liu9/TimLiu-iOS 自己总结的iOS.mac开源项目及库,持续更新.... github排名 https://github.com/trending,github搜索:https://github.com/search 目录 UI 下拉刷新 模糊效果 AutoLayout 富文本 图表 表相关与Tabbar 隐藏与显示 HUD与Toast 对话框 其他UI 动画 侧滑与右滑返回手势 gif动画 其他动画 网络相关 网络连接 图像获取 网络

iOS学习笔记---oc语言第五天

字典,数组 ,集排序 一.字典类 存储以下数据 name:张三; sex:男;age:18 film:风暴; playcount:10000次;price:60元 字典类用于保存具有映射关系(key-value对)的数据 对于“name:张三”来讲,key就是“name”,key对应的value是“张 三” 一个key-value对认为是一个元素(实体),字典是存储key-value对 的容器. 特点: 与数组不同,数组靠下标存取数据,数组的下标是唯一的. 字典靠key存取元素.key不能重复,