运行iPhone作为背景的iBeacon显示 [英] Run iPhone as an iBeacon in the background
问题描述
是否有可能运行在iOS 7设备作为蓝牙LE外围设备(iBeacon显示),并有在后台做广告?我已经能够得到它与下面的code前景做广告,可以看到它从其他iOS设备,但只要我回到主屏幕停止广告。我没有添加蓝牙外设背景模式的plist中,但似乎并没有帮助,虽然我得到提示说该设备要在后台使用蓝牙。我是不是做错了什么或者这只是不可能在iOS的7?
peripManager = [[CBPeripheralManager页头] initWithDelegate:自队列:无]; - (无效)peripheralManagerDidUpdateState:(CBPeripheralManager *)外设
{
如果(peripheral.state!= CBPeripheralManagerStatePoweredOn){
返回;
} * NSString的标识符= @MyBeacon
//构建区域
CLBeaconRegion * beaconRegion = [[CLBeaconRegion页头] initWithProximityUUID:UUID标识:标识]。 //传递零将使用设备默认的电源
* NSDictionary的有效载荷= [beaconRegion peripheralDataWithMeasuredPower:无]; //开始广告
[peripManager startAdvertising:有效载荷]。
}
下面是code是在接收/收听结束:
- (空)的LocationManager:(CLLocationManager *)经理didRangeBeacons:(NSArray的*)标
inRegion:(CLBeaconRegion *)区域
{
//检查我们是否移近或远离iBeacon显示...
如果(beacons.count大于0){
CLBeacon *信标= [信标objectAtIndex:0]; 开关(beacon.proximity){
案例CLProximityImmediate:
[self日志:[的NSString stringWithFormat:@!你坐在它立%,(长)beacon.rssi]];
打破;
案例CLProximityNear:
[self日志:[的NSString stringWithFormat:@!逐渐回暖%礼,(长)beacon.rssi]];
打破;
默认:
[self日志:[的NSString stringWithFormat:@!这是在这附近立%,(长)beacon.rssi]];
打破;
}
}
}
标准CoreBluetooth广告可以播放,而应用程序是在后台运行,但如果他们开始与 CLBeaconRegion
词典。解决办法是干脆抛弃CoreLocation框架,并创建自己的近水楼台框架只用CoreBlueTooth。
您还需要使用适当的背景说明符的Info.plist文件(例如:蓝牙外设
和蓝牙中央
)。
在code看起来是这样的:
1),使用创建一个标准的外围广告 CBPeripheralManager
的NSDictionary * advertisingData = @ {CBAdvertisementDataLocalNameKey:@我外设
CBAdvertisementDataServiceUUIDsKey:@ [CBUUID UUIDWithString:标识符]};//超过BLE开始投放广告
[peripheralManager startAdvertising:advertisingData];
2)使用使用 CBCentralManager
使用指定的UUID以扫描服务。
的NSDictionary * scanOptions = @ {CBCentralManagerScanOptionAllowDuplicatesKey:@(YES)};
NSArray的*服务= @ [CBUUID UUIDWithString:标识符]];[centralManager scanForPeripheralsWithServices:服务选项:scanOptions];
3) CBCentralManagerDelegate
方法 didDiscoverPeripheral
,阅读 RSSI
广告的价值。
- (无效)centralManager:(CBCentralManager *)中央didDiscoverPeripheral:(CBPeripheral *)外设
advertisementData:(NSDictionary的*)advertisementData RSSI(NSNumber的*)RSSI
{ 的NSLog(@RSSI数:%d,[RSSI的intValue]);
}
4)翻译的RSSI值成距离
- (INDetectorRange)convertRSSItoINProximity:(NSInteger的)接近
{
如果(接近< -70)
返回INDetectorRangeFar;
如果(接近< -55)
返回INDetectorRangeNear;
如果(接近℃,)
返回INDetectorRangeImmediate; 返回INDetectorRangeUnknown;
}
我发现我需要放松或平均的RSSI值得到任何可行的。这绝不是当你与任何传感器数据的工作(例如加速计数据),比不同。
我有这个概念完全工作,希望在某个时候某个地方发表。
此外,使用docs (蓝牙核心编程指南),如果你会被卡住。
更新::一种满code样品达Github上。我从事这是一个工作相关的项目的一部分。
更新#2: 苹果释放到iBeacon显示后台行为主要改进为iOS7.1
Is it possible to run an iOS 7 device as a Bluetooth LE peripheral (iBeacon) and have it advertise in the background? I have been able to get it to advertise in the foreground with the code below and can see it from another iOS device but as soon as I go back to the home screen it stops advertising. I did add the bluetooth-peripheral background mode in the plist but that didn't seem to help although I do get the prompt saying the device wants to use bluetooth in the background. Am I doing something wrong or is this just not possible in iOS 7?
peripManager = [[CBPeripheralManager alloc] initWithDelegate:self queue:nil];
- (void)peripheralManagerDidUpdateState:(CBPeripheralManager *)peripheral
{
if (peripheral.state != CBPeripheralManagerStatePoweredOn) {
return;
}
NSString *identifier = @"MyBeacon";
//Construct the region
CLBeaconRegion *beaconRegion = [[CLBeaconRegion alloc] initWithProximityUUID:uuid identifier:identifier];
//Passing nil will use the device default power
NSDictionary *payload = [beaconRegion peripheralDataWithMeasuredPower:nil];
//Start advertising
[peripManager startAdvertising:payload];
}
Here is the code that is on the receiving/listening end:
- (void)locationManager:(CLLocationManager *)manager didRangeBeacons:(NSArray *)beacons
inRegion:(CLBeaconRegion *)region
{
//Check if we have moved closer or farther away from the iBeacon…
if (beacons.count > 0) {
CLBeacon *beacon = [beacons objectAtIndex:0];
switch (beacon.proximity) {
case CLProximityImmediate:
[self log:[NSString stringWithFormat:@"You're Sitting on it! %li", (long)beacon.rssi]];
break;
case CLProximityNear:
[self log:[NSString stringWithFormat:@"Getting Warmer! %li", (long)beacon.rssi]];
break;
default:
[self log:[NSString stringWithFormat:@"It's around here somewhere! %li", (long)beacon.rssi]];
break;
}
}
}
Standard CoreBluetooth advertisements can broadcast while the app is in the background, but not if they were started with CLBeaconRegion
dictionary. The workaround is to ditch CoreLocation framework altogether and create your own proximity "framework" using only CoreBlueTooth.
You still need to use the appropriate background specifiers in the Info.plist file (e.g. bluetooth-peripheral
and bluetooth-central
).
The code looks something like this:
1) create a standard peripheral advertisement using CBPeripheralManager
NSDictionary *advertisingData = @{CBAdvertisementDataLocalNameKey:@"my-peripheral",
CBAdvertisementDataServiceUUIDsKey:@[[CBUUID UUIDWithString:identifier]]};
// Start advertising over BLE
[peripheralManager startAdvertising:advertisingData];
2) use use CBCentralManager
to scan for that service using the UUID you specified.
NSDictionary *scanOptions = @{CBCentralManagerScanOptionAllowDuplicatesKey:@(YES)};
NSArray *services = @[[CBUUID UUIDWithString:identifier]];
[centralManager scanForPeripheralsWithServices:services options:scanOptions];
3) in the CBCentralManagerDelegate
method didDiscoverPeripheral
, read the RSSI
value of the advertisement.
- (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral
advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI
{
NSLog(@"RSSI: %d", [RSSI intValue]);
}
4) Translate the RSSI values into a distance.
- (INDetectorRange)convertRSSItoINProximity:(NSInteger)proximity
{
if (proximity < -70)
return INDetectorRangeFar;
if (proximity < -55)
return INDetectorRangeNear;
if (proximity < 0)
return INDetectorRangeImmediate;
return INDetectorRangeUnknown;
}
I found that I needed to "ease" or "average" the RSSI values to get anything workable. This is no different than when you are working with any sensor data (e.g. accelerometer data).
I have this concept fully working hope to publish it somewhere at some point.
Also, use the docs (Core Bluetooth Programming Guide) if you get stuck.
Update: A full code sample is up on Github. I worked on this as part of a work related project.
Update #2: Apple release major improvements to iBeacon background behavior for iOS7.1
这篇关于运行iPhone作为背景的iBeacon显示的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!