前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >iOS中的蓝牙开发以及对iOS中设计模式的进一步理解(47,48,49,50周总结)

iOS中的蓝牙开发以及对iOS中设计模式的进一步理解(47,48,49,50周总结)

作者头像
iOS Development
发布2019-02-14 18:07:50
8880
发布2019-02-14 18:07:50
举报

蓝牙开发之第一次:

忙完IOMix,还在研究iOS的音频框架,老板突然就说要先做蓝牙相关的项目了。于是就开始了第一次开发iOS蓝牙应用。两周时间,厘清了很多之前模糊的地方。

首先有三个事情需要说明:

1、BLE(蓝牙4.0)可以实现1连多(我做的项目就是1台手机连接8个蓝牙模块);

2、iOS这边是拿不到蓝牙模块的mac地址的(安卓可以)(网上说可以通过蓝牙模块额外的返回值传送);

3、iOS BLE的开发,用到的官方框架是CoreBluetooth。当然,会有人基于此封装成其它第三方框架(基本上是将官方的“代理回调”封装成“block回调”),此次开发就是用了第三方的封装框架。

框架的选择。一开始经理建议我可以使用YmsCoreBluetooth,不过我看它的星星数,就感觉有点儿不靠谱儿,后面使用,果不其然,有个坑一直跳不出去(好像是发送指令时peripheral对象一直为空,数据发不出去,当时对蓝牙的整个流程也不熟悉,所以坑没跳出去)。所以后面又上网查了一下,找到BabyBluetooth(有想过用回官方框架,不过2周时间,猜想是来不及了),运行它们demo,看起来不错。又按照demo自己写了一下,可以链接和发数据,于是就决定用这个了。

因为之前开发过Wi-Fi通讯类型的APP,所以对比着Wi-Fi来理解。一开始,我猜想:一个“服务”,会不会就是一条指令,而“服务”下一层的若干“特征”,就是每条指令里面的对应属性?后来又猜想,是不是一个“特征”对应一条指令?上面的猜想都是错的。那“服务”和“特征究竟是什么鬼?

现在手上接触到的蓝牙模块,都只有一个“服务”(我也不知道该对应socket(Wi-Fi)通讯里的哪部分内容),然后“服务”里面的若干“特征”,有一个“特征”的属性是“Data In”的,这个“特征”就是用于写入(发送)数据(指令)给硬件的,没错,就是无论你有多少条指令,都是通过这个“特征”写入。在我们的蓝牙模块中,要用到的“服务”的UUID(唯一标示符)是“FF12”,写入数据的这个“特征”是“FF01”。

所以,你如果要写入(发送)数据,在打包好指令(指令的定义、打包就和socket通讯的类似)后,找到peripheral对象(决定你要发给哪个蓝牙模块.在链接多个蓝牙的时候要鉴别确定,连结单个蓝牙就不需要了),找到“特征”,再利用peripheral对象调用writeValue: forCharacteristic: type:方法(或者说发送writeValue: forCharacteristic: type:消息给peripheral对象),第1个参数传指令内容,第2个参数传写入的“特征”对象,第3个参数传是否有回应。是不是很明白清晰?

所以,(写入)“特征”它就像一个管道、一个通道,表示可以通过它来进行指令的写入,无论你有多少指令,都是利用这个“特征”发送。

硬件返回的数据,就不是走这个“通道了”,它另外有一个“Data Out”的“特征”,这个“特征”专门负责数据从模块发出(发给连结的手机)。只要“监听”了这个“特征”,就能收到从模块发出的数据了。所以,和走tcp传输的Wi-Fi不同,tcp发送和接收数据,都是在同一个“通道”进行;而蓝牙,则数据发送用一个“特征”,数据接收,又用另外一个“特征”,是两个不同的“管道”(容许我暂时这么理解)。

上面说到用writeValue: forCharacteristic: type:方法发送指令,好像没有用到“服务”,那“服务”还有什么用?用于发送数据时找“特征”,因为“服务”和“特征”是树状结构,要找到“特征”,就必须通过“服务”。

另外,writeValue: forCharacteristic: type:的第三个参数,其实只有两种情况,一个是有返回值的CBCharacteristicWriteWithResponse,另外一个是没有返回值的CBCharacteristicWriteWithoutResponse。这个参数可不是你想写哪个就写哪个,要决定于该“特征”的属性(CBCharacteristicProperties类型),有10种可能。CBCharacteristicPropertyWriteWithoutResponse对应的是CBCharacteristicWriteWithoutResponse,CBCharacteristicPropertyWrite对应的是CBCharacteristicWriteWithResponse,不能写错,否则就会发不出去指令。我就之前就掉进这个坑一次。

对iOS中“设计模式”的进一步理解:

随着写项目的数量提升,再回头去看MVC,又有了深一点的认识。

在项目实践中,我发现很难严格遵守MVC模式,当然我不是指大家把MVC三者搞混,而是大家都会想方设法给控制器“C”减肥,将一些其它功能独立出控制器之外。所以无论是《iOS编程》书中提及到的MVCS,还是在网上大家经常讨论的MVVM,两者的目标应该是一致的——给控制器“C”瘦身。

其实从经理写Device类(负责实现和硬件通讯功能的类)开始,项目就不是严格意义上的MVC模式了,它将“负责和硬件通讯的功能”从控制器“V”中独立开来。然后我又将“负责数据本地保存的功能”独立到Store类中。再用一个单例“持有”它们,其它控制器通过这个单例获取对应的能力(和硬件通讯、保存数据)或获取数据。

所以我们以后和硬件通讯类型的APP,我们项目的组织模式可以说是MVCDS了:D负责和硬件通讯,S负责保存数据。也正是用了这种“设计”(其实我并不是事先设计好的),才能实现和同事的分工合作:我专心写和硬件通讯的功能;同事专心实现UI。

而关于MVVM这种模式,这两天看到有人翻译的国外一篇《ReactiveCocoa 和 MVVM 入门》的文章,终于有了一点初步认识(之前看的文章,都是不明所以),文章用一个图示说明VM(view model)是分别从控制器“C”及视图“V”中瘦身出来的一部分内容(“C”的占大部分)。所以,我可以从另一个角度去理解MVVM了:VM也可以看作是对“C”瘦身出来的内容,就类似我们的项目瘦身出“D”和“S”的内容,只是大家的瘦身方式不一样,而且VM还包含了部分“V”的内容(不知道是否就是ReactiveCocoa这一部分涉及到的,后续再深入研究)

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2015.12.20 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档