在一家大型商场,医院或是大楼里,你是否会曾经有过找不到想要去的地方的经历呢?
这种情况下采用上面介绍的传统定位方式,就有些”力不从心”了,首先不能采用GPS定位,而WiFi 和蜂窝式移动电话基站定位误差比较大,这种情况下的定位就是 “微定位”技术了
#地理围栏
微定位技术中一个比较重要的概念—地理围栏. 地理围栏(Geo-fencing)是LBS的一种新应用,就是用一个虚拟的栅栏围出一个虚拟地理边界. 当手机进入,离开某个特定地理区域,或在该区域活动时,手机可以可以接受自动通知和警告.有了地理围栏技术,位置社交网站就可以帮助用户进入某一个地区时自动登记.
地理围栏可以采用传统定位或微定位实现,当然微定位更加有现实意义,建立地理围栏技术往往是处于电子商务,店内导航和设计活动等目的. 定位环境比较复杂,定位要求比较精确.
#iBeacon 技术
苹果公司在iOS 7 之后 支持iBeacon技术,iBeacon技术是苹果公司研发的,它使用低功率蓝牙技术,通过多个iBeacon 基站创建一个信号区域(地理围栏),当设备进去该区域时,相应的应用便会提示用户进入这个地理围栏.
iBeacon 是苹果公司推出的一项室内定位技术,通过软件和硬件的结合,从而大大提高室内精度,从原来的几百米,几十米,提高到一米以内的定位精度。有了这么高精度的定位能力,许多原来只能想一想的事情,现在可以做到了:当你走到某个商品前,手机应用自动跳出商品的介绍,让你的购物体验感,大大增强。下图是一个典型的应用场景:

