From fc628c493aec959bfad215fc195bffaf2868d3c8 Mon Sep 17 00:00:00 2001 From: GuanZhenwei Date: Wed, 13 Jun 2018 10:00:24 +0800 Subject: [PATCH] 1. added the VPN status check method; solved the status issue in the VPN case 2. refactor the demo --- RealReachability/RealReachability.h | 9 + RealReachability/RealReachability.m | 115 ++++++++++- .../project.pbxproj | 17 ++ testRealReachability/KVO/NSObject+SimpleKVO.h | 34 ++++ testRealReachability/KVO/NSObject+SimpleKVO.m | 190 ++++++++++++++++++ testRealReachability/ViewController.m | 130 +++++++----- 6 files changed, 438 insertions(+), 57 deletions(-) create mode 100644 testRealReachability/KVO/NSObject+SimpleKVO.h create mode 100644 testRealReachability/KVO/NSObject+SimpleKVO.m diff --git a/RealReachability/RealReachability.h b/RealReachability/RealReachability.h index 57cbc07..f83c7e4 100755 --- a/RealReachability/RealReachability.h +++ b/RealReachability/RealReachability.h @@ -35,6 +35,8 @@ ///We post self to this notification, then you can invoke currentReachabilityStatus method to fetch current status. extern NSString *const kRealReachabilityChangedNotification; +extern NSString *const kRRVPNStatusChangedNotification; + typedef NS_ENUM(NSInteger, ReachabilityStatus) { ///Direct match with Apple networkStatus, just a force type convert. RealStatusUnknown = -1, @@ -54,6 +56,7 @@ typedef NS_ENUM(NSInteger, WWANAccessType) { @optional /// TODO:通过挂载一个定制的代理请求来检查网络,需要用户自己实现,我们会给出一个示例。 /// 可以通过这种方式规避解决http可用但icmp被阻止的场景下框架判断不正确的问题。 +/// (Update: 已经添加了判断VPN的相关逻辑,以解决这种场景下大概率误判的问题) /// 此方法阻塞?同步返回?还是异步?如果阻塞主线程超过n秒是不行的。 /// 当CustomAgent的doubleCheck被启用时,ping的doubleCheck将不再工作。 /// TODO: We introduce a custom agent to check the network by making http request, that need @@ -117,4 +120,10 @@ typedef NS_ENUM(NSInteger, WWANAccessType) { */ - (WWANAccessType)currentWWANtype; +// Sometimes people use VPN on the device. +// In this situation we need to ignore the ping error.(VPN usually do not support ICMP.) +// 目前内部使用轮询来实现,并没有监听,如果谁知道如何监听,请告诉我:)。 +// +- (BOOL)isVPNOn; + @end diff --git a/RealReachability/RealReachability.m b/RealReachability/RealReachability.m index c98648e..767ccd4 100755 --- a/RealReachability/RealReachability.m +++ b/RealReachability/RealReachability.m @@ -6,6 +6,8 @@ // Copyright © 2016 Dustturtle. All rights reserved. // +#include + #import "RealReachability.h" #import "FSMEngine.h" #import "LocalConnection.h" @@ -26,7 +28,13 @@ NSString *const kRealReachabilityChangedNotification = @"kRealReachabilityChangedNotification"; +NSString *const kRRVPNStatusChangedNotification = @"kRRVPNStatusChangedNotification"; + @interface RealReachability() +{ + BOOL _vpnFlag; +} + @property (nonatomic, strong) FSMEngine *engine; @property (nonatomic, assign) BOOL isNotifying; @@ -41,6 +49,7 @@ @interface RealReachability() /// for double check @property (nonatomic, strong) PingHelper *pingChecker; + @end @implementation RealReachability @@ -73,6 +82,8 @@ - (id)init _autoCheckInterval = kDefaultCheckInterval; _pingTimeout = kDefaultPingTimeout; + _vpnFlag = NO; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(appBecomeActive) name:UIApplicationDidBecomeActiveNotification @@ -182,6 +193,17 @@ - (void)reachabilityWithBlock:(void (^)(ReachabilityStatus status))asyncHandler return; } + // special case, VPN on; just skipping (ICMP not working now). + if ([self isVPNOn]) + { + ReachabilityStatus status = [self currentReachabilityStatus]; + if (asyncHandler != nil) + { + asyncHandler(status); + } + return; + } + __weak __typeof(self)weakSelf = self; [self.pingHelper pingWithBlock:^(BOOL isSuccess) { @@ -215,13 +237,20 @@ - (void)reachabilityWithBlock:(void (^)(ReachabilityStatus status))asyncHandler } else { - // delay 1 seconds, then make a double check. - dispatch_time_t time = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1*NSEC_PER_SEC)); - __weak __typeof(self)weakSelf = self; - dispatch_after(time, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ - __strong __typeof(weakSelf)self = weakSelf; - [self makeDoubleCheck:asyncHandler]; - }); + if ([self isVPNOn]) + { + // special case, VPN connected. Just ignore the ping result. + } + else + { + // delay 1 seconds, then make a double check. + dispatch_time_t time = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1*NSEC_PER_SEC)); + __weak __typeof(self)weakSelf = self; + dispatch_after(time, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ + __strong __typeof(weakSelf)self = weakSelf; + [self makeDoubleCheck:asyncHandler]; + }); + } } }]; } @@ -290,7 +319,7 @@ - (WWANAccessType)currentWWANtype { if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0) { - CTTelephonyNetworkInfo *teleInfo= [[CTTelephonyNetworkInfo alloc] init]; + CTTelephonyNetworkInfo *teleInfo = [[CTTelephonyNetworkInfo alloc] init]; NSString *accessString = teleInfo.currentRadioAccessTechnology; if ([accessString length] > 0) { @@ -445,5 +474,75 @@ - (void)localConnectionHandler:(NSNotification *)notification } } +// TODO: 这里比较特别;最终决定采用提供一个外部调用方法;不提供kvo;整合应用内部的状态变化的通知提供到外部。 +// 这样一个综合的策略来实现。 kvo不适合用在这里,只有get方法会操作数据(没有真正意义上的set)。 +// 而如果获取用一个方法,而kvo又是另外一个的话又会很怪异. +- (BOOL)isVPNOn +{ + BOOL flag = NO; + NSString *version = [UIDevice currentDevice].systemVersion; + // need two ways to judge this. + if (version.doubleValue >= 9.0) + { + NSDictionary *dict = CFBridgingRelease(CFNetworkCopySystemProxySettings()); + NSArray *keys = [dict[@"__SCOPED__"] allKeys]; + for (NSString *key in keys) { + if ([key rangeOfString:@"tap"].location != NSNotFound || + [key rangeOfString:@"tun"].location != NSNotFound || + [key rangeOfString:@"ipsec"].location != NSNotFound || + [key rangeOfString:@"ppp"].location != NSNotFound){ + flag = YES; + break; + } + } + } + else + { + struct ifaddrs *interfaces = NULL; + struct ifaddrs *temp_addr = NULL; + int success = 0; + + // retrieve the current interfaces - returns 0 on success + success = getifaddrs(&interfaces); + if (success == 0) + { + // Loop through linked list of interfaces + temp_addr = interfaces; + while (temp_addr != NULL) + { + NSString *string = [NSString stringWithFormat:@"%s" , temp_addr->ifa_name]; + if ([string rangeOfString:@"tap"].location != NSNotFound || + [string rangeOfString:@"tun"].location != NSNotFound || + [string rangeOfString:@"ipsec"].location != NSNotFound || + [string rangeOfString:@"ppp"].location != NSNotFound) + { + flag = YES; + break; + } + temp_addr = temp_addr->ifa_next; + } + } + + // Free memory + freeifaddrs(interfaces); + } + + if (_vpnFlag != flag) + { + // reset flag + _vpnFlag = flag; + + // post notification + __weak __typeof(self)weakSelf = self; + dispatch_async(dispatch_get_main_queue(), ^{ + __strong __typeof(weakSelf)strongSelf = weakSelf; + [[NSNotificationCenter defaultCenter] postNotificationName:kRRVPNStatusChangedNotification + object:strongSelf]; + }); + } + + return flag; +} + @end diff --git a/testRealReachability.xcodeproj/project.pbxproj b/testRealReachability.xcodeproj/project.pbxproj index 11d725b..d6d65b1 100644 --- a/testRealReachability.xcodeproj/project.pbxproj +++ b/testRealReachability.xcodeproj/project.pbxproj @@ -13,6 +13,7 @@ 8EE0B63C1C40F71900CBABCA /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 8EE0B63A1C40F71900CBABCA /* Main.storyboard */; }; 8EE0B63E1C40F71900CBABCA /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 8EE0B63D1C40F71900CBABCA /* Assets.xcassets */; }; 8EE0B6411C40F71900CBABCA /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 8EE0B63F1C40F71900CBABCA /* LaunchScreen.storyboard */; }; + 8EF6153420CFEDD100D425CD /* NSObject+SimpleKVO.m in Sources */ = {isa = PBXBuildFile; fileRef = 8EF6153320CFEDD100D425CD /* NSObject+SimpleKVO.m */; }; 8EFA08DA1C50E25800F6D790 /* LocalConnection.m in Sources */ = {isa = PBXBuildFile; fileRef = 8EFA08C01C50E25800F6D790 /* LocalConnection.m */; }; 8EFA08DB1C50E25800F6D790 /* FSMEngine.m in Sources */ = {isa = PBXBuildFile; fileRef = 8EFA08C41C50E25800F6D790 /* FSMEngine.m */; }; 8EFA08DC1C50E25800F6D790 /* FSMStateUtil.m in Sources */ = {isa = PBXBuildFile; fileRef = 8EFA08C61C50E25800F6D790 /* FSMStateUtil.m */; }; @@ -38,6 +39,8 @@ 8EE0B63D1C40F71900CBABCA /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 8EE0B6401C40F71900CBABCA /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 8EE0B6421C40F71900CBABCA /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 8EF6153220CFEDD100D425CD /* NSObject+SimpleKVO.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSObject+SimpleKVO.h"; sourceTree = ""; }; + 8EF6153320CFEDD100D425CD /* NSObject+SimpleKVO.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSObject+SimpleKVO.m"; sourceTree = ""; }; 8EFA08BF1C50E25800F6D790 /* LocalConnection.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LocalConnection.h; sourceTree = ""; }; 8EFA08C01C50E25800F6D790 /* LocalConnection.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LocalConnection.m; sourceTree = ""; }; 8EFA08C21C50E25800F6D790 /* FSMDefines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FSMDefines.h; sourceTree = ""; }; @@ -95,6 +98,7 @@ 8EE0B6301C40F71900CBABCA /* testRealReachability */ = { isa = PBXGroup; children = ( + 8EF6153120CFEDD100D425CD /* KVO */, 8EFA08BD1C50E25800F6D790 /* RealReachability */, 8EE0B6341C40F71900CBABCA /* AppDelegate.h */, 8EE0B6351C40F71900CBABCA /* AppDelegate.m */, @@ -117,6 +121,15 @@ name = "Supporting Files"; sourceTree = ""; }; + 8EF6153120CFEDD100D425CD /* KVO */ = { + isa = PBXGroup; + children = ( + 8EF6153220CFEDD100D425CD /* NSObject+SimpleKVO.h */, + 8EF6153320CFEDD100D425CD /* NSObject+SimpleKVO.m */, + ); + path = KVO; + sourceTree = ""; + }; 8EFA08BD1C50E25800F6D790 /* RealReachability */ = { isa = PBXGroup; children = ( @@ -204,6 +217,7 @@ TargetAttributes = { 8EE0B62D1C40F71800CBABCA = { CreatedOnToolsVersion = 7.1.1; + DevelopmentTeam = K93K8C6UUM; }; }; }; @@ -255,6 +269,7 @@ 8EFA08DC1C50E25800F6D790 /* FSMStateUtil.m in Sources */, 8EFA08DB1C50E25800F6D790 /* FSMEngine.m in Sources */, 8EFA08E21C50E25800F6D790 /* ReachStateWWAN.m in Sources */, + 8EF6153420CFEDD100D425CD /* NSObject+SimpleKVO.m in Sources */, 8EFA08E01C50E25800F6D790 /* ReachStateUnReachable.m in Sources */, 8EFA08E11C50E25800F6D790 /* ReachStateWIFI.m in Sources */, 8EFA08DF1C50E25800F6D790 /* ReachStateUnloaded.m in Sources */, @@ -367,6 +382,7 @@ isa = XCBuildConfiguration; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + DEVELOPMENT_TEAM = K93K8C6UUM; INFOPLIST_FILE = testRealReachability/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 7.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; @@ -379,6 +395,7 @@ isa = XCBuildConfiguration; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + DEVELOPMENT_TEAM = K93K8C6UUM; INFOPLIST_FILE = testRealReachability/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 7.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; diff --git a/testRealReachability/KVO/NSObject+SimpleKVO.h b/testRealReachability/KVO/NSObject+SimpleKVO.h new file mode 100644 index 0000000..03d46a7 --- /dev/null +++ b/testRealReachability/KVO/NSObject+SimpleKVO.h @@ -0,0 +1,34 @@ +// +// NSObject+SimpleKVO.h +// ExMobi +// +// Created by achen on 16/7/1. +// Simply modified from NSObject+YYAddForKVO. +// +// 一个从YYAddForKVO修改而来的极致简化的KVO封装(从API参数设计到调用方式) +// +// 注意:这里监听的是值的变化,其值确实改变后才会触发回调; +// 其行为和原始KVO以及YYAddForKVO都不同。 +// 后两者的行为是只要被赋值就会触发(由KVO的实现原理决定的,而simpleKVO作了特别处理), +// 使其更易用于某些业务场景的需求实现。 +// +// 单元测试覆盖率100/100。 +// +// Thanks to ibireme! +// Original project: +// YYKit (author ibireme): +// + +#import + +#define ENABLE_SWIZZ_IN_SIMPLEKVO + +@interface NSObject (SimpleKVO) + +- (void)addKVOForPath:(NSString*)path withBlock:(void (^)(id newValue))block; + +- (void)removeKVOForPath:(NSString *)path; + +- (void)removeAllKVOs; + +@end diff --git a/testRealReachability/KVO/NSObject+SimpleKVO.m b/testRealReachability/KVO/NSObject+SimpleKVO.m new file mode 100644 index 0000000..32f7201 --- /dev/null +++ b/testRealReachability/KVO/NSObject+SimpleKVO.m @@ -0,0 +1,190 @@ +// +// NSObject+SimpleKVO.m +// ExMobi +// +// Created by achen on 16/7/1. +// +// + +#import "NSObject+SimpleKVO.h" +#import + +static const int block_key; + +@interface SimpleKVOBlockTarget : NSObject + +@property (nonatomic, copy) void (^block)(id newVal); + +- (id)initWithBlock:(void (^)(id newValue))block; + +@end + +@implementation SimpleKVOBlockTarget + +- (id)initWithBlock:(void (^)(id newValue))block +{ + self = [super init]; + if (self) + { + self.block = block; + } + + return self; +} + +- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context +{ + if (self.block != nil) + { + id oldValue = [change objectForKey:NSKeyValueChangeOldKey]; + if (oldValue == [NSNull null]) + { + oldValue = nil; + } + + id newValue = [change objectForKey:NSKeyValueChangeNewKey]; + if (newValue == [NSNull null]) + { + newValue = nil; + } + + if (oldValue == nil && newValue == nil) + { + return; + } + + if (oldValue == nil || newValue == nil) + { + self.block(newValue); + } + // 根据测试发现这里所有的基本类型值都被系统自动转换成了NSXXX,因此可以对其使用isEqual进行比较。 + else if (![oldValue isEqual:newValue]) + { + self.block(newValue); + } + } +} + +@end + +@implementation NSObject (SimpleKVO) + +- (void)addKVOForPath:(NSString *)path withBlock:(void (^)(id newValue))block +{ + if ([path length] <= 0 || block == nil) + { + return; + } + + SimpleKVOBlockTarget *target = [[SimpleKVOBlockTarget alloc] initWithBlock:block]; + NSMutableDictionary *dic = [self simpleKVOBlocksLazyLoad]; + NSMutableArray *blockTargetsForPath = dic[path]; + if (!blockTargetsForPath) + { + blockTargetsForPath = [NSMutableArray new]; + dic[path] = blockTargetsForPath; + } + [blockTargetsForPath addObject:target]; + [self addObserver:target forKeyPath:path options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld context:NULL]; +} + +- (void)removeKVOForPath:(NSString *)path +{ + if ([path length] > 0) + { + NSMutableDictionary *dic = [self simpleKVOBlocks]; + + if (dic == nil) + { + return; + } + + NSMutableArray *arr = dic[path]; + [arr enumerateObjectsUsingBlock: ^(id obj, NSUInteger idx, BOOL *stop) { + [self removeObserver:obj forKeyPath:path]; + }]; + + [dic removeObjectForKey:path]; + } +} + +- (void)removeAllKVOs +{ + NSMutableDictionary *dic = [self simpleKVOBlocks]; + + if (dic == nil) + { + return; + } + + [dic enumerateKeysAndObjectsUsingBlock: ^(NSString *key, NSArray *arr, BOOL *stop) { + [arr enumerateObjectsUsingBlock: ^(id obj, NSUInteger idx, BOOL *stop) { + [self removeObserver:obj forKeyPath:key]; + }]; + }]; + + [dic removeAllObjects]; + + objc_setAssociatedObject(self, &block_key, nil, OBJC_ASSOCIATION_RETAIN_NONATOMIC); +} + +- (NSMutableDictionary *)simpleKVOBlocksLazyLoad +{ + NSMutableDictionary *targets = objc_getAssociatedObject(self, &block_key); + + if (!targets) + { + targets = [NSMutableDictionary new]; + objc_setAssociatedObject(self, &block_key, targets, OBJC_ASSOCIATION_RETAIN_NONATOMIC); + } + + return targets; +} + +- (NSMutableDictionary *)simpleKVOBlocks +{ + return objc_getAssociatedObject(self, &block_key); +} + +#ifdef ENABLE_SWIZZ_IN_SIMPLEKVO + ++ (void)load +{ + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + NSString *selString = @"dealloc"; + NSString *kvoSelString = [@"simpleKVO_" stringByAppendingString:selString]; + Method originalDealloc = class_getInstanceMethod(self, NSSelectorFromString(selString)); + Method kvoDealloc = class_getInstanceMethod(self, NSSelectorFromString(kvoSelString)); + method_exchangeImplementations(originalDealloc, kvoDealloc); + }); +} + +- (BOOL)isSimpleKVO +{ + if (objc_getAssociatedObject(self, &block_key) != nil) + { + return YES; + } + else + { + return NO; + } +} + +- (void)simpleKVO_dealloc +{ + + if ([self isSimpleKVO]) + { + [self removeAllKVOs]; + } + + [self simpleKVO_dealloc]; +} + +#endif + +@end + + diff --git a/testRealReachability/ViewController.m b/testRealReachability/ViewController.m index 36eb1e8..0ecb16b 100644 --- a/testRealReachability/ViewController.m +++ b/testRealReachability/ViewController.m @@ -8,6 +8,7 @@ #import "ViewController.h" #import "RealReachability.h" +#import "NSObject+SimpleKVO.h" @interface ViewController () @@ -28,23 +29,17 @@ - (void)viewDidLoad name:kRealReachabilityChangedNotification object:nil]; + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(VPNStatusChanged:) + name:kRRVPNStatusChangedNotification + object:nil]; + ReachabilityStatus status = [GLobalRealReachability currentReachabilityStatus]; NSLog(@"Initial reachability status:%@",@(status)); - if (status == RealStatusNotReachable) - { - self.flagLabel.text = @"Network unreachable!"; - } - - if (status == RealStatusViaWiFi) - { - self.flagLabel.text = @"Network wifi! Free!"; - } - - if (status == RealStatusViaWWAN) - { - self.flagLabel.text = @"Network WWAN! In charge!"; - } + [self setupFlagLabelWithStatus:status + isVPNOn:[GLobalRealReachability isVPNOn] + accessType:[GLobalRealReachability currentWWANtype]]; self.alert = [[UIAlertView alloc] initWithTitle:@"RealReachability" message:@"" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil, nil]; } @@ -54,9 +49,16 @@ - (void)dealloc [[NSNotificationCenter defaultCenter] removeObserver:self]; } - - (IBAction)testAction:(id)sender { +// NSLog(@"begin"); +// // performance test of this method; ok. +// for (NSInteger i=0; i<10000; i++) +// { +// [GLobalRealReachability isVPNOn]; +// } +// NSLog(@"end"); + [GLobalRealReachability reachabilityWithBlock:^(ReachabilityStatus status) { switch (status) { @@ -79,32 +81,17 @@ - (IBAction)testAction:(id)sender case RealStatusViaWWAN: { self.alert.message = @"Take care of your money! You are in charge!"; - [self.alert show]; - - WWANAccessType accessType = [GLobalRealReachability currentWWANtype]; - if (accessType == WWANType2G) - { - self.flagLabel.text = @"RealReachabilityStatus2G"; - } - else if (accessType == WWANType3G) - { - self.flagLabel.text = @"RealReachabilityStatus3G"; - } - else if (accessType == WWANType4G) - { - self.flagLabel.text = @"RealReachabilityStatus4G"; - } - else - { - self.flagLabel.text = @"Unknown RealReachability WWAN Status, might be iOS6"; - } - break; } default: + { + self.alert.message = @"Error status, needs debugging!"; break; + } } + + [self.alert show]; }]; } @@ -115,42 +102,87 @@ - (void)networkChanged:(NSNotification *)notification ReachabilityStatus previousStatus = [reachability previousReachabilityStatus]; NSLog(@"networkChanged, currentStatus:%@, previousStatus:%@", @(status), @(previousStatus)); - if (status == RealStatusNotReachable) - { - self.flagLabel.text = @"Network unreachable!"; - } + [self setupFlagLabelWithStatus:status + isVPNOn:[GLobalRealReachability isVPNOn] + accessType:[GLobalRealReachability currentWWANtype]]; +} + +- (void)VPNStatusChanged:(NSNotification *)notification +{ + // refreshing the status. + [self setupFlagLabelWithStatus:[GLobalRealReachability currentReachabilityStatus] + isVPNOn:[GLobalRealReachability isVPNOn] + accessType:[GLobalRealReachability currentWWANtype]]; +} + +- (void)setupFlagLabelWithStatus:(ReachabilityStatus)status + isVPNOn:(BOOL)isVPNOn + accessType:(WWANAccessType)accessType +{ + NSMutableString *labelStr = [@"" mutableCopy]; - if (status == RealStatusViaWiFi) + switch (status) { - self.flagLabel.text = @"Network wifi! Free!"; + case RealStatusNotReachable: + { + [labelStr appendString:@"Network unreachable! "]; + break; + } + + case RealStatusViaWiFi: + { + [labelStr appendString:@"Network wifi! Free! "]; + break; + } + + case RealStatusViaWWAN: + { + [labelStr appendString:@"WWAN in charge! "]; + break; + } + + case RealStatusUnknown: + { + [labelStr appendString:@"Unknown status! Needs debugging! "]; + break; + } + + default: + { + [labelStr appendString:@"Status error! Needs debugging! "]; + break; + } } - if (status == RealStatusViaWWAN) + if (isVPNOn) { - self.flagLabel.text = @"Network WWAN! In charge!"; + [labelStr appendString:@"VPN On! "]; } - WWANAccessType accessType = [GLobalRealReachability currentWWANtype]; - if (status == RealStatusViaWWAN) { + NSString *descStr; if (accessType == WWANType2G) { - self.flagLabel.text = @"RealReachabilityStatus2G"; + descStr = @"2G"; } else if (accessType == WWANType3G) { - self.flagLabel.text = @"RealReachabilityStatus3G"; + descStr = @"3G"; } else if (accessType == WWANType4G) { - self.flagLabel.text = @"RealReachabilityStatus4G"; + descStr = @"4G"; } else { - self.flagLabel.text = @"Unknown RealReachability WWAN Status, might be iOS6"; + descStr = @"Unknown Status, might be iOS6"; } + + [labelStr appendString:descStr]; } + + self.flagLabel.text = [labelStr copy]; } @end