Author: gavincornwell
Date: Thu May 22 15:04:26 2014
New Revision: 1596896
URL: http://svn.apache.org/r1596896
Log:
CMIS-805: Detect when no network is available and return error immediately.
Added:
chemistry/objectivecmis/trunk/ObjectiveCMIS/Utils/CMISReachability.h
chemistry/objectivecmis/trunk/ObjectiveCMIS/Utils/CMISReachability.m
Modified:
chemistry/objectivecmis/trunk/ObjectiveCMIS.xcodeproj/project.pbxproj
chemistry/objectivecmis/trunk/ObjectiveCMIS/Common/CMISErrors.h
chemistry/objectivecmis/trunk/ObjectiveCMIS/Common/CMISErrors.m
chemistry/objectivecmis/trunk/ObjectiveCMIS/Utils/CMISHttpRequest.m
Modified: chemistry/objectivecmis/trunk/ObjectiveCMIS.xcodeproj/project.pbxproj
URL:
http://svn.apache.org/viewvc/chemistry/objectivecmis/trunk/ObjectiveCMIS.xcodeproj/project.pbxproj?rev=1596896&r1=1596895&r2=1596896&view=diff
==============================================================================
--- chemistry/objectivecmis/trunk/ObjectiveCMIS.xcodeproj/project.pbxproj
(original)
+++ chemistry/objectivecmis/trunk/ObjectiveCMIS.xcodeproj/project.pbxproj Thu
May 22 15:04:26 2014
@@ -140,6 +140,10 @@
5892CC15192CB91300C7734A /* CMISNSDictionary+CMISUtil.h in
Headers */ = {isa = PBXBuildFile; fileRef = 5892CC11192CB91300C7734A /*
CMISNSDictionary+CMISUtil.h */; };
5892CC16192CB91300C7734A /* CMISNSDictionary+CMISUtil.m in
Sources */ = {isa = PBXBuildFile; fileRef = 5892CC12192CB91300C7734A /*
CMISNSDictionary+CMISUtil.m */; };
5892CC17192CB93E00C7734A /* CMISNSDictionary+CMISUtil.m in
Sources */ = {isa = PBXBuildFile; fileRef = 5892CC12192CB91300C7734A /*
CMISNSDictionary+CMISUtil.m */; };
+ 5892CC1A192CE23F00C7734A /* CMISReachability.h in Headers */ =
{isa = PBXBuildFile; fileRef = 5892CC18192CE23F00C7734A /* CMISReachability.h
*/; settings = {ATTRIBUTES = (Public, ); }; };
+ 5892CC1B192CE23F00C7734A /* CMISReachability.m in Sources */ =
{isa = PBXBuildFile; fileRef = 5892CC19192CE23F00C7734A /* CMISReachability.m
*/; };
+ 5892CC20192CEE3E00C7734A /* SystemConfiguration.framework in
Frameworks */ = {isa = PBXBuildFile; fileRef = 5892CC1F192CEE3E00C7734A /*
SystemConfiguration.framework */; };
+ 5892CC21192CEE4B00C7734A /* SystemConfiguration.framework in
Frameworks */ = {isa = PBXBuildFile; fileRef = 5892CC1F192CEE3E00C7734A /*
SystemConfiguration.framework */; };
750CB2BE159C56A5004576F7 /* AllowableActions.xml in Resources
*/ = {isa = PBXBuildFile; fileRef = 750CB2BB159C56A5004576F7 /*
AllowableActions.xml */; };
750CB2BF159C56A5004576F7 /* FolderChildren-webscripts.xml in
Resources */ = {isa = PBXBuildFile; fileRef = 750CB2BC159C56A5004576F7 /*
FolderChildren-webscripts.xml */; };
750CB2C0159C56A5004576F7 /* FolderChildren-opencmis.xml in
Resources */ = {isa = PBXBuildFile; fileRef = 750CB2BD159C56A5004576F7 /*
FolderChildren-opencmis.xml */; };
@@ -386,6 +390,10 @@
5892CC10192CB91300C7734A /* CMISMimeHelper.m */ = {isa =
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name
= CMISMimeHelper.m; path = Utils/CMISMimeHelper.m; sourceTree = "<group>"; };
5892CC11192CB91300C7734A /* CMISNSDictionary+CMISUtil.h */ =
{isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h;
name = "CMISNSDictionary+CMISUtil.h"; path =
"Utils/CMISNSDictionary+CMISUtil.h"; sourceTree = "<group>"; };
5892CC12192CB91300C7734A /* CMISNSDictionary+CMISUtil.m */ =
{isa = PBXFileReference; fileEncoding = 4; lastKnownFileType =
sourcecode.c.objc; name = "CMISNSDictionary+CMISUtil.m"; path =
"Utils/CMISNSDictionary+CMISUtil.m"; sourceTree = "<group>"; };
+ 5892CC18192CE23F00C7734A /* CMISReachability.h */ = {isa =
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name =
CMISReachability.h; path = Utils/CMISReachability.h; sourceTree = "<group>"; };
+ 5892CC19192CE23F00C7734A /* CMISReachability.m */ = {isa =
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name
= CMISReachability.m; path = Utils/CMISReachability.m; sourceTree = "<group>";
};
+ 5892CC1C192CE2F700C7734A /* Security.framework */ = {isa =
PBXFileReference; lastKnownFileType = wrapper.framework; name =
Security.framework; path = System/Library/Frameworks/Security.framework;
sourceTree = SDKROOT; };
+ 5892CC1F192CEE3E00C7734A /* SystemConfiguration.framework */ =
{isa = PBXFileReference; lastKnownFileType = wrapper.framework; name =
SystemConfiguration.framework; path =
System/Library/Frameworks/SystemConfiguration.framework; sourceTree = SDKROOT;
};
750CB2BB159C56A5004576F7 /* AllowableActions.xml */ = {isa =
PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path =
AllowableActions.xml; sourceTree = "<group>"; };
750CB2BC159C56A5004576F7 /* FolderChildren-webscripts.xml */ =
{isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path =
"FolderChildren-webscripts.xml"; sourceTree = "<group>"; };
750CB2BD159C56A5004576F7 /* FolderChildren-opencmis.xml */ =
{isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path =
"FolderChildren-opencmis.xml"; sourceTree = "<group>"; };
@@ -516,6 +524,7 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
+ 5892CC20192CEE3E00C7734A /*
SystemConfiguration.framework in Frameworks */,
828072A715153DE800EF635C /*
Foundation.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
@@ -524,6 +533,7 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
+ 5892CC21192CEE4B00C7734A /*
SystemConfiguration.framework in Frameworks */,
828073DE15154F9400EF635C /*
MobileCoreServices.framework in Frameworks */,
828072B815153DE900EF635C /*
Foundation.framework in Frameworks */,
828072BB15153DE900EF635C /* libObjectiveCMIS.a
in Frameworks */,
@@ -611,6 +621,8 @@
828072A515153DE800EF635C /* Frameworks */ = {
isa = PBXGroup;
children = (
+ 5892CC1F192CEE3E00C7734A /*
SystemConfiguration.framework */,
+ 5892CC1C192CE2F700C7734A /* Security.framework
*/,
82807383151542F400EF635C /*
MobileCoreServices.framework */,
828072A615153DE800EF635C /*
Foundation.framework */,
);
@@ -818,6 +830,8 @@
5892CC12192CB91300C7734A /*
CMISNSDictionary+CMISUtil.m */,
828073291515407000EF635C /*
CMISObjectConverter.h */,
8280732A1515407000EF635C /*
CMISObjectConverter.m */,
+ 5892CC18192CE23F00C7734A /* CMISReachability.h
*/,
+ 5892CC19192CE23F00C7734A /* CMISReachability.m
*/,
4EA61BD31564F70C00C759E4 /*
CMISStringInOutParameter.h */,
4EA61BD41564F70C00C759E4 /*
CMISStringInOutParameter.m */,
4EA61BD51564F70C00C759E4 /* CMISURLUtil.h */,
@@ -984,6 +998,7 @@
FE417D5715761A0C009056AA /*
CMISOperationContext.h in Headers */,
5892CB80192CB65D00C7734A /*
CMISFolderTypeDefinition.h in Headers */,
FE417D5915761A0C009056AA /* CMISPagedResult.h
in Headers */,
+ 5892CC1A192CE23F00C7734A /* CMISReachability.h
in Headers */,
FE417D6315761A34009056AA /* CMISLinkCache.h in
Headers */,
FE417D6515761A34009056AA /*
CMISPropertyDefinition.h in Headers */,
FE417D6715761A34009056AA /*
CMISTypeDefinition.h in Headers */,
@@ -1208,6 +1223,7 @@
5892CBBC192CB7D900C7734A /*
CMISAtomEntryParser.m in Sources */,
4EA61BEA1564F75000C759E4 /* CMISErrors.m in
Sources */,
5892CB75192CB5DF00C7734A /* CMISLinkRelations.m
in Sources */,
+ 5892CC1B192CE23F00C7734A /* CMISReachability.m
in Sources */,
752067F6156AC06300231A5D /* CMISExtensionData.m
in Sources */,
5892CBF9192CB83800C7734A /*
CMISBroswerFormDataWriter.m in Sources */,
752067FB156AC0FE00231A5D /*
CMISExtensionElement.m in Sources */,
@@ -1367,6 +1383,7 @@
isa = XCBuildConfiguration;
buildSettings = {
ARCHS = "$(ARCHS_STANDARD_INCLUDING_64_BIT)";
+ CLANG_ENABLE_MODULES = YES;
DSTROOT = /tmp/ObjectiveCMIS.dst;
GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER =
"ObjectiveCMIS/ObjectiveCMIS-Prefix.pch";
@@ -1383,6 +1400,7 @@
isa = XCBuildConfiguration;
buildSettings = {
ARCHS = "$(ARCHS_STANDARD_INCLUDING_64_BIT)";
+ CLANG_ENABLE_MODULES = YES;
DSTROOT = /tmp/ObjectiveCMIS.dst;
GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER =
"ObjectiveCMIS/ObjectiveCMIS-Prefix.pch";
@@ -1399,6 +1417,7 @@
isa = XCBuildConfiguration;
buildSettings = {
ARCHS = "$(ARCHS_STANDARD_INCLUDING_64_BIT)";
+ CLANG_ENABLE_MODULES = NO;
FRAMEWORK_SEARCH_PATHS = (
"$(SDKROOT)/Developer/Library/Frameworks",
"$(inherited)",
@@ -1414,6 +1433,7 @@
isa = XCBuildConfiguration;
buildSettings = {
ARCHS = "$(ARCHS_STANDARD_INCLUDING_64_BIT)";
+ CLANG_ENABLE_MODULES = NO;
FRAMEWORK_SEARCH_PATHS = (
"$(SDKROOT)/Developer/Library/Frameworks",
"$(inherited)",
Modified: chemistry/objectivecmis/trunk/ObjectiveCMIS/Common/CMISErrors.h
URL:
http://svn.apache.org/viewvc/chemistry/objectivecmis/trunk/ObjectiveCMIS/Common/CMISErrors.h?rev=1596896&r1=1596895&r2=1596896&view=diff
==============================================================================
--- chemistry/objectivecmis/trunk/ObjectiveCMIS/Common/CMISErrors.h (original)
+++ chemistry/objectivecmis/trunk/ObjectiveCMIS/Common/CMISErrors.h Thu May 22
15:04:26 2014
@@ -33,7 +33,7 @@ typedef NS_ENUM(NSInteger, CMISErrorCode
kCMISErrorCodeBasicMaximum = 255,
//basic CMIS errors
- kCMISErrorCodeNoReturn = 0,
+ kCMISErrorCodeUnknown = 0,
kCMISErrorCodeConnection = 1,
kCMISErrorCodeProxyAuthentication = 2,
kCMISErrorCodeUnauthorized = 3,
@@ -41,6 +41,7 @@ typedef NS_ENUM(NSInteger, CMISErrorCode
kCMISErrorCodeNoRepositoryFound = 5,
kCMISErrorCodeCancelled = 6,
kCMISErrorCodeParsingFailed = 7,
+ kCMISErrorCodeNoNetworkConnection = 8,
//error ranges for General errors
kCMISErrorCodeGeneralMinimum = 256,
@@ -74,7 +75,7 @@ typedef NS_ENUM(NSInteger, CMISErrorCode
extern NSString * const kCMISErrorDomainName;
//to be used in the userInfo dictionary as Localized error description
//Basic Errors
-extern NSString * const kCMISErrorDescriptionNoReturn;
+extern NSString * const kCMISErrorDescriptionUnknown;
extern NSString * const kCMISErrorDescriptionConnection;
extern NSString * const kCMISErrorDescriptionProxyAuthentication;
extern NSString * const kCMISErrorDescriptionUnauthorized;
@@ -82,6 +83,7 @@ extern NSString * const kCMISErrorDescri
extern NSString * const kCMISErrorDescriptionRepositoryNotFound;
extern NSString * const kCMISErrorDescriptionCancelled;
extern NSString * const kCMISErrorDescriptionParsingFailed;
+extern NSString * const kCMISErrorDescriptionNoNetworkConnection;
//General errors as defined in 2.2.1.4.1 of spec
extern NSString * const kCMISErrorDescriptionInvalidArgument;
extern NSString * const kCMISErrorDescriptionObjectNotFound;
Modified: chemistry/objectivecmis/trunk/ObjectiveCMIS/Common/CMISErrors.m
URL:
http://svn.apache.org/viewvc/chemistry/objectivecmis/trunk/ObjectiveCMIS/Common/CMISErrors.m?rev=1596896&r1=1596895&r2=1596896&view=diff
==============================================================================
--- chemistry/objectivecmis/trunk/ObjectiveCMIS/Common/CMISErrors.m (original)
+++ chemistry/objectivecmis/trunk/ObjectiveCMIS/Common/CMISErrors.m Thu May 22
15:04:26 2014
@@ -30,7 +30,7 @@ NSString * const kCMISErrorDomainName =
*/
//Basic Errors
-NSString * const kCMISErrorDescriptionNoReturn = @"Unknown Error";
+NSString * const kCMISErrorDescriptionUnknown = @"Unknown Error";
NSString * const kCMISErrorDescriptionConnection = @"Connection Error";
NSString * const kCMISErrorDescriptionProxyAuthentication = @"Proxy
Authentication Error";
NSString * const kCMISErrorDescriptionUnauthorized = @"Unauthorized access
error";
@@ -38,6 +38,7 @@ NSString * const kCMISErrorDescriptionNo
NSString * const kCMISErrorDescriptionRepositoryNotFound = @"Repository Not
Found Error";
NSString * const kCMISErrorDescriptionCancelled = @"Operation Cancelled";
NSString * const kCMISErrorDescriptionParsingFailed = @"Parsing Failed";
+NSString * const kCMISErrorDescriptionNoNetworkConnection = @"No Network
Connection";
//General errors as defined in 2.2.1.4.1 of spec
NSString * const kCMISErrorDescriptionInvalidArgument = @"Invalid Argument
Error";
@@ -90,8 +91,8 @@ NSString * const kCMISErrorDescriptionVe
+ (NSString *)localizedDescriptionForCode:(CMISErrorCodes)code
{
switch (code) {
- case kCMISErrorCodeNoReturn:
- return kCMISErrorDescriptionNoReturn;
+ case kCMISErrorCodeUnknown:
+ return kCMISErrorDescriptionUnknown;
case kCMISErrorCodeConnection:
return kCMISErrorDescriptionConnection;
case kCMISErrorCodeProxyAuthentication:
@@ -106,6 +107,8 @@ NSString * const kCMISErrorDescriptionVe
return kCMISErrorDescriptionCancelled;
case kCMISErrorCodeParsingFailed:
return kCMISErrorDescriptionParsingFailed;
+ case kCMISErrorCodeNoNetworkConnection:
+ return kCMISErrorDescriptionNoNetworkConnection;
case kCMISErrorCodeInvalidArgument:
return kCMISErrorDescriptionInvalidArgument;
case kCMISErrorCodeObjectNotFound:
@@ -133,7 +136,7 @@ NSString * const kCMISErrorDescriptionVe
case kCMISErrorCodeVersioning:
return kCMISErrorDescriptionVersioning;
default:
- return kCMISErrorDescriptionNoReturn;
+ return kCMISErrorDescriptionUnknown;
}
}
Modified: chemistry/objectivecmis/trunk/ObjectiveCMIS/Utils/CMISHttpRequest.m
URL:
http://svn.apache.org/viewvc/chemistry/objectivecmis/trunk/ObjectiveCMIS/Utils/CMISHttpRequest.m?rev=1596896&r1=1596895&r2=1596896&view=diff
==============================================================================
--- chemistry/objectivecmis/trunk/ObjectiveCMIS/Utils/CMISHttpRequest.m
(original)
+++ chemistry/objectivecmis/trunk/ObjectiveCMIS/Utils/CMISHttpRequest.m Thu May
22 15:04:26 2014
@@ -21,6 +21,7 @@
#import "CMISHttpResponse.h"
#import "CMISErrors.h"
#import "CMISLog.h"
+#import "CMISReachability.h"
//Exception names as returned in the <!--exception> tag
NSString * const kCMISExceptionInvalidArgument = @"invalidArgument";
@@ -76,6 +77,8 @@ NSString * const kCMISExceptionVersionin
- (BOOL)startRequest:(NSMutableURLRequest*)urlRequest
{
+ BOOL startedRequest = NO;
+
if (self.requestBody) {
if ([CMISLog sharedInstance].logLevel == CMISLogLevelTrace) {
CMISLogTrace(@"Request body: %@", [[NSString alloc]
initWithData:self.requestBody encoding:NSUTF8StringEncoding]);
@@ -93,18 +96,25 @@ NSString * const kCMISExceptionVersionin
}];
self.connection = [[NSURLConnection alloc] initWithRequest:urlRequest
delegate:self startImmediately:NO];
- if (self.connection) {
+ CMISReachability *reachability = [CMISReachability networkReachability];
+
+ if (self.connection && reachability.hasNetworkConnection) {
[self.connection scheduleInRunLoop:[NSRunLoop currentRunLoop]
forMode:NSRunLoopCommonModes];
[self.connection start];
- return YES;
- } else {
+ startedRequest = YES;
+ } else if (!reachability.hasNetworkConnection) {
+ NSError *noConnectionError = [CMISErrors
createCMISErrorWithCode:kCMISErrorCodeNoNetworkConnection
detailedDescription:kCMISErrorDescriptionNoNetworkConnection];
+ [self connection:self.connection didFailWithError:noConnectionError];
+ }
+ else {
if (self.completionBlock) {
NSString *detailedDescription = [NSString stringWithFormat:@"Could
not create connection to %@", urlRequest.URL];
NSError *cmisError = [CMISErrors
createCMISErrorWithCode:kCMISErrorCodeConnection
detailedDescription:detailedDescription];
self.completionBlock(nil, cmisError);
}
- return NO;
}
+
+ return startedRequest;
}
- (void)cancel
@@ -163,7 +173,15 @@ NSString * const kCMISExceptionVersionin
[self.authenticationProvider updateWithHttpURLResponse:self.response];
if (self.completionBlock) {
- CMISErrorCodes cmisErrorCode = (error.code == NSURLErrorCancelled) ?
kCMISErrorCodeCancelled : kCMISErrorCodeConnection;
+ CMISErrorCodes cmisErrorCode = kCMISErrorCodeConnection;
+
+ // swap error code if necessary
+ if (error.code == NSURLErrorCancelled) {
+ cmisErrorCode = kCMISErrorCodeCancelled;
+ } else if (error.code == kCMISErrorCodeNoNetworkConnection) {
+ cmisErrorCode = kCMISErrorCodeNoNetworkConnection;
+ }
+
NSError *cmisError = [CMISErrors cmisError:error
cmisErrorCode:cmisErrorCode];
self.completionBlock(nil, cmisError);
}
Added: chemistry/objectivecmis/trunk/ObjectiveCMIS/Utils/CMISReachability.h
URL:
http://svn.apache.org/viewvc/chemistry/objectivecmis/trunk/ObjectiveCMIS/Utils/CMISReachability.h?rev=1596896&view=auto
==============================================================================
--- chemistry/objectivecmis/trunk/ObjectiveCMIS/Utils/CMISReachability.h (added)
+++ chemistry/objectivecmis/trunk/ObjectiveCMIS/Utils/CMISReachability.h Thu
May 22 15:04:26 2014
@@ -0,0 +1,28 @@
+/*
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+ */
+
+#import <Foundation/Foundation.h>
+
+@interface CMISReachability : NSObject
+
+@property (nonatomic, assign, readonly, getter = hasNetworkConnection) BOOL
networkConnection;
+
++ (instancetype)networkReachability;
+
+@end
Added: chemistry/objectivecmis/trunk/ObjectiveCMIS/Utils/CMISReachability.m
URL:
http://svn.apache.org/viewvc/chemistry/objectivecmis/trunk/ObjectiveCMIS/Utils/CMISReachability.m?rev=1596896&view=auto
==============================================================================
--- chemistry/objectivecmis/trunk/ObjectiveCMIS/Utils/CMISReachability.m (added)
+++ chemistry/objectivecmis/trunk/ObjectiveCMIS/Utils/CMISReachability.m Thu
May 22 15:04:26 2014
@@ -0,0 +1,144 @@
+/*
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+ */
+
+#import "CMISReachability.h"
+#import <netinet/in.h>
+#import "CMISLog.h"
+
+@import SystemConfiguration;
+
+static CMISReachability *networkReachability = NULL;
+
+@interface CMISReachability ()
+
+@property (nonatomic, assign) SCNetworkReachabilityRef networkReachabilityRef;
+
+@end
+
+@implementation CMISReachability
+
++ (instancetype)networkReachability
+{
+ if (networkReachability == NULL)
+ {
+ struct sockaddr_in zeroAddress;
+ bzero(&zeroAddress, sizeof(zeroAddress));
+ zeroAddress.sin_len = sizeof(zeroAddress);
+ zeroAddress.sin_family = AF_INET;
+ networkReachability = [self reachabilityWithAddress:&zeroAddress];
+ SCNetworkReachabilityFlags currentFlags = 0;
+ if
(SCNetworkReachabilityGetFlags(networkReachability->_networkReachabilityRef,
¤tFlags))
+ {
+ handleFlags(currentFlags);
+ }
+ }
+ return networkReachability;
+}
+
+- (void)dealloc
+{
+ [self stopNotifier];
+ if (self.networkReachabilityRef != NULL)
+ {
+ CFRelease(self.networkReachabilityRef);
+ }
+}
+
+#pragma mark - Private Functions
+
+static void ReachabilityChangedCallback(SCNetworkReachabilityRef target,
SCNetworkReachabilityFlags flags, void * info)
+{
+ handleFlags(flags);
+}
+
+void handleFlags(SCNetworkReachabilityFlags flags)
+{
+ // At the moment we only care if we have network access
+#if TARGET_OS_IPHONE
+ BOOL reachable = (flags & kSCNetworkReachabilityFlagsReachable) || (flags
& kSCNetworkReachabilityFlagsIsWWAN);
+#elif TARGET_OS_MAC
+ BOOL reachable = (flags & kSCNetworkReachabilityFlagsReachable);
+#endif
+
+ BOOL connected = !(flags & kSCNetworkReachabilityFlagsConnectionRequired);
+
+ if (reachable && connected)
+ {
+ networkReachability->_networkConnection = YES;
+ }
+ else
+ {
+ networkReachability->_networkConnection = NO;
+ }
+
+ if ([CMISLog sharedInstance].logLevel == CMISLogLevelDebug)
+ {
+ CMISLogDebug(@"Network reachable: %@", (reachable && connected) ?
@"YES" : @"NO");
+ }
+}
+
++ (instancetype)reachabilityWithAddress:(const struct sockaddr_in
*)hostAddress;
+{
+ CMISReachability *returnReachability = NULL;
+
+ SCNetworkReachabilityRef reachability =
SCNetworkReachabilityCreateWithAddress(kCFAllocatorDefault, (const struct
sockaddr *)hostAddress);
+
+ if (reachability != NULL)
+ {
+ returnReachability = [[self alloc] init];
+ if (returnReachability != NULL)
+ {
+ returnReachability.networkReachabilityRef = reachability;
+ [returnReachability startNotifier];
+ }
+ }
+
+ return returnReachability;
+}
+
+- (BOOL)startNotifier
+{
+ BOOL started = NO;
+
+ SCNetworkReachabilityContext context = {0, (__bridge void *)(self), NULL,
NULL, NULL};
+
+ if (SCNetworkReachabilitySetCallback(self.networkReachabilityRef,
ReachabilityChangedCallback, &context))
+ {
+ if
(SCNetworkReachabilityScheduleWithRunLoop(self.networkReachabilityRef,
CFRunLoopGetCurrent(), kCFRunLoopDefaultMode))
+ {
+ started = YES;
+ }
+ }
+
+ return started;
+}
+
+- (BOOL)stopNotifier
+{
+ BOOL stopped = NO;
+
+ if (self.networkReachabilityRef != NULL)
+ {
+
SCNetworkReachabilityUnscheduleFromRunLoop(self.networkReachabilityRef,
CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
+ }
+
+ return stopped;
+}
+
+@end