Skip to content
Browse files

Added wrapper around reachability for easier setup

  • Loading branch information...
1 parent c4024d8 commit c0d184204537b095e799e9787f7d16eaff74a499 @myell0w myell0w committed
Showing with 160 additions and 0 deletions.
  1. +8 −0 PSFoundation.xcodeproj/project.pbxproj
  2. +44 −0 Reachability/PSReachability.h
  3. +108 −0 Reachability/PSReachability.m
View
8 PSFoundation.xcodeproj/project.pbxproj
@@ -36,6 +36,8 @@
39C27BD713146056000C0C94 /* UIView+Animation.m in Sources */ = {isa = PBXBuildFile; fileRef = 39C27BD513146056000C0C94 /* UIView+Animation.m */; };
39C27C0F131469A1000C0C94 /* NSString+Truncation.h in Headers */ = {isa = PBXBuildFile; fileRef = 39C27C0D131469A1000C0C94 /* NSString+Truncation.h */; };
39C27C10131469A1000C0C94 /* NSString+Truncation.m in Sources */ = {isa = PBXBuildFile; fileRef = 39C27C0E131469A1000C0C94 /* NSString+Truncation.m */; };
+ 39C7950D13B5F445000AAB01 /* PSReachability.h in Headers */ = {isa = PBXBuildFile; fileRef = 39C7950B13B5F445000AAB01 /* PSReachability.h */; };
+ 39C7950E13B5F445000AAB01 /* PSReachability.m in Sources */ = {isa = PBXBuildFile; fileRef = 39C7950C13B5F445000AAB01 /* PSReachability.m */; };
39C917A4139832D10045489C /* NSManagedObject+MTSafeSetValuesForKeysWithDictionary.h in Headers */ = {isa = PBXBuildFile; fileRef = 39C917A2139832D10045489C /* NSManagedObject+MTSafeSetValuesForKeysWithDictionary.h */; };
39C917A5139832D10045489C /* NSManagedObject+MTSafeSetValuesForKeysWithDictionary.m in Sources */ = {isa = PBXBuildFile; fileRef = 39C917A3139832D10045489C /* NSManagedObject+MTSafeSetValuesForKeysWithDictionary.m */; };
39C918171398D7580045489C /* MTSplashScreen.h in Headers */ = {isa = PBXBuildFile; fileRef = 39C918151398D7580045489C /* MTSplashScreen.h */; };
@@ -613,6 +615,8 @@
39C27BD513146056000C0C94 /* UIView+Animation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "UIView+Animation.m"; path = "Categories/UIView/UIView+Animation.m"; sourceTree = SOURCE_ROOT; };
39C27C0D131469A1000C0C94 /* NSString+Truncation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "NSString+Truncation.h"; path = "Categories/NSString/NSString+Truncation.h"; sourceTree = SOURCE_ROOT; };
39C27C0E131469A1000C0C94 /* NSString+Truncation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "NSString+Truncation.m"; path = "Categories/NSString/NSString+Truncation.m"; sourceTree = SOURCE_ROOT; };
+ 39C7950B13B5F445000AAB01 /* PSReachability.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PSReachability.h; sourceTree = "<group>"; };
+ 39C7950C13B5F445000AAB01 /* PSReachability.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PSReachability.m; sourceTree = "<group>"; };
39C917A2139832D10045489C /* NSManagedObject+MTSafeSetValuesForKeysWithDictionary.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSManagedObject+MTSafeSetValuesForKeysWithDictionary.h"; sourceTree = "<group>"; };
39C917A3139832D10045489C /* NSManagedObject+MTSafeSetValuesForKeysWithDictionary.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSManagedObject+MTSafeSetValuesForKeysWithDictionary.m"; sourceTree = "<group>"; };
39C918151398D7580045489C /* MTSplashScreen.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MTSplashScreen.h; sourceTree = "<group>"; };
@@ -1225,6 +1229,8 @@
78692143126B4195000259AC /* Reachability */ = {
isa = PBXGroup;
children = (
+ 39C7950B13B5F445000AAB01 /* PSReachability.h */,
+ 39C7950C13B5F445000AAB01 /* PSReachability.m */,
78692144126B4195000259AC /* Reachability.h */,
78692145126B4195000259AC /* Reachability.m */,
);
@@ -2085,6 +2091,7 @@
39C9181A1398D7AC0045489C /* MTSplashScreenDelegate.h in Headers */,
39F258B31399587C0084A471 /* UIView+MTRotation.h in Headers */,
39DDF4D4139FE7CB000B76BD /* PSScrollContentView.h in Headers */,
+ 39C7950D13B5F445000AAB01 /* PSReachability.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -2516,6 +2523,7 @@
39C918181398D7580045489C /* MTSplashScreen.m in Sources */,
39F258B41399587C0084A471 /* UIView+MTRotation.m in Sources */,
39DDF4D5139FE7CB000B76BD /* PSScrollContentView.m in Sources */,
+ 39C7950E13B5F445000AAB01 /* PSReachability.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
View
44 Reachability/PSReachability.h
@@ -0,0 +1,44 @@
+//
+// PSReachability.h
+// WhereTU
+//
+// Created by Tretter Matthias on 25.06.11.
+// Copyright 2011 @myell0w. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+#import "Reachability.h"
+
+// we define our own notification to be more independent of Reachability
+#define kPSReachabilityChangedNotification @"kPSReachabilityChangedNotification"
+#define kPSNetworkStatusKey @"kPSNetworkStatusKey"
+
+
+/** Protocol for ViewController that are configured to use Reachability */
+@protocol PSReachabilityAware <NSObject>
+
+@optional
+- (void)configureForNetworkStatus:(NSNotification *)notification;
+
+@end
+
+/** Reachabilty Singleton instance */
+@interface PSReachability : NSObject {
+ Reachability *reachability_;
+ NetworkStatus currentNetworkStatus_;
+
+ NSString *hostAddress_;
+}
+
+@property (nonatomic, retain, readonly) Reachability *reachability;
+@property (nonatomic, assign, readonly) NetworkStatus currentNetworkStatus;
+@property (nonatomic, copy, readonly) NSString *hostAddress;
+
++ (PSReachability *)sharedPSReachability;
+
+- (void)startCheckingHostAddress:(NSString *)hostAddress;
+
+- (void)setupReachabilityFor:(id)object;
+- (void)shutdownReachabilityFor:(id)object;
+
+@end
View
108 Reachability/PSReachability.m
@@ -0,0 +1,108 @@
+//
+// PSReachability.m
+// WhereTU
+//
+// Created by Tretter Matthias on 25.06.11.
+// Copyright 2011 @myell0w. All rights reserved.
+//
+
+#import "PSReachability.h"
+#import "PSFoundation.h"
+
+@interface PSReachability ()
+
+@property (nonatomic, retain, readwrite) Reachability *reachability;
+@property (nonatomic, assign, readwrite) NetworkStatus currentNetworkStatus;
+@property (nonatomic, copy, readwrite) NSString *hostAddress;
+
+- (void)reachabilityChanged:(NSNotification *)note;
+
+@end
+
+@implementation PSReachability
+
+SYNTHESIZE_SINGLETON_FOR_CLASS(PSReachability);
+
+@synthesize reachability = reachability_;
+@synthesize currentNetworkStatus = currentNetworkStatus_;
+@synthesize hostAddress = hostAddress_;
+
+////////////////////////////////////////////////////////////////////////
+#pragma mark -
+#pragma mark Lifecycle
+////////////////////////////////////////////////////////////////////////
+
+- (void)dealloc {
+ [[NSNotificationCenter defaultCenter] removeObserver:self name:kReachabilityChangedNotification object:nil];
+ [reachability_ stopNotifier];
+ MCRelease(reachability_);
+ MCRelease(hostAddress_);
+
+ [super dealloc];
+}
+
+////////////////////////////////////////////////////////////////////////
+#pragma mark -
+#pragma mark Reachability
+////////////////////////////////////////////////////////////////////////
+
+- (void)startCheckingHostAddress:(NSString *)hostAddress {
+ self.hostAddress = hostAddress;
+
+ // Listen for reachability changes
+ [[NSNotificationCenter defaultCenter] addObserver:self
+ selector:@selector(reachabilityChanged:)
+ name:kReachabilityChangedNotification object:nil];
+
+ self.reachability = [Reachability reachabilityWithHostName:hostAddress];
+ self.currentNetworkStatus = self.reachability.currentReachabilityStatus;
+
+ // start continous updates
+ [self.reachability startNotifier];
+}
+
+- (void)setupReachabilityFor:(id)object {
+ if ([object respondsToSelector:@selector(configureForNetworkStatus:)]) {
+ // listen for PSReachability Notifications
+ [[NSNotificationCenter defaultCenter] addObserver:object
+ selector:@selector(configureForNetworkStatus:)
+ name:kPSReachabilityChangedNotification
+ object:self];
+
+ // perform initial setup
+ NSNotification *notification = [NSNotification notificationWithName:kPSReachabilityChangedNotification
+ object:self
+ userInfo:XDICT($I(self.currentNetworkStatus),kPSNetworkStatusKey)];
+ [object performSelector:@selector(configureForNetworkStatus:) withObject:notification];
+
+ DDLogVerbose(@"Object %@ was setup to use PSReachability", object);
+ } else {
+ DDLogVerbose(@"Object %@ isn't configured to use PSReachability", object);
+ }
+}
+
+- (void)shutdownReachabilityFor:(id)object {
+ if ([object respondsToSelector:@selector(configureForNetworkStatus:)]) {
+ [[NSNotificationCenter defaultCenter] removeObserver:object name:kPSReachabilityChangedNotification object:self];
+ }
+}
+
+- (void)reachabilityChanged:(NSNotification *)note {
+ // get Reachability instance from notification
+ Reachability* reachability = [note object];
+
+ // get current status
+ NetworkStatus newNetworkStatus = [reachability currentReachabilityStatus];
+
+ // if network status has changed, post notification
+ if (newNetworkStatus != self.currentNetworkStatus) {
+ self.currentNetworkStatus = newNetworkStatus;
+
+ [[NSNotificationCenter defaultCenter] postNotificationName:kPSReachabilityChangedNotification
+ object:self
+ userInfo:[NSDictionary dictionaryWithObject:[NSNumber numberWithInt:newNetworkStatus]
+ forKey:kPSNetworkStatusKey]];
+ }
+}
+
+@end

2 comments on commit c0d1842

@zwaldowski
Collaborator

While I really like what you're doing with this, what is the practical advantage of doing this? I might just be tired, but I'm not really seeing it (don't worry about that, you can just point it out and call me stupid and move on, haha). Plus, on the more pedantic side, I was going to use the PSReachability name so that our sorta-fork doesn't collide with people including their own.

@myell0w
Collaborator

No problem, could turn out you're completely right because I have never gotten around to use Reachability until that point so what I did might be unnecessary and there could be other ways I don't know of. The main reasons I did this are the following:
1) I wanted to follow the following scheme in each viewcontroller, where reachability is neccessary:
-) setup in viewDidLoad, depending on current reachability status
-) get notified whenever reachability changes and react on it
I found the iterated test [Reachability currentReachabilityStatus] a bit slow, so I came up with a Singleton design where this test has to be done only once
2) I wanted to get independent of the actual Reachability implementation since it's no official API and is therefore not guaranteed to stay the same. By implementing a wrapper around Reachability we gain a bit flexibility although I have to admit that I didn't fully abstract from Reachability, since I use the defined NetworkStates e.g.
3) I wanted this to be as easy as possible and found that there was a lot of duplicated code when using Reachability directly in each viewController. So I came up with this solution and in combination with PSBaseViewController from the app template the only thing I have to do in each viewController is to write a method configureForNetworkStatus: and reachability gets set up

Please sign in to comment.
Something went wrong with that request. Please try again.