正如其他人所說,可達性檢測硬件的變化,而不是服務器的真實可用性。讀了很多帖子後,我突然想到了這個代碼。
下面是使用Reachability和URLConnection來確保連接可用或不可用的ReachabilityManager類的完整實現。請注意,這取決於可達性類(我使用的是Tony Million實現,但我確定它可以與Apple一起使用)
如果在模擬器中測試並啓用/禁用無線連接,您將看到它檢測(有時需要幾秒鐘)的連接/斷開。之前只有可達性類沒有用的東西。
我還在代碼的其餘部分中添加了一些比來自Reachability的通知更有效的通知。您可能想要以不同的方式處理此問題。
此外,這是一個單身人士,所以你可以從任何地方實例化。您可以將其轉換爲非靜態類並從AppDelegate實例化它。
我希望這對於任何人爲了可達性不能正確檢測可用性而中斷他/他的頭部都是有用的。
如果你們有時間爲它創建一些UnitTests,請讓我知道,這樣我們就可以共享更多知識。
只需創建一個新的NSObject類並複製此內容:
.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
感謝所有。我以前見過這個鏈接。但是我聽說Reachability在檢查遠程主機可用性時有缺陷。那麼哪個是主機可用性的最佳選擇? – 2011-01-21 08:22:16