当用户(安装了特定应用的iOS用户)进入一家大型商场,在门口会有一个iBeacon 基站,它会提示用户是否需要接入这个信号网络。如果用户选择了”是”,他就可以享受到很多服务,iBeacon基站可以核对用户的 Passbook中是否具有本店的某种商品的优惠券或打折卡,当然也可以为用户发放电子优惠
打折卡(即pass),然后存人到passbook中。
也可以为用户提供商场的室内导航。最后要结账的时候,iBeacon可以提供零接触支付。
此外,每个iBeacon基站内置ARM架构cpu、蓝牙模块和闪存,以及加速度计、陀螺仪 寺传愁器。由于采用低功耗蓝牙技术通信,iBeacon基站更加省电,一个小纽扣电池使能为 一个iBeacon基站提供长达两年的续航时间。
#iBeacon技术实现微定位
iBeacon技术通信的核心是低功耗蓝牙通信,iBeacon基站就是一个外设,它只是负责广
播数据,而中心是用户iOS设备上的应用。我们在开发阶段可以使用一个ios设备,在上
面安装一个特定应用使其作为iBeacon基站角色。如果不考虑成本,我们可以使用iOS设
备作为iBeacon基站,但事实上这样一个方案过于奢侈了,现在已经有一些公司开发出了功
能完善的iBeacon技术的基站,它只需要很低的费用就可以构建iBeacon地理围栏。
##iBeacon 基站服务端
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
| import UIKit import CoreBluetooth import CoreLocation
let kUUID = "88936DF5-E10B-4382-89D6-8AE0D80373F8"
let kID = "com.williamxie.AirLocate"
let kPower = -59
class ViewController: UIViewController , CBPeripheralManagerDelegate { var peripheralManager : CBPeripheralManager! override func viewDidLoad() { super.viewDidLoad() self.peripheralManager = CBPeripheralManager(delegate: self, queue: nil) } @IBAction func valueChanged(sender: AnyObject) { let swc = sender as! UISwitch if swc.on { let uuid = NSUUID(UUIDString: kUUID) let region = CLBeaconRegion(proximityUUID: uuid!, identifier: kID) let peripheralData = region.peripheralDataWithMeasuredPower(kPower) let dict:NSDictionary = peripheralData self.peripheralManager.startAdvertising(dict as! [String : AnyObject] ) } else { self.peripheralManager.stopAdvertising() } } func peripheralManagerDidUpdateState(peripheral: CBPeripheralManager) { print("外设状态变化") } }
|
##iBeacon 客户端
ViewController.swift
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123
| import UIKit import CoreBluetooth import CoreLocation
let kUUID = "88936DF5-E10B-4382-89D6-8AE0D80373F8"
let kID = "com.williamxie.AirLocate"
let kPower = -59
class ViewController: UIViewController, CLLocationManagerDelegate { @IBOutlet weak var lblRanging: UILabel! var locationManager : CLLocationManager! var region : CLBeaconRegion! override func viewDidLoad() { super.viewDidLoad() self.locationManager = CLLocationManager() self.locationManager.delegate = self let uuid = NSUUID(UUIDString: kUUID) self.region = CLBeaconRegion(proximityUUID: uuid!, identifier: kID) self.locationManager.requestAlwaysAuthorization() } override func viewDidDisappear(animated: Bool) { super.viewDidDisappear(false) self.locationManager.stopMonitoringForRegion(self.region) self.locationManager.stopRangingBeaconsInRegion(self.region) } @IBAction func rangValue(sender: AnyObject) { let swc = sender as! UISwitch if swc.on { self.locationManager.startRangingBeaconsInRegion(self.region) } else { self.locationManager.stopRangingBeaconsInRegion(self.region) } } @IBAction func onClickMonitoring(sender: AnyObject) { self.locationManager.startMonitoringForRegion(self.region) } func locationManager(manager: CLLocationManager, didDetermineState state: CLRegionState, forRegion region: CLRegion) { let notification = UILocalNotification() if state == .Inside { notification.alertBody = "你在围栏内" } else if state == .Outside { notification.alertBody = "你在围栏外" } else { return } UIApplication.sharedApplication().presentLocalNotificationNow(notification) } func locationManager(manager: CLLocationManager, didEnterRegion region: CLRegion) { let notification = UILocalNotification() notification.alertBody = "你进入围栏" UIApplication.sharedApplication().presentLocalNotificationNow(notification) } func locationManager(manager: CLLocationManager, didExitRegion region: CLRegion) { let notification = UILocalNotification() notification.alertBody = "你退出围栏" UIApplication.sharedApplication().presentLocalNotificationNow(notification) } func locationManager(manager: CLLocationManager, didRangeBeacons beacons: [CLBeacon], inRegion region: CLBeaconRegion) { let aryBeacons = beacons as NSArray var predicate = NSPredicate(format: "proximity = %d", CLProximity.Unknown.rawValue) let unknownBeacons = aryBeacons.filteredArrayUsingPredicate(predicate) if unknownBeacons.count > 0 { self.lblRanging.text = "未检测到" } predicate = NSPredicate(format: "proximity = %d", CLProximity.Immediate.rawValue) let immediateBeacons = aryBeacons.filteredArrayUsingPredicate(predicate) if immediateBeacons.count > 0 { self.lblRanging.text = "最接近" } predicate = NSPredicate(format: "proximity = %d", CLProximity.Near.rawValue) let nearBeacons = aryBeacons.filteredArrayUsingPredicate(predicate) if nearBeacons.count > 0 { self.lblRanging.text = "近距离" } predicate = NSPredicate(format: "proximity = %d", CLProximity.Far.rawValue) let farBeacons = aryBeacons.filteredArrayUsingPredicate(predicate) if farBeacons.count > 0 { self.lblRanging.text = "远距离" } } }
要用到通知,所以配置通知的环境 在Info.plist 添加字段
`AppDelegate.swift` ```swift func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool { let setting = UIUserNotificationSettings(forTypes: [.Alert, .Badge, .Sound], categories: nil) UIApplication.sharedApplication().registerUserNotificationSettings(setting) return true }
|
参考:
CLBeaconRegion 类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| public class CLBeaconRegion : CLRegion { public init(proximityUUID: NSUUID, identifier: String) public init(proximityUUID: NSUUID, major: CLBeaconMajorValue, identifier: String) public init(proximityUUID: NSUUID, major: CLBeaconMajorValue, minor: CLBeaconMinorValue, identifier: String)
public func peripheralDataWithMeasuredPower(measuredPower: NSNumber?) -> NSMutableDictionary
public var proximityUUID: NSUUID { get } public var major: NSNumber? { get } public var minor: NSNumber? { get } public var notifyEntryStateOnDisplay: Bool }
|