Network error while switching from WiFi to 3G - iphone

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 ! ;)

Related

iPhone and iPad can't find each other via bluetooth

I have an iPhone 4s and an iPad 2 which should be able to establish a connection via bluetooth.
Bluetooth is activated on both devices, and both are scanning for other devices, but none of them shows up on the other one.
If i turn on the personal hotspot on the iPhone, both devices find each other.
Sadly, this is not a solution for me, because I´m writing an app which should establish the connection (using GameKit), so the user must not be forced to activate the personal hotspot before using the app.
So my question is: Is there anything I am missing, to make both iOS devices see each other without using the personal hotspot function?
Any help is appreciated!
iPad 2 is NOT supporting BLE 4.0 and it has different hardware module for bluetooth. Maybe that's the main problem.
Make sure the session id in both is the same, or they will not find each other.
- (GKSession *)peerPickerController:(GKPeerPickerController *)picker sessionForConnectionType: (GKPeerPickerConnectionType)type{
GKSession* session = [[GKSession alloc] initWithSessionID:#"com.cilk.id" displayName:nil sessionMode:GKSessionModePeer];
return [session autorelease];
}

Determining when GKSession bluetooth devices go out of range

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.

Is there any way to track the Wi-Fi connection of the device during communication

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.

Why GKSession always tries to use bluetooth when running on a device and doesn't on simulator?

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

iphone ios 3.0.1, device is not being able to get a device token nor reporting an error?

ok i have an iphone with ios 3.0.1
i have wifi turned on, no cellular network.
I have created my provisioning profile, my certificate correctly. why?... gonna tell you in a while
anyway, when i run the application, i have put NSLog in
- (void)application:(UIApplication *)app didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
- (void)application:(UIApplication *)app didFailToRegisterForRemoteNotificationsWithError:(NSError *)err
but when i run the application i don't get anything, no success nor error.
anyway i tried the SAME APPLICATION and run it on iphone with ios 4.0 and it did work and it printed the device token.
Oh and they are both using the same wifi network.
could it be the device? the ios ? or the security of the wifi connection?
and shouldn't at least give me an error in that case?
could that be caused by the missing library file
warning: Unable to read symbols for "/Library/MobileSubstrate/MobileSubstrate.dylib" (file not found).
thank you
According to Apple Documentation :
No Delegate Callbacks
When the first push-capable app is installed on a device, iOS attempts to
establish a persistent network connection to the push service that
will be shared by all push-capable apps on the device.
If neither delegate callback
application:didRegisterForRemoteNotificationsWithDeviceToken:
nor
application:didFailToRegisterForRemoteNotificationsWithError:
is called, that means that this
connection has not yet been
established.
This is not necessarily an error
condition. The device may not have
Internet connectivity at all because
it is out of range of any cell towers
or Wi-Fi access points, or it may be
in airplane mode. Instead of treating
this as an error, your app should
continue normally, disabling only that
functionality that relies on push
notifications.
Keep in mind that network availability
can change frequently. Once the
persistent connection to the push
service succeeds, one of the
previously-mentioned application
delegate methods will be called.
Push notifications use the cellular
data network whenever possible, even
if the device is currently using Wi-Fi
for other network activity such as web
browsing or email. However, the push
service will fall back to Wi-Fi if
cellular data service isn't available.
If your device is capable of using the
cellular data network, check that it
has an active cellular data plan. Turn
off Wi-Fi in Settings and see if you
can still browse the web with Safari,
for example. On the other hand, if the
push service is using Wi-Fi, any
firewalls between your device and the
Internet must allow TCP traffic to and
from port 5223.
NOTE: There is a separate persistent
connection to the push service for
each environment. iOS establishes a
persistent connection to the sandbox
environment for development builds; ad
hoc and distribution builds connect to
the production environment.
About second part of your question, MobileSubstrate is not the culprit, this is a normal log message... from a jailbroken iPhone :)