DFBle.swift
//
// DFBle.swift
// DFBle
//
// Created by LeeYaping on 15/9/2.
// Copyright (c) 2015年 lisper. All rights reserved.
//
import Foundation
import CoreBluetooth
/**
* easy protocol, to use ble
*/
@objc public protocol BleProtocol {
optional func didDiscover (name:String, rssi:NSNumber)
optional func didConnect (name:String)
optional func didDisconnect ()
optional func didBleReady()
optional func didReadRSSI (rssi:NSNumber)
}
public class DFBle:NSObject, CBCentralManagerDelegate, CBPeripheralDelegate {
public static let sharedInstance = DFBle ()
struct peripheralWithRssi {
var RSSI: NSNumber
var peripheral :CBPeripheral
}
var bright:UInt8 = 255
var color:UInt8 = 0
public var delegate :BleProtocol?
let DFUUID :CBUUID = CBUUID(string: "DFB0")
var rescanTimer :NSTimer?
var rssiTimer :NSTimer?
var centralManager :CBCentralManager!
var myperipheral :CBPeripheral?
var mychar :CBCharacteristic?
var myservice :CBService?
var peripherals :[peripheralWithRssi]!
var isKeepConnect = true
var isConnect :Bool = false
var isScanning :Bool = false
private override init () {
super.init ()
print ("shared instance")
self.centralManager = CBCentralManager(delegate: self, queue: nil)
peripherals = [peripheralWithRssi]()
}
/*
override init () {
super.init ()
self.centralManager = CBCentralManager(delegate: self, queue: nil)
peripherals = [peripheralWithRssi]()
}
*/
private convenience init (delegate: BleProtocol) {
self.init ()
self.delegate = delegate
}
public func beginScan () {
if isScanning == false {
isKeepConnect = true
self.centralManager.scanForPeripheralsWithServices([DFUUID], options: nil)
rescanTimer = NSTimer.scheduledTimerWithTimeInterval(2, target: self, selector: "updateScan", userInfo: nil, repeats: true)
isScanning = true
}
}
/**
stop scan ble device
*/
public func breakScan () {
rescanTimer?.invalidate()
rescanTimer = nil
centralManager.stopScan()
isScanning = false
}
public func disConnect () {
isKeepConnect = false
centralManager.cancelPeripheralConnection(myperipheral!)
}
/**
rescan ble device every 2 seconds
*/
func updateScan () {
if let p = getMaxPeripheral() {
myperipheral = p
connect(myperipheral!)
} else {
print ("rescan")
self.centralManager.scanForPeripheralsWithServices([DFUUID], options: nil)
}
}
/**
connect a peripheral
- parameter peripheral: that rssi is best
*/
func connect (peripheral:CBPeripheral) {
myperipheral = peripheral
centralManager.stopScan()
isScanning = false
self.rescanTimer?.invalidate()
self.rescanTimer = nil
centralManager.connectPeripheral(peripheral, options: nil)
}
/**
send one byte to connected peripheral
- parameter value: one byte data will send
*/
public func sendByte (value :UInt8) {
var myvalue = value
let data = NSData(bytes: &myvalue, length: 1)
myperipheral?.writeValue(data, forCharacteristic: mychar!, type: CBCharacteristicWriteType.WithoutResponse)
}
/**
send String to connected peripheral
- parameter value: -> a string will send
*/
public func sendString (value :String) {
if value.lengthOfBytesUsingEncoding(NSASCIIStringEncoding) == 0 {
return
}
let data = value.dataUsingEncoding(NSASCIIStringEncoding, allowLossyConversion: true)
print ("data: \(data)")
myperipheral?.writeValue(data!, forCharacteristic: mychar!, type: CBCharacteristicWriteType.WithoutResponse)
}
/**
send data to control a car
- parameter left: left speed
- parameter right: right speed
*/
func sendRunCommand (left left:Int8, right:Int8) {
let cmd :UInt8 = 0x10
let cmdString = String(format: "$%02X%02X%02X\r", cmd, UInt8(bitPattern: left) , UInt8(bitPattern: right))
print("cmd=\(cmdString.lengthOfBytesUsingEncoding(NSASCIIStringEncoding)):\(cmdString)")
sendString(cmdString)
}
@objc public func centralManagerDidUpdateState(central: CBCentralManager) {
if centralManager.state == .PoweredOn {
print ("ble opened")
} else {
print ("ble open error")
}
}
public func centralManager(central: CBCentralManager, didDiscoverPeripheral peripheral: CBPeripheral, advertisementData: [String : AnyObject], RSSI: NSNumber) {
//println ("didDiscoverPeripheral ")
print ("name=\(peripheral.name) RSSI=\(Int32(RSSI.intValue))")
if peripheral.name == "car_007" {
connect(peripheral)
}
if RSSI.integerValue > -50 && RSSI.integerValue < -10 {
appendPeripheral(peripheral, RSSI: RSSI)
}
delegate?.didDiscover?(peripheral.name!, rssi: RSSI)
}
/**
append new find peripheral to peripherals and update rssi
- parameter peripheral:
- parameter RSSI:
*/
func appendPeripheral (peripheral :CBPeripheral, RSSI :NSNumber) {
for var p=1; p < self.peripherals.count; p++ {
if self.peripherals[p].peripheral == peripheral {
self.peripherals[p].RSSI = RSSI
return
}
}
self.peripherals.append(peripheralWithRssi(RSSI: RSSI, peripheral: peripheral))
}
/**
return the max rssi peripheral tin peripherals
- returns: peripheral with best rssi or nil
*/
func getMaxPeripheral () -> CBPeripheral? {
if self.peripherals.count == 0 {
return nil
}
var max :NSNumber = self.peripherals[0].RSSI
var maxPeripheral :CBPeripheral = self.peripherals[0].peripheral
for p in self.peripherals {
if p.RSSI.integerValue > max.integerValue {
max = p.RSSI
maxPeripheral = p.peripheral
}
}
return maxPeripheral
}
public func centralManager(central: CBCentralManager, didConnectPeripheral peripheral: CBPeripheral) {
//println ("didConnectPeripheral ")
peripheral.delegate = self
peripheral.discoverServices(nil)
peripheral.readRSSI()
rescanTimer?.invalidate()
rescanTimer = nil
delegate?.didConnect?(peripheral.name!)
}
public func centralManager(central: CBCentralManager, didDisconnectPeripheral peripheral: CBPeripheral, error: NSError?) {
//println ("didDisconnectPeripheral ")
isConnect = false
rssiTimer?.invalidate()
rssiTimer = nil
rescanTimer?.invalidate()
if isKeepConnect == true {
centralManager.connectPeripheral(myperipheral!, options: nil)
}
delegate?.didDisconnect?()
}
public func peripheral(peripheral: CBPeripheral, didDiscoverServices error: NSError?) {
//println ("didDiscoverServices ")
if (peripheral.services![1] ).UUID.UUIDString == "DFB0" {
//println ("get DFB0")
myservice = peripheral.services![1]// as? CBService
peripheral.discoverCharacteristics(nil, forService: peripheral.services![1])// as! CBService)
}
}
public func peripheral(peripheral: CBPeripheral, didDiscoverCharacteristicsForService service: CBService, error: NSError?) {
//println ("didDiscoverCharacteristicsForService ")
let char = (service.characteristics![0]) //as! CBCharacteristic)
if char.UUID.UUIDString == "DFB1" {
//println ("get DFB1")
mychar = char
myperipheral?.setNotifyValue(true, forCharacteristic: mychar!)
isConnect = true
rssiTimer = NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: "updateRSSI", userInfo: nil, repeats: true)
delegate?.didBleReady?()
}
}
/**
read rssi every seconds
*/
func updateRSSI () {
myperipheral?.readRSSI()
}
public func peripheral(peripheral: CBPeripheral, didUpdateNotificationStateForCharacteristic characteristic: CBCharacteristic, error: NSError?) {
//println ("didUpdateNotificationStateForCharacteristic ")
}
//
public func peripheral(peripheral: CBPeripheral, didUpdateValueForCharacteristic characteristic: CBCharacteristic, error: NSError?) {
print ("didUpdateValueForCharacteristic")
let str = NSString(data: characteristic.value!, encoding: NSASCIIStringEncoding)
//var str = NSString(data: characteristic.value(), encoding: NSASCIIStringEncoding)
if str != nil {
print ("read:(\(str!.length)) \(str!)")
}
}
public func peripheral(peripheral: CBPeripheral, didWriteValueForCharacteristic characteristic: CBCharacteristic, error: NSError?) {
//println ("didWriteValueForCharacteristic ")
}
/*
func peripheralDidUpdateRSSI(peripheral: CBPeripheral!, error: NSError!) {
rssiLabel.text = peripheral.RSSI.stringValue
}
*/
func peripheral(peripheral: CBPeripheral!, didReadRSSI RSSI: NSNumber!, error: NSError!) {
// println ("didReadRSSI ")
delegate?.didReadRSSI?(RSSI)
}
}
DFBle.swift的更多相关文章
- iOS代码规范(OC和Swift)
下面说下iOS的代码规范问题,如果大家觉得还不错,可以直接用到项目中,有不同意见 可以在下面讨论下. 相信很多人工作中最烦的就是代码不规范,命名不规范,曾经见过一个VC里有3个按钮被命名为button ...
- Swift与C#的基础语法比较
背景: 这两天不小心看了一下Swift的基础语法,感觉既然看了,还是写一下笔记,留个痕迹~ 总体而言,感觉Swift是一种前后端多种语言混合的产物~~~ 做为一名.NET阵营人士,少少多多总喜欢通过对 ...
- iOS开发系列--Swift语言
概述 Swift是苹果2014年推出的全新的编程语言,它继承了C语言.ObjC的特性,且克服了C语言的兼容性问题.Swift发展过程中不仅保留了ObjC很多语法特性,它也借鉴了多种现代化语言的特点,在 ...
- 算法与数据结构(十七) 基数排序(Swift 3.0版)
前面几篇博客我们已经陆陆续续的为大家介绍了7种排序方式,今天博客的主题依然与排序算法相关.今天这篇博客就来聊聊基数排序,基数排序算法是不稳定的排序算法,在排序数字较小的情况下,基数排序算法的效率还是比 ...
- 算法与数据结构(十五) 归并排序(Swift 3.0版)
上篇博客我们主要聊了堆排序的相关内容,本篇博客,我们就来聊一下归并排序的相关内容.归并排序主要用了分治法的思想,在归并排序中,将我们需要排序的数组进行拆分,将其拆分的足够小.当拆分的数组中只有一个元素 ...
- Swift enum(枚举)使用范例
//: Playground - noun: a place where people can play import UIKit var str = "Hello, playground& ...
- swift开发新项目总结
新项目用swift3.0开发,现在基本一个月,来总结一下遇到的问题及解决方案 1,在确定新项目用swift后,第一个考虑的问题是用纯swift呢?还是用swift跟OC混编 考虑到新项目 ...
- swift 中关于open ,public ,fileprivate,private ,internal,修饰的说明
关于 swift 中的open ,public ,fileprivate,private, internal的区别 以下按照修饰关键字的访问约束范围 从约束的限定范围大到小的排序进行说明 open,p ...
- 【swift】BlockOperation和GCD实用代码块
//BlockOperation // // ViewController.swift import UIKit class ViewController: UIViewController { @I ...
随机推荐
- mysql explain 命令解释
转载http://bzyyc.happy.blog.163.com/blog/static/6143064720115102551554/ key实 际使用的索引.如果为NULL,则没有使用索引.很少 ...
- 学习WCF(1)
1. 什么是WCF WCF是创建面向服务应用程序的一个框架,用WCF, 你可以发送异步消息. 一个服务的终结点可以是服务宿主在IIS上面,也可以是一个服务宿主在应用程序上面.一个终结点也可以是客户端的 ...
- 利用CSS实现居中对齐
1. 文本居中 首先编写一个简单的html代码,设置一个类名为parentDiv的div对象.html代码如下: <div class="parentDiv"> 这里随 ...
- Design Pattern ——Factory Method&Abstract Factory
今天开始复习设计模式.设计模式相关的资料有很多,概念性的东西就画个图就可以了.把关注点放在例子上,设计模式还是要使用中才有感受. 从Factory Method&Abstract Factor ...
- java socket报文通信(三)java对象和xml格式文件的相互转换
前两节讲了socket服务端,客户端的建立以及报文的封装.今天就来讲一下java对象和xml格式文件的相互转换. 上一节中我们列举了一个报文格式,其实我们可以理解为其实就是一个字符串.但是我们不可能每 ...
- iOS判断UIScrollView的滚动方向
- (void) scrollViewDidScroll:(UIScrollView *)scrollView { CGFloat newY = scrollView.contentOffset.y; ...
- icon font
简而言之,就是: 使用 特殊字符 + (使用@font-face)自定义的字体 来代替图片文件显示图标. 关于@font-face, 参考来自W3CPLUS 的详细解释: css3 @font-fac ...
- Centos 中 vim 的配置
工欲善其事,必先利其器,我们要用好 vim 就先来把它配置的顺手一点,这样可以大大提高我们的工作学习效率 1.跳转指令 Ctags1 从下面地址下载ctags,将其中的ctags.exe复制到vim目 ...
- VS2013 编译 MySql Connector C 6.1.6
1.下载cmake http://cmake.org/ 2.下载最新版MySql Connector C http://www.mysql.com 3.命令行下,转到源代码目录下,"cmak ...
- jq事件绑定
有些时候我们在页面中会动态的添加一下dom结构,当我们想要给这些结点添加事件时需要在此节点绑定一系列的操作. <a href="#" onclick="addBtn ...