最近开发一个蓝牙挖宝的功能,记录一下
需求:一个商场每家店铺有好几种优惠券 ,通过摇一摇获取,并获取最近的
参考资料:http://www.tuicool.com/articles/iI7nQf
http://www.jianshu.com/p/7816b016ceac
总结一下就是: UUID 你的唯一标识,用来监听商场的所有商铺 ,major 每一家店铺的标识, minor 店铺内每个商品的标识。
1,准备工作
首先在info.plist 文件中设置
Privacy - Bluetooth Peripheral Usage Description (我要访问蓝牙,需要您的授权)
Privacy - Location When In Use Usage Description (在使用期间,我要访问您的位置)
2,在你需要实现的页面导入
#import <CoreBluetooth/CoreBluetooth.h>
#import <CoreLocation/CoreLocation.h>
声明代理 <CLLocationManagerDelegate,CBPeripheralManagerDelegate>>
@property (nonatomic, strong) CLLocationManager *locationManager;
@property (nonatomic, strong) CLBeaconRegion *beaconRegion;//被扫描的iBeacon
@property (nonatomic, strong) NSArray *beaconArr;//存放扫描到的iBeacon
@property (nonatomic, copy) NSString *uuidString;
@property (nonatomic, strong) CBPeripheralManager *manager;
3.在viewDidLoad中 设置iBeacon数据
// 设置允许摇一摇功能
[UIApplication sharedApplication].applicationSupportsShakeToEdit =YES;
self.manager = [[CBPeripheralManager alloc]initWithDelegate:self queue:nil];
self.locationManager = [[CLLocationManager alloc] init];
if(![CLLocationManager isRangingAvailable]){//是否支持测距
return;
}
self.locationManager.delegate = self;
[self.locationManager requestWhenInUseAuthorization];
//iBeacon uuid
NSUUID *proximityUUID = [[NSUUID alloc] initWithUUIDString:@"你的UUID"];
self.beaconRegion = [[CLBeaconRegion alloc] initWithProximityUUID:proximityUUID identifier:@"Identifier"];
self.beaconRegion.notifyEntryStateOnDisplay = YES;//进入监测区域时是否通知
[self.locationManager startMonitoringForRegion:self.beaconRegion];//开始检测
然后实现代理方法
#pragma mark - CBPeripheralManagerDelegate
- (void)peripheralManagerDidUpdateState:(CBPeripheralManager *)peripheral{
switch (peripheral.state) {
case CBPeripheralManagerStatePoweredOn: {
NSLog(@"蓝牙开启且可用");
[SVProgressHUD showSuccessWithStatus:@"蓝牙可用"];
}
break;
default:
NSLog(@"蓝牙不可用");
[SVProgressHUD showErrorWithStatus:@"蓝牙不可用"];
break;
}
}
#pragma mark - CLLocationManagerDelegate
//进入监测区域的时候调用
-(void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region{
[self.locationManager startRangingBeaconsInRegion:self.beaconRegion];
}
//离开监测区域的时候调用
-(void)locationManager:(CLLocationManager *)manager didExitRegion:(nonnull CLRegion *)region{
[self.locationManager stopRangingBeaconsInRegion:self.beaconRegion];
}
//改变授权状态的时候调用
- (void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status
{
[CLLocationManager authorizationStatus];
[self.locationManager startRangingBeaconsInRegion:self.beaconRegion];
}
//在监测区域中找到我们的iBeacon设备的时候调用
- (void)locationManager:(CLLocationManager *)manager
didRangeBeacons:(NSArray *)beacons
inRegion:(CLBeaconRegion *)region {
//判断一下是不是你的UUID
if (![[region.proximityUUID UUIDString] isEqualToString:@"你的UUID"]){
[self.locationManager stopMonitoringForRegion:region];
[self.locationManager stopRangingBeaconsInRegion:region];
}
//打印所有iBeacon的信息
for (CLBeacon* beacon in beacons) {
switch (beacon.proximity) {
case CLProximityNear: {
NSLog(@"近");
self.uuidString = [NSString stringWithFormat:@"%@-%@-%@",beacon.proximityUUID.UUIDString,major,beacon.minor];
break;
}
case CLProximityFar: {
NSLog(@"远");
self.uuidString =[NSString stringWithFormat:@"%@-%@-%@",beacon.proximityUUID.UUIDString,major,beacon.minor];
break;
}
default:
break;
}
}
}
这样应该可以了吧,结果现场测试的时候有问题,不能根据距离自动获取比较近的uuidString,原来是
- (void)locationManager:(CLLocationManager *)manager
didRangeBeacons:(NSArray *)beacons
inRegion:(CLBeaconRegion *)region
这个方法只调用了一次,没有办法,我只好在
- (void)motionBegan:(UIEventSubtype)motion withEvent:(UIEvent *)event{
self.locationManager = [[CLLocationManageralloc] init];
if(![CLLocationManagerisRangingAvailable]){//是否支持测距
return;
}
if (self.locationManager.rangedRegions.count > 0) {
NSLog(@"Didn't turn on ranging: Ranging already on.");
return;
}
self.locationManager.delegate =self;
[self.locationManagerrequestWhenInUseAuthorization];
[self.locationManagerstartMonitoringForRegion:self.beaconRegion];
}
重新初始化了一下,效果是实现了,但如果一直摇,它就会一直分配新的内存地址,总觉得这样是不对的。 想看看它占多大内存,导入
#import <malloc/malloc.h>
NSLog(@"Size of %@: %zd",NSStringFromClass([self.locationManagerclass]), malloc_size((__bridgeconst void *)self.locationManager));
结果是
Size of CLLocationManager: 16
参考:点击打开链接后来想了想,用完以后:把对象置为nil,但是不行,代理方法不执行,暂时就只能先这样了。