将 iOS 6 设备作为 BLE 外设运行
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/13041930/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Run iOS 6 device as a BLE peripheral
提问by Bagusflyer
As we know, iOS 6 support running devices (iPhone 4s and above, and new iPad) as a BLE peripheral. There is a demo in WWDC 2012 Session 705 called "advanced core bluetooth". I asked for the source code from Apple. They sent me a modified version of source code (BTLE_Transfer_Draft). Then I:
众所周知,iOS 6 支持将运行设备(iPhone 4s 及更高版本和新 iPad)作为 BLE 外设。WWDC 2012 Session 705 中有一个名为“高级核心蓝牙”的演示。我向 Apple 索要源代码。他们向我发送了源代码的修改版本 (BTLE_Transfer_Draft)。然后我:
- Run the app in iPhone 5 (iOS 6) in "Peripheral Mode" and start "Advertising"
- Run the app in new iPad (iOS 5.1.1) in "Central Mode"
- 在 iPhone 5 (iOS 6) 中以“外围模式”运行应用程序并启动“广告”
- 在新 iPad (iOS 5.1.1) 中以“中央模式”运行应用程序
The problem is that the peripheral is never been discovered at all. So I use other testing applications including some downloaded from App Store. All failed to discover peripherals. I think the problem should be in BTLE_Transfer_Draft. Because I'm not sure whether I'm allowed to present the whole source code. So I just show the "peripheral mode" part here:
问题是外围设备根本没有被发现。所以我使用其他测试应用程序,包括一些从 App Store 下载的应用程序。都未能发现外围设备。我认为问题应该出在 BTLE_Transfer_Draft 中。因为我不确定是否允许我展示整个源代码。所以我只在这里展示“外围模式”部分:
- (void)viewDidLoad {
[super viewDidLoad];
// Start up the CBPeripheralManager
_peripheralManager = [[CBPeripheralManager alloc] initWithDelegate:self queue:nil];
}
- (void)peripheralManagerDidUpdateState:(CBPeripheralManager *)peripheral {
// Opt out from any other state
if (peripheral.state != CBPeripheralManagerStatePoweredOn) {
return;
}
// We're in CBPeripheralManagerStatePoweredOn state...
NSLog(@"self.peripheralManager powered on.");
// ... so build our service.
// Start with the CBMutableCharacteristic
self.transferCharacteristic = [[CBMutableCharacteristic alloc] initWithType:[CBUUID UUIDWithString:TRANSFER_CHARACTERISTIC_UUID]
properties:CBCharacteristicPropertyNotify
value:nil
permissions:CBAttributePermissionsReadable];
// Then the service
CBMutableService *transferService = [[CBMutableService alloc] initWithType:[CBUUID UUIDWithString:TRANSFER_SERVICE_UUID]
primary:YES];
// Add the characteristic to the service
transferService.characteristics = @[self.transferCharacteristic];
// And add it to the peripheral manager
[self.peripheralManager addService:transferService];
}
/** Start advertising
*/
- (IBAction)switchChanged:(id)sender
{
if (self.advertisingSwitch.on) {
// All we advertise is our service's UUID
[self.peripheralManager startAdvertising:@{ CBAdvertisementDataServiceUUIDsKey : @[[CBUUID UUIDWithString:TRANSFER_SERVICE_UUID]] }];
}
else {
[self.peripheralManager stopAdvertising];
}
}
The BLE is in powered on status and the startAdvertising is called. But the BLE central can never discover it.
BLE 处于开机状态,并调用 startAdvertising。但是 BLE 中心永远无法发现它。
Post updated:
帖子更新:
According to mttrb's suggestion I added "CBAdvertisementDataLocalNameKey" when I startAdvertising. But my service is still can't be discovered by most of the apps including some apps from app store. The only one app can discover my service is an app from app store called "BLE scanner".
根据mttrb的建议,我在开始广告时添加了“CBAdvertisementDataLocalNameKey”。但是我的服务仍然无法被大多数应用程序发现,包括应用程序商店中的一些应用程序。唯一可以发现我的服务的应用程序是应用程序商店中名为“BLE 扫描仪”的应用程序。
My question is: does this mean my application is working as a peripheral? But why my own code can't discover the service? How am I supposed to debug it ?
我的问题是:这是否意味着我的应用程序作为外围设备工作?但是为什么我自己的代码不能发现服务呢?我应该如何调试它?
My code in Central Mode is like this:
我在中央模式下的代码是这样的:
- (void)viewDidLoad
{
[super viewDidLoad];
// Start up the CBCentralManager
_centralManager = [[CBCentralManager alloc] initWithDelegate:self queue:nil];
}
- (void)centralManagerDidUpdateState:(CBCentralManager *)central
{
if (central.state != CBCentralManagerStatePoweredOn) {
return;
}
[self.centralManager scanForPeripheralsWithServices:nil options:nil];
}
- (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI
{
......
}
- (void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError *)error
{
if (error) {
NSLog(@"Error discovering services: %@", [error localizedDescription]);
return;
}
}
- (void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(NSError *)error
{
// Deal with errors (if any)
if (error) {
NSLog(@"Error discovering characteristics: %@", [error localizedDescription]);
return;
}
}
- (void)centralManager:(CBCentralManager *)central didDisconnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error
{
NSLog(@"Peripheral Disconnected");
self.discoveredPeripheral = nil;
}
The didDiscoverPeripheral and didDiscoverServices are never called. What could be wrong? Any idea? Thanks
didDiscoverPeripheral 和 didDiscoverServices 永远不会被调用。可能有什么问题?任何的想法?谢谢
回答by kevinejohn
There is also a high quality free app called LightBluethat you can use to test your code with. It should be able to pick up all devices advertising in peripheral mode and it can even turn itself into an advertising peripheral if you want to make sure your device is working properly.
还有一个名为LightBlue 的高质量免费应用程序,您可以使用它来测试您的代码。它应该能够接收所有在外围模式下做广告的设备,如果你想确保你的设备正常工作,它甚至可以把自己变成一个广告外围设备。
回答by mttrb
I would try moving the startAdvertising:
method call up and into the end of your peripheralManagerDidUpdateState:
delegate method and see if that helps.
我会尝试将startAdvertising:
方法调用移到peripheralManagerDidUpdateState:
委托方法的末尾,看看是否有帮助。
I would also add a CBAdvertisementDataLocalNameKey
key-value pair to your startAdvertising:
method call. I found things were unreliable when the advertisement didn't have a name.
我还会CBAdvertisementDataLocalNameKey
在您的startAdvertising:
方法调用中添加一个键值对。当广告没有名字时,我发现事情是不可靠的。
Finally, I would invest in the BLExplr appavailable in the App Store to help with scanning for your peripheral. It removes the assumption that your central is working correctly.
最后,我会投资App Store 中提供的BLExplr 应用程序,以帮助扫描您的外围设备。它消除了您的中心工作正常的假设。
回答by Nick T
This Git hub project also throws some light on the CBPeripheralManager API. Called PeripheralModeTest. This line is particularly useful for setting the advertising data
这个 Git 中心项目还对 CBPeripheralManager API 有所了解。称为PeripheralModeTest。此行对于设置广告数据特别有用
NSDictionary *advertisingData = @{CBAdvertisementDataLocalNameKey : @"Device Name", CBAdvertisementDataServiceUUIDsKey : @[[CBUUID UUIDWithString:CBUUIDGenericAccessProfileString]]};
Though I can't see any official documentation in the Apple iOS Developer Library yet. More specifically anything about setting the repeat period for the advertising.
虽然我在 Apple iOS Developer Library 中看不到任何官方文档。更具体地说,有关设置广告重复周期的任何内容。
回答by Jens Schwarzer
The BTLE Transferexample has this piece of (odd) code, which may cause some troubles:
所述BTLE传输实例具有这片(奇数)的代码,这可能会造成一些麻烦:
- (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI
{
// Reject any where the value is above reasonable range
if (RSSI.integerValue > -15) {
return;
}
// Reject if the signal strength is too low to be close enough (Close is around -22dB)
if (RSSI.integerValue < -35) {
return;
}
Just remove those two if-statements as it makes no sense!
只需删除这两个 if 语句,因为它没有意义!
I have made a simplified version available herethat can be used to test high volumes of messages being sent from peripheral to central.
我在这里提供了一个简化版本,可用于测试从外围设备发送到中央设备的大量消息。
Please note that the CBPeripheralManager
class was first introduced in iOS 6.0.
请注意,CBPeripheralManager
该类最初是在 iOS 6.0 中引入的。
回答by vedrano
I do not know witch version of BTLE Central Peripheral Transferyou did actually test but current version has iOS 6 as requirement.
我不知道您实际测试过的BTLE Central Peripheral Transfer 的女巫版本,但当前版本要求使用 iOS 6。
So I would suggest to test linkage against iOS 5.1 to see what compatibility issues it shows.
因此,我建议针对 iOS 5.1 测试链接以查看它显示的兼容性问题。