socketket与lkdbhelper来处理数据

客户需求:

当我们有需要从自己的后台推送消息给我们的用户时,用户需要实时的接收到来自我们的推送消息。前提是没有使用第三方的推送框架,那么这个使用websocket来接收消息,app端把接收到的消息存储在本地的数据库,让我们直接从数据库去读取数据。

SocketRocket是facebook基于socket进行的二次封装。下面是它的下载地址:

facebook/SocketRocket

LKDBHelper-SQLite-ORM这个第三方库,全自动的插入,查询,更新,删除。 是对sqlite的封装,使开发者不必关心sqlite复杂的语句。这个是github的下载地址:

li6185377/LKDBHelper-SQLite-ORM

从上面的需求中可以分析出做的事情,有2件事需要做。

一、Socket连接获取到后台推送的数据

SocketRocket提供的官方接口:

@interface SRWebSocket : NSObject

// 初始化方法,这只是一种还有很多种,具体请自己看
- (instancetype)initWithURLRequest:(NSURLRequest *)request; // 代理方法
@property (nonatomic, weak) id <SRWebSocketDelegate> delegate; // 打开socket
- (void)open; // 关闭socket
- (void)close; // 发送数据NSData
- (void)sendData:(nullable NSData *)data error:(NSError **)error; // Send a UTF8 String 发送字符串数据
- (void)sendString:(NSString *)string error:(NSError **)error; @end

Socket连接流程:

建议对这个第三方的库进行再一次封装,以便以后需要改换成其它的第三方库,只需要修改此处,而不必去整个工程的修改。

1.发送socket建立连接请求

代码:

/**
* Socket建立连接
*/
- (void)connectSocket
{
//此地址不代表真实地址
NSString *url = @"xsp://push.lala.com:8888";
//初始化
self.socket = [[SRWebSocket alloc] initWithURL:[NSURL URLWithString:url]];
//设置代理
self.socket.delegate = self;
//打开socket连接
[self.socket open];
}

2.从代理方法中收到连接情况,比如心跳报文等。在这个代理方法里面处理接收到的数据保存到本地数据库中

#pragma mark -- SocketDelegate
/**
* 收到服务器的消息
*
* @param webSocket socket
* @param message 收到服务器的消息,有可能是字符串,或是NSData数据
*/
- (void)webSocket:(SRWebSocket *)webSocket didReceiveMessage:(id)message
{
NSError *error = nil;
NSString *receiveMessage = (NSString *)message; //如果数据不能解析,很有可能是后台传的时候有tab键或是空格,找后台排查,或者就用字符替换掉这些多余的字符
NSData *data = [receiveMessage dataUsingEncoding:NSUTF8StringEncoding]; //NSJSONReadingAllowFragments不管外层的类型是什么
NSDictionary *responseObj = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:&error]; NSString *type = responseObj[@"type"];
//这里的代码不准确,主要是根据后台的返回类型来处理
NSUInteger index = [NSString stringWithFormat:@"%@",type]; switch (index) {
case 0:
{
//心跳报文
}
break; case 1:
{
//推送的消息1,处理数据,保存到数据库
}
break; case 2:
{
//推送的消息2,处理数据,保存到数据库
}
break; default:
break;
} }

3.断开连接

/**
* Socket断开连接
* 分为服务器断开和客户端断开
* 此处为客户端断开
*/
- (void)discononectSocket
{
//关闭socket连接
[self.socket close];
self.socket = nil;
self.socket.delegate = nil;
}

SocketRocket 提供的代理方法:

@protocol SRWebSocketDelegate <NSObject>
- (void)webSocket:(SRWebSocket *)webSocket didReceiveMessage:(id)message; @optional //socket连接成功
- (void)webSocketDidOpen:(SRWebSocket *)webSocket;
//
- (void)webSocket:(SRWebSocket *)webSocket didReceiveMessageWithString:(NSString *)string; - (void)webSocket:(SRWebSocket *)webSocket didReceiveMessageWithData:(NSData *)data; - (void)webSocket:(SRWebSocket *)webSocket didFailWithError:(NSError *)error; - (void)webSocket:(SRWebSocket *)webSocket didCloseWithCode:(NSInteger)code reason:(nullable NSString *)reason wasClean:(BOOL)wasClean; @end

