I wanted to check whether internet is connected or not using either the SystemConfiguration or the CFNetwork i am not quite sure which one.
Then i want to know that if the internet is connected then is it connected through wifi or not.
I tried an example where i used the below code
-(IBAction) shownetworkStatus
{
NSString *str = #"http://www.google.com";
NSURL *url = [NSURL URLWithString:str];
NSURLRequest *req = [NSURLRequest requestWithURL:url];
if (req!=NULL) {
lbl.text = #"Connected";
}
else {
lbl.text = #"notConnected";
}
}
some say that its not valid as per apple and you have to use the SystemConfiguration Framework, Please let me know what needs to be done.
Also i personally think that what i am doing in the above code is not proper as if one day google may also be down due to maintenance or some other factors.
Also if you could provide me a link where i could display the name of the WIFI network then it would be really cool.
I searched the internet then i got these Reachability.h code which again is a bouncer as i wana learn the concepts not copy paste them
Thanks and Regards
Building on top of what Raxit mentions, I use the following code (extracted from the reachability example mentioned by Raxit) to check for internet access in my application delegate:
- (BOOL)isReachableWithoutRequiringConnection:(SCNetworkReachabilityFlags)flags
{
BOOL isReachable = flags & kSCNetworkReachabilityFlagsReachable;
BOOL noConnectionRequired = !(flags & kSCNetworkReachabilityFlagsConnectionRequired);
if ((flags & kSCNetworkReachabilityFlagsIsWWAN)) {
noConnectionRequired = YES;
}
return (isReachable && noConnectionRequired) ? YES : NO;
}
- (BOOL)isHostReachable:(NSString *)host
{
if (!host || ![host length]) {
return NO;
}
SCNetworkReachabilityFlags flags;
SCNetworkReachabilityRef reachability = SCNetworkReachabilityCreateWithName(NULL, [host UTF8String]);
BOOL gotFlags = SCNetworkReachabilityGetFlags(reachability, &flags);
CFRelease(reachability);
if (!gotFlags) {
return NO;
}
return [self isReachableWithoutRequiringConnection:flags];
}
- (BOOL)connectedToNetwork {
return [self isHostReachable:#"www.hostyoureallycareabouthavingaconnectionwith.com"];
}
You can use the reachability code provided by Apple. It is sample code. you can find whole detail regarding internet connection. This is the link http://developer.apple.com/library/ios/#samplecode/Reachability/Introduction/Intro.html
Related
I am trying to connect 2 devices using GKSession. When the devices are on same WiFi network it is working but when i am trying to connect devices on different WiFi network it is not working.
This is my code for GKSession
chatSession = [[GKSession alloc] initWithSessionID:AppName displayName:name sessionMode:GKSessionModePeer];
[chatSession setDataReceiveHandler:self withContext:nil];
chatSession.delegate = self;
chatSession.available = YES;
-(void)session:(GKSession *)session peer:(NSString *)peerID didChangeState:(GKPeerConnectionState)state{
NSLog(#"state=%d", state);
if(state == GKPeerStateDisconnected)
{
// A peer disconnected
chatSession.available = YES;
NSLog(#"Disconnected");
[data removeAllObjects];
chatInput.hidden = YES;
}
else if(state == GKPeerStateConnected)
{
// You can now send messages to the connected peer(s)
NSData *imgData = UIImageJPEGRepresentation(myImage, 0.5);
if(imgData==nil)
NSLog(#"myImage is nil");
NSError *err;
//NSLog(#"pid=%#", pID);
NSLog(#"before sending image");
[chatSession sendData:imgData toPeers:[NSArray arrayWithObject:pID] withDataMode:GKSendDataReliable error:&err];
NSLog(#"after send data");
if(err)
NSLog(#"error:%#", err.description);
}
else if (state == GKPeerStateAvailable)
{
pID = peerID;
[session connectToPeer:peerID withTimeout:60*120];
}
}
-(void)session:(GKSession *)session didReceiveConnectionRequestFromPeer:(NSString *)peerID{
// We can now decide to deny or accept
bool shouldAccept = YES;
if(shouldAccept)
{
pID = peerID;
[session acceptConnectionFromPeer:peerID error:nil];
}
else
{
[session denyConnectionFromPeer:peerID];
}}
I am not sure if it is possible using GKSession.
According to Apple
A GKSession object provides the ability to discover and connect to nearby iOS devices using Bluetooth or Wi-fi.
Please help me ia m trying to create a chat app using GKSession.
iOS' GameKit most probably uses Bonjour for this, which works by doing broadcasts on a local network. It won't work between two separate Wi-Fi networks.
This means you'll need a central server (at least during connection set-up). Have a look at XMPP, if you haven't done so already.
Good luck!
I am currently creating a Game Center game, and am using the peer-to-peer functionality available. However, I would like to select one of the players (2 players) to act as a host, to ensure synchronization.
What is the best way to select a host (even randomly) from the players available and ensure that the other device knows which host was chosen?
This is a nice, simple tutorial with code that demonstrates how to do this. They randomly choose one of the peers to be the host. Hope that Helps!
already posted answer , still here is sample code to do that thing
NSString *uid = [[UIDevice currentDevice] uniqueIdentifier];
CoinTossID = [uid hash];
now in delegate Function
- (void)match:(GKMatch *)match didReceiveData:(NSData *)data fromPlayer:(NSString *)playerID
{
NSMutableArray *ReceivedArray = [[NSMutableArray alloc] init];
ReceivedArray = [NSKeyedUnarchiver unarchiveObjectWithData:data];
int flag = [[ReceivedArray objectAtIndex:0] intValue];
[ReceivedArray removeObjectAtIndex:0];
int CoinValue = [ReceivedCoinTossID intValue];
if(CoinValue > CoinTossID)
{
isPlayer1 = YES;
}
else
{
isPlayer1 = NO;
}
}
Is it wise to use Reachability Class(from Apple) to check for a remote host's availability ? say for example, www.google.com
or should I use
NSString *connectedString = [[NSString alloc] initWithContentsOfURL:[NSURL URLWithString:#"http://www.google.com/"]];
if ([connectedString length] != 0) // Host Available
Which is the best option since I've heard that Reachability is having bug with checking for host's availability ?
Here is a good way to check if host is reachable:
NSURLResponse *response=nil;
NSError *error=nil;
NSData *data = nil;
NSURLRequest *request = [NSURLRequest requestWithURL:your_url];
data = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
If host is offline you will receive some error code in error, nil in data and nil in response variables.
If host is online and responds there will be some response, data, and error==nil.
Reachability will not tell you if a remote host is contactable. It only tests the first hop i.e. can you send a packet to your router. If the router cannot reach the wider internet, reachability will still tell you that you have a wifi connection. You have to implement one of the other suggested solutions to test "true" reachability.
As mentioned by others, reachability detects changes in your hardware instead of the real availability of a server. After reading many posts, I came up with this code.
Here is a full implementation of a ReachabilityManager class that uses both Reachability and URLConnection to make sure that the connection is available or not. Please note that depends on the Reachability classes (I am using the Tony Million implementation but I am sure it works with the Apple one)
If you test this in the simulator and enable/disable your wireless connection you will see that it detects (sometimes takes a few seconds) the connection/disconnection. Something that before with just the reachability class did not work.
I have also added a couple of notifications that are more effective than the ones from Reachability for the rest of your code. You may want to handle this in a different way.
Also, this is a singleton so you can instantiate if from anywhere. You can convert it to a non static class and instantiate it from the AppDelegate.
If a reader has time to create some UnitTests for it, let me know, so we can share more knowledge around the Reachability.
Just create a new NSObject class and copy this contents:
.h
#import <Foundation/Foundation.h>
#interface ReachabilityManager : NSObject
+ (void)startReachabilityWithHost : (NSURL *)hostName;
#end
.m
#import "ReachabilityManager.h"
#import "Reachability.h"
#implementation ReachabilityManager
static ReachabilityManager *_sharedReachabilityManager;
static Reachability *reachability;
static NSURL *_hostName;
static BOOL isServerReachable;
+ (void)initialize
{
static BOOL initialized = NO;
if(!initialized)
{
initialized = YES;
_sharedReachabilityManager = [[ReachabilityManager alloc] init];
}
}
+ (void)startReachabilityWithHost : (NSURL *)hostName{
_hostName = hostName;
reachability = [Reachability reachabilityWithHostname:hostName.host];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(reachabilityChanged:)
name:kReachabilityChangedNotification
object:nil];
[reachability startNotifier];
}
+ (void)stopReachability{
[reachability stopNotifier];
[[NSNotificationCenter defaultCenter]removeObserver:kReachabilityChangedNotification];
}
+(void)reachabilityChanged: (NSNotification *)notification{
dispatch_async( dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
BOOL isServerCurrentlyReachable = NO;
do{
isServerCurrentlyReachable = [self checkConnectivityToServer];
BOOL wasServerPreviouslyReachable = isServerReachable;
isServerReachable = isServerCurrentlyReachable;
if (NO == wasServerPreviouslyReachable && YES == isServerCurrentlyReachable)
{
NSLog(#"REACHABLE!");
[[NSNotificationCenter defaultCenter]postNotificationName:#"kNetworkReachabilityCustom" object:[NSNumber numberWithBool:YES]];
}
else if (YES == wasServerPreviouslyReachable && NO == isServerCurrentlyReachable)
{
NSLog(#"UNREACHABLE!");
[[NSNotificationCenter defaultCenter]postNotificationName:#"kNetworkReachabilityCustom" object:[NSNumber numberWithBool:NO]];
}
[NSThread sleepForTimeInterval:5.0];
}while(!isServerCurrentlyReachable);
});
}
+(BOOL)checkConnectivityToServer{
NSURLResponse *response;
NSError *error=nil;
NSData *data = nil;
NSURLRequest *request = [NSURLRequest requestWithURL:_hostName];
data = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
return (data && response);
}
#end
It is wise to check if you have any internet connection first, and for that I use Reachability. And I try to do my connection with the server only I have internet.
Here is a tutorial on how to use Reachability.
http://www.raddonline.com/blogs/geek-journal/iphone-sdk-testing-network-reachability/
NSString *connectedString = [[NSString alloc] initWithContentsOfURL:[NSURL URLWithString:#"http://www.google.com/"]];
if ([connectedString length] != 0) // Host Available
The code you provided should also work but might not give the desired result.. Reachability is more reliable..
The following code from developer.apple.com might help you..
// Create the request.
NSURLRequest *theRequest=[NSURLRequest requestWithURL:[NSURL URLWithString:#"http://www.apple.com/"]
cachePolicy:NSURLRequestUseProtocolCachePolicy
timeoutInterval:60.0];
// create the connection with the request
// and start loading the data
NSURLConnection *theConnection=[[NSURLConnection alloc] initWithRequest:theRequest delegate:self];
if (theConnection) {
// Create the NSMutableData to hold the received data.
// receivedData is an instance variable declared elsewhere.
receivedData = [[NSMutableData data] retain];
} else {
// Inform the user that the connection failed.
}
using iphone sdk 3.1.2.
Is there anyway of knowing if a Bluetooth headset is connected to the device? Don't need any info except if its connected or not. This is different from knowing if one was plugged in or not which one can do via a Property Listener of an Audio Session.
Thanks
Call this method to find out the bluetooth headset is connected or not.
First import this framework #import <AVFoundation/AVFoundation.h>
- (BOOL) isBluetoothHeadsetConnected
{
AVAudioSession *session = [AVAudioSession sharedInstance];
AVAudioSessionRouteDescription *routeDescription = [session currentRoute];
NSLog(#"Current Routes : %#", routeDescription);
if (routeDescription)
{
NSArray *outputs = [routeDescription outputs];
if (outputs && [outputs count] > 0)
{
AVAudioSessionPortDescription *portDescription = [outputs objectAtIndex:0];
NSString *portType = [portDescription portType];
NSLog(#"dataSourceName : %#", portType);
if (portType && [portType isEqualToString:#"BluetoothA2DPOutput"])
{
return YES;
}
}
}
return NO;
}
Have you looked at the: kAudioSessionProperty_AudioRoute?
Also see this post:
How can I find out if an external headset is connected to an iPhone?
I would like to check "reachability" before/when a webView is shown in my app.
So far I've included the reachbility.h/.m files as well as added the SystemConfiguration.framework to the project.
And that's about where the agreements I have found on the internet end, from all of the posts and blogs etc. etc. everyone has a different idea/opinion of what to do after that. Additionally, I have found a lot partial code snippets that aren't really a complete solution, on which reachibility methods to call etc. etc. how to use them etc.
I have also found that some warn that you should try to reconnect before checking reachability...but I haven't found a consensus or a full solution. My app seems to reconnect to wifi without any extra code... so I'm a litte confused here too...
Any help to clear the muddy waters would be appreciated. I'm just looking for a simple straightforward solution.
Answer Accepted: I would like to note to newbies who may read this q/a later... that you will want to do the following:
Add this into your .h file:
- (BOOL) connectedToNetwork: (NSString *) remoteServer;
- (void) appLoadError: (NSString *) altertTitle alertMessage: (NSString *) altertMsg;
And you will need to import these at the top of your .m file:
sys/socket.h
netinet/in.h
netinet6/in6.h
arpa/inet.h
ifaddrs.h
netdb.h
SystemConfiguration/SystemConfiguration.h
Correct me if it is wrong... It seems to work fine for me...
I have always used this method in my App Delegate when I need to require Internet access. I have tuned it for different access types over time and it has served me well. It is a variant of one of the many methods you can find after a quick Google search on this topic.
It is a tricky thing to come up with a hard and fast strategy around this. The platform itself offers different connectivity options that have pros and cons based on the needs of each specific application. The method I use below is just a general connectivity test meaning the device can reach the Internet via some connectivity mechanism.
- (BOOL) connectedToNetwork: (NSString *) remoteServer {
// Create zero addy
struct sockaddr_in zeroAddress;
bzero(&zeroAddress, sizeof(zeroAddress));
zeroAddress.sin_len = sizeof(zeroAddress);
zeroAddress.sin_family = AF_INET;
// Recover reachability flags
SCNetworkReachabilityRef defaultRouteReachability = SCNetworkReachabilityCreateWithAddress(NULL, (struct sockaddr *)&zeroAddress);
SCNetworkReachabilityFlags flags;
BOOL didRetrieveFlags = SCNetworkReachabilityGetFlags(defaultRouteReachability, &flags);
CFRelease(defaultRouteReachability);
if (!didRetrieveFlags){
NSLog(#"Error. Could not recover network reachability flags");
return NO;
}
BOOL isReachable = flags & kSCNetworkFlagsReachable;
BOOL needsConnection = flags & kSCNetworkFlagsConnectionRequired;
BOOL nonWiFi = flags & kSCNetworkReachabilityFlagsTransientConnection;
NSURL *testURL = [NSURL URLWithString: remoteServer];
NSURLRequest *testRequest = [NSURLRequest requestWithURL:testURL cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:20.0];
NSURLConnection *testConnection = [[NSURLConnection alloc] initWithRequest:testRequest delegate:self];
return ((isReachable && !needsConnection) || nonWiFi) ? (testConnection ? YES : NO) : NO;
}
I usually call this inside applicationDidFinishLaunching. If the check returns false, I usually generate an error message (see below). This is because Apple forbids exiting the application by any means other than the home button on the device.
...
else if(![self connectedToNetwork: [NSString stringWithFormat: #"http://%#:%#/", sharedSettings.server, sharedSettings.port]]){
[self appLoadError: #"No Internet Detected" alertMessage:#"This application requires an active Internet connection. No content is available."];
}
...
- (void) appLoadError: (NSString *) altertTitle alertMessage: (NSString *) altertMsg {
UIAlertView *loadErr = [[UIAlertView alloc] initWithTitle: altertTitle message: altertMsg delegate: self cancelButtonTitle: #"OK" otherButtonTitles: nil];
[loadErr show];
[loadErr release];
// Load static screen
UIImage *image = [UIImage imageNamed:#"Error_NoInternet.png"];
UIImageView *imageView = [[UIImageView alloc] initWithImage:image];
[controller setNavigationBarHidden: YES animated: NO];
[window addSubview: imageView];
[imageView release];
}
Just a quick note, I believe that method is leaking an NSURLConnection on every call (at the bottom, testConnection).
You might want to use
+ (NSURLConnection *)connectionWithRequest:
(NSURLRequest *)request delegate:(id)delegate
instead.