IOS 蓝牙技术之CoreBluetooth

iOS 蓝牙技术CoreBluetooth IOS蓝牙技术—CoreBluetooth 一、iOS蓝牙简述 二、CoreBluetooth简介 1、基本概念 2、CoreBluetooth 框架介绍 三、开发模式 1、中心模式 2、外设模式 一、iOS蓝牙简述 ​ iOS开发中关于蓝牙技术的框架有四种: GameKit.framework 多用于游戏开发,iOS设备之间的连接。 MultipeerConnectivity.framework... 阅读详情

蓝牙常见名称和缩写

  • BLE:(Bluetooth low energy)蓝牙4.0设备因为低耗电,也叫BLE
  • peripheral,central:外设和中心设备,发起链接的是central(一般是指手机),被链接的设备是peripheral(运动手环),也可两个手机,一个座位外设一个作为中心设备
  • service and characteristic:(服务和特征)每个设备会提供服务和特征,类似于服务端的API,但是结构不同.每个设备会有很多服务,每个服务中包含很多字段,这些字段的权限一般分为读(read),写(write),通知(notify)几种,就是我们连接设备后具体需要操作的内容
  • Description:每个characteristic可以对应一个或者多个Description用于描述characteristic的信息或属性(eg.范围,计量单位)

蓝牙基础知识

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

    结构图
  • 这两组api粉笔对应不同的业务常见:左侧叫中心模式,就是以你的app作为中心,连接其他的外设的场景;而右侧称为外设模式,使用手机作为外设连接其他中心设备操作的场景
  • 服务和特征(service and characteristic)
typedef NS_OPTIONS(NSUInteger, CBCharacteristicProperties) {
    CBCharacteristicPropertyBroadcast                                                = 0x01,
    CBCharacteristicPropertyRead                                                    = 0x02,
    CBCharacteristicPropertyWriteWithoutResponse                                    = 0x04,
    CBCharacteristicPropertyWrite                                                    = 0x08,
    CBCharacteristicPropertyNotify                                                    = 0x10,
    CBCharacteristicPropertyIndicate                                                = 0x20,
    CBCharacteristicPropertyAuthenticatedSignedWrites                                = 0x40,
    CBCharacteristicPropertyExtendedProperties                                        = 0x80,
    CBCharacteristicPropertyNotifyEncryptionRequired NS_ENUM_AVAILABLE(NA, 6_0)        = 0x100,
    CBCharacteristicPropertyIndicateEncryptionRequired NS_ENUM_AVAILABLE(NA, 6_0)    = 0x200
};
  • 外设,服务,特征的关系

    外设,服务,特征关系

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):作为从设备链接到其它设备


BLE中心模式流程-coding,手机作为中心设备发现链接外设

实现步骤

1.导入CB头文件,建立主设备管理类,设置主设备代理

import UIKit
import CoreBluetooth
class ViewController: UIViewController
{
    
    /// 中心管理者
    var cMgr: CBCentralManager!
    
    /// 外设
    var per: CBPeripheral?
    var readWriteCharicter: CBCharacteristic?
    
    
    override func viewDidLoad()
    {
        super.viewDidLoad()
        
    }


    @IBAction func startConnectiOthers(_ sender: Any)
    {
        cMgr = CBCentralManager(delegate: self, queue: DispatchQueue.main)
    }
    
    @IBAction func disConnectOthers(_ sender: Any)
    {
        guard per == nil else
        {
            return
        }
        cMgr.cancelPeripheralConnection(per!)
    }
    @IBAction func writeDataClick(_ sender: Any)
    {
        let valueDic = ["name":"SuLuo", "age":"18"]
        let readWriteData = try? JSONSerialization.data(withJSONObject: valueDic, options: [])
        periheral(perheral: per!, writeData: readWriteData!, forCharacteristic: readWriteCharicter!)
    }
}
 //MARK:- 中心管理者的代理 -
extension ViewController: CBCentralManagerDelegate
{
    //更新状态
    func centralManagerDidUpdateState(_ central: CBCentralManager)
    {
        switch central.state
        {
            case .poweredOff:
                print("poweredOff")
            case .poweredOn:
                print("poweredOn")
                //开始扫描周围的外设
                //第一个参数nil就是扫描周围所有的外设,扫描到外设后会进入didDiscoverPeripheral
                central.scanForPeripherals(withServices: nil, options: nil)
            case .resetting:
                print("resetting")
            case .unauthorized:
                print("unauthorized")
            case .unsupported:
                print("unsupported")
            default:
                print("others")
        }
    }
    
