主要是用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 无需操作

 #import <Foundation/Foundation.h>

 @interface Text : NSObject
//聊天内容
@property(nonatomic,copy)NSString *userText;
//聊天内容发送的时间
@property(nonatomic,copy)NSString *currentTime;
@end

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

 #import <Foundation/Foundation.h>
#import <sqlite3.h>
@class Text;
@interface TextModel : NSObject
//建表
-(BOOL)createList:(sqlite3 *)db;
//插入
-(BOOL)insertList:(Text *)insertList;
//获取数据
-(NSMutableArray *)getList;
@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, -, &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, -, &stmt, NULL);
if (success != SQLITE_OK) {
NSLog(@"insert failed");
sqlite3_close(_database);
return NO;
}
sqlite3_bind_text(stmt, , [insertList.userText UTF8String], -, SQLITE_TRANSIENT);
sqlite3_bind_text(stmt, , [insertList.currentTime UTF8String], -, 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, -, &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, );
//做个判断,如果记录为nil,不执行,这里自己要想一下,为什么要判断
if (strText != NULL) {
p.userText = [NSString stringWithUTF8String:strText];
}
char *strTime = (char *)sqlite3_column_text(stmt, );
//时间为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 ;
}
@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(, , width-, )];
_OtherLabel.font = [UIFont systemFontOfSize:];
_OtherLabel.numberOfLines = ;
_OtherLabel.lineBreakMode = NSLineBreakByTruncatingTail;
_OtherLabel.textAlignment = NSTextAlignmentRight;
[self.contentView addSubview:_OtherLabel]; _timeLabel = [[UILabel alloc]initWithFrame:CGRectMake(width/-, , , )];
_timeLabel.font = [UIFont systemFontOfSize:];
[self.contentView addSubview:_timeLabel]; _meImageView = [[UIImageView alloc]initWithFrame:CGRectMake(width-, , , )];
_meImageView.image = [UIImage imageNamed:@""];
[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

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

  1. iOS学习——iOS常用的存储方式

    不管是在iOS还是Android开发过程中,我们都经常性地需要存储一些状态和数据,比如用户对于App的相关设置.需要在本地缓存的数据等等.根据要存储的的数据的大小.存储性质以及存储类型,在iOS和An ...

  2. iOS学习之应用数据存储1-属性列表、偏好设置、NSKeyedArchiver归档

    iOS应用数据存储的常用方式(持久化方式) 属性列表(plist)归档(XML文件) Preference(偏好设置) NSKeyedArchiver归档(NSCoding) SQLite3 Core ...

  3. iOS学习笔记--数据存储

    iOS应用数据存储的常用方式 XML属性列表(plist)归档 Preference(偏好设置) NSKeyedArchiver归档(NSCoding) SQLite3 Core Data 1. XM ...

  4. 【原】iOS学习47之第三方-FMDB

    将 CocoaPods 安装后,按照 CocoaPods 的使用说明就可以将 FMDB 第三方集成到工程中,具体请看博客iOS学习46之第三方CocoaPods的安装和使用(通用方法) 1. FMDB ...

  5. iOS学习路线图

    一.iOS学习路线图   二.iOS学习路线图--视频篇       阶 段 学完后目标 知识点 配套学习资源(笔记+源码+PPT) 密码 基础阶段 学习周期:24天       学习后目标:    ...

  6. 【原】iOS学习之SQLite和CoreData数据库的比较

    1. SQLite数据库 sqlite数据库操作的基本流程是, 创建数据库, 再通过定义一些字段来定义表格结构, 可以利用sql语句向表格中插入记录, 删除记录, 修改记录, 表格之间也可以建立联系. ...

  7. iOS学习笔记-精华整理

    iOS学习笔记总结整理 一.内存管理情况 1- autorelease,当用户的代码在持续运行时,自动释放池是不会被销毁的,这段时间内用户可以安全地使用自动释放的对象.当用户的代码运行告一段 落,开始 ...

  8. iOS学习笔记总结整理

    来源:http://mobile.51cto.com/iphone-386851_all.htm 学习IOS开发这对于一个初学者来说,是一件非常挠头的事情.其实学习IOS开发无外乎平时的积累与总结.下 ...

  9. 【IOS学习基础】NSObject.h学习

    一.<NSObject>协议和代理模式 1.在NSObject.h头文件中,我们可以看到 // NSObject类是默认遵守<NSObject>协议的 @interface N ...

随机推荐

  1. LINQ的Any方法

    返回布尔值,判断集合中是否有元素满足某一条件. source code: IEnumerable<string> str = new List<string> { " ...

  2. 一道java算法题分析

    最近在面试中遇到这样的一道算法题:       求100!的结果的各位数之和为多少?       如:5!=5*4*3*2*1=120,那么他们的和为1+2+0=3这道题不算难,不过倒是注意的细节也有 ...

  3. C#自定义特性实例

    元数据,就是C#中封装的一些类,无法修改.类成员的特性被称为元数据中的注释. 1.什么是特性   (1)属性与特性的区别  属性(Property):属性是面向对象思想里所说的封装在类里面的数据字段, ...

  4. 一个故事讲清楚NIO

    转载请引用:一个故事讲清楚NIO 假设某银行只有10个职员.该银行的业务流程分为以下4个步骤: 1) 顾客填申请表(5分钟): 2) 职员审核(1分钟): 3) 职员叫保安去金库取钱(3分钟): 4) ...

  5. C#中WinForm窗体事件的执行次序

    C#中WinForm窗体事件的执行次序如下: 当 Windows Form 应用程序启动时,会以下列顺序引发主要表单的启动事件:        System.Windows.Forms.Control ...

  6. 获取PC或移动设备的所有IP地址

    不论是PC还是移动设备,都有可能同时存在几个IP地址(如具有多块网卡),本文介绍怎样获得PC或移动设备的所有IP地址. // 获得所有IP地址 public static void get_ip(){ ...

  7. sql server删除默认值(default)的方法

    不废话了----- 例如要删除student表的sex默认值 sp_help student;查询结果 找到constraiont_name的对应的值 最后 ALTER TABLE student D ...

  8. 调整 FMX Android 文字显示「锯齿」效果

    说明:调整 Firemonkey Android 显示文字有「锯齿」效果 适用:Firemonkey Android 平台 修改方法: 请将源码 FMX.FontGlyphs.Android.pas  ...

  9. ahjesus code simith 存储过程模板

    <%------------------------------------------------------------------------------------------ * Au ...

  10. servlet同一用户不同页面共享数据

    如何实现不同页面之间的数据传递,实现页面的数据共享?常见的方法有以下4种: 1)表单提交(form) 2)sendRedirect()跳转 3)session技术 4)Cookie技术 表单提交 这是 ...