0

I am trying to create an app in which two different devices can communicate to each other using the same UIControlView to send notifications back and forth using iBeacon and send data back and forth using bluetoothle.

I first send out a proximity iBeacon to ask people in the area if they want to play a game.

If someone who gets the notification taps the "OK" button they advertise a bluetooth characteristic who's value is a unique user id and service which the original person is listening for and then an iBeacon notification alerting the original person they want to play.

After this is accomplished the app stops the peripheral advertising and starts the centralManager scanning for a different service UUID based on their own userid and a partial UUID.

I use location manager to get the invitation notification. Then when the "OK" button is tapped I use

    -(void) alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex{

        if (AlertView) {
         NSLog(@"idenify:%@",identifierString);
            if ([identifierString isEqualToString:@"com.checkers.bluetooth"]) {
                    if (buttonIndex == 0) {
                        [UIView animateWithDuration:2 delay:0 options:UIViewAnimationOptionCurveEaseIn animations:^{ 
//here I clear the CentralManager so a new service can be looked for
centralManager = nil;
//here the peripheralManager sends the unique code
[self.peripheralManager startAdvertising:@{ CBAdvertisementDataServiceUUIDsKey : @[[CBUUID UUIDWithString:sendUUID]] }]; recieve.frame = CGRectMake(147,55,20,20);  } completion:^ (BOOL completed) {
//here the peripheralManager sends the proximity notification
 NSUUID * uid = [[NSUUID alloc] initWithUUIDString:@"55DCE9F4-7942-4B9D-B914-50426D6CC976"];
                        self.beaconRegion = [[CLBeaconRegion alloc] initWithProximityUUID:uid identifier:@"com.checkersok.bluetooth"];
                        [self configureTransmitter];
                           [self.peripheralManager startAdvertising:self.peripheralData];inviteCheckers.hidden = YES; [self.recieve setBackgroundImage:[UIImage imageNamed:@"accept.png"] forState:UIControlStateNormal];[UIView animateWithDuration:1 delay:2 options:UIViewAnimationOptionCurveEaseIn animations:^{ movementImage.frame = CGRectMake(300,292,17,17);
                        } completion:^ (BOOL completed) {
//here the peripheral manager is stopped
 [self.peripheralManager stopAdvertising];
                            NSString *startString2 = userId.text;
                            NSString *endString2 = [startString2 stringByAppendingString:@"-2C29-40E0-8E1E-1D7A9E5D0964"];
                            recieverUUID =endString2;
                            self.userUUIDString = @"YES";
                            NSLog(@"userUUIDString2;%@",userUUIDString);
                            NSLog(@"recieverUUID7;%@",recieverUUID);

//here the centralManager is allocated again and starts scanning for the new service UUID
 centralManager = [[CBCentralManager alloc] initWithDelegate:self queue:nil];
                            [self.centralManager scanForPeripheralsWithServices:@[[CBUUID UUIDWithString:recieverUUID]] options:@{ CBCentralManagerScanOptionAllowDuplicatesKey : @YES }];}         ];}         ];


                        NSLog(@"userUUIDString:%@",userUUIDString);

                        [[UIApplication sharedApplication] setApplicationIconBadgeNumber: 0];
                        [[UIApplication sharedApplication] cancelAllLocalNotifications];
                }

When the sender receives the notification that someone is willing to play I set the peripheralManager to nil so I can set it to something else.

When the original person (sender) taps the "OK" button I realloc the peripheral manager and start broadcasting the service UUID based on the second persons userid and the same end of the UUID. which is the sendUUID.

else if ([identifierString isEqualToString:@"com.checkersok.bluetooth"]) {
            if (buttonIndex == 0) {

                [timer4 invalidate];
self.peripheralManager = [[CBPeripheralManager alloc] initWithDelegate:self queue:nil];
               [self.peripheralManager startAdvertising:@{ CBAdvertisementDataServiceUUIDsKey : @[[CBUUID UUIDWithString:sendUUID]] }];
                 movementImage.frame = CGRectMake(283,292,17,17);  } completion:^ (BOOL completed) {
                    }         ];
                [[UIApplication sharedApplication] setApplicationIconBadgeNumber: 0];
                [[UIApplication sharedApplication] cancelAllLocalNotifications];
                self.userUUIDString = userField.text;

            }

Here is where the problem lies. I know the peripheralManager is being called and is sending the data and that the CentralManager is connecting by the logs.

this is the sender log.

2014-07-23 16:34:53.215 BTLE Games[344:60b] self.peripheralManager powered on.
2014-07-23 16:34:53.218 BTLE Games[344:60b] transfer char1:(
    "<CBMutableCharacteristic: 0x17db26f0 UUID = C63CBCC0-6DE3-48D5-BB59-2BEFB9F3AE01, Value = (null), Properties = 0x10, Permissions = 0x1, Descriptors = (null), SubscribedCentrals = (\n)>"
)
2014-07-23 16:34:53.220 BTLE Games[344:60b] serviceUUID;CDEF5678-2C29-40E0-8E1E-1D7A9E5D0964
2014-07-23 16:34:54.030 BTLE Games[344:60b] Central subscribed to characteristic
2014-07-23 16:34:54.032 BTLE Games[344:60b] datatosend2:<41424344 31323334>
2014-07-23 16:34:54.033 BTLE Games[344:60b] stringOne:ABCD1234

and this is the receiver log.

2014-07-23 17:22:39.723 BTLE Games[358:60b] CoreBluetooth[WARNING] <CBCentralManager: 0x170247ec0> is disabling duplicate filtering, but is using the default queue (main thread) for delegate events
2014-07-23 17:22:39.724 BTLE Games[358:60b] CoreBluetooth[API MISUSE] <CBCentralManager: 0x170247ec0> can only accept commands while in the powered on state
2014-07-23 17:22:39.743 BTLE Games[358:60b] Discovered iPhone at -50
2014-07-23 17:22:39.744 BTLE Games[358:60b] Connecting to peripheral <CBPeripheral: 0x1782a0480 identifier = DFDBFE05-B652-D5AD-ABA7-10162669E837, Name = "iPhone", state = disconnected>
2014-07-23 17:22:39.745 BTLE Games[358:60b] Discovered iPhone at -50
2014-07-23 17:22:39.747 BTLE Games[358:60b] Peripheral Connected
2014-07-23 17:22:39.747 BTLE Games[358:60b] Scanning stopped
2014-07-23 17:22:39.748 BTLE Games[358:60b] recieverUUIDP;CDEF5678-2C29-40E0-8E1E-1D7A9E5D0964
2014-07-23 17:22:39.965 BTLE Games[358:60b] discovered characteristic13 C63CBCC0-6DE3-48D5-BB59-2BEFB9F3AE01
2014-07-23 17:22:39.966 BTLE Games[358:60b] Found Notify Characteristic31 <CBCharacteristic: 0x17808f730 UUID = C63CBCC0-6DE3-48D5-BB59-2BEFB9F3AE01, Value = (null), Properties = 0x10, Notifying = NO, Broadcasting = NO>
2014-07-23 17:22:39.967 BTLE Games[358:60b] value1:(null)
2014-07-23 17:22:40.009 BTLE Games[358:60b] CoreBluetooth[WARNING] <CBCentralManager: 0x170247ec0> is disabling duplicate filtering, but is using the default queue (main thread) for delegate events
2014-07-23 17:22:40.010 BTLE Games[358:60b] 

as you can see the peripheralManager is advertising and the centralManager is scanning. the central finds the peripheral and connects but stops. Usually the peripheral continues to advertise and the central has to connect and disconnect a few time before it get the data. This is what I don't know how to get to work since I am using the same code to send and receive this data and I did with the data sent from the second person to the first.

I have tried several different things to get this to work but can't. Can anyone enlighten me about how I can get this to work?

user1114881
  • 731
  • 1
  • 12
  • 25
  • 1
    Why not just the multipeer connectivity framework? – Paulw11 Jul 22 '14 at 22:37
  • No sure what you mean by this. – user1114881 Jul 22 '14 at 22:59
  • There is a framework in ios called the multipeer connection framework that does everything you are trying to do here plus it can operate over wifi as well as bluetooth – Paulw11 Jul 22 '14 at 23:00
  • Did a little research on this and don't think it would serve my purposes since once each person has the others unique code it would be used to open other parts of the app to play interactive games between only these two. Don't know if I could do this using multipeer – user1114881 Jul 22 '14 at 23:12
  • upon further looking maybe it will work. I will do some trial coding. Thanks but if someone can give me help with just getting the original question answered I'd appreciate that too. – user1114881 Jul 22 '14 at 23:32
  • 1
    You should implement the delegate method to remove the warning. You should simply your question to include only the relevant code to reproduce your problem. – Paulw11 Jul 23 '14 at 03:25
  • 1
    This line - "CoreBluetooth[API MISUSE] can only accept commands while in the powered on state" indicates that you are not waiting for your central manager to report that it is in the powered on state before attempting to use it - Have you implemented `centralManagerDidUpdateState:` correctly? – Paulw11 Jul 24 '14 at 00:53
  • That was it I have forgot to get a NSString from the characteristic.value and then put that in the textField in the didUpdateValueForCharacteristic. thank you thank you thank you. I'd been looking at it too long and didn't see it. – user1114881 Jul 24 '14 at 04:58
  • possible duplicate of [When would CBCentralManager's state ever be powered on but still give me a "not powered on" warning?](http://stackoverflow.com/questions/17118534/when-would-cbcentralmanagers-state-ever-be-powered-on-but-still-give-me-a-not) – Tommy Devoy Jul 24 '14 at 16:53

0 Answers0