    //扫描到外部设备
    func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String : Any], rssi RSSI: NSNumber)
    {
        //一般会根据advertisementData来过滤出我们想要连接的外设(当然,信号强度RSSI也可以作为过滤凭据)kCBAdvDataLocalName
        print("peripheral\(peripheral)\n; advertisementData\(advertisementData); rssi\(RSSI)\n **************")
        //过滤设备接下来可以连接设备
        //如果你没有设备,可以下载一个app叫lightbule的app去模拟一个设备
        //这里自己去设置下连接规则,我设置的是二维码扫描到的运动手环的设备号
        // 判断设备号是否扫描到
        guard let periheralName = peripheral.name  else
        {
            print("没有名字")
            return;
        }
        
        if periheralName.contains("5s")
        {
            print("找到设备")
            //5.1停止扫描
            central.stopScan()
            //5.2将外设存入外设数组,(1~7)个
            self.per = peripheral;
            //5.3请求连接
            central.connect(peripheral, options: nil)
        }
        else
        {
            print("没有扫描到设备,重新扫描")
        }
    }
    //6连接外设的状态
    //6.1连接成功的代理
    func centralManager(_ central: CBCentralManager, didConnect peripheral: CBPeripheral)
    {
        print("连接\(peripheral.name) 成功 ")
        
        //7.与外设进行信息交互,设置的peripheral代理CBPeripheralDelegate
        peripheral.delegate = self
        //扫描外设Services,成功后会进入方法:-(void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError *)error{
        peripheral.discoverServices(nil)
        
    }
    //6.2连接失败
    func centralManager(_ central: CBCentralManager, didFailToConnect peripheral: CBPeripheral, error: Error?)
    {
        guard error == nil else
        {
            print("连接失败")
            return
        }
        
    }
    
    //6.3连接丢失取消连击
    func centralManager(_ central: CBCentralManager, didDisconnectPeripheral peripheral: CBPeripheral, error: Error?)
    {
        print("连接丢失")
    }
    
    
}
 //MARK:- 外设的代理 -
extension ViewController: CBPeripheralDelegate
{
    //7.1发现外设的服务
    func peripheral(_ peripheral: CBPeripheral, didDiscoverServices error: Error?)
    {
        guard error == nil else
        {
            print("服务有错误")
            return
        }
        for server in (peripheral.services)!
        {
            // 7.2 扫描外设服务中的每一个特征 peripheral:didDiscoverCharacteristicsForService
            //扫描每个service的Characteristics,扫描到后会进入方法: -(void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(NSError *)error
            print("外设服务UUID = \(server.uuid)")
            print("******************************")
           //判断服务
            if server.uuid == CBUUID(string: "FFE0") //FFF0服务1 里面有两个特征一个 通知 一个读写FFE0 服务2
            {
                peripheral.discoverCharacteristics(nil, for: server)
            }
            
        }
        
    }
    //7.3扫描到外设服务中的特征值
    func peripheral(_ peripheral: CBPeripheral, didDiscoverCharacteristicsFor service: CBService, error: Error?)
    {
        guard error == nil else
        {
            print("服务特征有错误")
            return
        }
        print("扫描到服务\(service.uuid)特征数目\(service.characteristics?.count)")
        for character in (service.characteristics)!
        {
            print("特征的UUID:\(character.uuid)")
             // 7.4 外设检索特征的描述
            //搜索Characteristic的Descriptors,读到数据会进入方法:-(void)peripheral:(CBPeripheral *)peripheral didDiscoverDescriptorsForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error
            // 扫描外设特征的描述
            peripheral.discoverDescriptors(for: character)
            if character.uuid.uuidString == "FFF1"
            {
                print("这是一个notify特征可以订阅")
//                periheral(periheral: per! , setNotifyValueForCharacteristic: character)
                periheral(periheral: per!, cancleNotifyValueForCharacteristic: character)
            }

            //7.5读取特征的值
            guard character.properties.contains(.read) else
            {
                print("特征不可读")
                continue
            }
            print("读取外部特征的值")
            //获取Characteristic的值,读到数据会进入方法:-(void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error
            // 外设读取特征的值
            peripheral.readValue(for: character)
            //写数据
            guard character.properties.contains([.read,.write]) else
            {
               print("该特征不具备读写")
               continue
            }
            //写操作

//            let dataDic = try? JSONSerialization.jsonObject(with: data!, options: [])
//            print("读写数据\(dataDic)")
            if character.uuid.uuidString == "FFF2"
            {
                readWriteCharicter = character
            }
            
        }
        print("******************服务\(service.uuid)的特征扫描完毕********************")
    }
    
