精华内容
下载资源
问答
  • iOS App连接外设的几种方式

    千次阅读 2016-11-08 17:36:24
    iOS App连接外设的几种方式

    iOS development

    一般iOS开发者做APP开发大部分时候都是通过Http(s)请求跟后台服务器打交道,做一些信息展示和用户交互。很少涉及到去跟外部硬件设备连接的开发。随着近年来车联网和物联网的兴起,智能家居和智能硬件的逐步火热,越来越多的app被开发出来,用来跟硬件设备进行来连接,获取硬件相关信息展示或者发送指令控制硬件来提供服务。故本文就针对iOS的app如何跟外部设备进行连接通信这个问题跟大家交流一下,如有不正确的地方恳请各位看官指正。本文原创,欢迎转载,转载请注明出处。

    iOS App连接外设的几种方式

    如上图所示,我把iOS App连接外设的常用方式总结了一下,可以分为三大类:

    iOS App连接外部硬件方式第一类是通过网络端口

    建立Socket使用TCP/IP协议族进行通信,天然支持多通道,想要几个通道就建几个socket就行了。它主要有三种方式,第一种方式是Wi-Fi连接,优点是:简单,不需要集成MFi芯片,只要对应的硬件有无线网卡,然后手机和硬件连接到同一个局域网中就可以使用socket通过网络协议通信了。缺点也很明显:(1)无线连接信号容易受到干扰,不太稳定,容易断开;(2)如果硬件使用的场合没有公共wifi,就需要手机自建热点共享,硬件进行热点接入,操作步骤较多,对用户来说学习使用成本较高,并且热点共享要求手机本身的数据移动网络是稳定的,在没有移动数据网络信号的地方,热点无法建立。

    使用网络端口的第二种方式是USB热点共享,这个其实跟Wi-Fi中的热点共享非常类似,也不需要集成MFI芯片,区别就是USB线共享热点,走的是有线,不容易受到干扰,更稳定,而且iPhone可以边使用可以边充电;缺点也是操作步骤比较复杂,需要先打开个人热点共享;

    使用网络端口的第三种方式是NCM,就是把USB端口虚拟成标准的网络端口,然后手机和外设就能通过有线网络直连了,可以理解成手机和外设通过一跟网线连起来了,然后就可以用socket通过TCP,UDP进行通信了。它的优点是:有线连接,非常稳定,带宽足够;也不依赖移动网络信号;但是它的缺点就是:需要集成MFI芯片并进行MFI认证,有一定门槛。更变态的是这么好的一种方式,苹果只允许它自己的CarPlay使用,如果硬件使用NCM跟其他app通信,是不能通过MFI认证的。

    关于如何使用Socket进行TCP、UDP连接,推荐github上的开源项目CocoaAsyncSocket

    iOS App连接外部硬件方式的第二大类是EAP

    EAP全拼是External Accessory Protocol ,外部设备协议。这个是苹果推荐使用的外设连接方式。需要外设集成MFI芯片进行MFI认证。手机端开发相对简单,只要集成iOS系统提供的一个框架ExternalAccessory.framework,并且在info.plist中配置好协议字符串(Supported external accessory protocols),当iOS 设备通过USB线或者蓝牙连接到对应硬件时,iOS系统会把符合MFI认证要求的外设抽象成了一个流对象,App通过指定的协议字符串来创建一个EASession类的实例来访问到该流对象,就能通过NSInputStream和NSOutputStream跟硬件件进行通信了。它有两种模式,一种是叫EASession的模式,它带宽相对较低,但是允许同时通过多个协议字符串创建多个会话,也就是说直接支持多个通道;另外一种是Native Transport的模式,这种模式的优点是带宽足够大,理论值是100MB以上,但是不支持多通道,如果业务层需要支持多数据通道的话需要App自己进行通道的复用与拆分,并且Native Transport需要iPhone工作在USB host模式,硬件需要支持USB 模式切换。

    关于如何使用EAP跟外部设备进行通信,可以参考苹果官方的demo进行入门和学习。

    iOS App连接外部硬件方式的第三大类就是BLE

    BLE即低功耗蓝牙,是iOS7.0以后才支持的连接方式。它的优点是不需要集成MFI芯片做认证,功耗低,手机端开发也相对简单,集成iOS系统提供的CoreBluetooth.framework就行。缺点是:带宽很低,一般适合于只需要传输少量数据的场景。比如前两年非常火爆的各种所谓智能硬件,像智能水杯,智能体重计,运动手环等,都是采用这种连接方式。

    关于如何使用BLE进行硬件连接,可以参考本人在github的一个小开源项目(https://github.com/luoxubin/BlueTooth4.0)。另外本人自己业余时间也做过一个BLE连接外设的App-裤宝(名字有创意吧,裤子里的宝贝,是跟我另外两个小伙伴一起做的创业项目,目前该项目黄了, 不过app还在线上,AppStore里搜索“裤宝”可以下载到

    总结一下,图中带MFI字样的表示该连接方式需要硬件集成MFi芯片,做MFi认证。关于苹果的MFI认证,对iOS开发中来说其实是一个比较陌生并且繁琐的topic,原因如下:

    (1)网上鲜有资料,Google基本上查不到。 因为MFi认证是由硬件生产商主导进行的,苹果首先对硬件生产商的实力(质量,信誉,生产规模)有很苛刻的要求,满足要求的才有进行MFI认证的资格。满足MFi认证资格要求的硬件生产商,提交了MFi产品计划后才能得到苹果MFi开发的官方文档,这个文档是带水印的,不允许外泄;

    (2)MFi认证周期很长,过程也很复杂;

    (3)苹果官方沟通渠道很窄,电话打不通,邮件回复不及时。

    后面我计划找时间写一篇文章专门介绍本人关于MFI认证的一些经验和感想,有兴趣的可以关注我的微信公众号:云峰雾阁。谢谢大家宝贵时间阅读此文。

    http://www.toutiao.com/i6314562449295016450/?group_id=6312036206315028737&group_flags=0

    展开全文
  • iOS App 连接外设的几种方式

    万次阅读 2017-05-31 18:00:10
    原创作者: Max_Marry ... 随着近年来车联网和物联网的兴起,智能家居和智能硬件的逐步火热,越来越多的 App 被用来跟硬件设备进行来连接,获取...iOS App 连接外设的常用方式可以分为三大类: 网络端口 建立 Soc

    原创作者: Max_Marry

    文章地址: http://www.jianshu.com/p/852bf92c5c92

    随着近年来车联网和物联网的兴起,智能家居和智能硬件的逐步火热,越来越多的 App 被用来跟硬件设备进行来连接,获取硬件相关信息用以展示或者发送指令控制硬件来提供服务。

    iOS App 连接外设的常用方式可以分为三大类:

    网络端口

    建立 Socket 使用 TCP/IP 协议族进行通信,天然支持多通道,想要几个通道就建几个 Socket 就可以。它主要有三种方式,

    Wi-Fi 连接

    优点:

    • 简单,不需要集成 MFi 芯片

    • 只要对应的硬件有无线网卡,然后将手机和硬件连接到同一个局域网中就可以使用 Socket 通过网络协议通信

    缺点:

    • 无线连接信号容易受到干扰,不太稳定,容易断开

    • 如果硬件使用的场合没有公共 Wi-Fi,就需要手机自建热点共享,硬件进行热点接入,操作步骤较多,对用户来说学习使用成本较高,并且热点共享要求手机本身的数据移动网络是稳定的,在没有移动数据网络信号的地方,热点无法建立。

    USB 热点共享

    这个其实跟 Wi-Fi 中的热点共享非常类似,也不需要集成 MFi 芯片。

    优点:

    • USB 热点共享,走的是有线,不容易受到干扰,更稳定,

    • iPhone 可以边使用可以边充电

    缺点:

    • 操作步骤比较复杂,需要先打开个人热点共享

    NCM

    就是把 USB 端口虚拟成标准的网络端口,然后手机和外设就能通过有线网络直连了,可以理解成手机和外设通过一跟网线连起来了,然后就可以用 Socket 通过 TCP,UDP 进行通信了。

    优点:

    • 有线连接,非常稳定,带宽足够

    • 不依赖移动网络信号

    缺点:

    • 需要集成 MFi 芯片并进行 MFi 认证,有一定门槛

    • 除了 CarPlay,其他跟 iPhone 连接的外设都不能使用 NCM 的方式跟 iPhone 上的 App 进行连接和通信

    EAP

    EAP 全拼是 External Accessory Protocol,即外部设备协议。这个是苹果推荐使用的外设连接方式。需要外设集成 MFi 芯片进行 MFi 认证。手机端开发相对简单,只要集成 iOS 系统提供的一个框架 ExternalAccessory.framework,并且在 info.plist 中配置好协议字符串 (Supported external accessory protocols),当 iOS 设备通过 USB 或者蓝牙连接到对应硬件时,iOS 系统会把符合 MFi 认证要求的外设抽象成了一个流对象,App 通过指定的协议字符串来创建一个 EASession 类的实例来访问到该流对象,就能通过 NSInputStream 和 NSOutputStream 跟硬件件进行通信了。

    • EASession 模式:它的带宽相对较低,但是允许同时通过多个协议字符串创建多个会话,也就是说直接支持多通道

    • Native Transport 模式:它的带宽足够大,理论值是 100MB 以上,但是不支持多通道,如果业务层需要支持多数据通道的话需要 App 自己进行通道的复用与拆分,并且 Native Transport 需要 iPhone 工作在 USB Host 模式,硬件需要支持 USB 模式切换

    关于如何使用 EAP 跟外部设备进行通信,可以参考苹果官方的 Demo (https://developer.apple.com/library/content/samplecode/EADemo/Introduction/Intro.html)进行入门和学习。

    BLE

    BLE 即低功耗蓝牙,是 iOS7.0 以后才支持的连接方式。

    • 优点:不需要集成 MFi 芯片做认证,功耗低,手机端开发也相对简单,集成 iOS 系统提供的 CoreBluetooth.framework 即可

    • 缺点:带宽很低,一般适合于只需要传输少量数据的场景。比如各种智能硬件,像智能水杯,智能体重计,运动手环等,都是采用这种连接方式

    总结一下,图中带 MFi 字样的表示该连接方式需要硬件集成 MFi 芯片,做 MFi 认证。关于苹果的 MFi 认证,对 iOS 开发中来说其实是一个比较陌生并且繁琐的 Topic,原因如下:

    • 网上鲜有资料,Google 基本上查不到。 因为 MFi 认证是由硬件生产商主导进行的,苹果首先对硬件生产商的实力 (质量,信誉,生产规模) 有很苛刻的要求,满足要求的才有进行 MFi 认证的资格。满足 MFi 认证资格要求的硬件生产商,提交了 MFi 产品计划后才能得到苹果 MFi 开发的官方文档,这个文档是带水印的,不允许外泄

    • MFi认证周期很长,过程也很复杂

    • 苹果官方沟通渠道很窄,电话打不通,邮件回复不及时

    关于 MFi 申请的一些事情

    什么是 MFi 认证?

    苹果 MFi 认证,是苹果公司(Apple Inc.)对其授权配件厂商生产的外置配件的一种标识使用许可,是 Apple 公司 “Made for iOS” 的英文缩写。

    为什么要做 MFi 认证?

    • 从苹果角度来看,为了更好的巩固苹果的生态圈,只有集成了有
      MFi 芯片,才能跟 iPhone、iPod,iPad 进行连接通信。而只有经过了 MFi 认证的企业才能批量购买 MFi 芯片,并且都 MFi 芯片的供销链条都有很严格的监督管理,所以这样苹果可以严格控制只有那些满足苹果规范和要求的外设才能加入到苹果生态圈。

    • 从生产厂商来看,经过苹果官方授权,配件产品能完美兼容苹果智能设备。提交 MFi 认证过程中,硬件设备需要经过苹果要求的
      ATS 自测以及苹果的严格测试,产品质量更有保证。消费者也更加信任经过了 MFi 认证授权的配件;最后成功获得 MFi 授权这也成为技术与质量实力的一种标志,因为 MFi 认证通过率仅 2%,其中大部分企业因为申请资格不符合直接被拒绝。

    • 从 iOS 开发人员来看,MFi 认证是由硬件生产商主导进行申请的,是苹果对外设配件的一种认证和授权。但是很多外设跟苹果进行连接,并不只是跟 iOS 设备硬件或者 iOS 系统配合就可以完成对应的功能 (比如充电、CarPlay、播放 iPod 音乐 (A2DP)、接听蓝牙电话 (HPF) 或者提供 GPS 输入源等)。很多时候为了实现特定的需求,需要由 iOS App 的配合,由 iOS App 跟对应外设进行连接和通信,传输相关的控制命令对外设进行控制,或者传输相关的外设数据进行展示。iOS App 跟外设的连接方式有网络、EAP 和 BLE,其中 EAP 是苹果官方推荐的跟外设连接的方式。只有经过 MFi 认证的外设才能使用 EAP 跟 App 进行通信。

    如何做 MFi 认证?

    MFi 认证的流程比较复杂,可以归纳总结为三个部分,如下图所示。

    其中黄色背景标注的部分是可能跟 iOS App 开发者相关的。

    一、申请人提交申请资料

    首先,收集公司资料信息,这些资料主要包括了认证负责人联系信息,企业情况介绍,公司组织架构、企业网站,物料品质控制以及 ISO 体系证书等资料。然后是在苹果 MFi 官网(mfi.apple.com)上进行注册,并提交第一步收集到的公司资料,进行账号申请。

    接下来苹果会进行 MFi 体系审核。这个是非常关键的一个步骤。 主要考察公司对 MFi 芯片的管理体系,看公司是否有规范的流程和系统来管理 MFi 芯片,能有效防止转售芯片或者挪用芯片 (把芯片用到未通过 MFi 认知的项目上),苹果会安排专人或者代理公司来抽查。

    如果 MFi 体系审核过了,苹果还会对公司其他情况进行考察,来评估该公司是否满足 MFi 会员的资格。审核的标准主要看公司相关资质,是否有较大的生产规模;是否拥有自主品牌;品牌在业内是否有较高的地位 (主要表现为各类荣誉);是否曾为其他国际知名企业供货;研发人员是否达到苹果要求的人数等,申请者一定保证申报资料的真实性,苹果公司都会一一核实。

    如果这些条件都满足,恭喜你公司成为了 MFi 会员,能够有资格购买样品芯片,并且拿到苹果提供的 MFi 官方开发文档,该文档的每一页都是带有申请人姓名水印的,禁止对外公开,如果被发现,有可能会被取消 MFi 会员资格。据说大部分的企业都会被卡在会员资格审核这一步。

    二、提交产品计划,研发和自测

    如果你的公司是属于那幸运的那一小部分通过了 MFi 会员资格审核,拿到了苹果的 MFi 研发官方文档,也购买了 MFi 样品芯片,那么就可以提交产品计划,进行产品研发和自测了。

    提交产品计划是非常关键的一步,需要根据要研发的公司产品的形态、所用技术方案和需要支持的 iOS 设备、iOS 的相关信息都进行详细的描述,其中比较重要信息有。

    (1) 附件概览 (Accessory Overview)

    技术方案 (Technology) 如果你是做支持 CapPlay 的车机,那么就选择 CarPlay,否则都应该选择 iAP;如果你的硬件需要跟 iPhone 连接,并且处理相关业务,而不仅仅是充电线或者数据线,那么在 Components 里应该选择 Authentication coprocessor。

    (2) 固件和硬件 (Firmware & Hardware)


    现在所有的 MFi 认证的硬件都需要支持 iAP2 协议,所以必须要选
    iAP2 或者同时支持 iAP2 和 iAP1。然后外设硬件跟苹果设备是如何通信的,是使用 USB 的 Host 模式,还 USB 的 Devices 模式,还是串口或者蓝牙,这个需要根据产品的需求、特性进行选择。

    (3) 选择硬件所支持的 iAP2 的特性

    (4) 选择所支持的苹果设备型号

    根据产品的设计选择所需要支持的苹果设备型号,包括 iPad,iPhone 和 iPod 的各种型号。

    (5) App 相关的信息

    这部分也是 iOS 开发者需要重点关注的部分,包括 App 的版本号,BundleID 和协议字符串以及 iOS App 的主要功能特性描述,这部分信息需要跟最后送 MFi 审核时附带的 App 测试包的信息保持一致。提交了产品计划之后,就可以拿到 PPID (Product Plan ID)。这个 PPID 也是跟 iOS App 开发者需要关注的。当 App 开发完成,提交 AppStore 上线时,需要在版本审核备注信息里带上这个 PPID,否则审核是过不了的。

    接下来就可以进行产品研发了。主要是硬件生成商需要根据苹果提供的开发文档进行硬件和驱动认证程序的开发。而 iOS App 开发者则主要是需要成 iOS 系统提供的一个系统框架 ExternalAccessory.framework,并且在 info.plist 中配置好协议字符串 (Supported external accessory protocols)。当 iOS 设备通过
    USB 线或者蓝牙连接到对应硬件时,iOS 系统会把符合 MFi 认证要求的外设抽象成了一个流对象,App 通过指定的协议字符串来创建一个 EASession 类的实例来访问到该流对象,就能通过
    NSInputStream 和 NSOutputStream 跟硬件件进行通信了。这部分功能实现可以参考苹果官方的 EADemo( https://developer.apple.com/library/content/samplecode/EADemo/Introduction/Intro.html )进行入门和学习。

    产品研发完成后需要进行 ATS (Accessory Test System) 自测,并提供自测报告。ATS 自测苹果会提供 ATS Box 的测试工具和软件,主要是针对硬件进行电气特性相关的测试,包括各个节点的电压电流值是否满足苹果要求,然后传输带宽是否稳定,是否达到苹果要求等等。

    自测完成之后就可以把硬件和所配套的软件 (iOS App 的 ipa 安装包) 送到苹果指定的测试实验室进行认证测试。iOS 开发者在这个步骤需要关注的是如何打包 ipa 包。因为如果直接用开发证书打包,那么苹果测试人员的 iPhone 不在你开发证书的设备列表中,是无法安装的。如果用企业证书打包的话,可能 AppStore 发布证书对应的 BundleID 跟企业证书的 BundleID 不一致,所以也不可行。所以推荐的做法是,等到产品研发完成和自测之后,就带上产品计划中拿到的 PPID,提交 AppStore 进行审核。等审核通过之后,就可以直接从 AppStore 下载对应的 ipa 安装包,配合硬件一起送 MFi 认证测试了。

    三、测试审核和批量生产

    这个阶段也是硬件生产商主导进行的,跟 iOS App 开发者关系不大。当硬件的 MFi 认证送审通过之后,还需要对产品的包装也提交认证和审核。审核通过之后,就可以获得苹果授权进行 MFi 芯片的批量购买,然后根据销售计划进行硬件的批量生产和销售了。

    整个 MFi 认证的周期大概需要3个月到半年的时间,并且每次提交认证测试都需要支付一笔600美金的测试费用,所寄去测试的硬件测试样品苹果也是不会寄回来的。

    iOS 外设连接黑科技,不需要 MFi 认证,实现 USB 连接

    USBMuxd,利用这种连接方式不需要做 MFi 认证,支持 iPhone 上的 App 跟外设通过进行通信,非常方便。

    基本原理 
    iPhone 的 iOS 系统中自带了 USBMuxd 服务,该服务能够实现
    USB-TCP 协议的转换,能够把 USB 的端口映射到本机 (localhost) 的 TCP 端 (基于 Unix Domain Socket )。只需要在外设端也实现一个 USBMuxd 服务,并指定端口映射关系, 那
    iPhone 的 App 和外设上的应用就可以使用 Socket 进行 TCP 进行通信了。

    一个开源实例
    开源项目 peertalk( https://github.com/rsms/peertalk ) 是一个完整的使用 USBMuxd 方式实现 iPhone App 跟 Mac App 进行 TCP 通信的例子。因为 Mac OS 系统中天生就自带了 USBMuxd 服务,所以 peertalk 的 Mac 端程序是比较简单的。外设一般都不会是 Mac 系统,而是 Android 或者 Linux 系统,那怎么办呢?那就自己在系统中集成 USBMuxd 服务,这里可以利用到 libimobiledevice( https://github.com/libimobiledevice ) 实现在外设上集成 USBMuxd 服务。

    MFi iOS App 端开发步骤

    与附件设备通讯的 App 需设备支持的协议,这些协议由设备制造商维护,可是自定义或标准协议,标准协议可与其他设备通信,iOS不负责这些协议的维护。

    为防止命名空间冲突,推荐使用反 DNS 形式命名协议,如
    com.apple.myProtocol、com.dji.video、com.dji.protocol、com.dji.common。

    1、编程步骤

    1.1、引入框架与头文件

    外部附件框架 (ExternalAccessory.framework) 为 App 与附件设备通信提供了桥梁。因此,在 Xcode 项目中,需要为每个与附件设备通信相关的项目添加 ExternalAccessory.framework。

    下一步是引入头文件 #import <ExternalAccessory/ExternalAccessory.h>

    1.2、声明App支持的协议

    不声明协议直接调用EA框架的类会崩溃。
    使用 UISupportedExternalAccessoryProtocols 键在 Info.plist 中声明支持的协议,值为数组,数组的元素为支持的协议,元素的顺序任意且不限数量。这些值只用于判断 App 与附件设备的通信能力。当App与设备通信时,具体通信协议由我们编程决定。

    当附件设备插入 iOS 设备时,系统才知道 App 可被新插入的设备启动。若当前已安装的 App 都没注册协议,则系统可能到 App Store 去搜索支持新设备声明的协议的 App。

    UISupportedExternalAccessoryProtocols 对应的值虽说可参考UISupportedExternalAccessoryProtocols( https://developer.apple.com/library/content/documentation/General/Reference/InfoPlistKeyReference/Articles/iPhoneOSKeys.html#//apple_ref/doc/uid/TP40009252-SW4 ),实际此链接并没给出有帮助的信息,《MFi Accessory Interface Specification for Apple Devices》也没给出所谓标准协议的字符串值。

    1.3、开始通信

    1. 创建 EASession。此对象管理与附件设备交互的情况,它与底层系统工作,在设备上来回传输数据。一旦会话建立,数据通过
      NSInputStream 和 NSOutputStream 的实例在 App 中传输。收发的数据包的格式由与附件设备通信的协议决定。

    2. 接收数据。使用自定义委托对象,监视 NSInputStream 实例可从附件设备接收数据。

    3. 发送数据。向 NSOutputStream 写入数据包即可发送至附件设备。

    1.4、一个读取外接设备的示例

    1. Info.plist 中加入 Supported external accessory protocols,值为 com.apple.p1。这个只是令系统认为我们的应用有能力与外接设备沟通,这里使用 Lightning USB Camera Adapter 测试。

    2. 读取外接设备信息代码:

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

     NSMutableString *info = [[NSMutableString alloc] initWithCapacity:1024];


     EAAccessoryManager *manager = [EAAccessoryManager sharedAccessoryManager];


     NSArray<EAAccessory *> *accessArr = [manager connectedAccessories];


     for (EAAccessory *access in accessArr) {

         for (NSString *proStr in access.protocolStrings) {

             [info appendFormat:@"protocolString = %@\n", proStr];

         }


         [info appendFormat:@"\n"];

         [info appendFormat:@"manufacturer = %@\n", access.manufacturer];

         [info appendFormat:@"name = %@\n", access.name];

         [info appendFormat:@"modelNumber = %@\n", access.modelNumber];

         [info appendFormat:@"serialNumber = %@\n", access.serialNumber];

         [info appendFormat:@"firmwareRevision = %@\n", access.firmwareRevision];

         [info appendFormat:@"hardwareRevision = %@\n", access.hardwareRevision];

         [info appendFormat:@"dockType = %@\n", access.dockType];

     }


     dispatch_async(dispatch_get_main_queue(), ^{

         label.text = info;

     });

    });


    运行结果为:

    manufacturer = Apple

    name = Apple USB Camera Adapter

    modelNumber = A1440

    serialNumber = 

    firmwareRevision = 1.0.0

    hardwareRevision = 1.0.0

    dockType = (null)


    1.5、与外接设备交互数据的示例

    如下代码展示与 DXO One 相机通信。

    1. 在非 UI 线程中打开设备,否则可能导致程序崩溃。

    EAAccessoryManager *manager = [EAAccessoryManager sharedAccessoryManager];


    NSArray<EAAccessory *> *accessArr = [manager connectedAccessories];


    if (accessArr.first) {

      EASession *session = [[EASession alloc] initWithAccessory:accessArr.firstObject forProtocol:@"com.dxo.one.protocol"];


      if (!session) return;


      NSInputStream *inputStream = [session inputStream];


      if (!inputStream) {

        // LOG inputStream = null

      }


      inputStream.delegate = self;


      [inputStream open];

    }


    1. 实现 NSStreamDelegate 协议

    - (void)stream:(NSStream *)aStream handleEvent:(NSStreamEvent)eventCode {

       // LOG stream & event code

        switch (eventCode) {

            case NSStreamEventNone:

                break;

            case NSStreamEventOpenCompleted:

                // 开始读取

                break;

            case NSStreamEventHasBytesAvailable:

                // 获取可读数据大小,读取流才有效。

                break;

            case NSStreamEventHasSpaceAvailable:

                // 获取可写空间大小,写入流才有效。

                break;

            case NSStreamEventErrorOccurred:

                // 出错处理

                break;

            case NSStreamEventEndEncountered:

                // 读取结束

                break;

        }

    }


    2、ExternalAccessory框架

    1、EAAccessory 
    提供一个已连接的设备的信息,如制造商,固件版本等。

    2、EAAccessoryManager 
    协调MFi设备与iOS设备之间的工作。

    3、EASession 
    用来创建 App 与附件设备之间的通信通道。

    4、EAWiFiUnconfiguredAccessory 
    提供未配置的 MFi Wireless Accessory Configuration 设备的信息给 App。

    5、EAWiFiUnconfiguredAccessoryBrowser 
    让 App 访问 MFi Wireless Accessory Configuration 进程。

    3、开发技巧

    Lightning 接了设备则不能连接计算机,所以直观的做法是,将日志用 UITextView 显示出来。写成日志就得每次都拔掉设备,插上电脑,如此反复。

    另一个办法是,通过蓝牙测试传输协议,手机连接电脑,可单步调试。验证完再用 Lightning 连接设备联调。

    因本人目前在做关于 iOS App 连接外设方面的工作,因此搜集查找相关信息,文章中信息出自于以下简友:我是云峰小罗熊皮皮,在此对两位的分享表示感谢。

    展开全文
  • android蓝牙app连接外设时崩溃问题

    千次阅读 2018-09-18 13:57:15
    连接蓝牙设备的app在连接时,如遇到蓝牙设备的信号名称错误或蓝牙设备关闭时,app有一定概率出现程序闪退; 经查证原因出现在接收蓝牙信号的广播的地方,原代码如下: public BroadcastReceiver mReceiver = new ...

    近期公司有蓝牙设备项目,遇到个问题;

    连接蓝牙设备的app在连接时,如遇到蓝牙设备的信号名称错误或蓝牙设备关闭时,app有一定概率出现程序闪退;

    经查证原因出现在接收蓝牙信号的广播的地方,原代码如下:

    public BroadcastReceiver mReceiver = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                //g_Context.unregisterReceiver(this); ---deleted by jerry
                String action = intent.getAction();
                String strDevName = new String();
              
                if ( BluetoothDevice.ACTION_FOUND.equals(action) ) {
                    BluetoothDevice device = intent
                            .getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                    strDevName = device.getName();

                    
                    if ( strDevName.equalsIgnoreCase(bt_Name)) {
                        if( mBluetoothAdapter != null )
                        mBluetoothAdapter.cancelDiscovery(); //---deleted by jerry                    
                        int connectState = device.getBondState(); 
                        switch (connectState) {
                        case BluetoothDevice.BOND_NONE: // Not Matched
                            dataReturn(0xA1, "FPIBTStatus", 1, null); // buletooth bonded
                            try {
                                Method createBondMethod = BluetoothDevice.class
                                        .getMethod("createBond");
                                createBondMethod.invoke(device);
                            } catch (Exception e) {
                                e.printStackTrace();
                            }                        
                            break;
                        case BluetoothDevice.BOND_BONDED: // Has Matched
                            connectDevice(device.getAddress(), mSecureFlag);
                            break;
                        }
                    }
                }
                //return;
            }
        };

    上面代码会出现一定概率的崩溃,在此app搜索到的蓝牙信号中,如果有蓝牙名称是null 的话,这个比较的代码就会因为空对象调用接口而崩溃:strDevName.equalsIgnoreCase(bt_Name);

    我这里加了句如为空直接返回了       

     if( strDevName == null )
          return;

    多唠一句,intent.getAction() 在返回"android.bluetooth.adapter.action.DISCOVERY_FINISHED"时说明蓝牙信号搜索完毕,最好返回提示,不然接收端不知道什么情况,以为还在搜索中,一直在等待;

    展开全文
  • BLE 蓝牙 与APP 得交互 内设 外设

    千次阅读 2016-11-26 10:07:36
    这两组api粉笔对应不同的业务常见:左侧叫中心模式,就是以你的app作为中心,连接其他的外设的场景;而右侧称为外设模式,使用`手机作为外设`连接其他中心设备操作的场景 服务和特征(service andcharacteristic)  ...

    蓝牙设置 


    CoreBluetooth框架的核心其实是:peripheral和central,对应他们分别有一组相关的API和类

    这两组api粉笔对应不同的业务常见:左侧叫中心模式,就是以你的app作为中心,连接其他的外设的场景;而右侧称为外设模式,使用`手机作为外设`连接其他中心设备操作的场景

    服务和特征(service andcharacteristic)

        * 每个设备都会有1个or多个服务

        * 每个服务里都会有1个or多个特征

           * 特征就是具体键值对,提供数据的地方

        * 每个特征属性分为:读,写,通知等等

    - 外设,服务,特征的关系

     

    BLE中心模式流程

    - 1.建立中心角色

    - 2.扫描外设(Discover Peripheral)

    - 3.连接外设(Connect Peripheral)

    - 4.扫描外设中的服务和特征(Discover Services And Characteristics)

        * 4.1 获取外设的services

        * 4.2 获取外设的Characteristics,获取characteristics的值,,获取Characteristics的Descriptor和Descriptor的值

    - 5.利用特征与外设做数据交互(Explore And Interact)

    - 6.订阅Characteristic的通知

    - 7.断开连接(Disconnect)

    BLE外设模式流程

    - 1.启动一个Peripheral管理对象

    - 2.本地peripheral设置服务,特征,描述,权限等等

    - 3.peripheral发送广告

    - 4.设置处理订阅,取消订阅,读characteristic,写characteristic的代理方法

    蓝牙设备的状态

    - 1.待机状态(standby):设备没有传输和发送数据,并且没有连接到任何外设

    - 2.广播状态(Advertiser):周期性广播状态

    - 3.扫描状态(Scanner):主动搜索正在广播的设备

    - 4.发起链接状态(Initiator):主动向扫描设备发起连接

    - 5.主设备(Master):作为主设备连接到其它设备.

    - 6.从设备(Slave):作为从设备链接到其它设备

    蓝牙设备的五种工作状态

    - 准备(Standby)              - 广播(Advertising)

    - 监听扫描(Scanning)         - 发起连接(Initiating)

    - 已连接(Connected)

    牙和版本使用限制

    - 蓝牙2.0:越狱设备

    - BLE:iOS6以上

    - MFI认证设备:无限制

    BLE测试

    - 两台BLE设备

    - 如何让iOS模拟器也能测试BLE?

       * 买一个CSR蓝牙4.0 USB适配器,插在Mac上

       * 在终端输入sudo nvrambluetoothHostControllerSwitchBehavior="never"

          * 重启Mac

          * 用Xcode4.6调试代码,将程序跑在iOS6.1模拟器上

       * 苹果把iOS7.0模拟器对BLE的支持移除了

    BLE中心模式流程-coding

    BLE中心模式流程

    - 1.建立中心角色

    - 2.扫描外设(Discover Peripheral)

    - 3.连接外设(Connect Peripheral)

    - 4.扫描外设中的服务和特征(Discover Services And Characteristics)

        * 4.1 获取外设的services

        * 4.2 获取外设的Characteristics,获取characteristics的值,,获取Characteristics、Descriptor和Descriptor的值

    - 5.利用特征与外设做数据交互(Explore And Interact)

    - 6.订阅Characteristic的通知

    - 7.断开连接(Disconnect)

    - central模式用的都是左边的类,而peripheral模式用的是右边的类

     peripheral模式的流程

    - 1.引入CoreBluetooth框架,初始化peripheralManager

    - 2.设置peripheralManager中的内容

    - 3.开启广播advertising

    - 4.对central的操作进行响应

        - 4.1 读characteristics请求

        - 4.2 写characteristics请求

        - 4.4 订阅和取消订阅characteristics

    -MFI:(make foriPhone/iPad/iTouch)专门为苹果设备制作的设备

    - 支持MFI的设备开发使用此框架

    iBeacon简介

    - iBeacon起源:苹果在WWDC2013上正式推出了iBeacon,并且在iOS7设备商配置了该功能

    - iBeacon应用:苹果期望将其作为一种技术标准,这个标准允许移动App(包括iOS和Android设备)监听来自于iBeacon设备上的信号并作出响应.

    - iBeacon设备:配备有BLE通信功能,并使用BLE向周围发送自己特有的ID,移动设备上的App在接收到该ID后可以作出相应的反应.比如,我们在店铺里设置iBeacon发射器,便可以让应用接收到信息并将这一信息通知给服务器,服务器向我们的App返回与该店铺相关的产品或折扣信息.

    - 本质上讲,iBeacon技术允许App了解他们在某个局部范围内的位置,并向用户分发基于位置的超文本上下文内容.

    MultipeerConnectivity

    - 在iOS7中,引入了一个全新的框架——Multipeer Connectivity(多点连接)。

    - 利用Multipeer Connectivity框架,即使在`没有连接到WiFi(WLAN)或移动网络(xG)`的情况下,距离较近的Apple设备(iMac/iPad/iPhone)之间可基于`蓝牙和WiFi(P2P WiFi)`技术进行发现和连接实现近场通信。

    - Multipeer Connectivity扩充的功能与利用AirDrop传输文件非常类似,可以将其看作AirDrop不能直接使用的补偿,代价是需要自己实现。

    - 手机不联网也能跟附近的人聊得火热的`FireChat`和`See You Around`等近场聊天App、近距离无网遥控交互拍照神器`拍咯App`就是基于Multipeer Connectivity框架实现。

    - 相比AirDrop,Multipeer Connectivity在进行发现和会话时并不要求同时打开WiFi和蓝牙,也不像AirDrop那样强制打开这两个开关,而是根据条件适时选择使用蓝牙或(和)WiFi。

    - 粗略测试情况如下:

        * 双方WiFi和蓝牙`都未打开`:无法发现。

        * 双方都开启`蓝牙`:通过蓝牙发现和传输。

        * 双方都开启`WiFi`:通过WiFi Direct发现和传输,速度接近AirDrop(Reliable速率稍低),不知道同一WLAN下是否优先走局域网?

        * 双方都`同时开启了WiFi和蓝牙`:应该是模拟AirDrop,通过低功耗蓝牙技术扫描发现握手,然后通过WiFi Direct传输。

    常用类

    - MCPeerID

    类似sockaddr,用于标识连接的两端endpoint,通常是`昵称或设备名称`。该对象只开放了displayName属性,私有MCPeerIDInternal对象持有的设备相关的_idString/_pid64字段并未公开

    在许多情况下,客户端同时广播并发现同一个服务,这将导致一些混乱,尤其是在`client/server`模式中。所以,每一个服务都应有一个类型标示符——`serviceType,它是由ASCII字母、数字和“-”组成的短文本串,最多15个字符`。

     

    -MCNearbyServiceAdvertiser

    类似broadcaster,`可以接收,并处理用户请求连接的响应。但是,这个类会有回调,告知有用户要与您的设备连接,然后可以自定义提示框,以及自定义连接处理`。

    主线程(com.apple.main-thread(serial))创建MCNearbyServiceAdvertiser并启动startAdvertisingPeer。

    MCNearbyServiceAdvertiserDelegate异步回调(didReceiveInvitationFromPeer)切换回主线程。

    在主线程didReceiveInvitationFromPeer中创建MCSession并invitationHandler(YES,session)接受会话连接请求(accept参数为YES)。

    - MCNearbyServiceBrowser

    类似servo listen+clientconnect,`用于搜索附近的用户,并可以对搜索到的用户发出邀请加入某个会话中`。

    主线程(com.apple.main-thread(serial))创建MCNearbyServiceBrowser并启动startBrowsingForPeers。

    MCNearbyServiceBrowserDelegate异步回调(foundPeer/lostPeer)切换回主线程。

    主线程创建MCSession并启动invitePeer。

     

    - MCSession

    `启用和管理Multipeer连接会话中的所有人之间的沟通。 通过Sesion,给别人发送数据`

    注意,peerID并不具备设备识别属性。

    类似TCP链接中的socket。创建MCSession时,需指定自身MCPeerID,类似bind。

    为避免频繁的会话数据通知阻塞主线程,MCSessionDelegate异步回调(didChangeState/didReceiveCertificate/didReceiveData/didReceiveStream)有一个专门的回调线程——com.apple.MCSession.callbackQueue(serial)。为避免阻塞MCSeesion回调线程,最好新建数据读(写)线程!

     

    -MCAdvertiserAssistant/MCBrowserViewController

    `MCAdvertiserAssistant   //可以接收,并处理用户请求连接的响应。没有回调,会弹出默认的提示框,并处理连接。`

    `MCBrowserViewController弹出搜索框,需要手动modal`

     

    MCAdvertiserAssistant为针对Advertiser封装的管理助手;MCBrowserViewController继承自UIViewController,提供了基本的UI应用框架。

    MCBrowser/MCAdvertiser的回调线程一般是delegate所在线程Queue:com.apple.main-thread(serial)。

     

    iOS中的蓝牙

    概述:OS中提供了4个框架用于实现蓝牙连接

     

    - 1.GameKit.framework(用法简单)

        * `只能用于iOS设备之间的同个应用内连接`,多用于游戏(eg.拳皇,棋牌类),从`iOS7开始过期`

    -2.MultipeerConnectivity.framework(代替1)

        * `只能用于iOS设备之间的连接,从iOS7开始引入`,主要用于`非联网状态`下,通过wifi或者蓝牙进行文件共享(仅限于沙盒的文件),多用于附近无网聊天

    - 3.ExternalAccessory.framework(MFi)

        * `可用于第三方蓝牙设备交互`,但是蓝牙设备必须经过`苹果MFi认证`(国内很少)

    -4.CoreBluetooth.framework(时下热门)

        * `可用于第三方蓝牙设备交互`,必须要支持蓝牙4.0

        * 硬件至少是4s,系统至少是iOS6

        * 蓝牙4.0以低功耗著称,一般也叫BLE(Bluetooth Low Energy)

        * 目前应用比较多的案例:运动手环,嵌入式设备,智能家居

    设计到的系统/框架

    - HealthKit/物联网HomeKit/wathOS1,2/iBeacon



    展开全文
  • 一、需求 为了降低stm32单片机在非工作状态下的功耗,需要实现通过手机端软件,tong'g 二、硬件电路 三、软件 四、实现效果
  • 上一篇文章涂鸦智能暖风机软件实现之利用B3950实现温度采集功能已经实现了暖风机的温度采集功能,本文将实现暖风机的基本外设驱动,例如驱动继电器开关实现档位调节、驱动摇头电机、驱动蜂鸣器等。 一、智能暖风机...
  • 软件测试理论和APP测试案例

    万次阅读 多人点赞 2017-02-17 12:45:17
    1、软件测试流程和软件测试方法 软件工程模型基本就是业务建模-〉系统分析-〉概要设计-〉详细设计-〉编码-〉测试-〉部署。其中测试过程按4个步骤进行,即单元测试、集成测试、系统及发版测试和回归测试。  (1)、...
  • App蓝牙通讯技术

    千次阅读 2019-02-13 13:06:54
    通过蓝牙进行通讯交互分为两方,一方为中心设备central,一方为外设 peripheral,外设通过广播的方式向外发送信息,中心设备检索到外设发的广播信息,可以进行配对连接,进而进行数据交互。 具体实践: Swift项目中...
  • APP安全

    2019-03-07 17:30:00
    APP源代码对于一个公司是非常重要的信息资源,对APP的保护也尤为重要,APP的反编译会造成源代码被恶意者读取,以及APP的逻辑设计, 反编译方法 我们一般想要反编译一个apk,无非就是想获得三样东西:图片资源...
  • 在笔者前期使用Dave3开发infineon单片机时发现,Dave可以通过建立dave ce project 加载APP来自动生成主程序及各部分外设的驱动代码,可视化地配置你选用的单片机及各外设单元。即通过使用app即可通过用户的需求配置...
  • 下一个app,然后购买一个配合使用的外设,将外设插在手机上,打开app,即可在app 上修改位置,也可以设置坐标进行路线规划,虚拟出行驶路径;【例如:Supergo(现已停产)】 2.如何禁止此类修改位置的工具 2.1:高德...
  • 2.2.1.1 UI Automator Viewer 在进行Android UI自动化测试之前,作为测试人员,应当了解待测App的UI,包括使用了哪些控件、控件的类名、控件的id,等等。获知这些信息之后才能写测试脚本进行自动化测试。 Android ...
  • NuMaker Uni亦支持第三方开发软件工具,如:Keil RVMDK、IAR EWARM等。 主控板:NuMaker Uni 采用新唐 Cortex:registered:-M0 NANO100NE3BN 单片机为核心,主频率达42 MHz,支持3.7V 锂电池或5V电源输入以及ADC、PWM、...
  • 手机app测试要点

    2018-10-01 12:43:00
    手机app测试要点 一、简介   移动应用App已经渗透到每个人的生活、娱乐、学习、工作当中,令人激动、兴奋且具有创造性的各种App犹如雨后春笋般交付到用户手中。各类智能终端也在快速发布,而开发者对于全球移动...
  • Android APP测试流程

    千次阅读 2018-01-08 13:30:47
    软件工程模型基本就是业务建模-〉系统分析-〉概要设计-〉详细设计-〉编码-〉测试-〉部署。 其中Android App测试流程如下: 关于测试的几个概念: 1) 单元测试,集中对每一个程序单元进行测试,检查各个程序...
  • 移动APP安全测试

    2019-01-03 21:27:41
    无意中发现一篇关于APP安全测试的文章,深以为然,原文搬至鄙人的博客以做知识储备,现附上原文链接,已示对大佬辛勤付出的致敬和对知识产权的尊重。原文原始链接。 1 移动APP安全风险分析 1.1 安全威胁分析 ...
  • 文章目录前言硬件平台相关配置APP主要实现的功能APP层代码分析JNI native层代码...这个APP是以前在MT6735平台Android 5.1(L1)调试验证UART外设发送过来的数据是否正确,想着也许后面调试还用的着,就记录一下。...
  • 优点:设备即插即用,可修改iPhone,iPad系统位置,目前手上的iPad NEW/MAX都能,还没有发现哪个软件改不动,其中路径规划这个功能好像对读大学的同学挺有用,需要跑步?好像是,嘿嘿嘿 下边这个
  • 谈谈工业App (1)

    千次阅读 2019-03-10 22:16:54
    本人虽然自喻为资深软件工程师,还是感觉孤陋寡闻,看不明白所谓“工业App”到是什么?使用英文 “Industry Apps” 谷歌一番,好像也搜不出什么像样的文章。估计“工业App”不是舶来品,而是中国...
  • App功耗优化

    2017-12-07 18:37:21
    iOS进阶–App功耗优化看这篇就够了一款好的App一定要有非常好的用户体验,这一点已经是大多数开发者的共识。功耗是用户体验中一个重要的组成部分,但这部分因为各种问题,很多时候会被大家忽略。之前公司让我在内部...
  • 01-app测试点

    2021-03-04 14:19:09
    1.功能性测试: 根据产品需求文档编写测试用例而进行测试。 ps:1.安装卸载测试,2.升级测试,3.业务逻辑测试,4.ui测试,5....**0.功能测试:**1)评审需求,多方面...安装运行卸载测试:**1)验证app能否正确安装运行
  • Android Things:外设I/O接口-I2C

    千次阅读 2017-04-11 15:06:58
    一、接口简介内部集成电路(IIC或者I2C)总线使用小数据负载连接简单的外部设备。...控制时钟信号的设备被称为master,其它所有连接的外设被认为是Slaves,每个设备连接到同一组数据信号以形成总线。 I2C设备连接使用3
  • 来源:知乎 文章收录于:风云社区SCOEE,提供上千款mac软件下载 基于从事Apps设计或开发者,使用 MacBook Pro,以下罗列一些必需的外设和应用程序推荐。 Retina 256GB SSD 是否够用/必要? 除非购买17“ MBP,...
  • iOS - App 应用

    2016-09-09 07:14:00
    iOS - App 应用 1、Xcode 项目属性 Product Name 软件名称、产品名称、项目名称 Organization Name 公司名称、组织名称 Organization Identifier 公司的唯一标识 一般是公司域名的反写,...
  • WEB APP的跨平台特性确实很吸引人,但是大家普遍都认为WEB APP在用户体验上,目前软硬件环境下,还是不如Native APP。 具体是那些方面不如呢?下面是我的总结: 一、进程切换的体验差异 不考虑机器性能和网速...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 4,903
精华内容 1,961
关键字:

外设app软件