Netzwerk-Verfügbarkeit wird nun getestet.
This commit is contained in:
parent
29118b03ac
commit
f272285193
@ -7,6 +7,8 @@
|
|||||||
objects = {
|
objects = {
|
||||||
|
|
||||||
/* Begin PBXBuildFile section */
|
/* Begin PBXBuildFile section */
|
||||||
|
ECB32E3718210D1D00D3C886 /* Reachability.m in Sources */ = {isa = PBXBuildFile; fileRef = ECB32E3618210D1D00D3C886 /* Reachability.m */; };
|
||||||
|
ECB32E3918210F3A00D3C886 /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = ECB32E3818210F3A00D3C886 /* SystemConfiguration.framework */; };
|
||||||
ECE5811B181A77090066D073 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = ECE5811A181A77090066D073 /* Cocoa.framework */; };
|
ECE5811B181A77090066D073 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = ECE5811A181A77090066D073 /* Cocoa.framework */; };
|
||||||
ECE58125181A77090066D073 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = ECE58123181A77090066D073 /* InfoPlist.strings */; };
|
ECE58125181A77090066D073 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = ECE58123181A77090066D073 /* InfoPlist.strings */; };
|
||||||
ECE58127181A77090066D073 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = ECE58126181A77090066D073 /* main.m */; };
|
ECE58127181A77090066D073 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = ECE58126181A77090066D073 /* main.m */; };
|
||||||
@ -33,6 +35,9 @@
|
|||||||
/* End PBXContainerItemProxy section */
|
/* End PBXContainerItemProxy section */
|
||||||
|
|
||||||
/* Begin PBXFileReference section */
|
/* Begin PBXFileReference section */
|
||||||
|
ECB32E3518210D1D00D3C886 /* Reachability.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Reachability.h; sourceTree = "<group>"; };
|
||||||
|
ECB32E3618210D1D00D3C886 /* Reachability.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Reachability.m; sourceTree = "<group>"; };
|
||||||
|
ECB32E3818210F3A00D3C886 /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = System/Library/Frameworks/SystemConfiguration.framework; sourceTree = SDKROOT; };
|
||||||
ECE58117181A77090066D073 /* ipbc-Client.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "ipbc-Client.app"; sourceTree = BUILT_PRODUCTS_DIR; };
|
ECE58117181A77090066D073 /* ipbc-Client.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "ipbc-Client.app"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
ECE5811A181A77090066D073 /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; };
|
ECE5811A181A77090066D073 /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; };
|
||||||
ECE5811D181A77090066D073 /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = System/Library/Frameworks/AppKit.framework; sourceTree = SDKROOT; };
|
ECE5811D181A77090066D073 /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = System/Library/Frameworks/AppKit.framework; sourceTree = SDKROOT; };
|
||||||
@ -63,6 +68,7 @@
|
|||||||
isa = PBXFrameworksBuildPhase;
|
isa = PBXFrameworksBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
|
ECB32E3918210F3A00D3C886 /* SystemConfiguration.framework in Frameworks */,
|
||||||
ECE5811B181A77090066D073 /* Cocoa.framework in Frameworks */,
|
ECE5811B181A77090066D073 /* Cocoa.framework in Frameworks */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
@ -101,6 +107,7 @@
|
|||||||
ECE58119181A77090066D073 /* Frameworks */ = {
|
ECE58119181A77090066D073 /* Frameworks */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
ECB32E3818210F3A00D3C886 /* SystemConfiguration.framework */,
|
||||||
ECE5811A181A77090066D073 /* Cocoa.framework */,
|
ECE5811A181A77090066D073 /* Cocoa.framework */,
|
||||||
ECE58139181A77090066D073 /* XCTest.framework */,
|
ECE58139181A77090066D073 /* XCTest.framework */,
|
||||||
ECE5811C181A77090066D073 /* Other Frameworks */,
|
ECE5811C181A77090066D073 /* Other Frameworks */,
|
||||||
@ -168,6 +175,8 @@
|
|||||||
ECE6FED5181E8AFD004F6C1F /* WebserviceClient.m */,
|
ECE6FED5181E8AFD004F6C1F /* WebserviceClient.m */,
|
||||||
ECE6FED8181E8BE4004F6C1F /* WebServiceConstants.h */,
|
ECE6FED8181E8BE4004F6C1F /* WebServiceConstants.h */,
|
||||||
ECE6FED9181E8BE4004F6C1F /* WebServiceConstants.m */,
|
ECE6FED9181E8BE4004F6C1F /* WebServiceConstants.m */,
|
||||||
|
ECB32E3518210D1D00D3C886 /* Reachability.h */,
|
||||||
|
ECB32E3618210D1D00D3C886 /* Reachability.m */,
|
||||||
);
|
);
|
||||||
name = WebService;
|
name = WebService;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@ -278,6 +287,7 @@
|
|||||||
ECE5812E181A77090066D073 /* ipbcAppDelegate.m in Sources */,
|
ECE5812E181A77090066D073 /* ipbcAppDelegate.m in Sources */,
|
||||||
ECE58127181A77090066D073 /* main.m in Sources */,
|
ECE58127181A77090066D073 /* main.m in Sources */,
|
||||||
ECE6FED6181E8AFE004F6C1F /* WebserviceClient.m in Sources */,
|
ECE6FED6181E8AFE004F6C1F /* WebserviceClient.m in Sources */,
|
||||||
|
ECB32E3718210D1D00D3C886 /* Reachability.m in Sources */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
|
|||||||
Binary file not shown.
@ -0,0 +1,10 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
<key>HasAskedToTakeAutomaticSnapshotBeforeSignificantChanges</key>
|
||||||
|
<true/>
|
||||||
|
<key>SnapshotAutomaticallyBeforeSignificantChanges</key>
|
||||||
|
<true/>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
||||||
109
ipbc-Client/ipbc-Client/Reachability.h
Normal file
109
ipbc-Client/ipbc-Client/Reachability.h
Normal file
@ -0,0 +1,109 @@
|
|||||||
|
/*
|
||||||
|
Copyright (c) 2011, Tony Million.
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
|
1. Redistributions of source code must retain the above copyright notice, this
|
||||||
|
list of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
this list of conditions and the following disclaimer in the documentation
|
||||||
|
and/or other materials provided with the distribution.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||||
|
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#import <Foundation/Foundation.h>
|
||||||
|
#import <SystemConfiguration/SystemConfiguration.h>
|
||||||
|
|
||||||
|
#import <sys/socket.h>
|
||||||
|
#import <netinet/in.h>
|
||||||
|
#import <netinet6/in6.h>
|
||||||
|
#import <arpa/inet.h>
|
||||||
|
#import <ifaddrs.h>
|
||||||
|
#import <netdb.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Does ARC support GCD objects?
|
||||||
|
* It does if the minimum deployment target is iOS 6+ or Mac OS X 8+
|
||||||
|
*
|
||||||
|
* @see http://opensource.apple.com/source/libdispatch/libdispatch-228.18/os/object.h
|
||||||
|
**/
|
||||||
|
#if OS_OBJECT_USE_OBJC
|
||||||
|
#define NEEDS_DISPATCH_RETAIN_RELEASE 0
|
||||||
|
#else
|
||||||
|
#define NEEDS_DISPATCH_RETAIN_RELEASE 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create NS_ENUM macro if it does not exist on the targeted version of iOS or OS X.
|
||||||
|
*
|
||||||
|
* @see http://nshipster.com/ns_enum-ns_options/
|
||||||
|
**/
|
||||||
|
#ifndef NS_ENUM
|
||||||
|
#define NS_ENUM(_type, _name) enum _name : _type _name; enum _name : _type
|
||||||
|
#endif
|
||||||
|
|
||||||
|
extern NSString *const kReachabilityChangedNotification;
|
||||||
|
|
||||||
|
typedef NS_ENUM(NSInteger, NetworkStatus) {
|
||||||
|
// Apple NetworkStatus Compatible Names.
|
||||||
|
NotReachable = 0,
|
||||||
|
ReachableViaWiFi = 2,
|
||||||
|
ReachableViaWWAN = 1
|
||||||
|
};
|
||||||
|
|
||||||
|
@class Reachability;
|
||||||
|
|
||||||
|
typedef void (^NetworkReachable)(Reachability * reachability);
|
||||||
|
typedef void (^NetworkUnreachable)(Reachability * reachability);
|
||||||
|
|
||||||
|
@interface Reachability : NSObject
|
||||||
|
|
||||||
|
@property (nonatomic, copy) NetworkReachable reachableBlock;
|
||||||
|
@property (nonatomic, copy) NetworkUnreachable unreachableBlock;
|
||||||
|
|
||||||
|
|
||||||
|
@property (nonatomic, assign) BOOL reachableOnWWAN;
|
||||||
|
|
||||||
|
+(Reachability*)reachabilityWithHostname:(NSString*)hostname;
|
||||||
|
+(Reachability*)reachabilityForInternetConnection;
|
||||||
|
+(Reachability*)reachabilityWithAddress:(const struct sockaddr_in*)hostAddress;
|
||||||
|
+(Reachability*)reachabilityForLocalWiFi;
|
||||||
|
|
||||||
|
-(Reachability *)initWithReachabilityRef:(SCNetworkReachabilityRef)ref;
|
||||||
|
|
||||||
|
-(BOOL)startNotifier;
|
||||||
|
-(void)stopNotifier;
|
||||||
|
|
||||||
|
-(BOOL)isReachable;
|
||||||
|
-(BOOL)isReachableViaWWAN;
|
||||||
|
-(BOOL)isReachableViaWiFi;
|
||||||
|
|
||||||
|
// WWAN may be available, but not active until a connection has been established.
|
||||||
|
// WiFi may require a connection for VPN on Demand.
|
||||||
|
-(BOOL)isConnectionRequired; // Identical DDG variant.
|
||||||
|
-(BOOL)connectionRequired; // Apple's routine.
|
||||||
|
// Dynamic, on demand connection?
|
||||||
|
-(BOOL)isConnectionOnDemand;
|
||||||
|
// Is user intervention required?
|
||||||
|
-(BOOL)isInterventionRequired;
|
||||||
|
|
||||||
|
-(NetworkStatus)currentReachabilityStatus;
|
||||||
|
-(SCNetworkReachabilityFlags)reachabilityFlags;
|
||||||
|
-(NSString*)currentReachabilityString;
|
||||||
|
-(NSString*)currentReachabilityFlags;
|
||||||
|
|
||||||
|
@end
|
||||||
527
ipbc-Client/ipbc-Client/Reachability.m
Normal file
527
ipbc-Client/ipbc-Client/Reachability.m
Normal file
@ -0,0 +1,527 @@
|
|||||||
|
/*
|
||||||
|
Copyright (c) 2011, Tony Million.
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
|
1. Redistributions of source code must retain the above copyright notice, this
|
||||||
|
list of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
this list of conditions and the following disclaimer in the documentation
|
||||||
|
and/or other materials provided with the distribution.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||||
|
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#import "Reachability.h"
|
||||||
|
|
||||||
|
|
||||||
|
NSString *const kReachabilityChangedNotification = @"kReachabilityChangedNotification";
|
||||||
|
|
||||||
|
@interface Reachability ()
|
||||||
|
|
||||||
|
@property (nonatomic, assign) SCNetworkReachabilityRef reachabilityRef;
|
||||||
|
|
||||||
|
|
||||||
|
#if NEEDS_DISPATCH_RETAIN_RELEASE
|
||||||
|
@property (nonatomic, assign) dispatch_queue_t reachabilitySerialQueue;
|
||||||
|
#else
|
||||||
|
@property (nonatomic, strong) dispatch_queue_t reachabilitySerialQueue;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
@property (nonatomic, strong) id reachabilityObject;
|
||||||
|
|
||||||
|
-(void)reachabilityChanged:(SCNetworkReachabilityFlags)flags;
|
||||||
|
-(BOOL)isReachableWithFlags:(SCNetworkReachabilityFlags)flags;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
static NSString *reachabilityFlags(SCNetworkReachabilityFlags flags)
|
||||||
|
{
|
||||||
|
return [NSString stringWithFormat:@"%c%c %c%c%c%c%c%c%c",
|
||||||
|
#if TARGET_OS_IPHONE
|
||||||
|
(flags & kSCNetworkReachabilityFlagsIsWWAN) ? 'W' : '-',
|
||||||
|
#else
|
||||||
|
'X',
|
||||||
|
#endif
|
||||||
|
(flags & kSCNetworkReachabilityFlagsReachable) ? 'R' : '-',
|
||||||
|
(flags & kSCNetworkReachabilityFlagsConnectionRequired) ? 'c' : '-',
|
||||||
|
(flags & kSCNetworkReachabilityFlagsTransientConnection) ? 't' : '-',
|
||||||
|
(flags & kSCNetworkReachabilityFlagsInterventionRequired) ? 'i' : '-',
|
||||||
|
(flags & kSCNetworkReachabilityFlagsConnectionOnTraffic) ? 'C' : '-',
|
||||||
|
(flags & kSCNetworkReachabilityFlagsConnectionOnDemand) ? 'D' : '-',
|
||||||
|
(flags & kSCNetworkReachabilityFlagsIsLocalAddress) ? 'l' : '-',
|
||||||
|
(flags & kSCNetworkReachabilityFlagsIsDirect) ? 'd' : '-'];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Start listening for reachability notifications on the current run loop
|
||||||
|
static void TMReachabilityCallback(SCNetworkReachabilityRef target, SCNetworkReachabilityFlags flags, void* info)
|
||||||
|
{
|
||||||
|
#pragma unused (target)
|
||||||
|
#if __has_feature(objc_arc)
|
||||||
|
Reachability *reachability = ((__bridge Reachability*)info);
|
||||||
|
#else
|
||||||
|
Reachability *reachability = ((Reachability*)info);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// We probably don't need an autoreleasepool here, as GCD docs state each queue has its own autorelease pool,
|
||||||
|
// but what the heck eh?
|
||||||
|
@autoreleasepool
|
||||||
|
{
|
||||||
|
[reachability reachabilityChanged:flags];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@implementation Reachability
|
||||||
|
|
||||||
|
@synthesize reachabilityRef;
|
||||||
|
@synthesize reachabilitySerialQueue;
|
||||||
|
|
||||||
|
@synthesize reachableOnWWAN;
|
||||||
|
|
||||||
|
@synthesize reachableBlock;
|
||||||
|
@synthesize unreachableBlock;
|
||||||
|
|
||||||
|
@synthesize reachabilityObject;
|
||||||
|
|
||||||
|
#pragma mark - Class Constructor Methods
|
||||||
|
|
||||||
|
+(Reachability*)reachabilityWithHostName:(NSString*)hostname
|
||||||
|
{
|
||||||
|
return [Reachability reachabilityWithHostname:hostname];
|
||||||
|
}
|
||||||
|
|
||||||
|
+(Reachability*)reachabilityWithHostname:(NSString*)hostname
|
||||||
|
{
|
||||||
|
SCNetworkReachabilityRef ref = SCNetworkReachabilityCreateWithName(NULL, [hostname UTF8String]);
|
||||||
|
if (ref)
|
||||||
|
{
|
||||||
|
id reachability = [[self alloc] initWithReachabilityRef:ref];
|
||||||
|
|
||||||
|
#if __has_feature(objc_arc)
|
||||||
|
return reachability;
|
||||||
|
#else
|
||||||
|
return [reachability autorelease];
|
||||||
|
#endif
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
+(Reachability *)reachabilityWithAddress:(const struct sockaddr_in *)hostAddress
|
||||||
|
{
|
||||||
|
SCNetworkReachabilityRef ref = SCNetworkReachabilityCreateWithAddress(kCFAllocatorDefault, (const struct sockaddr*)hostAddress);
|
||||||
|
if (ref)
|
||||||
|
{
|
||||||
|
id reachability = [[self alloc] initWithReachabilityRef:ref];
|
||||||
|
|
||||||
|
#if __has_feature(objc_arc)
|
||||||
|
return reachability;
|
||||||
|
#else
|
||||||
|
return [reachability autorelease];
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
+(Reachability *)reachabilityForInternetConnection
|
||||||
|
{
|
||||||
|
struct sockaddr_in zeroAddress;
|
||||||
|
bzero(&zeroAddress, sizeof(zeroAddress));
|
||||||
|
zeroAddress.sin_len = sizeof(zeroAddress);
|
||||||
|
zeroAddress.sin_family = AF_INET;
|
||||||
|
|
||||||
|
return [self reachabilityWithAddress:&zeroAddress];
|
||||||
|
}
|
||||||
|
|
||||||
|
+(Reachability*)reachabilityForLocalWiFi
|
||||||
|
{
|
||||||
|
struct sockaddr_in localWifiAddress;
|
||||||
|
bzero(&localWifiAddress, sizeof(localWifiAddress));
|
||||||
|
localWifiAddress.sin_len = sizeof(localWifiAddress);
|
||||||
|
localWifiAddress.sin_family = AF_INET;
|
||||||
|
// IN_LINKLOCALNETNUM is defined in <netinet/in.h> as 169.254.0.0
|
||||||
|
localWifiAddress.sin_addr.s_addr = htonl(IN_LINKLOCALNETNUM);
|
||||||
|
|
||||||
|
return [self reachabilityWithAddress:&localWifiAddress];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Initialization methods
|
||||||
|
|
||||||
|
-(Reachability *)initWithReachabilityRef:(SCNetworkReachabilityRef)ref
|
||||||
|
{
|
||||||
|
self = [super init];
|
||||||
|
if (self != nil)
|
||||||
|
{
|
||||||
|
self.reachableOnWWAN = YES;
|
||||||
|
self.reachabilityRef = ref;
|
||||||
|
}
|
||||||
|
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
-(void)dealloc
|
||||||
|
{
|
||||||
|
[self stopNotifier];
|
||||||
|
|
||||||
|
if(self.reachabilityRef)
|
||||||
|
{
|
||||||
|
CFRelease(self.reachabilityRef);
|
||||||
|
self.reachabilityRef = nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
self.reachableBlock = nil;
|
||||||
|
self.unreachableBlock = nil;
|
||||||
|
|
||||||
|
#if !(__has_feature(objc_arc))
|
||||||
|
[super dealloc];
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma mark - Notifier Methods
|
||||||
|
|
||||||
|
// Notifier
|
||||||
|
// NOTE: This uses GCD to trigger the blocks - they *WILL NOT* be called on THE MAIN THREAD
|
||||||
|
// - In other words DO NOT DO ANY UI UPDATES IN THE BLOCKS.
|
||||||
|
// INSTEAD USE dispatch_async(dispatch_get_main_queue(), ^{UISTUFF}) (or dispatch_sync if you want)
|
||||||
|
|
||||||
|
-(BOOL)startNotifier
|
||||||
|
{
|
||||||
|
SCNetworkReachabilityContext context = { 0, NULL, NULL, NULL, NULL };
|
||||||
|
|
||||||
|
// this should do a retain on ourself, so as long as we're in notifier mode we shouldn't disappear out from under ourselves
|
||||||
|
// woah
|
||||||
|
self.reachabilityObject = self;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// First, we need to create a serial queue.
|
||||||
|
// We allocate this once for the lifetime of the notifier.
|
||||||
|
self.reachabilitySerialQueue = dispatch_queue_create("com.tonymillion.reachability", NULL);
|
||||||
|
if(!self.reachabilitySerialQueue)
|
||||||
|
{
|
||||||
|
return NO;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if __has_feature(objc_arc)
|
||||||
|
context.info = (__bridge void *)self;
|
||||||
|
#else
|
||||||
|
context.info = (void *)self;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (!SCNetworkReachabilitySetCallback(self.reachabilityRef, TMReachabilityCallback, &context))
|
||||||
|
{
|
||||||
|
#ifdef DEBUG
|
||||||
|
NSLog(@"SCNetworkReachabilitySetCallback() failed: %s", SCErrorString(SCError()));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Clear out the dispatch queue
|
||||||
|
if(self.reachabilitySerialQueue)
|
||||||
|
{
|
||||||
|
#if NEEDS_DISPATCH_RETAIN_RELEASE
|
||||||
|
dispatch_release(self.reachabilitySerialQueue);
|
||||||
|
#endif
|
||||||
|
self.reachabilitySerialQueue = nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
self.reachabilityObject = nil;
|
||||||
|
|
||||||
|
return NO;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set it as our reachability queue, which will retain the queue
|
||||||
|
if(!SCNetworkReachabilitySetDispatchQueue(self.reachabilityRef, self.reachabilitySerialQueue))
|
||||||
|
{
|
||||||
|
#ifdef DEBUG
|
||||||
|
NSLog(@"SCNetworkReachabilitySetDispatchQueue() failed: %s", SCErrorString(SCError()));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// UH OH - FAILURE!
|
||||||
|
|
||||||
|
// First stop, any callbacks!
|
||||||
|
SCNetworkReachabilitySetCallback(self.reachabilityRef, NULL, NULL);
|
||||||
|
|
||||||
|
// Then clear out the dispatch queue.
|
||||||
|
if(self.reachabilitySerialQueue)
|
||||||
|
{
|
||||||
|
#if NEEDS_DISPATCH_RETAIN_RELEASE
|
||||||
|
dispatch_release(self.reachabilitySerialQueue);
|
||||||
|
#endif
|
||||||
|
self.reachabilitySerialQueue = nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
self.reachabilityObject = nil;
|
||||||
|
|
||||||
|
return NO;
|
||||||
|
}
|
||||||
|
|
||||||
|
return YES;
|
||||||
|
}
|
||||||
|
|
||||||
|
-(void)stopNotifier
|
||||||
|
{
|
||||||
|
// First stop, any callbacks!
|
||||||
|
SCNetworkReachabilitySetCallback(self.reachabilityRef, NULL, NULL);
|
||||||
|
|
||||||
|
// Unregister target from the GCD serial dispatch queue.
|
||||||
|
SCNetworkReachabilitySetDispatchQueue(self.reachabilityRef, NULL);
|
||||||
|
|
||||||
|
if(self.reachabilitySerialQueue)
|
||||||
|
{
|
||||||
|
#if NEEDS_DISPATCH_RETAIN_RELEASE
|
||||||
|
dispatch_release(self.reachabilitySerialQueue);
|
||||||
|
#endif
|
||||||
|
self.reachabilitySerialQueue = nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
self.reachabilityObject = nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma mark - reachability tests
|
||||||
|
|
||||||
|
// This is for the case where you flick the airplane mode;
|
||||||
|
// you end up getting something like this:
|
||||||
|
//Reachability: WR ct-----
|
||||||
|
//Reachability: -- -------
|
||||||
|
//Reachability: WR ct-----
|
||||||
|
//Reachability: -- -------
|
||||||
|
// We treat this as 4 UNREACHABLE triggers - really apple should do better than this
|
||||||
|
|
||||||
|
#define testcase (kSCNetworkReachabilityFlagsConnectionRequired | kSCNetworkReachabilityFlagsTransientConnection)
|
||||||
|
|
||||||
|
-(BOOL)isReachableWithFlags:(SCNetworkReachabilityFlags)flags
|
||||||
|
{
|
||||||
|
BOOL connectionUP = YES;
|
||||||
|
|
||||||
|
if(!(flags & kSCNetworkReachabilityFlagsReachable))
|
||||||
|
connectionUP = NO;
|
||||||
|
|
||||||
|
if( (flags & testcase) == testcase )
|
||||||
|
connectionUP = NO;
|
||||||
|
|
||||||
|
#if TARGET_OS_IPHONE
|
||||||
|
if(flags & kSCNetworkReachabilityFlagsIsWWAN)
|
||||||
|
{
|
||||||
|
// We're on 3G.
|
||||||
|
if(!self.reachableOnWWAN)
|
||||||
|
{
|
||||||
|
// We don't want to connect when on 3G.
|
||||||
|
connectionUP = NO;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return connectionUP;
|
||||||
|
}
|
||||||
|
|
||||||
|
-(BOOL)isReachable
|
||||||
|
{
|
||||||
|
SCNetworkReachabilityFlags flags;
|
||||||
|
|
||||||
|
if(!SCNetworkReachabilityGetFlags(self.reachabilityRef, &flags))
|
||||||
|
return NO;
|
||||||
|
|
||||||
|
return [self isReachableWithFlags:flags];
|
||||||
|
}
|
||||||
|
|
||||||
|
-(BOOL)isReachableViaWWAN
|
||||||
|
{
|
||||||
|
#if TARGET_OS_IPHONE
|
||||||
|
|
||||||
|
SCNetworkReachabilityFlags flags = 0;
|
||||||
|
|
||||||
|
if(SCNetworkReachabilityGetFlags(reachabilityRef, &flags))
|
||||||
|
{
|
||||||
|
// Check we're REACHABLE
|
||||||
|
if(flags & kSCNetworkReachabilityFlagsReachable)
|
||||||
|
{
|
||||||
|
// Now, check we're on WWAN
|
||||||
|
if(flags & kSCNetworkReachabilityFlagsIsWWAN)
|
||||||
|
{
|
||||||
|
return YES;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return NO;
|
||||||
|
}
|
||||||
|
|
||||||
|
-(BOOL)isReachableViaWiFi
|
||||||
|
{
|
||||||
|
SCNetworkReachabilityFlags flags = 0;
|
||||||
|
|
||||||
|
if(SCNetworkReachabilityGetFlags(reachabilityRef, &flags))
|
||||||
|
{
|
||||||
|
// Check we're reachable
|
||||||
|
if((flags & kSCNetworkReachabilityFlagsReachable))
|
||||||
|
{
|
||||||
|
#if TARGET_OS_IPHONE
|
||||||
|
// Check we're NOT on WWAN
|
||||||
|
if((flags & kSCNetworkReachabilityFlagsIsWWAN))
|
||||||
|
{
|
||||||
|
return NO;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return YES;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NO;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// WWAN may be available, but not active until a connection has been established.
|
||||||
|
// WiFi may require a connection for VPN on Demand.
|
||||||
|
-(BOOL)isConnectionRequired
|
||||||
|
{
|
||||||
|
return [self connectionRequired];
|
||||||
|
}
|
||||||
|
|
||||||
|
-(BOOL)connectionRequired
|
||||||
|
{
|
||||||
|
SCNetworkReachabilityFlags flags;
|
||||||
|
|
||||||
|
if(SCNetworkReachabilityGetFlags(reachabilityRef, &flags))
|
||||||
|
{
|
||||||
|
return (flags & kSCNetworkReachabilityFlagsConnectionRequired);
|
||||||
|
}
|
||||||
|
|
||||||
|
return NO;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Dynamic, on demand connection?
|
||||||
|
-(BOOL)isConnectionOnDemand
|
||||||
|
{
|
||||||
|
SCNetworkReachabilityFlags flags;
|
||||||
|
|
||||||
|
if (SCNetworkReachabilityGetFlags(reachabilityRef, &flags))
|
||||||
|
{
|
||||||
|
return ((flags & kSCNetworkReachabilityFlagsConnectionRequired) &&
|
||||||
|
(flags & (kSCNetworkReachabilityFlagsConnectionOnTraffic | kSCNetworkReachabilityFlagsConnectionOnDemand)));
|
||||||
|
}
|
||||||
|
|
||||||
|
return NO;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Is user intervention required?
|
||||||
|
-(BOOL)isInterventionRequired
|
||||||
|
{
|
||||||
|
SCNetworkReachabilityFlags flags;
|
||||||
|
|
||||||
|
if (SCNetworkReachabilityGetFlags(reachabilityRef, &flags))
|
||||||
|
{
|
||||||
|
return ((flags & kSCNetworkReachabilityFlagsConnectionRequired) &&
|
||||||
|
(flags & kSCNetworkReachabilityFlagsInterventionRequired));
|
||||||
|
}
|
||||||
|
|
||||||
|
return NO;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#pragma mark - reachability status stuff
|
||||||
|
|
||||||
|
-(NetworkStatus)currentReachabilityStatus
|
||||||
|
{
|
||||||
|
if([self isReachable])
|
||||||
|
{
|
||||||
|
if([self isReachableViaWiFi])
|
||||||
|
return ReachableViaWiFi;
|
||||||
|
|
||||||
|
#if TARGET_OS_IPHONE
|
||||||
|
return ReachableViaWWAN;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
return NotReachable;
|
||||||
|
}
|
||||||
|
|
||||||
|
-(SCNetworkReachabilityFlags)reachabilityFlags
|
||||||
|
{
|
||||||
|
SCNetworkReachabilityFlags flags = 0;
|
||||||
|
|
||||||
|
if(SCNetworkReachabilityGetFlags(reachabilityRef, &flags))
|
||||||
|
{
|
||||||
|
return flags;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
-(NSString*)currentReachabilityString
|
||||||
|
{
|
||||||
|
NetworkStatus temp = [self currentReachabilityStatus];
|
||||||
|
|
||||||
|
if(temp == reachableOnWWAN)
|
||||||
|
{
|
||||||
|
// Updated for the fact that we have CDMA phones now!
|
||||||
|
return NSLocalizedString(@"Cellular", @"");
|
||||||
|
}
|
||||||
|
if (temp == ReachableViaWiFi)
|
||||||
|
{
|
||||||
|
return NSLocalizedString(@"WiFi", @"");
|
||||||
|
}
|
||||||
|
|
||||||
|
return NSLocalizedString(@"No Connection", @"");
|
||||||
|
}
|
||||||
|
|
||||||
|
-(NSString*)currentReachabilityFlags
|
||||||
|
{
|
||||||
|
return reachabilityFlags([self reachabilityFlags]);
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma mark - Callback function calls this method
|
||||||
|
|
||||||
|
-(void)reachabilityChanged:(SCNetworkReachabilityFlags)flags
|
||||||
|
{
|
||||||
|
if([self isReachableWithFlags:flags])
|
||||||
|
{
|
||||||
|
if(self.reachableBlock)
|
||||||
|
{
|
||||||
|
self.reachableBlock(self);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(self.unreachableBlock)
|
||||||
|
{
|
||||||
|
self.unreachableBlock(self);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// this makes sure the change notification happens on the MAIN THREAD
|
||||||
|
dispatch_async(dispatch_get_main_queue(), ^{
|
||||||
|
[[NSNotificationCenter defaultCenter] postNotificationName:kReachabilityChangedNotification
|
||||||
|
object:self];
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma mark - Debug Description
|
||||||
|
|
||||||
|
- (NSString *) description
|
||||||
|
{
|
||||||
|
NSString *description = [NSString stringWithFormat:@"<%@: %#x>",
|
||||||
|
NSStringFromClass([self class]), (unsigned int) self];
|
||||||
|
return description;
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
@ -10,6 +10,7 @@
|
|||||||
|
|
||||||
@interface WebServiceConstants : NSObject
|
@interface WebServiceConstants : NSObject
|
||||||
|
|
||||||
|
extern NSString * const WS_BASE;
|
||||||
extern NSString * const WS_RESOURCE;
|
extern NSString * const WS_RESOURCE;
|
||||||
extern NSString * const WS_GET_USERS_IP_SERVICE;
|
extern NSString * const WS_GET_USERS_IP_SERVICE;
|
||||||
|
|
||||||
|
|||||||
@ -10,6 +10,7 @@
|
|||||||
|
|
||||||
@implementation WebServiceConstants
|
@implementation WebServiceConstants
|
||||||
|
|
||||||
|
NSString * const WS_BASE = @"www.ip-bc.org";
|
||||||
NSString * const WS_RESOURCE = @"http://www.ip-bc.org/ws/update/ip";
|
NSString * const WS_RESOURCE = @"http://www.ip-bc.org/ws/update/ip";
|
||||||
NSString * const WS_GET_USERS_IP_SERVICE = @"http://www.ip-bc.org/ws/info/ip";
|
NSString * const WS_GET_USERS_IP_SERVICE = @"http://www.ip-bc.org/ws/info/ip";
|
||||||
|
|
||||||
|
|||||||
@ -12,8 +12,10 @@
|
|||||||
|
|
||||||
NSTimer *updateTimer;
|
NSTimer *updateTimer;
|
||||||
NSString *usersIPv4;
|
NSString *usersIPv4;
|
||||||
|
BOOL isNetworkAvailable;
|
||||||
}
|
}
|
||||||
|
|
||||||
-(BOOL)updateDomain;
|
-(BOOL)updateDomain;
|
||||||
|
-(void)checkNetworkAvailability;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|||||||
@ -8,6 +8,7 @@
|
|||||||
|
|
||||||
#import "WebserviceClient.h"
|
#import "WebserviceClient.h"
|
||||||
#import "WebServiceConstants.h"
|
#import "WebServiceConstants.h"
|
||||||
|
#import "Reachability.h"
|
||||||
|
|
||||||
@implementation WebserviceClient
|
@implementation WebserviceClient
|
||||||
|
|
||||||
@ -17,11 +18,16 @@
|
|||||||
selector: @selector(tick:)
|
selector: @selector(tick:)
|
||||||
userInfo: nil
|
userInfo: nil
|
||||||
repeats: YES];
|
repeats: YES];
|
||||||
|
|
||||||
|
isNetworkAvailable = NO;
|
||||||
|
[self checkNetworkAvailability];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)tick:(NSTimer *)theTimer {
|
- (void)tick:(NSTimer *)theTimer {
|
||||||
|
if(isNetworkAvailable) {
|
||||||
[self updateDomain];
|
[self updateDomain];
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
-(BOOL)updateDomain {
|
-(BOOL)updateDomain {
|
||||||
usersIPv4 = [self fetchIPv4];
|
usersIPv4 = [self fetchIPv4];
|
||||||
@ -42,6 +48,27 @@
|
|||||||
return updateResult;
|
return updateResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
-(void)checkNetworkAvailability {
|
||||||
|
// Allocate a reachability object
|
||||||
|
Reachability* reach = [Reachability reachabilityWithHostname:WS_BASE];
|
||||||
|
|
||||||
|
// Set the blocks
|
||||||
|
reach.reachableBlock = ^(Reachability*reach)
|
||||||
|
{
|
||||||
|
NSLog(@"%@ REACHABLE", WS_BASE);
|
||||||
|
isNetworkAvailable = YES;
|
||||||
|
};
|
||||||
|
|
||||||
|
reach.unreachableBlock = ^(Reachability*reach)
|
||||||
|
{
|
||||||
|
NSLog(@"%@ UNREACHABLE", WS_BASE);
|
||||||
|
isNetworkAvailable = NO;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Start the notifier, which will cause the reachability object to retain itself!
|
||||||
|
[reach startNotifier];
|
||||||
|
}
|
||||||
|
|
||||||
-(BOOL)checkUpdateNeeded {
|
-(BOOL)checkUpdateNeeded {
|
||||||
NSString *storedIPv4 = [[NSUserDefaults standardUserDefaults] stringForKey:@"value.ip.ipv4"];
|
NSString *storedIPv4 = [[NSUserDefaults standardUserDefaults] stringForKey:@"value.ip.ipv4"];
|
||||||
NSString *fetchedIPv4 = usersIPv4;
|
NSString *fetchedIPv4 = usersIPv4;
|
||||||
@ -53,7 +80,7 @@
|
|||||||
NSLog(@"fetched IPv4 NULL");
|
NSLog(@"fetched IPv4 NULL");
|
||||||
return NO;
|
return NO;
|
||||||
} else {
|
} else {
|
||||||
//NSLog(@"compare stored %@ with %@", storedIPv4, fetchedIPv4);
|
NSLog(@"compare stored %@ with %@", storedIPv4, fetchedIPv4);
|
||||||
BOOL changed = [storedIPv4 isEqualToString:fetchedIPv4];
|
BOOL changed = [storedIPv4 isEqualToString:fetchedIPv4];
|
||||||
|
|
||||||
if(changed) {
|
if(changed) {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user