服务器中断连接, Socket关闭连接

/**
* Socket关闭连接
*
* @param webSocket <#webSocket description#>
* @param code 描述
* @param reason 原因
* @param wasClean <#wasClean description#>
*/
- (void)webSocket:(SRWebSocket *)webSocket didCloseWithCode:(NSInteger)code reason:(NSString *)reason wasClean:(BOOL)wasClean
{
self.socket.delegate = nil;
self.socket = nil; NSLog(@"socket close原因: %@,",reason);
}

Socket连接失败,客户端断网会调用


/**
* Socket连接失败,客户端断网会调用
*
* @param webSocket <#webSocket description#>
* @param error 失败原因
*/
- (void)webSocket:(SRWebSocket *)webSocket didFailWithError:(NSError *)error
{
NSLog(@"客户端网络异常:%@",error);
}

暂未使用到

//暂未使用到
- (void)webSocket:(SRWebSocket *)webSocket didReceivePong:(NSData *)pongPayload
{ }

到这里基本就把Socket的连接和可以接收到服务器的数据了,现在就需要把收到的数据存到本地数据库了。

二、把接受到的信息存储到本地的数据库中

在准备数据库之前需要了解怎么做呢?

1.首先是数据模型

2.把数据转换成模型存储数据库

1.创建一个继承自NSObject的类,如:SQliteModel

#import <Foundation/Foundation.h>
#import <YYModel.h> @interface SQliteModel : NSObject <YYModel> @end


注: 此处添加`YYModel`是为了方便好数据转模型,虽然lkdbhelper里面有映射的方法,个人不是很习惯。

2.给模型添加字段 SQliteModel.h

#import <Foundation/Foundation.h>
#import <YYModel.h>
#import <LKDBHelper.h> @interface ptInfo : NSObject <YYModel> /**发送者名字*/
@property (nonatomic, copy) NSString *sendName;
/**发送头像*/
@property (nonatomic, copy) NSString *headUrl; @end @interface SQliteModel : NSObject <YYModel>
/**用户ID*/
@property (nonatomic, copy) NSString *userID;
/**当前时间*/
@property (nonatomic, copy) NSString *ptime;
/**用户名字*/
@property (nonatomic, copy) NSString *userName;
/**联系方法*/
@property (nonatomic, copy) NSString *userPhone; @property (nonatomic, strong) ptInfo *info; @end

3.实现方法 SQliteModel.m

#import "SQliteModel.h"

@implementation ptInfo

@end

@implementation SQliteModel

+ (NSDictionary<NSString *,id> *)modelCustomPropertyMapper
{
return @{@"userID":@"id",@"ptInfo":@"info"};
} + (NSDictionary<NSString *,id> *)modelContainerPropertyGenericClass
{
return @{@"info":[ptInfo class]};
} /**
*
* @return 是否将父实体类的属性也映射到SQLITE库中
*/
+ (BOOL)isContainParent
{
return YES;
} /**
* 设置数据库的表名,在查询的时候可以根据表名来查询
* 我在使用的时候不知道为什么不成功。总是提示sqlite语法错误
*/
+ (NSString *)getTableName
{
return @"SQLiteModel";
} /**
* 设置表的单个主键
*/
+ (NSString *)getPrimaryKey
{
return @"userID";
} @end

4.Model模型已经准备好了,接下来就是准备开始创建数据库、保存、查询、删除等。

在需要使用的地方包含模型#import "SQliteModel.h"就可以使用了。

4.1 创建并保存到数据库

 case 1:
{
//推送的消息1,处理数据,保存到数据库 //获取到的数据为字典
NSDictionary *dict = responseObj[@"data"];
//数据转为模型
SQliteModel *firstModel = [SQliteModel yy_modelWithDictionary:dict]; //保存模型
BOOL isSaved = [firstModel saveToDB]; }
break;

保存的时候返回一个BOOL值来判断是否保存数据库成功

多种查询语句的公式如下:

★注意:

