Skip to content

Commit

Permalink
Reworked reachability initialization to support usage when there is n…
Browse files Browse the repository at this point in the history
…o Internet connectivity.

* When the reachabilityObserver property of RKClient is nil, assume we have reachability
* When the baseURL configured contains an IP address or localhost, use hostname based reachability
* Else fall through to using Internet reachability if the user has not configured an observer directly
  • Loading branch information
blakewatters committed Nov 9, 2011
1 parent dad00a4 commit fd80eae
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 4 deletions.
19 changes: 15 additions & 4 deletions Code/Network/RKClient.m
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#import "../Support/RKAlert.h"
#import "../Support/RKLog.h"
#import "../Support/RKPathMatcher.h"
#import "../Support/NSString+RestKit.h"

// Set Logging Component
#undef RKLogComponent
Expand Down Expand Up @@ -128,7 +129,6 @@ - (id)init {

// Configure reachability and queue
[self addObserver:self forKeyPath:@"reachabilityObserver" options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld context:nil];
self.reachabilityObserver = [RKReachabilityObserver reachabilityObserverForInternet];
self.requestQueue = [RKRequestQueue requestQueue];

[self addObserver:self forKeyPath:@"baseURL" options:NSKeyValueObservingOptionNew context:nil];
Expand Down Expand Up @@ -187,7 +187,7 @@ - (NSString *)cachePath {
}

- (BOOL)isNetworkReachable {
BOOL isNetworkReachable = NO;
BOOL isNetworkReachable = YES;
if (self.reachabilityObserver) {
isNetworkReachable = [self.reachabilityObserver isNetworkReachable];
}
Expand Down Expand Up @@ -277,14 +277,25 @@ - (void)reachabilityObserverDidChange:(NSDictionary *)change {
}

- (void)baseURLDidChange:(NSDictionary *)change {
NSString *newBaseURL = [change objectForKey:NSKeyValueChangeNewKey];
NSString *newBaseURLString = [change objectForKey:NSKeyValueChangeNewKey];

// Don't crash if baseURL is nil'd out (i.e. dealloc)
if (! [newBaseURL isEqual:[NSNull null]]) {
if (! [newBaseURLString isEqual:[NSNull null]]) {
// Configure a cache for the new base URL
[_requestCache release];
_requestCache = [[RKRequestCache alloc] initWithCachePath:[self cachePath]
storagePolicy:RKRequestCacheStoragePolicyPermanently];

// Determine reachability strategy (if user has not already done so)
if (self.reachabilityObserver == nil) {
NSURL *newBaseURL = [NSURL URLWithString:newBaseURLString];
NSString *hostName = [newBaseURL host];
if ([newBaseURLString isEqualToString:@"localhost"] || [hostName isIPAddress]) {
self.reachabilityObserver = [RKReachabilityObserver reachabilityObserverForHost:hostName];
} else {
self.reachabilityObserver = [RKReachabilityObserver reachabilityObserverForInternet];
}
}
}
}

Expand Down
8 changes: 8 additions & 0 deletions Code/Support/NSString+RestKit.h
Original file line number Diff line number Diff line change
Expand Up @@ -117,4 +117,12 @@
*/
- (NSString *)MIMETypeForPathExtension;

/**
Returns YES if the receiver contains a valid IP address
For example, @"127.0.0.1" and @"10.0.1.35" would return YES
while @"restkit.org" would return NO
*/
- (BOOL)isIPAddress;

@end
9 changes: 9 additions & 0 deletions Code/Support/NSString+RestKit.m
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@
#import "NSString+RestKit.h"
#import "../Network/RKClient.h"
#import "RKFixCategoryBug.h"
#include <netdb.h>
#include <arpa/inet.h>

RK_FIX_CATEGORY_BUG(NSString_RestKit)

Expand Down Expand Up @@ -132,4 +134,11 @@ - (NSString *)MIMETypeForPathExtension {
return nil;
}

- (BOOL)isIPAddress {
struct sockaddr_in sa;
char *hostNameOrIPAddressCString = (char *) [self UTF8String];
int result = inet_pton(AF_INET, hostNameOrIPAddressCString, &(sa.sin_addr));
return (result != 0);
}

@end
7 changes: 7 additions & 0 deletions Specs/Support/NSStringRestKitSpec.m
Original file line number Diff line number Diff line change
Expand Up @@ -75,4 +75,11 @@ - (void)itShouldReturnTheMIMETypeForAPath {
assertThat(MIMEType, is(equalTo(@"application/xml")));
}

- (void)itShouldKnowIfTheReceiverContainsAnIPAddress {
assertThatBool([@"127.0.0.1" isIPAddress], equalToBool(YES));
assertThatBool([@"173.45.234.197" isIPAddress], equalToBool(YES));
assertThatBool([@"google.com" isIPAddress], equalToBool(NO));
assertThatBool([@"just some random text" isIPAddress], equalToBool(NO));
}

@end

0 comments on commit fd80eae

Please sign in to comment.