IOS learning 4. Storing chat records and ios storing chat records
It mainly uses sqlite3 to store chat records
Import sqlite3.dylib, click Add Other, and press shift + command + G to enter/Usr/lib/libsqlite3.dylibAnd then OK. Import <sqlite3.h>
1. A new file Text class is used for storage, and. m does not require any operation.
1 # import <Foundation/Foundation. h> 2 3 @ interface Text: NSObject4 // chat content 5 @ property (nonatomic, copy) NSString * userText; 6 // The time when the chat content is sent 7 @ property (nonatomic, copy) NSString * currentTime; 8 @ end
2. encapsulate another TextModel class for Data Operations
1 # import <Foundation/Foundation. h> 2 # import <sqlite3.h> 3 @ class Text; 4 @ interface TextModel: NSObject 5 // create table 6-(BOOL) createList :( sqlite3 *) db; 7 // insert 8-(BOOL) insertList :( Text *) insertList; 9 // get data 10-(NSMutableArray *) getList; 11 @ end
. M
/// TextModel. m // Save the chat record /// 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 // defines a variable static sqlite3 * _ database;-(NSString *) filename {NSString * path = [NSSearchPathForDirectoriesInDomains (NSDocumentDirectory, NSUserDomainMask, YES) lastObject]; // print it here. It is convenient to use MesaSQLite to open the sqlite3 file, which can be added, deleted, modified, and queried. It is mainly free of charge ~~~ NSLog (@ "% @", path); return [path stringByAppendingPathComponent: @ "LIKE. sqlite "];}-(BOOL) openDB {// obtain path NSString * path = [self filename]; NSFileManager * fileManager = [NSFileManager defaultManager]; // determine whether the database has BOOL find = [fileManager fileExistsAtPath: path]; // if it is true, open the database. if it does not exist, if (find) is automatically created) {NSLog (@ "database exists"); if (sqlite3_open ([path UTF8String], & _ database )! = SQLITE_ OK) {// failed disabled. It is said that this is a good habit. It is hard to understand sqlite3_close (_ database); NSLog (@ "failed to open the database"); return NO ;} // create a table [self createList: _ database]; return YES;} // same as if (sqlite3_open (path. UTF8String, & _ database) = SQLITE_ OK) {[self createList: _ database]; return YES;} else {sqlite3_close (_ database ); NSLog (@ "failed to open database"); return NO;} # pragma mark -- Create Table-(BOOL) createList :( sqlite3 *) db {// I am missing a primary key Add it by yourself. -- id integer primary key autoincrement NSString * SQL = [NSString stringWithFormat: @ "CREATE TABLE IF NOT EXISTS DRINK (userText TEXT, currentTime TEXT)"]; sqlite3_stmt * stmt; // The sqlite3_prepare_v2 interface resolves an SQL statement to the statement structure. using this interface to access the database is currently a better method NSInteger sqlReturn = sqlite3_prepare_v2 (_ database, SQL. UTF8String,-1, & stmt, NULL); //-1 indicates the length of the SQL statement. <0 automatically calculates if (sqlReturn! = SQLITE_ OK) {NSLog (@ "failed to create table"); return NO;} int success = sqlite3_step (stmt); // release stmt sqlite3_finalize (stmt); if (success! = SQLITE_DONE) {NSLog (@ "Table creation failed"); return NO;} NSLog (@ "table created successfully"); return YES ;} # pragma mark -- insert-(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); // execute the insert statement success = sqlite3_step (stmt); // release stmt sqlite3_finalize (stmt); NSLog (@ "% @", insertList. userText); NSLog (@ "% @", insertList. currentTime); // If fail Ed if (success = SQLITE_ERROR) {NSLog (@ "failed insert into database"); sqlite3_close (_ database); return NO;} sqlite3_close (_ database); return YES ;} return NO; }# pragma mark -- Get-(NSMutableArray *) getList {NSMutableArray * array = nil; // you can check whether the function is enabled, here we can use dispatch_once to execute only 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]; // traverses records, starting from 0, do not write the error while (sqlite3_step (stmt) = SQLITE_ROW) {Text * p = [[Text alloc] init]; char * strText = (char *) sqlite3_column_text (stmt, 0); // make a judgment. if the record is nil and it is not executed, let's think about it here, why should we judge if (strText! = NULL) {p. userText = [NSString stringwithuf8string: strText];} char * strTime = (char *) sqlite3_column_text (stmt, 1); // if (strTime! = NULL) {p. currentTime = [NSString stringwithuf8string: strTime] ;}// Add a variable array [array addObject: p] ;}// release stmt sqlite3_finalize (stmt); sqlite3_close (_ database );} return array;} @ end
3. ViewController. h: drag a tableview and a textfield on the storyboard.
#import <UIKit/UIKit.h>@interface ViewController : UIViewController@property (weak, nonatomic) IBOutlet UITableView *tableview;@property (weak, nonatomic) IBOutlet UITextField *textField;@end
. M
/// ViewController. m // Save the chat record /// 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 "// implement UITablevView and UITextField proxy @ interface ViewController () <UITableViewDataSource, UITableViewDelegate, UITextFieldDelegate> // data source @ property (nonatomic, strong) NSMutableArray * dataSource; // data processing class @ property (nonatomic, strong) TextModel * textModel; @ end @ implementation ViewController // load data-(void) reloadDataSource {if (_ textModel = nil) {_ textModel = [[TextModel alloc] init];} // get data _ dataSource = [_ textModel getList];}-(void) viewDidLoad {[super viewDidLoad]; // sets proxy _ textField. delegate = self; // call the data loading method [self reloadDataSource];}-(void) didreceivemorywarning {[super didreceivemorywarning];}-(void) sendMessageContent :( NSString *) text {// obtain the time NSDate * date = [NSDate date]; NSDateFormatter * dateForMatter = [[NSDateFormatter alloc] init]; // hh: mm is in the format, datformatter can be used freely. dateFormat = @ "hh: mm"; NSString * timeString = [dateForMatter stringFromDate: date]; Text * t = [[Text alloc] init]; // The property t that saves the time to Text. currentTime = timeString; // input content t. userText = text; // insert it to the database [_ textModel insertList: t];} # pragma mark -- UITextField proxy-(BOOL) textFieldShouldReturn :( UITextField *) textField {// custom method to save the input content to Text [self sendMessageContent: textField. text]; // cancel the first response [textField resignFirstResponder]; // clear the keyboard textField. text = @ ""; // after the data is inserted, load the data once, equivalent to adding data to the data source [self reloadDataSource]; // refresh the interface, display the newly inserted data [_ tableview reloadData]; return YES ;}# pragma mark -- TableView Data Source-(NSInteger) tableView :( UITableView *) tableView numberOfRowsInSection :( NSInteger) section {return _ dataSource. count;}-(UITableViewCell *) tableView :( UITableView *) tableView cellForRowAtIndexPath :( NSIndexPath *) indexPath {Text * p = _ dataSource [indexPath. row]; // custom Cell TableViewCell * cell = [TableViewCell tableView: tableView]; // cell cannot be clicked. selectionStyle = UITableViewCellSelectionStyleNone; cell. timeLabel. text = p. currentTime; cell. otherLabel. text = p. userText; return cell ;}# pragma mark -- proxy method-(CGFloat) tableView :( UITableView *) tableView heightForRowAtIndexPath :( NSIndexPath *) indexPath {return 80 ;}@ end
4. Custom cell
# Import <UIKit/UIKit. h> @ interface TableViewCell: UITableViewCell // chat content @ property (strong, nonatomic) UILabel * OtherLabel; // time @ property (strong, nonatomic) UILabel * timeLabel; // avatar, find a graph by yourself @ property (strong, nonatomic) UIImageView * meImageView; + (instancetype) tableView :( UITableView *) tableView; @ end
. M
/// TableViewCell. m // Save the chat record /// Created by 736376103@qq.com on 16/4/4. // Copyright©2016 736376103@qq.com. all rights reserved. // # import "TableViewCell. h "@ implementation TableViewCell // create the control-(id) initWithStyle :( identifier) 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 reuse if (cell = nil) {cell = [[TableViewCell alloc] initWithStyle: UITableViewCellStyleDefault reuseIdentifier: @ "ChatTableViewCell"];} return cell;} @ end