单条件:
@"rowid = 1" 或者 @{@"rowid":@1} 多条件:
@“rowid = 1 and sex = 0" 或者 @{@"rowid":@1,@"sex":@0}
如果是or类型的条件,则只能用字符串的形式:@"rowid = 1 or sex = 0" in条件:
@"rowid in (1,2,3)" 或者 @{@"rowid":@[@1,@2,@3]}
多条件带in:@"rowid in (1,2,3) and sex=0 " 或者 @{@"rowid":@[@1,@2,@3],@"sex":@0} 时间也只能用字符串:
@"date >= '2013-04-01 00:00:00'" like也只能用字符串: @"userName like '%%JY%%'"

因为这个只是写一个流程和思路,所有请按照实际的需求来写代码,不要完全按照我的这个顺序,因为我是全都写在一个- (void)viewDidLoad 方法里面,如果完全这样写是不行滴哟!!!!

- (void)viewDidLoad {
[super viewDidLoad]; NSString *userID = @"12345"; LKDBHelper *allHelper = [SQliteModel getUsingLKDBHelper];
SQliteModel *model = [[SQliteModel alloc] init];
//1.查询
//1.1 删除所有的表
[allHelper dropAllTable]; //1.2 插入数据
model.userID = @"1129";
model.userName = @"我是锤锤";
model.userPhone = @"18786642655";
model.ptime = @"2016-11-15"; [model saveToDB];
//1.3 另一种插入方式
model.userPhone = @"1399998888";
[allHelper insertToDB:model]; //1.4查询的方式
/**
* 第一个参数是查询的条件
* orderBy:第二个参数是排序是以时间为降序
* offset:0代表从第0个位置开始,比如在加载更多的时候会用到
* count:0代表所有的,非0代表一共查询多少行数据
*/
NSMutableArray *array = @[].mutableCopy;
array = [SQliteModel searchWithWhere:[NSString stringWithFormat:@"userID=%@",userID] orderBy:@"ptime desc" offset:0 count:0]; if (array.count>0) {
//将查询到的数据保存到本地的数组中
//这样看起来有没有很熟悉的感觉?是不是简单多了
//多说一句,因为我这里并没有写的很详细。请在哪里需要用到的进行自己选择,千万不要看都不看就直接按照我的顺序来炒,那样是不行滴哟。
//各种组合的查询我后面会给出参考的地址,有需要的请参考。
self.dataSource = array;
}
//查询符合条件的条数
NSInteger rowCount=[SQliteModel rowCountWithWhere:@"userID=2250"];
NSLog(@"rowCount %ld",rowCount); //2.更新,带条件更新
//根据userID来进行更新
[SQliteModel updateToDB:model where:@{@"userID":model.userID}]; //3.删除 NSString * user=[allHelper searchSingle:[SQliteModel class] where:@{@"userPhone":@"12345678911"} orderBy:nil];
BOOL ishas=[allHelper isExistsModel:user];
if (ishas) {
[allHelper deleteToDB:user];
} //删除多条
BOOL isDeleteMore=[allHelper deleteWithClass:[SQliteModel class] where:@"userName=1239"];
if (isDeleteMore) {
NSLog(@"符合条件的都被删除");
} }

参考资料:http://www.cnblogs.com/wujy/p/4522493.html

代码下载地址

如果有什么问题请在下方留言,也可以直接Email。

Email:marlonxlj@163.com

