好的,所以我想让这个应用程序显示网络错误警报代码。我添加了SystemConfiguration.framework框架和Apple的“Reachability”示例代码。
这是viewcontroller.h文件:
#import <UIKit/UIKit.h>
@class Reachability;
@interface Test_Internet_ConnectionViewController : UIViewController {
Reachability* internetReachable;
Reachability* hostReachable;
}
@property BOOL internetActive;
@property BOOL hostActive;
- (void) checkNetworkStatus:(NSNotification *)notice;
@end
这是viewcontroller.m文件:
#import "Test_Internet_ConnectionViewController.h"
#import "Reachability.h";
@implementation Test_Internet_ConnectionViewController
@synthesize internetActive;
@synthesize hostActive;
/*
// The designated initializer. Override to perform setup that is required before the view is loaded.
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
*/
/*
// Implement loadView to create a view hierarchy programmatically, without using a nib.
- (void)loadView {
}
*/
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
[super viewDidLoad];
// check for internet connection
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(checkNetworkStatus:) name:kReachabilityChangedNotification object:nil];
internetReachable = [[Reachability reachabilityForInternetConnection] retain];
[internetReachable startNotifier];
// check if a pathway to a random host exists
hostReachable = [[Reachability reachabilityWithHostName: @"www.apple.com"] retain];
[hostReachable startNotifier];
// now patiently wait for the notification
}
/*
// Override to allow orientations other than the default portrait orientation.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
*/
- (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
- (void)viewDidUnload {
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (void) checkNetworkStatus:(NSNotification *)notice
{
// called after network status changes
NetworkStatus internetStatus = [internetReachable currentReachabilityStatus];
switch (internetStatus)
{
case NotReachable:
{
NSLog(@"The internet is down.");
self.internetActive = NO;
UIAlertView *errorView = [[UIAlertView alloc] initWithTitle:@"Internet Unavailable" message:@"This page cannot load, please check your internet connection and try again." delegate:nil cancelButtonTitle:@"Dismiss" otherButtonTitles:nil];
[errorView show];
[errorView release];
break;
}
case ReachableViaWiFi:
{
NSLog(@"The internet is working via WIFI.");
self.internetActive = YES;
break;
}
case ReachableViaWWAN:
{
NSLog(@"The internet is working via WWAN.");
self.internetActive = YES;
break;
}
}
NetworkStatus hostStatus = [hostReachable currentReachabilityStatus];
switch (hostStatus)
{
case NotReachable:
{
NSLog(@"A gateway to the host server is down.");
self.hostActive = NO;
break;
}
case ReachableViaWiFi:
{
NSLog(@"A gateway to the host server is working via WIFI.");
self.hostActive = YES;
break;
}
case ReachableViaWWAN:
{
NSLog(@"A gateway to the host server is working via WWAN.");
self.hostActive = YES;
break;
}
}
}
- (void)dealloc {
[super dealloc];
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
@end
如果在打开应用程序时没有互联网,则错误按预期工作,但如果应用程序在最初使用互联网连接打开后失去连接,则错误显示3次,此时我显然只希望显示一次。
我认为它可能是Reachability类中的一个东西,它发送通知3次,可能在3个不同的地方。我不知道为什么会这样做,但我认为解决方案可能是从Reachability类中删除我不想要的两个调用,但我不知道如何。
有人可以帮帮我吗? 提前谢谢。
编辑:
8个警告和4个错误如下:
'TestViewController'可能无法响应'+ checkConnectivity'
初始化从没有强制转换的指针生成整数
'连接'的本地声明隐藏了实例变量
'MyReachability'未声明
'reachability'未声明
'TestViewController'可能无法响应'-siteAvailable'
'TestViewController'可能无法响应'-addConnectivityView'
重新定义' - [TestViewController reachabilityChanged:]'
'MyReachability'未声明
TestViewController可能无法响应'-siteAvailable'
TestViewController可能无法响应'-addConnectivityView'
TestViewController可能无法响应'-removeConnectivityView'
答案 0 :(得分:2)
是的,由于某种原因,它会多次发送通知。为了解决这个问题,我在应用程序委托中维护了一个网络状态变量,它是kReachabilityChangedNotification
的观察者。该视图是自定义kViewReachabilityChangedNotification
的观察者,该值由应用程序委托在值实际更改时发送。更重要的是,在从可达性获得通知后,我调用了Reachability函数来获取当前网络状态并相应地更改了我的应用程序委托变量。然后我可以向视图发送通知以更新自己。
这种解决方法很难看,但很有效。我花了很多时间来理解为什么以这种方式发送通知,最后放弃了找到这个解决方案。
编辑: 这是你的样本 - 我仍然没有一个放置所有工作示例的好地方,所以请尝试从代码示例中找出解决方案: 子类可达性:
@interface MyReachability:可达性 { } +(BOOL)connectedToNetwork; @end
@implementation MyReachability
+ (BOOL) connectedToNetwork {
// 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)
{
return NO;
}
BOOL isReachable = flags & kSCNetworkFlagsReachable;
BOOL needsConnection = flags & kSCNetworkFlagsConnectionRequired;
if (needsConnection && (flags & kSCNetworkReachabilityFlagsIsWWAN)) {
needsConnection = NO;
}
return (isReachable && !needsConnection) ? YES : NO;
}
@end 在YourApplicationDelegate.h中:
@interface YourApplicationDelegate :NSObject
{
BOOL connectivity;
}
- (void) reachabilityChanged:(NSNotification *) note;
- (BOOL) checkConnectivity;
@end
在YourApplicationDelegate.m中添加函数initReachability 将其命名为从Reachability类初始化您的通知。
- (void) initReachability
{
MyReachability * reachability = [ MyReachability sharedReachability ];
//[ reachability setHostName: [self hostName] ];
[ reachability setNetworkStatusNotificationsEnabled: YES ];
[self siteAvailable];
NSNotificationCenter * notificationCenter = [ NSNotificationCenter defaultCenter ];
[ notificationCenter addObserver: self
selector: @selector( reachabilityChanged: )
name: @"kNetworkReachabilityChangedNotification"
object: nil ];
connectivity = [MyReachability testConnection:NO];
if (!connectivity) {
if (![MyReachability testConnection:NO]) {
[self addConnectivityView];
}
}
}
- (BOOL) checkConnectivity
{
return connectivity;
}
- (void) reachabilityChanged:(NSNotification *) note
{
BOOL newConnectivity = [MyReachability testConnection:NO];
if (connectivity != newConnectivity) {
connectivity = newConnectivity;
[self siteAvailable];
if (![MyReachability testConnection:NO]) {
[self addConnectivityView];
} else {
[self removeConnectivityView];
connectivity = YES;
[[NSNotificationCenter defaultCenter] postNotificationName:@"kAppNetworkReachabilityChangedNotification" object:nil];
}
}
}
请注意,@“kAppNetworkReachabilityChangedNotification”是您的视图应订阅的自定义通知。
在视图控制器的viewDidLoad函数中:
-(void) viewDidLoad
{
// your customization
NSNotificationCenter * notificationCenter = [ NSNotificationCenter defaultCenter ];
[ notificationCenter addObserver: self
selector: @selector( reachabilityChanged: )
name: @"kAppNetworkReachabilityChangedNotification"
object: nil ];
}
- (void) reachabilityChanged: (NSNotification *) note
{
BOOL connectivity = [YourAppDelegate checkConnectivity];
if (connectivity) {
// update your view accordingly
}
}
答案 1 :(得分:0)
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(handleNetworkChange:)
name:kReachabilityChangedNotification object:nil];
上述代码行应该只为整个应用程序调用一次。如果在多次调用的函数中调用此行代码,则通知还会显示许多警报。所以我建议你创建一个单例类,它将贯穿整个应用程序,并在创建单例类对象的区域中调用上面的代码行。
注意:上述代码行只应为整个应用程序调用一次。