    // 7.6 外设发现了特征中的描述
    // 发现特征Characteristics的描述Descriptor
    func peripheral(_ peripheral: CBPeripheral, didDiscoverDescriptorsFor characteristic: CBCharacteristic, error: Error?)
    {
        guard error == nil else
        {
            print("DiscoverDescriptorsFor characteristic Error")
            return
        }
        for des in characteristic.descriptors!
        {
            print("特征描述.uuid:\(des.uuid)")
            //读取特征的描述,读到之后会执行
            // didUpdateValueFor descriptor:
            peripheral.readValue(for: des)
            
        }
        print("******************特征\(characteristic.uuid)中的描述完毕************")

    }
    
       //MARK: 7.7更新特征value
    // 读取到特征characteristic的值
    func peripheral(_ peripheral: CBPeripheral, didUpdateValueFor characteristic: CBCharacteristic, error: Error?)
    {
        //读取到了特征值
        //打印出characteristic的UUID和值
        //!注意,value的类型是NSData,具体开发时,会根据外设协议制定的方式去解析数据
        guard error == nil else
        {
            print("特征值有错")
         return
        }
        if characteristic.uuid.uuidString == "FFF2"
        {
            let newValue = characteristic.value
            print("new\(newValue)")
        }
        print("服务\(characteristic.service.uuid)的特征")
        //!注意,value的类型是NSData,具体开发时,会根据外设协议制定的方式去解析数据
        let valueString = String(data: characteristic.value!, encoding: .utf8)
        
        print("特征的.uuid=\(characteristic.uuid);特征的value=\(valueString)")
        
        print("******************读取特征\(characteristic.uuid)值完毕************")

    }
    // 获取Characteristics的 descriptor的值
    //读取到外部设备特征的描述
    func peripheral(_ peripheral: CBPeripheral, didUpdateValueFor descriptor: CBDescriptor, error: Error?)
    {
        //打印出DescriptorsUUID 和value
        //这个descriptor都是对于characteristic的描述,一般都是字符串,所以这里我们转换成字符串去解析
        
//        print("服务\(descriptor.characteristic.service.uuid)]\n特征uuid=\(descriptor.characteristic.uuid);\n特征描述的value=\(descriptor.value)")
       // print("******************特征描述扫描完毕************")

    }
       //MARK: - 写数据回调 -
    func peripheral(_ peripheral: CBPeripheral, didWriteValueFor characteristic: CBCharacteristic, error: Error?)
    {
        print("写数据完成\(characteristic.uuid)")
        if characteristic.uuid.uuidString == "FFF2"
        {
            peripheral.discoverCharacteristics([characteristic.uuid], for: characteristic.service)
        }

    }
    
    func peripheral(_ peripheral: CBPeripheral, didModifyServices invalidatedServices: [CBService])
    {
        
    }
    
    
       //MARK: 手动去写数据
    func periheral(perheral: CBPeripheral,  writeData data: Data , forCharacteristic charicteristic: CBCharacteristic) -> ()
    {
        /*
        typedef NS_OPTIONS(NSUInteger, CBCharacteristicProperties) {
            CBCharacteristicPropertyBroadcast                                                = 0x01,
            CBCharacteristicPropertyRead                                                    = 0x02,
            CBCharacteristicPropertyWriteWithoutResponse                                    = 0x04,
            CBCharacteristicPropertyWrite                                                    = 0x08,
            CBCharacteristicPropertyNotify                                                    = 0x10,
            CBCharacteristicPropertyIndicate                                                = 0x20,
            CBCharacteristicPropertyAuthenticatedSignedWrites                                = 0x40,
            CBCharacteristicPropertyExtendedProperties                                        = 0x80,
            CBCharacteristicPropertyNotifyEncryptionRequired NS_ENUM_AVAILABLE(NA, 6_0)        = 0x100,
            CBCharacteristicPropertyIndicateEncryptionRequired NS_ENUM_AVAILABLE(NA, 6_0)    = 0x200
        };
         打印出特征的权限(characteristic.properties),可以看到有很多种,这是一个NS_OPTIONS的枚举,可以是多个值
         常见的又read,write,noitfy,indicate.知道这几个基本够用了,前俩是读写权限,后俩都是通知,俩不同的通知方式
         */
        // 只有特征的properties中有写的属性时候,才写
        if charicteristic.properties.contains(.write)
        {
            // 这句才是正宗的核心代码
            perheral.writeValue(data, for: charicteristic, type: .withResponse)
        }
    }
    