webSocket and LKDBHelper的使用说明的更多相关文章

  1. 【Egret】WebSocket 的使用说明

    在Egret里可以使用WebSocket ,也可以使用socket.io 首先先深入了解一下 WebSocket 在Egret里的机制,看这篇文章: 主要讲解Egret里使用WebSocket和pro ...

  2. 用Java构建一个简单的WebSocket聊天项目之新增HTTP接口调度

    采用框架 我们整个Demo基本不需要大家花费太多时间,就可以实现以下的功能. 用户token登录校验 自我聊天 点对点聊天 群聊 获取在线用户数与用户标签列表 发送系统通知 首先,我们需要介绍一下我们 ...

  3. EMQ、Websocket、MQTT

    mqtt.fx的安装和使用 https://blog.csdn.net/nicholaszao/article/details/79211965 EMO 使用说明 http://emqtt.com/d ...

  4. XT交易所Websocket API

    WebSocketAPI xt为用户提供了一个简单的而又强大的API,旨在帮助用户快速高效的将xt交易功能整合到自己应用当中. WebSocket服务地址 xt WebSocket服务连接地址:wss ...

  5. 用Java构建一个简单的WebSocket聊天室

    前言 首先对于一个简单的聊天室,大家应该都有一定的概念了,这里我们省略用户模块的讲解,而是单纯的先说说聊天室的几个功能:自我对话.好友交流.群聊.离线消息等. 今天我们要做的demo就能帮我们做到这一 ...

  6. 借助FreeHttp任意篡改Websocket报文(Websocket改包)

    前言 作为Web应用中最常见的数据传输协议之一的Websocket,在我们日常工作中也势必会经常使用到,而在调试或测试中我们常常也有直接改变Websocket数据报文以确认其对应用的影响的需求,本文将 ...

  7. 漫扯:从polling到Websocket

    Http被设计成了一个单向的通信的协议,即客户端发起一个request,然后服务器回应一个response.这让服务器很为恼火:我特么才是老大,我居然不能给小弟发消息... 轮询 老大发火了,小弟们自 ...

  8. 细说WebSocket - Node篇

    在上一篇提高到了 web 通信的各种方式,包括 轮询.长连接 以及各种 HTML5 中提到的手段.本文将详细描述 WebSocket协议 在 web通讯 中的实现. 一.WebSocket 协议 1. ...

  9. java使用websocket,并且获取HttpSession,源码分析

    转载请在页首注明作者与出处 http://www.cnblogs.com/zhuxiaojie/p/6238826.html 一:本文使用范围 此文不仅仅局限于spring boot,普通的sprin ...

随机推荐

  1. 【每日一linux命令3】参数(或称选项)顺序

    一般除了特殊情况,参数是没有顺序的.举例而言,输入"–a –v"与输入"–v –a"以及"–av" 的执行效果是相同的.但若该参数后指定了要 ...

  2. 做一个gulp+webpack+vue的单页应用开发架子

    1.目标 最近项目上的事情不多,根据我自己的开发习惯,决定开发一些简单的开发架子,方便以后事情多的时候直接套用.本文讲的一个gulp+webpack+vue的单页应用架子,想要达到的目的: 可以通过命 ...

  3. Spring Enable annotation – writing a custom Enable annotation

    原文地址:https://www.javacodegeeks.com/2015/04/spring-enable-annotation-writing-a-custom-enable-annotati ...

  4. Django

    一.Django 简介 Django 是一个由 Python 写成的开放源代码的 Web 应用框架.它最初是被开发来用于管理劳伦斯出版集团旗下的一些以新闻内容为主的网站的,即是 CMS(内容管理系统) ...

  5. 深入理解CSS六种颜色模式

    前面的话 赏心悦目的颜色搭配让人感到舒服,修改元素颜色的功能让人趋之若鹜.但颜色规划不当,会让网站用户无所适从.颜色从<font color="">发展至今,保留了很多 ...

  6. javascript动画系列第二篇——磁性吸附

    × 目录 [1]范围限定 [2]拖拽范围 [3]磁性吸附 前面的话 上一篇,我们介绍了元素拖拽的实现.但在实际应用中,常常需要为拖拽的元素限定范围.而通过限定范围,再增加一些辅助的措施,就可以实现磁性 ...

  7. 游戏AI系列内容 咋样才能做个有意思的AI呢

    游戏AI系列内容 咋样才能做个有意思的AI呢 写在前面的话 怪物AI怎么才能做的比较有意思.其实这个命题有点大,我作为一个仅仅进入游戏行业两年接触怪物AI还不到一年的程序员来说,来谈这个话题,我想我是 ...

  8. Win10 UWP开发系列——开源控件库:UWPCommunityToolkit

    在开发应用的过程中,不可避免的会使用第三方类库.之前用过一个WinRTXamlToolkit.UWP,现在微软官方发布了一个新的开源控件库—— UWPCommunityToolkit 项目代码托管在G ...

  9. crontab介绍

    1.Cron的启动与关闭 由于Cron是Linux的内置服务,可以用以下的方法启动.关闭这个服务: /sbin/service crond start           //启动服务/sbin/se ...

  10. Linux虚拟化学习笔记<一>

    关于虚拟化,原理的东西是非常复杂的,要想完全理解,没有足够的耐心是不不能完全学透这部分内容的.那下面我主要以资源汇总的形式把一些资料罗列出来,帮助大家快速理解虚拟化,快速使用和配置. 为什么要虚拟化: ...