swift 蓝牙开发、OTA升级

swift 蓝牙开发、OTA升级,第1张

公司项目需要用到BLE以CBCentralManager的身份和硬件交互,开发过程中解决了一些遇到的问题和一些处理思路,这里简单记录一下。如果有什么问题或写的不对的地方希望大家可以一起讨论。

首先了解一下什么是BLE,蓝牙低能耗(Bluetooth Low Energy,或称Bluetooth LE、BLE,旧商标Bluetooth Smart,蓝牙版本40),也称低功耗蓝牙。相较经典蓝牙(蓝牙版本20),低功耗蓝牙旨在保持同等通信范围的同时显著降低功耗和成本。

设备的交互使用的是16进制,所以要对发送的数据进行16进制转换,转换方法放在末尾

连接和 *** 作一个设备就要持有这个设备对象,系统不维护设备对象的内存管理

发送数据异步回调可以封装一个任务机制,发送数据后生成一个任务,在收到想要的数据的时候关闭任务或者等待任务超时关闭任务。

iOS更换手机的时候设备的UUID会改变,如果想换手机后依然可以重连设备,就需要让设备端配合把设备唯一MAC地址放入广播内容中,给设备扩充MAC属性,根据MAC来选择设备进行连接,做到设备MAC和UUID的匹配

本篇只做了简单的功能介绍和使用,OTA部分需要按照实际协议来做。如果大家有遇到问题或者有好的主意可以找我一起讨论,万分荣幸。

iOS对蓝牙库进行了封装,封装在CoreBluetooth库,所以使用时

接下来是对一些名词的介绍

大致结构如下

注:一个CBPeripheral可以包含多个CBService ,而一个CBService 也可以包含多个CBCharacteristic 。

接下来介绍蓝牙从打开到连接到发送数据到接收数据的一整个流程

1首先肯定是权限设置,Infoplist里面加入

Privacy - Bluetooth Peripheral Usage Description

2然后是初始化中心管理者,初始化有三种方式,我使用的默认的初始化方法即

如果想自己设置线程和其他条件,则可以通过接下来的初始化方法一次性进行设置

3判断蓝牙状态,通过CBCentralManager的state来获取

4如果状态为打开,则可以进行搜索 *** 作

注:如果连接和 *** 作一个设备就要持有这个设备对象,系统不维护设备对象的内存管理

接下来就是一系列的代理事件了,我会把主要代理按照流程来进行说明,大致流程如下:

搜索-连接-连接成功/失败(设置外设代理,搜索服务)-搜索到服务(搜索特征)-搜索到特征-监听需要的特征(读写、读、写等根据情况来确定)-通过外设读写特征写入指令-收到设备返回信息-断开连接

接下来对每个代理来进行详细介绍

CBCentralManagerDelegate:中心管理者代理,负责搜索,设备状态的一些回调

CBPeripheralDelegate:外设代理,负责对外设的一些 *** 作,特征的订阅,以及设备信息和消息的更新回调

搜索&连接

连接成功&失败

搜索到服务

搜索到特征

收到外设消息更新

断开设备连接

接下来介绍OTA升级

OTA是DFU(Device Firmware Update)的一种类型,准确说,OTA的全称应该是OTA DFU,就是设备固件升级的意思。只不过大家为了方便起见,直接用OTA来指代固件空中升级(有时候大家也将OTA称为FOTA)。

OTA升级并不复杂,只需要按照硬件定制的协议,把数据按照正常的写入方式发送给硬件即可(注意查看硬件是否规定数据的大小端),如果遇到问题可以找我,可以一起讨论。

16进制类型的字符串[A-F,0-9]和Data之间的转换可以使用下面的方法。如果是包含=之类的可以直接用字符串转换Data即可

swift同样可以实现OC中AFNetworking+MJExtension的效果,实现方法是Alamofire+SwiftyJSON+HandyJSON

Alamofire:网络请求

SwiftyJSON:数据解析

HandyJSON:映射为model

节约系统开支不用每次网络请求都生成一个SessionManager子类对象

新建model类

使用方法

可以看到网络请求成功之后返回了一个数组,数组内是自定义数据类型

HandyJSON用于数据映射时注意

2重命名属性时实现方法

3映射为model类和映射为model数组的用法分别为

Demo地址

>

通常我们用 head tail 指针来记录链表的头和尾。

注意,最后一个节点的“下一个”指针是nil,第一个节点的“前一个”指针也是nil。

链表和数组的比较

首先定义一个描述节点的类型:

构建 LinkedList

快慢指针

找到环的入口点

找出环开始的节点证明

题目描述:删除单链表倒数第 n 个节点,1 <= n <= length,尽量在一次遍历中完成。

题目描述:输出一个单链表的逆序反转后的链表。

方案一:

迭代:在链表第一个和第二个元素断开链表,保存后半段,前半段拼在新head前方,然后赋值给新head:具体如下面示意

方案二:

递归:递归找到最后一个节点作为新链表的头节点,然后再更新每一个node的next 值 ,实现链表的反转。而newhead 的值没有发生改变,为该链表的最后一个结点,所以,反转后,我们可以得到新链表的head。

更多链表算法题

从苹果公开的public文件内,我们能看到Codable 其实是Decodable和Encodable两个协议的总和遵从Codable协议就需要遵从这两个协议内声明的方法

     Decodable内声明的init(from)方法来实现解析并实例化,

     Encodable对应的encode(to encoder: Encoder)来实现归档

举例:结构体和Json 数据的相互转换

    结构体要遵守Codable 协议

结构体-> json 数据 使用JSEncoder

json 数据转化为结构体,使用JSDecoder

    

Codable 可以将网络数据解析为自定义模型:

从苹果公开的public文件内,我们能看到Codable 其实是Decodable和Encodable两个协议的总和遵从Codable协议就需要遵从这两个协议内声明的方法Decodable内声明的init(from)方法来实现解析并实例化,Encodable对应的encode(to encoder: Encoder)来实现归档。

如何使用Codable

    以结构体为模型数据为例:

    首先定义的结构体要遵守Codable协议:

如果你的部分参数和后台字段不一致,需要定义CodingKeys枚举,并且遵守String 和CodingKey协议,注意,书写这个枚举是为了修正和后台字段不一致的情况,一旦写了这个枚举,所有需要自动解析的字段你都需要写进来,因为自动解析需要这个枚举;反之如果不需要修正,就不要写这个枚举。

然后你就可以将网络数据转换为你的目标类型模型:

创建JSONDecoder变量,然后调用decode方法转换即可

如果你把类作为数据模型,如果数据模型B继承于A,则需要做一些处理

像下面就会出现问题,你只能解析子类中的属性,父类中无法拿到

这里需要手动对父类的属性进行赋值,同时还必须声明CodingKeys枚举

以上就是关于swift 蓝牙开发、OTA升级全部的内容,包括:swift 蓝牙开发、OTA升级、swift网络请求、Swift 数据结构 - 链表等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/9669577.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-30
下一篇 2023-04-30

发表评论

登录后才能评论

评论列表(0条)

保存