     //MARK:- 自定义订阅和取消 -
    
    func periheral(periheral:CBPeripheral, setNotifyValueForCharacteristic characteristic: CBCharacteristic)
    {
        guard characteristic.properties.contains(.notify) else
        {
            print("特征属性必须要wirte")
            return
        }
        print("订阅特征")
        periheral.setNotifyValue(true, for: characteristic)
    }
    
    //取消订阅
    func periheral(periheral:CBPeripheral, cancleNotifyValueForCharacteristic characteristic: CBCharacteristic)
    {
        guard characteristic.properties.contains(.notify) else
        {
            print("特征属性必须要notify")
            return
        }
        periheral.setNotifyValue(false, for: characteristic)
    }
    
    ///断开连接
    func centralMangerStopScan(manager: CBCentralManager, didConnectWithPeriheral periheral: CBPeripheral)
    {
        //停止扫描
        cMgr.stopScan()
        //断开连接
        cMgr.cancelPeripheralConnection(periheral)
    }
}

BLE-periphral外设模式流程,手机作为外设 被其他的设备发现链接

peripheral模式的流程

  • 1.引入CoreBluetooth框架,初始化peripheralManager
  • 2.设置peripheralManager中的内容
  • 3.开启广播advertising
  • 4.对central的操作进行响应
    • 4.1 读characteristics请求
    • 4.2 写characteristics请求
    • 4.4 订阅和取消订阅characteristics

具体操作步骤

import UIKit
import CoreBluetooth

let Service1StrUUID = "FFF0"
let Service2StrUUID = "FFE0"

let notiyCharacteristicStrUUID = "FFF1"
let readwriteCharacteristicStrUUID = "FFF2"
let readCharacteristicStrUUID = "FFE1"

let LocalNameKey = "SHLPriheralManagerDemo"
class ViewController: UIViewController
{
    
    @IBOutlet weak var timeLabel: UILabel!
    /// 外设管理者
    var priheralManager:CBPeripheralManager!
    ///定时器更新订阅特征的值
    var timer: Timer?
    //给外作为外设的自己添加两个服务
    @objc lazy var services :[CBMutableService] =
    {
        // 特征描述的UUID
        let characteristicDescritonUUID = CBUUID(string: CBUUIDCharacteristicUserDescriptionString)
//                    let characteristicDescritonUUID = CBUUID(string: "RWD001")

        //通知的特征UUID
        let notifyCharacteristicUUID = CBUUID(string: notiyCharacteristicStrUUID)
        // 读写特征的UUID
        let readwriteCharacteristicUUID =  CBUUID(string: readwriteCharacteristicStrUUID)
        // 只读特征的UUID
        let readCharacteristicUUID = CBUUID(string: readwriteCharacteristicStrUUID)
    
        let server1UUID = CBUUID(string: Service1StrUUID)
        let server2UUID = CBUUID(string: Service2StrUUID)
        
        //初始化一个特征描述
        let description1 = CBMutableDescriptor(type: characteristicDescritonUUID, value: "这是一个可读写的服务特征")
        // 可通知的特征
        let notifyCharacteristic = CBMutableCharacteristic(type: notifyCharacteristicUUID, properties: .notify, value: nil, permissions: .readable)
        
         // 可读写的特征
        
        let readwriteCharacteristic = CBMutableCharacteristic(type: readwriteCharacteristicUUID, properties: [.read,.write], value: nil, permissions: [.readable, .writeable])

        // 设置特征的描述
        readwriteCharacteristic.descriptors = [description1]

        //只读特征
        let valueDic = ["name":"SuLuo", "age":"18"]
        var readWriteData = try? JSONSerialization.data(withJSONObject: valueDic, options: [])
        let readCharacteristic = CBMutableCharacteristic(type: readCharacteristicUUID, properties: .read, value: readWriteData, permissions: .readable)
        
        //初始化服务1
        let server1 = CBMutableService(type: server1UUID, primary: true)
        // 为服务1设置俩特征(通知, 带描述的读写)
        server1.characteristics = [notifyCharacteristic, readwriteCharacteristic]
        
         // 初始化服务2,并且添加一个只读特征
        let server2 = CBMutableService(type: server2UUID, primary: true)
        server2.characteristics = [readCharacteristic]
        return [server1, server2]
    }()
    
    
    
