iphone - How to detect nearby devices with Bluetooth LE in iOS 7.1 both in background and foreground? -
i have app needs observe nearby (in range bluetooth le) devices running same application , ios 7.1. i've considered 2 alternatives detection:
having devices deed ibeacons , observe ibeacons in range using corebluetooth (like in vicinity implementation here) create ble peripheral, advertise , scan peripheralsit seems alternative 1 out of question because:
it may take @ to the lowest degree 15 minutes ios observe entering beacon part when application running background (ios 7.1)option 2 seems way go, there difficulties regarding implementation:
ios seems alter peripheral uuid in advertisement packets after period of time (around 15 minutes?). means it's not straight possible identify advertising device advertisement broadcast signal.regarding this, have next questions:
are there other methods of implementing nearby device detection haven't considered? is possible identify device through advertising (or other means) alternative 2 work?
i found way create work core bluetooth (option 2), procedure following:
the application advertises itself encoded device unique identifier incbadvertisementdatalocalnamekey (when broadcasting application runs foreground) , characteristic provides device unique identifier through bluetooth le service (when broadcasting application runs background) at same time, application scans other peripherals same service. the advertising works follows:
for other devices able identify device, utilize per-device unique uuid (i'm using urban airship's[uautils deviceid], because it's device identifier in other parts of program, - might utilize unique id implementation). when application running foreground, can pass device unique id directly in advertisement packet using cbadvertisementdatalocalnamekey. standard uuid representation long, utilize shortened form of uuid follows:
+ (nsstring *)shorteneddeviceid { nsstring *deviceid = [uautils deviceid]; nsuuid *uuid = [[nsuuid alloc] initwithuuidstring:deviceid]; uuid_t uuidbytes; [uuid getuuidbytes:uuidbytes]; nsdata *data = [nsdata datawithbytes:uuidbytes length:16]; nsstring *base64 = [data base64encodedstringwithoptions:0]; nsstring *encoded = [[[base64 stringbyreplacingoccurrencesofstring:@"/" withstring:@"_"] stringbyreplacingoccurrencesofstring:@"+" withstring:@"-"] stringbyreplacingoccurrencesofstring:@"=" withstring:@""]; homecoming encoded; } when application running background, advertisement packet gets stripped , cbadvertisementdatalocalnamekey not passed along anymore. this, application needs publish characteristic provides unique device identifier:
- (void)peripheralmanagerdidupdatestate:(cbperipheralmanager *)peripheral { if (peripheral.state == cbperipheralmanagerstatepoweredon) { [self startadvertising]; if (peripheralmanager) { cbuuid *serviceuuid = [cbuuid uuidwithstring:device_identifier_service_uuid]; cbuuid *characteristicuuid = [cbuuid uuidwithstring:device_identifier_characteristic_uuid]; cbmutablecharacteristic *characteristic = [[cbmutablecharacteristic alloc] initwithtype:characteristicuuid properties:cbcharacteristicpropertyread value:[[myutils shorteneddeviceid] datausingencoding:nsutf8stringencoding] permissions:cbattributepermissionsreadable]; cbmutableservice *service = [[cbmutableservice alloc] initwithtype:serviceuuid primary:yes]; service.characteristics = @[characteristic]; [peripheralmanager addservice:service]; } } } the scanning works follows:
you start scan peripherals service uuid follows (notice need specify service uuid, because otherwise background scan fails find device):
[self.centralmanager scanforperipheralswithservices:@[[cbuuid uuidwithstring:device_identifier_service_uuid]] options:scanoptions]; when device discovered @ - (void)centralmanager:(cbcentralmanager *)central diddiscoverperipheral:(cbperipheral *)peripheral advertisementdata:(nsdictionary *)advertisementdata rssi:(nsnumber *)rssi check if advertisementdata[cbadvertisementdatalocalnamekey] exists , seek convert uuid form this:
+ (nsstring *)deviceidfromshorteneddeviceid:(nsstring *)shorteneddeviceid { if (!shorteneddeviceid) homecoming nil; nsstring *decoded = [[[shorteneddeviceid stringbyreplacingoccurrencesofstring:@"_" withstring:@"/"] stringbyreplacingoccurrencesofstring:@"-" withstring:@"+"] stringbyappendingstring:@"=="]; nsdata *data = [[nsdata alloc] initwithbase64encodedstring:decoded options:0]; if (!data) homecoming nil; nsuuid *uuid = [[nsuuid alloc] initwithuuidbytes:[data bytes]]; homecoming uuid.uuidstring; } if conversion fails know broadcasting device in background, , need connect device read characteristic provides unique identifier. need utilize [self.central connectperipheral:peripheral options:nil]; (with peripheral.delegate = self; , implement chain of delegate methods follows:
- (void)centralmanager:(cbcentralmanager *)central didconnectperipheral:(cbperipheral *)peripheral { [peripheral discoverservices:@[[cbuuid uuidwithstring:device_identifier_service_uuid]]]; } - (void)peripheral:(cbperipheral *)peripheral diddiscoverservices:(nserror *)error { if (!error) { (cbservice *service in peripheral.services) { if ([service.uuid.uuidstring isequaltostring:device_identifier_service_uuid]) { nslog(@"service found uuid: %@", service.uuid); [peripheral discovercharacteristics:@[[cbuuid uuidwithstring:device_identifier_characteristic_uuid]] forservice:service]; } } } } - (void)peripheral:(cbperipheral *)peripheral diddiscovercharacteristicsforservice:(cbservice *)service error:(nserror *)error { if (!error) { (cbcharacteristic *characteristic in service.characteristics) { if ([characteristic.uuid isequal:[cbuuid uuidwithstring:device_identifier_characteristic_uuid]]) { [peripheral readvalueforcharacteristic:characteristic]; } } } } - (void)peripheral:(cbperipheral *)peripheral didupdatevalueforcharacteristic:(cbcharacteristic *)characteristic error:(nserror *)error { if (!error) { nsstring *shorteneddeviceid = [[nsstring alloc] initwithdata:characteristic.value encoding:nsutf8stringencoding]; nsstring *deviceid = [myutils deviceidfromshorteneddeviceid:shorteneddeviceid]; nslog(@"got device id: %@", deviceid); } } ios iphone bluetooth bluetooth-lowenergy core-bluetooth
No comments:
Post a Comment