iOS學習4.儲存聊天記錄,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 : NSObject4 //聊天內容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 736376103@qq.com on 16/4/4.// 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