    @IBAction func startPriheralMode(_ sender: UIButton)
    {
        //开启外设 完成后会执行peripheralManagerDidUpdateState
        self.priheralManager = CBPeripheralManager(delegate: self, queue: DispatchQueue.main)
    }
    
}

extension ViewController: CBPeripheralManagerDelegate
{
    // CBPeripheralManager初始化后会触发的方法
    func peripheralManagerDidUpdateState(_ peripheral: CBPeripheralManager)
    {
        if peripheral.state == .poweredOn
        {
            //代开设备成功
            // 配置各种服务入CBPeripheralManager
            setupPeriheral()
        }else
        {
            print("打开设备失败")
        }
    }
    //给外设管理者添加服务
    func peripheralManager(_ peripheral: CBPeripheralManager, didAdd service: CBService, error: Error?)
    {
        print("新的服务\(service)")
        // 由于添加了两次ser,所以方法会调用两次
        var i = 0
        if (error == nil)
        {
            i += 1
        }
        //开启广播
        // 当第二次进入方法时候,代表两个服务添加完毕,此时要用到2,由于没有扩展性,所以新增了可变数组,记录添加的服务数量
        
        let adv = [CBAdvertisementDataLocalNameKey:LocalNameKey, CBAdvertisementDataServiceUUIDsKey: services.map{$0.uuid}] as [String : Any]
        peripheral.startAdvertising(adv)
        
    }
    //开启广播后会执行
    func peripheralManagerDidStartAdvertising(_ peripheral: CBPeripheralManager, error: Error?)
    {
        guard error == nil else
        {
            print("广播发生错误\(error)")
            return
        }
        print("外设已经开启广播")
        
    }
    
    //对central的操作做出响应
    // 外设收到读的请求,然后读特征的值赋值给request
    func peripheralManager(_ peripheral: CBPeripheralManager, didReceiveRead request: CBATTRequest)
    {
      // 判断是否可读
        print("收到读数据请求")
        guard request.characteristic.properties.contains(.read) else
        {
            print("读不被允许")
            peripheral.respond(to: request, withResult: .readNotPermitted)
            return
        }
        peripheral.respond(to: request, withResult: .success)
        
    }
    
    // 外设收到写的请求,然后读request的值,写给特征
    func peripheralManager(_ peripheral: CBPeripheralManager, didReceiveWrite requests: [CBATTRequest])
    {
        //遍历请求
        for request in requests
        {
            //根据请求特征的属性判断是否可写
            guard request.characteristic.properties.contains(.write) else
            {
                peripheral.respond(to: request, withResult: .readNotPermitted)
                continue
            }
            //拿到请求的中数据
            let data = request.value
            print("修改的数据\(request.value)")

            //请此数据写入请求的特征中(需要注意特征类型转换)
            let mchr = request.characteristic as! CBMutableCharacteristic
            mchr.value = data
            // 4.2.4 发送修改后的请求和成功出去
            peripheral.respond(to: request, withResult: .success)
            
        }
        
    }
    
