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];
}
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.
Related
My iPhone app is web based.It works fine while running in WiFi and in 3G
But the problem is when I run the app on WiFi and minimize it,and turn off the WiFi and switch to 3G-it shows no network.
In user's case-when they use the app under WiFi and goes out it failed to connect with 3G network.I am using apple's Reachability class to check the network connection
Anybody please tell any solution
Do i code something to reconnect if the connection lost or switch from WiFi to 3G ?
You can use connection:didFailWithError: and implement into your method to reconnect your user.
Like this
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
[self reconnect];
}
- (void)reconnect
{
//reconnect your user
}
I hope it can help you ! ;)
Currently I'm developing an application which can send multiple files to other device over Wi-Fi using bonjour service same as developer.apple Wi-Tap application did. Only one difference is ,I'm sending files where Wi-Tap sending strings.
Now I would like to handle the Wi-Fi connection issues like connection loss in my application.
I can handle the NSStream Errors through handleEvent delegate for below cases
NSStreamEventErrorOccurred
NSStreamEventEndEncountered
However I'm Unable to find the Wi-Fi connection loss through this delegate. So the possible solutions in my mind is using the Reachability class for checking the wi-fi connection in a background thread. However it's a bad practice and it consumes more battery power of device.
So is there any other way to track the Wi-Fi connection of the device during the file transfer ?
One way around is to use use NSNetService
As this is just a service publishing tool it won't interfere in your data transfer so you just have to use
-(void)publishNetwork
{
//---publish the service---
netService = [[NSNetService alloc]
initWithDomain:#""
type:BonjourServiceName
name:#""
port:portNo];
netService.delegate = self;
[netService publish];
}
You have to run this in
[netService scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
if Wifi is on then this will be fired
- (void)netServiceDidPublish:(NSNetService *)sender
{
NSLog(#"Service did publish:%#",sender);
}
if there is no wifi
-(void)netService:(NSNetService *)aNetService didNotPublish:(NSDictionary *)dict
{
NSLog(#"Service did not publish: %#", dict);
}
These are the delegates of NSNetService you can refer the library .
This is just a way around your problem hope it helps.
I am having a BLE device acting as peripheral and an iPhone4s as central.Both are connected via BluetoothLE connection.My question is that can i get to know from the peripheral end that it has been disconnected from the central.
Depending on the implementation of your peripheral (HCI interface or proprietary) you would either get a Disconnection Complete Event (Bluetooth Core Spec 4.0 - Volume 2 Part E section 7.7.5) or the proprietary equivalent event.
Could you provide some more information about the peripheral you are using?
If the Peripheral disconnect you can catch the didDisconnect (on the iOS side)
-(void) centralManager:(CBCentralManager *)central didDisconnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)
You can also ask iOS about "Known" devices (only those PAIRED, thus remembered/Cached in iOS6)
Go through each one and check the peripheral.isConnected flag.
Unfortunately iOS seems to also cache this for too long so some times you will see the isConnected flag even though connection has been lsot.
From Peripheral side you must keep track of didConnects / didDisconnects.
I'm trying to implement GameKit connection without using GKPeerPickerController. What i need is to establish WiFi connection, not bluetooth.
This is how i do that
self.gameSession = [[GKSession alloc] initWithSessionID:#"test" displayName:nil sessionMode:GKSessionModePeer];
self.gameSession.available = YES;
self.gameSession.delegate = self;
self.gameSession.disconnectTimeout = 0;
[self.gameSession setDataReceiveHandler:self withContext:nil];
My problem is that devices always try to connect over Bluetooth. At least i think so cause the following always appears in the console
BTM: attaching to BTServer
Even if i turn bluetooth off it always tries to deal with bluetooth, not wifi. Moreover - if bluetooth is on - devices never see each other if i don't use GKPeerPickerController.
Also, simulator never tries to look for bluetooth and is always able to establish wifi connection and find any device easily. How do i make GKSession choose WiFi connection?
May be your issue arising with Jailbroken Device,
GKSession and GKSessionDelegate implementations works for both bluetooth and WiFi.
these two class checks wifi and bluetooth, and choose an appropriate transmission medium.
If your iPhone is Jailbroken, then there might be some issues with BlueTooth or wifi while connecting over those transmission medium, and possibly that is prevent to Work with gamekit Properly.
And also try to use
picker.connectionTypesMask = GKPeerPickerConnectionTypeOnline
check with Condition in Delegate methods
if (type == GKPeerPickerConnectionTypeOnline) {
}
Update :
Refer this sample code of Apple..
https://developer.apple.com/library/ios/#samplecode/GKTapper/Introduction/Intro.html#//apple_ref/doc/uid/DTS40010283
i read,seen the Reachablility example in Apple's website but still not quite sure about determining whether the iphone is connected to a wifi network/ or a pc(ipaddress). All i understand about that example is that you give it a address, and it checks how it is accessible either via wifi,WWAN or not reachable at all.
Could anyone shed some light on this? Im new to iPhone programming :\
What i want is to check whether the iPhone is connected to a particular ipaddress via wifi at that moment of time, like clicking a button and a UIAlertView shows "Not connected via wifi to "INSERT IPADDRESS HERE" "when its not connected. Am i making sense? lol.
The IP address is just used for testing a connection through wi-fi or WWAN to another machine on the Internet. All the Reachability framework tells you is if your device is connected to a TCP/IP network via wi-fi networking, via WWAN (through your cell phone connection), or not connected at all. It does not tell you if your phone is connected to a Mac or PC through the dock connector cable.
the reachability sample is strange, check this out
-(BOOL)hasWifiConnectivity{
SCNetworkReachabilityRef reachabilityRef = SCNetworkReachabilityCreateWithName(NULL,"apple.com");
SCNetworkReachabilityFlags flags;
if (SCNetworkReachabilityGetFlags(reachabilityRef,&flags)) {
CFRelease(reachabilityRef);
if (flags & kSCNetworkReachabilityFlagsReachable) {
if (flags & kSCNetworkReachabilityFlagsIsWWAN) {
//not wifi
return NO;
}else {
//wifi
return YES;
}
}
}
return NO;
}