0

I'm using GKSession, GKSessionDelegate to implement peer to peer bluetooth connectivity between a number of iX (iPod, iPad, iPhone, ...) devices. I want to display a list of the currently available/connected devices in range.

I'm currently relying on

- (void)session:(GKSession *)session peer:(NSString *)peerID didChangeState:(GKPeerConnectionState)state

to do this. Unfortunately, this method does not appear to be reliably called when a device goes out of range. Is there a "better" way to determine if a device is in range?

Some code:

- (void)session:(GKSession *)session peer:(NSString *)peerID didChangeState:(GKPeerConnectionState)state {

    NSString* connectionStateString=
    (state==GKPeerStateAvailable)?@"available":
    (state==GKPeerStateUnavailable)?@"unavailable":
    (state==GKPeerStateConnected)?@"connected":
    (state==GKPeerStateDisconnected)?@"disconnected":@"connecting";
    // Add the peer to the Dictionary
    NSArray* details=[NSArray arrayWithObjects:[session displayNameForPeer:peerID],connectionStateString,nil];
    [connectionPeers setObject:details forKey:peerID];

    if (state == GKPeerStateAvailable) {
        NSLog(@"Adding peerID:%@",peerID);
        [session connectToPeer:peerID withTimeout:60];//'connect' to everything, so data can be sent
    }
    else if (state == GKPeerStateUnavailable || state==GKPeerStateDisconnected) {
        [connectionPeers removeObjectForKey:peerID];
    }
    [self listPlayers];
}
iPadDeveloper2011
  • 4,560
  • 1
  • 25
  • 36

1 Answers1

1

GKSession is built on Bonjour over Bluetooth and I believe that your problem is that the bonjour service is still showing as active since Bonjour doesn't invalidate service advertisements when a peer has disconnected from the network. I think the mDNS records only expire either when the mDNS cache timeout occurs ( not something you can tweak ) or when the advertising peer manually invalidates the service.

I don't think GKSession is going to easily do what you want here via advertisement. Connected peers should however disconnect once they're out of Bluetooth range.

Mark Pauley
  • 1,445
  • 12
  • 11
  • Thanks for your reply @Mark. I solved this by periodically sending messages to all devices, and listening for the response. If I didn't get a response, I removed the device from the 'connected' list. I did not reliably get a 'disconnected' state change indicating that devices where out of range, which was the whole problem. I still think my solution is pretty horrible, and am hopeful that there is a better way. – iPadDeveloper2011 Mar 14 '13 at 03:13
  • 1
    GKSession over bluetooth is horrible ;) I recommend looking into BTLE and the CoreBluetooth API going forward. – Mark Pauley Mar 20 '13 at 23:00
  • Thanks for that @Mark. I think I will. GKSession BT didn't do what I wanted--the range was too good! I wanted something approximating line-of-sight. BTLE sounds like it will be good for that, and also communicating between different devices (eg android). – iPadDeveloper2011 Mar 21 '13 at 00:30
  • CoreBluetooth will give you rssi as well, which will give you an approximation of distance, even if you're in signal range. – Mark Pauley Mar 21 '13 at 01:25
  • OK @Mark, so it seems the answer is 'no there is not a better way when using GKSession' (because GKSession is crap). Thanks! – iPadDeveloper2011 Jun 07 '13 at 02:01