    // 与CBCentral的交互
    // 订阅特征
    func peripheralManager(_ peripheral: CBPeripheralManager, central: CBCentral, didSubscribeTo characteristic: CBCharacteristic)
    {
         // 4.3.1 既然被订阅,就要定时更新特征中的值
        print("收到订阅请求\(Thread.current)")
        timer = Timer(timeInterval: 5.0, target: self, selector: #selector(updataNotifyCharacteristic(timer:)), userInfo: characteristic, repeats: true)
        RunLoop.current.add(timer!, forMode: .default)
        
        
    }
    //中心设备取消订阅
    func peripheralManager(_ peripheral: CBPeripheralManager, central: CBCentral, didUnsubscribeFrom characteristic: CBCharacteristic)
    {
        print("设备取消订阅")

    }
    
    @objc func updataNotifyCharacteristic(timer: Timer)
    {
         // 将数据随着时间进行更新
        let now = Date()
        let formatter = DateFormatter()
        formatter.dateFormat = "yy-MM-dd HH:mm:ss"
        let nowStr = formatter.string(from: now)
        //转换成C类型String
        let dataStr = nowStr.data(using: String.Encoding.utf8)
        // 发送一个更新的特征值给订阅了特征的中心设备
        
        let characterictic = timer.userInfo as! CBMutableCharacteristic
        print(nowStr)

        // 发送一个更新的特征值给订阅了特征的中心设备
        priheralManager.updateValue(dataStr!, for: characterictic, onSubscribedCentrals: nil)
        
        timeLabel.text = nowStr
        
    }
    
    
    //MARK: - 私有方法 -
    func setupPeriheral()
    {
        // 添加服务进外设管理者
        // 添加操作会触发代理方法peripheralManager:didAddService:error:
        for server in services
        {
            priheralManager.add(server)
        }
    }
    
   
    
}
iOS 蓝牙入门CoreBluetooth 很久很久以前,曾经遇到一个做体感手环的科技公司,该公司有自己研发的手环设备,需要制作一款App通过蓝牙连接设备,听起来特别有学习劲头,因为市面上很多智能设备的公司都是有与之相配的App使用,比如家喻户晓的小米手环,我同事有一个小米手环借给我用了一段时间,我下了一个小米运动App,稍微给大家展示一下小米手环的界面。 这只是蓝牙用途的一个例子,不知道哪位博友是否有Apple Watch, 阅读详情

相关推荐

图片边界矢量化-地理配准

无地理和投影信息的JPG图片,通过ArcGIS进行地理配准(Georeferencing)完成数字化边界。

u012727861的博客 1904

iOS 使用蓝牙技术MultipeerConnectivity、CoreBluetooth

随着蓝牙低功耗技术BLE(Bluetooth Low Energy)的发展,蓝牙技术正在一步步成熟,如今的大部分移动设备都配备有蓝牙4.0,相比之前的蓝牙技术耗电量大大降低。从iOS的发展史也不难看出苹果目前对蓝牙技术也是越来越关注,例如苹果于2013年9月发布的iOS7就配备了iBeacon技术,这项技术完全基于蓝牙传输。但是众所周知苹果的设备对于权限要求也是比较高的,因此在iOS中并不能像And

meiyulong518的博客 742

黑客渗透测试后门隐藏技术揭秘

本文介绍了在授权渗透测试中隐藏后门文件(muma.exe)的多种技术手段。主要包括:通过WinRAR自解压脚本将后门与正常程序捆绑实现双开;利用系统自动运行目录和注册表实现开机自启;修改文件图标伪装成常用软件;将文件存放在冷门系统目录;设置系统+隐藏双重属性增强隐蔽性。此外还涉及对抗安全软件的加壳(UPX)、免杀(msfvenom编码)技术,以及进程注入、日志清除等运行隐藏方法。所有技术仅限合法授权测试使用,未经授权使用将面临法律责任。

m0_60781580的博客 1040

iOS 蓝牙技术CoreBluetooth 使用手册

最近很闲,没什么事可做,想来不能闲着,所以就想着研究下蓝牙相关的技术,所以就尝试了下,外设和中心设备都是手机,一个手机做当做虚拟外设,一个作为中心设备,尝试连接和通信一切都还顺利。当然也知道在实际开发中会遇到意想不到的问题。过来这人可以一起探讨。 文中所提有不足之处 还望指正。先谢过[抱拳]。 IOS蓝牙技术—CoreBluetooth 一、iOS蓝牙简述 二、Core...

用心工作 1989

多仓智能订单路由与动态优化方案设计

现在有很多商家会有多个仓库,并分布在不同的城市中,当用户下单后会根据商品库存及订单信息将订单分配到对应的仓库进行发货,如就近原则,本期基于多仓库设计一套订单路由方案,包含核心逻辑、规则优先级和实施方案,适用于多仓协同的订单自动分配场景

14年产品经理老兵,想把自己的经验及总结分享给大家,只讲思路及实操,不讲废话 2476

同花顺API实战指南:从零搭建股票数据自动化采集系统

本文提供了一份详尽的同花顺API实战指南,手把手教你从零开始搭建股票数据自动化采集系统。内容涵盖API权限申请、Python环境配置、数据采集与存储脚本编写、自动化定时任务实现以及数据清洗等核心环节,旨在帮助量化交易与数据分析爱好者构建稳定可靠的数据源,解放双手,提升研究效率。

weixin_29200741的博客 2395

iOS CoreBluetooth 教程蓝牙技术

去App Store搜索并下载“LightBlue”这个App,对调试你的app和理解Core Bluetooth会很有帮助。 ================================ Core Bluetooth for iOS 6 CoreBluetooth的API是基于BLE4.0的标准的。这个框架涵盖了BLE标准的所有细节。仅仅只有新的iOS设备和Mac是和BLE标准兼容的:

iOS_leungYL 1058

YOLOv8融合可变形注意力(DAT)实战教程:暴力涨点的科研级注意力机制优化方案

DAT的“可变形注意力”为目标检测的“精准特征捕捉”提供了全新思路,而YOLOv8的工程化优势让这种科研创新能快速落地到工业场景。希望这篇教程能帮你在“注意力机制优化+复杂场景检测”的痛点上找到突破口。如果你在实操中遇到“涨点不明显”的问题,不妨回到“DAT的采样点是否贴合目标形状”“注意力权重是否有效过滤背景”这些细节上找原因——科研的价值,就在于在细节打磨中推动技术进步。祝你在DAT与YOLOv8的结合探索中,既能做出有说服力的实验成果,又能沉淀出解决异形目标检测难题的实用经验。

know_F0727的博客 83

浅谈iOS中的蓝牙技术(二) -- CoreBluetooth

在上篇文章中我们提到了 iOS 开发中,使用GameKit 框架实现相同网络的 iOS 设备之间传输数据.但是 GameKit 框架在 iOS7 之后就过时了,那么本文将介绍另一种关于蓝牙的框架 CoreBluetooth. CoreBluetooth 简介 CoreBlueTooth.framework 使用 CoreBluetooth 要求设备必须要支持蓝牙4.0(一般也叫BL

努力,可能成功!放弃,注定失败! 4896

在 SAP 系统中,成本中心(Cost Center)是成本核算与费用管控的基础组织单元,其设计质量直接决定了后续成本归集、分摊、分析及责任考核的准确性

SAP系统成本中心设计核心要点:1. 设计原则包括责任可控、业务同质、核算颗粒度适配、组织对齐及稳定性平衡;2. 划分维度主要有部门、功能、地域、项目和资产5类,可组合使用;3. 需避免颗粒度过细、跨责任主体归集等常见误区;4. 建议采用"明确目标-梳理业务-设计编码"三步法,建立科学的成本中心体系。合理的成本中心设计能精准归集费用、明确责任主体,为成本分析和管控奠定基础。

金牌架构师 1437

2026年全国青少年信息素养大赛算法应用主题赛C++样题及答案解析

2026年全国青少年信息素养大赛算法应用主题赛C++样题

王老师青少年编程 3711

GD32H759+RT-Thread实战:USB CDC ACM虚拟串口配置与调试

USB CDC ACM是一种将USB接口模拟为串口通信的设备类协议,基于USB批量传输与中断传输实现数据收发。其核心原理是通过标准描述符向主机声明通信接口与数据接口,并借助IAD关联,使操作系统免驱识别为虚拟串口。在嵌入式工控领域,该技术能显著提升调试效率,避免频繁拆机接线。典型应用包括日志输出、参数下发、固件升级及多路复用。本文以GD32H759与RT-Thread为例,详解USB外设对接、描述符配置、端点分配及稳定性优化,帮助开发者快速构建免驱调试通道。

weixin_33835103的博客 401

2025.05.30【转录组】|Ribo-seq数据流程详解(一 质量控制)

本文详细介绍了Ribo-seq数据的质控分析流程,重点讲解了使用fastp进行原始数据质控的关键步骤和参数设置。作者通过Snakemake自动化流程示例,展示了如何去除接头序列、过滤低质量reads、生成质控报告等操作。文章强调高质量的Ribo-seq数据对转录后调控和翻译动态研究的重要性,并提供了兼顾数据质量和下游分析需求的参数配置建议。该流程有助于研究人员规范高效地完成Ribo-seq数据质控,为后续分析提供可靠数据基础。

784

在 iOS 11 中使用 Core Bluetooth

作者:Andrew Jaffee,原文链接,原文日期:2018-04-17 译者:灰s;校对:Cee,numbbbbb;定稿:Forelax 作为 iOS 开发,我们十分清楚人们都喜欢互通性。我们喜欢通过无线设备与其他人进行沟通这一点是显而易见的。最近,我们开始希望能够与那些曾经被认为是独立的普通设备进行通信。我们开始喜欢,甚至是期望,部分无线设备可以收集并且分析自己的数据(通常称为“可穿...

weixin_34167819的博客 261

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

iOS边城之蓝牙编程(Core Bluetooth)

http://blog.youkuaiyun.com/victormokai/article/details/42395669 CoreBluetooth.framework  函数名:CBXXX  参考官方 优快云小马 译   蓝牙技术,很早以前就被有了,如今已更新4.0版本。很多热门技术都是基于它工作的,如Android平台的NFC,iOS的iBeancon等,现在的智能家居基

mayimchen的专栏 846

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

CoreBluetooth

硬體週邊Tips Contents  [hide]  1 藍牙 1.1 BLE(CoreBluetooth) 1.1.1 Discover/Connect 1.1.1.1 CBCentralManager1.1.1.2 centralManagerDidUpdateState1.1.1.3 scanForPeriphera

jimoduwu的专栏 6591

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

蓝牙

随着蓝牙低功耗技术BLE(Bluetooth Low Energy)的发展,蓝牙技术正在一步步成熟,如今的大部分移动设备都配备有蓝牙4.0,相比之前的蓝牙技术耗电量大大降低。从iOS的发展史也不难看出苹果目前对蓝牙技术也是越来越关注,例如苹果于2013年9月发布的iOS7就配备了iBeacon技术,这项技术完全基于蓝牙传输。但是众所周知苹果的设备对于权限要求也是比较高的,因此在iOS中并不能像An

xiaobo0134的专栏 1521

ios 蓝牙开发总结

随着蓝牙低功耗技术BLE(Bluetooth Low Energy)的发展,蓝牙技术正在一步步成熟,如今的大部分移动设备都配备有蓝牙4.0,相比之前的蓝牙技术耗电量大大降低。从iOS的发展史也不难看出苹果目前对蓝牙技术也是越来越关注,例如苹果于2013年9月发布的iOS7就配备了iBeacon技术,这项技术完全基于蓝牙传输。但是众所周知苹果的设备对于权限要求也是比较高的,因此在iOS中并不能像An

小马哥好棒哦 1201

iOS开发之蓝牙(二)CoreBluetooth

Core Bluetooth的使用场景 运动手环、智能家居、嵌入式设备等等(金融刷卡器、心电测量器) Core Bluetooth测试比较麻烦,正常情况下,得至少有2台真实的蓝牙4.0设备 Core Bluetooth的核心结构图 Core Bluetooth的基本常识 Core Bluetooth的基本常识 每个蓝牙4.0设备都是通过服务(Service)和特征(Char...

weixin_30666401的博客 197

[Object-C] 蓝牙

蓝牙 随着蓝牙低功耗技术BLE(Bluetooth Low Energy)的发展,蓝牙技术正在一步步成熟,如今的大部分移动设备都配备有蓝牙4.0,相比之前的蓝牙技术耗电量大大降低。从iOS的发展史也不难看出苹果目前对蓝牙技术也是越来越关注,例如苹果于2013年9月发布的iOS7就配备了iBeacon技术,这项技术完全基于蓝牙传输。但是众所周知苹果的设备对于权限要求也是比较高的,因此在iOS中

Virgil_li的博客 2224

iOS的蓝牙部分了解

iOS的蓝牙部分。主要3种: 1、GameKit,这个是用在两台iOS设备之间进行蓝牙通讯用的。无法用于非iOS系统的外设。 2、CoreBluetooth,用于蓝牙4.0版本,iOS设备和外设必须同时支持4.0蓝牙,外设可以免MFI,直接和iOS设备通讯。一般用法是iOS设备做Central端接收数据,外设做Peripheral端广播数据。 3、External Accessory fra

fang8380的专栏 652

iOS中蓝牙的实现方案

niOS中提供了4个框架用于实现蓝牙连接 pGameKit.framework(用法简单) ü只能用于iOS设备之间的连接,多用于游戏(比如五子棋对战),从iOS7开始过期 pMultipeerConnectivity.framework ü只能用于iOS设备之间的连接,从iOS7开始引入,主要用于文件共享(仅限于沙盒的文件) p pExternalAccessory.fram

CC的专栏 1182

iOS 低功耗蓝牙(BLE)的IoT应用之 - 温度检测仪(上)

背景知识 蓝牙技术最初由爱立信(也就是多年前手机做得最丑最奇葩的公司,最终被用户以脚投票踢出市场)创制。技术始于爱立信公司的1994方案,它是研究在移动电话和其他配件间进行低功耗、低成本无线通信连接的方法。发明者希望为设备间的通讯创造一组统一规则(标准化协议),以解决用户间互不兼容的移动电子设备。1997年前...

weixin_33878457的博客 631

重要的链接

What's New in Core Bluetooth - WWDC19 - Videos - Apple Developerhttps://developer.apple.com/videos/play/wwdc2019/901/

feelinghappy的专栏 151
上一篇: IOS 创建CocoaPods远程私有代码库和公开库
下一篇: OC对象的本质
I微微一笑I
博客等级 码龄11年 0粉丝 86原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值