Как использовать класс достижимости для обнаружения действительного подключения к Интернету?
Я новичок в разработке iOS и изо всех сил стараюсь получить класс достижимости. h. Вот мой код для контроллера:
- (void)viewWillAppear:(BOOL)animated
{
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:@selector(checkNetworkStatus:)
name:kReachabilityChangedNotification
object:nil];
internetReachable = [Reachability reachabilityForInternetConnection];
[internetReachable startNotifier];
}
- (void)checkNetworkStatus:(NSNotification *)notice {
NetworkStatus internetStatus = [internetReachable currentReachabilityStatus];
NSLog(@"Network status: %i", internetStatus);
}
Он выглядит нормально, но ничего не появляется в консоли xcode при запуске приложения и переключении на это представление.
Я использую Reachability 2.2 и iOS 4.2.
Есть ли что-то очевидное, что я ошибаюсь?
Ответы
Ответ 1
EDITED: Если вы хотите проверить доступность до некоторого выполнения кода, вы должны просто использовать
Reachability *reachability = [Reachability reachabilityForInternetConnection];
NetworkStatus internetStatus = [reachability currentReachabilityStatus];
if (internetStatus != NotReachable) {
//my web-dependent code
}
else {
//there-is-no-connection warning
}
Вы также можете добавить наблюдателя достижимости где-нибудь (т.е. в viewDidLoad
):
Reachability *reachabilityInfo;
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(myReachabilityDidChangedMethod)
name:kReachabilityChangedNotification
object:reachabilityInfo];
Не забудьте вызвать [[NSNotificationCenter defaultCenter] removeObserver:self];
, когда вам больше не требуется обнаружение доступности (т.е. в методе dealloc
).
Ответ 2
Вот как я это делаю. У меня есть переменная экземпляра, которую я установил в моем методе init:
_reachability = [[APReachability reachabilityForInternetConnection] retain];
и когда мне нужно запросить статус сети, я:
NetworkStatus networkStatus = [_reachability currentReachabilityStatus];
if (networkStatus != NotReachable) {
// Network related code
}
else {
// No network code
}
Если вы заботитесь о Wi-Fi и т.д., статус сети может быть:
NotReachable // No network
ReachableViaWiFi // Reachable via Wifi
ReachableViaWWAN // Reachable via cellular
Ответ 3
Обновление: 4 ноября 2013 г.
Использование версии Reachability 3.0 на iOS7
Чтобы построить поверх ответов @NR4TR и @codecaffeine:
Есть 5 способов сделать это (не скомпилировано:)
#include <ifaddrs.h>
#include <arpa/inet.h>
//1 - Is www.apple.com reachable?
Reachability *rHostName = [Reachability reachabilityWithHostName:@"www.apple.com"];
NetworkStatus s1 = [rHostName currentReachabilityStatus];
//2 - Is local wifi router or access point reachable?
Reachability *rLocalWiFi = [Reachability reachabilityForLocalWiFi];
NetworkStatus s2 = [rLocalWiFi currentReachabilityStatus];
//3 - Is my access point connected to a router and the router connected to the internet?
Reachability *rConnection = [Reachability reachabilityForInternetConnection];
NetworkStatus s3 = [rConnection currentReachabilityStatus];
//4 IPv4 standard addresses checking instead of host to avoid dns lookup step
struct sockaddr_in saIPv4;
inet_pton(AF_INET, "74.125.239.51", &(saIPv4.sin_addr));
saIPv4.sin_len = sizeof(saIPv4);
saIPv4.sin_family = AF_INET;
Reachability *rIPv4 = [Reachability reachabilityWithAddress:&saIPv4];
NetworkStatus s4 = [rIPv4 currentReachabilityStatus];
//5 IPv6 addresses checking instead of host to avoid dns lookup step
struct sockaddr_in saIPv6;
inet_pton(AF_INET, "2607:f8b0:4010:801::1014", &(saIPv6.sin_addr));
saIPv6.sin_len = sizeof(saIPv6);
saIPv6.sin_family = AF_INET;
Reachability *rIPv6 = [Reachability reachabilityWithAddress:&saIPv6];
NetworkStatus s5 = [rIPv6 currentReachabilityStatus];
Состояние обработки одинаково
if (ReachableViaWiFi == s1)
return @"WiFi"; //@"WLAN"
if (ReachableViaWWAN == s1)
return @"Cellular"; //@"WWAN"
return @"None";
Ответ 4
Следуйте по этой ссылке, у нее очень полезный исходный код и этапы
https://github.com/tonymillion/Reachability.
Это дает вам информацию о том, как вы можете использовать разные методы в достижимости для воспроизведения.
Добавьте файл system.configuration.framewok, а также добавьте файлы Reachability.m и Reachability.h в свой проект. там после использования таких методов, как
+(instancetype)reachabilityWithHostName:(NSString*)hostname;
+(instancetype)reachabilityForInternetConnection;
+(instancetype)reachabilityWithAddress:(void *)hostAddress;
+(instancetype)reachabilityForLocalWiFi;
Пример фрагмента:
- (void)CheckConnection
{
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(reachabilityChanged:)
name:kReachabilityChangedNotification
object:nil];
Reachability * reach = [Reachability reachabilityWithHostname:@"www.google.com"];
reach.reachableBlock = ^(Reachability * reachability)
{
dispatch_async(dispatch_get_main_queue(), ^{
_blockLabel.stringValue = @"Block Says Reachable";
});
};
reach.unreachableBlock = ^(Reachability * reachability)
{
dispatch_async(dispatch_get_main_queue(), ^{
_blockLabel.stringValue = @"Block Says Unreachable";
});
};
[reach startNotifier];
}
Надеюсь, что это поможет
Ответ 5
просто импортируйте классы возвращаемости и после этого
-(BOOL) connectedToNetwork
{
const char *host_name = "www.google.com";
BOOL _isDataSourceAvailable = NO;
Boolean success;
SCNetworkReachabilityRef reachability = SCNetworkReachabilityCreateWithName(NULL,host_name);
SCNetworkReachabilityFlags flags;
success = SCNetworkReachabilityGetFlags(reachability, &flags);
_isDataSourceAvailable = success &&
(flags & kSCNetworkFlagsReachable) &&
!(flags & kSCNetworkFlagsConnectionRequired);
CFRelease(reachability);
return _isDataSourceAvailable;
}
Ответ 6
См. ниже код для проверки Internet Connectivity
:
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) {
return 0;
}
BOOL isReachable = flags & kSCNetworkFlagsReachable;
BOOL needsConnection = flags & kSCNetworkFlagsConnectionRequired;
BOOL nonWiFi = flags & kSCNetworkReachabilityFlagsTransientConnection;
NSURL *testURL = [NSURL URLWithString:@"http://www.google.com/"];
NSURLRequest *testRequest = [NSURLRequest requestWithURL:testURL cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:20.0];
NSURLResponse *response = nil;
NSError *error = nil;
NSData *connectiondata = [NSURLConnection sendSynchronousRequest:testRequest
returningResponse:&response
BOOL connection=NO;
if ([connectiondata length] > 0 &&
error == nil){
NSLog(@"Connection present" );
connection=YES;
} else {
NSLog(@"No Connection" );
connection=NO;
}
return ((isReachable && !needsConnection) || nonWiFi) ? (connection ? YES : NO) : NO;
Ответ 7
Самый простой способ (как только вы добавили в проект Reachability):
Reachability *reachability = [Reachability reachabilityForInternetConnection];
if (reachability.isReachable) {
NSLog(@"We have internet!");
} else {
NSLog(@"No internet!");
}