iOS學習4.存儲聊天記錄

来源:http://www.cnblogs.com/asamu/archive/2016/04/06/5361473.html
-Advertisement-
Play Games

主要是用sqlite3來存儲聊天記錄 先導入sqlite3.dylib, 點 Add Other,同時按住shift+command+G, 在彈出的Go to the folder中輸入/usr/lib/libsqlite3.dylib,就OK了。 還需要import<sqlite3.h> 1.ne ...


主要是用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

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 代碼: ...
  • 以下是三個IOS開發中最常用的控制項,作為IOS基礎學習教程知識 ,初學者需要瞭解其基本定義和常用設置,以便在開發在熟練運用。 UIButton按鈕 第一、UIButton的定義 UIButton *button=[[UIButton buttonWithType:(UIButtonType); 能夠 ...
  • 一、響應鏈 在IOS開發中會遇到各種操作事件,通過程式可以對這些事件做出響應。 首先,當發生事件響應時,必須知道由誰來響應事件。在IOS中,由響應者鏈來對事件進行響應,所有事件響應的類都是UIResponder的子類,響應者鏈是一個由不同對象組成的層次結構,其中的每個對象將依次獲得響應事件消息的機會 ...
  • 什麼是廣播 什麼是廣播 生活中的電視頻道、收音機、手機、都有自己的特定廣播,他們不管是否有人關心、收聽等,不管你是否看電視,每個頻道都實施按照自己的進步進行播放、收音機也是!所以我理解的android廣播機制也就是這樣--廣播發佈者只負責把發生的事件發出,至於是否有接聽者或者接聽者接收到怎樣處理並不 ...
  • 原文地址:http://blog.csdn.net/wzzvictory/article/details/18269713 出於安全考慮,iOS系統的沙盒機制規定每個應用都只能訪問當前沙盒目錄下麵的文件(也有例外,比如系統通訊錄能在用戶授權的情況下被第三方應用訪問),這個規則把iOS系統的封閉性展現 ...
  • Android開發獲取相冊圖片的方式網上有很多種,這裡說一個Android4.4後的方法,因為版本越高,一些老的api就會被棄用,新的api和老的api不相容,導致出現很多問題。 比如:managedQuery()現在已經被getContentResolver().query()替代了,不過它們的參 ...
  • 最終效果展示: 首先我們需要一個ViewPager控制項,不過可以發現在左側的控制項列表中並沒有這個控制項 這時我們要去升級包中查看 然後在釐米找到 ViewPager.class 這時我們雙擊這個發現不能查看源代碼 我們可以通過以 android-support-v4.jar.properties 的一 ...
  • 本文轉自:http://www.cnblogs.com/wendingding/p/3763330.html 一、項目結構和plist文件 二、實現代碼 1.說明: 主控制器直接繼承UITableViewController // YYViewController.h // 02-QQ好友列表(基本 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...