status_bar 0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (60) hide show
  1. checksums.yaml +15 -0
  2. data/.gitignore +14 -0
  3. data/Gemfile +10 -0
  4. data/Gemfile.lock +51 -0
  5. data/Guardfile +12 -0
  6. data/README.md +66 -0
  7. data/Rakefile +28 -0
  8. data/app/app_delegate.rb +10 -0
  9. data/app/controllers/demo_controller.rb +51 -0
  10. data/app/styles/demo_style.rb +88 -0
  11. data/lib/project/base.rb +101 -0
  12. data/lib/project/helper.rb +60 -0
  13. data/lib/project/style.rb +87 -0
  14. data/lib/project/view.rb +38 -0
  15. data/lib/resources/error.png +0 -0
  16. data/lib/resources/error@2x.png +0 -0
  17. data/lib/resources/success.png +0 -0
  18. data/lib/resources/success@2x.png +0 -0
  19. data/lib/status_bar.rb +37 -0
  20. data/resources/Default-568h@2x.png +0 -0
  21. data/resources/error.png +0 -0
  22. data/resources/error@2x.png +0 -0
  23. data/resources/success.png +0 -0
  24. data/resources/success@2x.png +0 -0
  25. data/screenshots/activity.png +0 -0
  26. data/screenshots/error.png +0 -0
  27. data/screenshots/notice.png +0 -0
  28. data/screenshots/success.png +0 -0
  29. data/spec/app_delegate_spec.rb +15 -0
  30. data/spec/demo_controller_spec.rb +52 -0
  31. data/status_bar.gemspec +24 -0
  32. data/vendor/Podfile.lock +10 -0
  33. data/vendor/Pods/.build/libPods-Reachability.a +0 -0
  34. data/vendor/Pods/.build/libPods.a +0 -0
  35. data/vendor/Pods/BuildHeaders/Reachability/Reachability.h +109 -0
  36. data/vendor/Pods/Headers/Reachability/Reachability.h +109 -0
  37. data/vendor/Pods/Headers/____Pods-Reachability-prefix.h +5 -0
  38. data/vendor/Pods/Headers/____Pods-environment.h +14 -0
  39. data/vendor/Pods/Manifest.lock +10 -0
  40. data/vendor/Pods/Pods-Reachability-Private.xcconfig +5 -0
  41. data/vendor/Pods/Pods-Reachability-dummy.m +5 -0
  42. data/vendor/Pods/Pods-Reachability-prefix.pch +5 -0
  43. data/vendor/Pods/Pods-Reachability.xcconfig +1 -0
  44. data/vendor/Pods/Pods-acknowledgements.markdown +17 -0
  45. data/vendor/Pods/Pods-acknowledgements.plist +47 -0
  46. data/vendor/Pods/Pods-dummy.m +5 -0
  47. data/vendor/Pods/Pods-environment.h +14 -0
  48. data/vendor/Pods/Pods-resources.sh +55 -0
  49. data/vendor/Pods/Pods.bridgesupport +100 -0
  50. data/vendor/Pods/Pods.xcconfig +4 -0
  51. data/vendor/Pods/Pods.xcodeproj/project.pbxproj +960 -0
  52. data/vendor/Pods/Pods.xcodeproj/xcuserdata/holgersindbaek.xcuserdatad/xcschemes/Pods-Reachability.xcscheme +59 -0
  53. data/vendor/Pods/Pods.xcodeproj/xcuserdata/holgersindbaek.xcuserdatad/xcschemes/Pods.xcscheme +59 -0
  54. data/vendor/Pods/Pods.xcodeproj/xcuserdata/holgersindbaek.xcuserdatad/xcschemes/xcschememanagement.plist +21 -0
  55. data/vendor/Pods/Reachability/LICENCE.txt +24 -0
  56. data/vendor/Pods/Reachability/README.md +65 -0
  57. data/vendor/Pods/Reachability/Reachability.h +109 -0
  58. data/vendor/Pods/Reachability/Reachability.m +527 -0
  59. data/vendor/Pods/build-iPhoneSimulator/libPods.a +0 -0
  60. metadata +175 -0
@@ -0,0 +1,59 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <Scheme
3
+ LastUpgradeVersion = "0500"
4
+ version = "1.3">
5
+ <BuildAction
6
+ parallelizeBuildables = "YES"
7
+ buildImplicitDependencies = "YES">
8
+ <BuildActionEntries>
9
+ <BuildActionEntry
10
+ buildForTesting = "YES"
11
+ buildForRunning = "YES"
12
+ buildForProfiling = "YES"
13
+ buildForArchiving = "YES"
14
+ buildForAnalyzing = "YES">
15
+ <BuildableReference
16
+ BuildableIdentifier = "primary"
17
+ BlueprintIdentifier = "C9BFAE48CD614704B2368B7C"
18
+ BuildableName = "libPods-Reachability.a"
19
+ BlueprintName = "Pods-Reachability"
20
+ ReferencedContainer = "container:Pods.xcodeproj">
21
+ </BuildableReference>
22
+ </BuildActionEntry>
23
+ </BuildActionEntries>
24
+ </BuildAction>
25
+ <TestAction
26
+ selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
27
+ selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
28
+ shouldUseLaunchSchemeArgsEnv = "YES"
29
+ buildConfiguration = "Debug">
30
+ <Testables>
31
+ </Testables>
32
+ </TestAction>
33
+ <LaunchAction
34
+ selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
35
+ selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
36
+ launchStyle = "0"
37
+ useCustomWorkingDirectory = "NO"
38
+ buildConfiguration = "Debug"
39
+ ignoresPersistentStateOnLaunch = "NO"
40
+ debugDocumentVersioning = "YES"
41
+ allowLocationSimulation = "YES">
42
+ <AdditionalOptions>
43
+ </AdditionalOptions>
44
+ </LaunchAction>
45
+ <ProfileAction
46
+ shouldUseLaunchSchemeArgsEnv = "YES"
47
+ savedToolIdentifier = ""
48
+ useCustomWorkingDirectory = "NO"
49
+ buildConfiguration = "Release"
50
+ debugDocumentVersioning = "YES">
51
+ </ProfileAction>
52
+ <AnalyzeAction
53
+ buildConfiguration = "Debug">
54
+ </AnalyzeAction>
55
+ <ArchiveAction
56
+ buildConfiguration = "Release"
57
+ revealArchiveInOrganizer = "YES">
58
+ </ArchiveAction>
59
+ </Scheme>
@@ -0,0 +1,59 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <Scheme
3
+ LastUpgradeVersion = "0500"
4
+ version = "1.3">
5
+ <BuildAction
6
+ parallelizeBuildables = "YES"
7
+ buildImplicitDependencies = "YES">
8
+ <BuildActionEntries>
9
+ <BuildActionEntry
10
+ buildForTesting = "YES"
11
+ buildForRunning = "YES"
12
+ buildForProfiling = "YES"
13
+ buildForArchiving = "YES"
14
+ buildForAnalyzing = "YES">
15
+ <BuildableReference
16
+ BuildableIdentifier = "primary"
17
+ BlueprintIdentifier = "0124EC28896A46DEA29298AF"
18
+ BuildableName = "libPods.a"
19
+ BlueprintName = "Pods"
20
+ ReferencedContainer = "container:Pods.xcodeproj">
21
+ </BuildableReference>
22
+ </BuildActionEntry>
23
+ </BuildActionEntries>
24
+ </BuildAction>
25
+ <TestAction
26
+ selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
27
+ selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
28
+ shouldUseLaunchSchemeArgsEnv = "YES"
29
+ buildConfiguration = "Debug">
30
+ <Testables>
31
+ </Testables>
32
+ </TestAction>
33
+ <LaunchAction
34
+ selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
35
+ selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
36
+ launchStyle = "0"
37
+ useCustomWorkingDirectory = "NO"
38
+ buildConfiguration = "Debug"
39
+ ignoresPersistentStateOnLaunch = "NO"
40
+ debugDocumentVersioning = "YES"
41
+ allowLocationSimulation = "YES">
42
+ <AdditionalOptions>
43
+ </AdditionalOptions>
44
+ </LaunchAction>
45
+ <ProfileAction
46
+ shouldUseLaunchSchemeArgsEnv = "YES"
47
+ savedToolIdentifier = ""
48
+ useCustomWorkingDirectory = "NO"
49
+ buildConfiguration = "Release"
50
+ debugDocumentVersioning = "YES">
51
+ </ProfileAction>
52
+ <AnalyzeAction
53
+ buildConfiguration = "Debug">
54
+ </AnalyzeAction>
55
+ <ArchiveAction
56
+ buildConfiguration = "Release"
57
+ revealArchiveInOrganizer = "YES">
58
+ </ArchiveAction>
59
+ </Scheme>
@@ -0,0 +1,21 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3
+ <plist version="1.0">
4
+ <dict>
5
+ <key>SchemeUserState</key>
6
+ <dict>
7
+ <key>Pods-Reachability.xcscheme</key>
8
+ <dict>
9
+ <key>isShown</key>
10
+ <false/>
11
+ </dict>
12
+ <key>Pods.xcscheme</key>
13
+ <dict>
14
+ <key>isShown</key>
15
+ <false/>
16
+ </dict>
17
+ </dict>
18
+ <key>SuppressBuildableAutocreation</key>
19
+ <dict/>
20
+ </dict>
21
+ </plist>
@@ -0,0 +1,24 @@
1
+ Copyright (c) 2011-2013, Tony Million.
2
+ All rights reserved.
3
+
4
+ Redistribution and use in source and binary forms, with or without
5
+ modification, are permitted provided that the following conditions are met:
6
+
7
+ 1. Redistributions of source code must retain the above copyright notice, this
8
+ list of conditions and the following disclaimer.
9
+
10
+ 2. Redistributions in binary form must reproduce the above copyright notice,
11
+ this list of conditions and the following disclaimer in the documentation
12
+ and/or other materials provided with the distribution.
13
+
14
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
15
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
18
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
19
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
20
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
22
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
23
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
24
+ POSSIBILITY OF SUCH DAMAGE.
@@ -0,0 +1,65 @@
1
+ # Reachability
2
+
3
+ This is a drop-in replacement for Apple's `Reachability` class. It is ARC-compatible, and it uses the new GCD methods to notify of network interface changes.
4
+
5
+ In addition to the standard `NSNotification`, it supports the use of blocks for when the network becomes reachable and unreachable.
6
+
7
+ Finally, you can specify whether a WWAN connection is considered "reachable".
8
+
9
+ ## Requirements
10
+
11
+ Once you have added the `.h/m` files to your project, simply:
12
+
13
+ * Go to the `Project->TARGETS->Build Phases->Link Binary With Libraries`.
14
+ * Press the plus in the lower left of the list.
15
+ * Add `SystemConfiguration.framework`.
16
+
17
+ Boom, you're done.
18
+
19
+ ## Examples
20
+
21
+ ### Block Example
22
+
23
+ This sample uses blocks to notify when the interface state has changed. The blocks will be called on a **BACKGROUND THREAD**, so you need to dispatch UI updates onto the main thread.
24
+
25
+ // Allocate a reachability object
26
+ Reachability* reach = [Reachability reachabilityWithHostname:@"www.google.com"];
27
+
28
+ // Set the blocks
29
+ reach.reachableBlock = ^(Reachability*reach)
30
+ {
31
+ NSLog(@"REACHABLE!");
32
+ };
33
+
34
+ reach.unreachableBlock = ^(Reachability*reach)
35
+ {
36
+ NSLog(@"UNREACHABLE!");
37
+ };
38
+
39
+ // Start the notifier, which will cause the reachability object to retain itself!
40
+ [reach startNotifier];
41
+
42
+ ### `NSNotification` Example
43
+
44
+ This sample will use `NSNotification`s to notify when the interface has changed. They will be delivered on the **MAIN THREAD**, so you *can* do UI updates from within the function.
45
+
46
+ In addition, it asks the `Reachability` object to consider the WWAN (3G/EDGE/CDMA) as a non-reachable connection (you might use this if you are writing a video streaming app, for example, to save the user's data plan).
47
+
48
+ // Allocate a reachability object
49
+ Reachability* reach = [Reachability reachabilityWithHostname:@"www.google.com"];
50
+
51
+ // Tell the reachability that we DON'T want to be reachable on 3G/EDGE/CDMA
52
+ reach.reachableOnWWAN = NO;
53
+
54
+ // Here we set up a NSNotification observer. The Reachability that caused the notification
55
+ // is passed in the object parameter
56
+ [[NSNotificationCenter defaultCenter] addObserver:self
57
+ selector:@selector(reachabilityChanged:)
58
+ name:kReachabilityChangedNotification
59
+ object:nil];
60
+
61
+ [reach startNotifier]
62
+
63
+ ## Tell the world
64
+
65
+ Head over to [Projects using Reachability](https://github.com/tonymillion/Reachability/wiki/Projects-using-Reachability) and add your project for "Maximum Wins!".
@@ -0,0 +1,109 @@
1
+ /*
2
+ Copyright (c) 2011, Tony Million.
3
+ All rights reserved.
4
+
5
+ Redistribution and use in source and binary forms, with or without
6
+ modification, are permitted provided that the following conditions are met:
7
+
8
+ 1. Redistributions of source code must retain the above copyright notice, this
9
+ list of conditions and the following disclaimer.
10
+
11
+ 2. Redistributions in binary form must reproduce the above copyright notice,
12
+ this list of conditions and the following disclaimer in the documentation
13
+ and/or other materials provided with the distribution.
14
+
15
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
19
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25
+ POSSIBILITY OF SUCH DAMAGE.
26
+ */
27
+
28
+ #import <Foundation/Foundation.h>
29
+ #import <SystemConfiguration/SystemConfiguration.h>
30
+
31
+ #import <sys/socket.h>
32
+ #import <netinet/in.h>
33
+ #import <netinet6/in6.h>
34
+ #import <arpa/inet.h>
35
+ #import <ifaddrs.h>
36
+ #import <netdb.h>
37
+
38
+ /**
39
+ * Does ARC support GCD objects?
40
+ * It does if the minimum deployment target is iOS 6+ or Mac OS X 8+
41
+ *
42
+ * @see http://opensource.apple.com/source/libdispatch/libdispatch-228.18/os/object.h
43
+ **/
44
+ #if OS_OBJECT_USE_OBJC
45
+ #define NEEDS_DISPATCH_RETAIN_RELEASE 0
46
+ #else
47
+ #define NEEDS_DISPATCH_RETAIN_RELEASE 1
48
+ #endif
49
+
50
+ /**
51
+ * Create NS_ENUM macro if it does not exist on the targeted version of iOS or OS X.
52
+ *
53
+ * @see http://nshipster.com/ns_enum-ns_options/
54
+ **/
55
+ #ifndef NS_ENUM
56
+ #define NS_ENUM(_type, _name) enum _name : _type _name; enum _name : _type
57
+ #endif
58
+
59
+ extern NSString *const kReachabilityChangedNotification;
60
+
61
+ typedef NS_ENUM(NSInteger, NetworkStatus) {
62
+ // Apple NetworkStatus Compatible Names.
63
+ NotReachable = 0,
64
+ ReachableViaWiFi = 2,
65
+ ReachableViaWWAN = 1
66
+ };
67
+
68
+ @class Reachability;
69
+
70
+ typedef void (^NetworkReachable)(Reachability * reachability);
71
+ typedef void (^NetworkUnreachable)(Reachability * reachability);
72
+
73
+ @interface Reachability : NSObject
74
+
75
+ @property (nonatomic, copy) NetworkReachable reachableBlock;
76
+ @property (nonatomic, copy) NetworkUnreachable unreachableBlock;
77
+
78
+
79
+ @property (nonatomic, assign) BOOL reachableOnWWAN;
80
+
81
+ +(Reachability*)reachabilityWithHostname:(NSString*)hostname;
82
+ +(Reachability*)reachabilityForInternetConnection;
83
+ +(Reachability*)reachabilityWithAddress:(const struct sockaddr_in*)hostAddress;
84
+ +(Reachability*)reachabilityForLocalWiFi;
85
+
86
+ -(Reachability *)initWithReachabilityRef:(SCNetworkReachabilityRef)ref;
87
+
88
+ -(BOOL)startNotifier;
89
+ -(void)stopNotifier;
90
+
91
+ -(BOOL)isReachable;
92
+ -(BOOL)isReachableViaWWAN;
93
+ -(BOOL)isReachableViaWiFi;
94
+
95
+ // WWAN may be available, but not active until a connection has been established.
96
+ // WiFi may require a connection for VPN on Demand.
97
+ -(BOOL)isConnectionRequired; // Identical DDG variant.
98
+ -(BOOL)connectionRequired; // Apple's routine.
99
+ // Dynamic, on demand connection?
100
+ -(BOOL)isConnectionOnDemand;
101
+ // Is user intervention required?
102
+ -(BOOL)isInterventionRequired;
103
+
104
+ -(NetworkStatus)currentReachabilityStatus;
105
+ -(SCNetworkReachabilityFlags)reachabilityFlags;
106
+ -(NSString*)currentReachabilityString;
107
+ -(NSString*)currentReachabilityFlags;
108
+
109
+ @end
@@ -0,0 +1,527 @@
1
+ /*
2
+ Copyright (c) 2011, Tony Million.
3
+ All rights reserved.
4
+
5
+ Redistribution and use in source and binary forms, with or without
6
+ modification, are permitted provided that the following conditions are met:
7
+
8
+ 1. Redistributions of source code must retain the above copyright notice, this
9
+ list of conditions and the following disclaimer.
10
+
11
+ 2. Redistributions in binary form must reproduce the above copyright notice,
12
+ this list of conditions and the following disclaimer in the documentation
13
+ and/or other materials provided with the distribution.
14
+
15
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
19
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25
+ POSSIBILITY OF SUCH DAMAGE.
26
+ */
27
+
28
+ #import "Reachability.h"
29
+
30
+
31
+ NSString *const kReachabilityChangedNotification = @"kReachabilityChangedNotification";
32
+
33
+ @interface Reachability ()
34
+
35
+ @property (nonatomic, assign) SCNetworkReachabilityRef reachabilityRef;
36
+
37
+
38
+ #if NEEDS_DISPATCH_RETAIN_RELEASE
39
+ @property (nonatomic, assign) dispatch_queue_t reachabilitySerialQueue;
40
+ #else
41
+ @property (nonatomic, strong) dispatch_queue_t reachabilitySerialQueue;
42
+ #endif
43
+
44
+
45
+ @property (nonatomic, strong) id reachabilityObject;
46
+
47
+ -(void)reachabilityChanged:(SCNetworkReachabilityFlags)flags;
48
+ -(BOOL)isReachableWithFlags:(SCNetworkReachabilityFlags)flags;
49
+
50
+ @end
51
+
52
+ static NSString *reachabilityFlags(SCNetworkReachabilityFlags flags)
53
+ {
54
+ return [NSString stringWithFormat:@"%c%c %c%c%c%c%c%c%c",
55
+ #if TARGET_OS_IPHONE
56
+ (flags & kSCNetworkReachabilityFlagsIsWWAN) ? 'W' : '-',
57
+ #else
58
+ 'X',
59
+ #endif
60
+ (flags & kSCNetworkReachabilityFlagsReachable) ? 'R' : '-',
61
+ (flags & kSCNetworkReachabilityFlagsConnectionRequired) ? 'c' : '-',
62
+ (flags & kSCNetworkReachabilityFlagsTransientConnection) ? 't' : '-',
63
+ (flags & kSCNetworkReachabilityFlagsInterventionRequired) ? 'i' : '-',
64
+ (flags & kSCNetworkReachabilityFlagsConnectionOnTraffic) ? 'C' : '-',
65
+ (flags & kSCNetworkReachabilityFlagsConnectionOnDemand) ? 'D' : '-',
66
+ (flags & kSCNetworkReachabilityFlagsIsLocalAddress) ? 'l' : '-',
67
+ (flags & kSCNetworkReachabilityFlagsIsDirect) ? 'd' : '-'];
68
+ }
69
+
70
+ // Start listening for reachability notifications on the current run loop
71
+ static void TMReachabilityCallback(SCNetworkReachabilityRef target, SCNetworkReachabilityFlags flags, void* info)
72
+ {
73
+ #pragma unused (target)
74
+ #if __has_feature(objc_arc)
75
+ Reachability *reachability = ((__bridge Reachability*)info);
76
+ #else
77
+ Reachability *reachability = ((Reachability*)info);
78
+ #endif
79
+
80
+ // We probably don't need an autoreleasepool here, as GCD docs state each queue has its own autorelease pool,
81
+ // but what the heck eh?
82
+ @autoreleasepool
83
+ {
84
+ [reachability reachabilityChanged:flags];
85
+ }
86
+ }
87
+
88
+
89
+ @implementation Reachability
90
+
91
+ @synthesize reachabilityRef;
92
+ @synthesize reachabilitySerialQueue;
93
+
94
+ @synthesize reachableOnWWAN;
95
+
96
+ @synthesize reachableBlock;
97
+ @synthesize unreachableBlock;
98
+
99
+ @synthesize reachabilityObject;
100
+
101
+ #pragma mark - Class Constructor Methods
102
+
103
+ +(Reachability*)reachabilityWithHostName:(NSString*)hostname
104
+ {
105
+ return [Reachability reachabilityWithHostname:hostname];
106
+ }
107
+
108
+ +(Reachability*)reachabilityWithHostname:(NSString*)hostname
109
+ {
110
+ SCNetworkReachabilityRef ref = SCNetworkReachabilityCreateWithName(NULL, [hostname UTF8String]);
111
+ if (ref)
112
+ {
113
+ id reachability = [[self alloc] initWithReachabilityRef:ref];
114
+
115
+ #if __has_feature(objc_arc)
116
+ return reachability;
117
+ #else
118
+ return [reachability autorelease];
119
+ #endif
120
+
121
+ }
122
+
123
+ return nil;
124
+ }
125
+
126
+ +(Reachability *)reachabilityWithAddress:(const struct sockaddr_in *)hostAddress
127
+ {
128
+ SCNetworkReachabilityRef ref = SCNetworkReachabilityCreateWithAddress(kCFAllocatorDefault, (const struct sockaddr*)hostAddress);
129
+ if (ref)
130
+ {
131
+ id reachability = [[self alloc] initWithReachabilityRef:ref];
132
+
133
+ #if __has_feature(objc_arc)
134
+ return reachability;
135
+ #else
136
+ return [reachability autorelease];
137
+ #endif
138
+ }
139
+
140
+ return nil;
141
+ }
142
+
143
+ +(Reachability *)reachabilityForInternetConnection
144
+ {
145
+ struct sockaddr_in zeroAddress;
146
+ bzero(&zeroAddress, sizeof(zeroAddress));
147
+ zeroAddress.sin_len = sizeof(zeroAddress);
148
+ zeroAddress.sin_family = AF_INET;
149
+
150
+ return [self reachabilityWithAddress:&zeroAddress];
151
+ }
152
+
153
+ +(Reachability*)reachabilityForLocalWiFi
154
+ {
155
+ struct sockaddr_in localWifiAddress;
156
+ bzero(&localWifiAddress, sizeof(localWifiAddress));
157
+ localWifiAddress.sin_len = sizeof(localWifiAddress);
158
+ localWifiAddress.sin_family = AF_INET;
159
+ // IN_LINKLOCALNETNUM is defined in <netinet/in.h> as 169.254.0.0
160
+ localWifiAddress.sin_addr.s_addr = htonl(IN_LINKLOCALNETNUM);
161
+
162
+ return [self reachabilityWithAddress:&localWifiAddress];
163
+ }
164
+
165
+
166
+ // Initialization methods
167
+
168
+ -(Reachability *)initWithReachabilityRef:(SCNetworkReachabilityRef)ref
169
+ {
170
+ self = [super init];
171
+ if (self != nil)
172
+ {
173
+ self.reachableOnWWAN = YES;
174
+ self.reachabilityRef = ref;
175
+ }
176
+
177
+ return self;
178
+ }
179
+
180
+ -(void)dealloc
181
+ {
182
+ [self stopNotifier];
183
+
184
+ if(self.reachabilityRef)
185
+ {
186
+ CFRelease(self.reachabilityRef);
187
+ self.reachabilityRef = nil;
188
+ }
189
+
190
+ self.reachableBlock = nil;
191
+ self.unreachableBlock = nil;
192
+
193
+ #if !(__has_feature(objc_arc))
194
+ [super dealloc];
195
+ #endif
196
+
197
+
198
+ }
199
+
200
+ #pragma mark - Notifier Methods
201
+
202
+ // Notifier
203
+ // NOTE: This uses GCD to trigger the blocks - they *WILL NOT* be called on THE MAIN THREAD
204
+ // - In other words DO NOT DO ANY UI UPDATES IN THE BLOCKS.
205
+ // INSTEAD USE dispatch_async(dispatch_get_main_queue(), ^{UISTUFF}) (or dispatch_sync if you want)
206
+
207
+ -(BOOL)startNotifier
208
+ {
209
+ SCNetworkReachabilityContext context = { 0, NULL, NULL, NULL, NULL };
210
+
211
+ // this should do a retain on ourself, so as long as we're in notifier mode we shouldn't disappear out from under ourselves
212
+ // woah
213
+ self.reachabilityObject = self;
214
+
215
+
216
+
217
+ // First, we need to create a serial queue.
218
+ // We allocate this once for the lifetime of the notifier.
219
+ self.reachabilitySerialQueue = dispatch_queue_create("com.tonymillion.reachability", NULL);
220
+ if(!self.reachabilitySerialQueue)
221
+ {
222
+ return NO;
223
+ }
224
+
225
+ #if __has_feature(objc_arc)
226
+ context.info = (__bridge void *)self;
227
+ #else
228
+ context.info = (void *)self;
229
+ #endif
230
+
231
+ if (!SCNetworkReachabilitySetCallback(self.reachabilityRef, TMReachabilityCallback, &context))
232
+ {
233
+ #ifdef DEBUG
234
+ NSLog(@"SCNetworkReachabilitySetCallback() failed: %s", SCErrorString(SCError()));
235
+ #endif
236
+
237
+ // Clear out the dispatch queue
238
+ if(self.reachabilitySerialQueue)
239
+ {
240
+ #if NEEDS_DISPATCH_RETAIN_RELEASE
241
+ dispatch_release(self.reachabilitySerialQueue);
242
+ #endif
243
+ self.reachabilitySerialQueue = nil;
244
+ }
245
+
246
+ self.reachabilityObject = nil;
247
+
248
+ return NO;
249
+ }
250
+
251
+ // Set it as our reachability queue, which will retain the queue
252
+ if(!SCNetworkReachabilitySetDispatchQueue(self.reachabilityRef, self.reachabilitySerialQueue))
253
+ {
254
+ #ifdef DEBUG
255
+ NSLog(@"SCNetworkReachabilitySetDispatchQueue() failed: %s", SCErrorString(SCError()));
256
+ #endif
257
+
258
+ // UH OH - FAILURE!
259
+
260
+ // First stop, any callbacks!
261
+ SCNetworkReachabilitySetCallback(self.reachabilityRef, NULL, NULL);
262
+
263
+ // Then clear out the dispatch queue.
264
+ if(self.reachabilitySerialQueue)
265
+ {
266
+ #if NEEDS_DISPATCH_RETAIN_RELEASE
267
+ dispatch_release(self.reachabilitySerialQueue);
268
+ #endif
269
+ self.reachabilitySerialQueue = nil;
270
+ }
271
+
272
+ self.reachabilityObject = nil;
273
+
274
+ return NO;
275
+ }
276
+
277
+ return YES;
278
+ }
279
+
280
+ -(void)stopNotifier
281
+ {
282
+ // First stop, any callbacks!
283
+ SCNetworkReachabilitySetCallback(self.reachabilityRef, NULL, NULL);
284
+
285
+ // Unregister target from the GCD serial dispatch queue.
286
+ SCNetworkReachabilitySetDispatchQueue(self.reachabilityRef, NULL);
287
+
288
+ if(self.reachabilitySerialQueue)
289
+ {
290
+ #if NEEDS_DISPATCH_RETAIN_RELEASE
291
+ dispatch_release(self.reachabilitySerialQueue);
292
+ #endif
293
+ self.reachabilitySerialQueue = nil;
294
+ }
295
+
296
+ self.reachabilityObject = nil;
297
+ }
298
+
299
+ #pragma mark - reachability tests
300
+
301
+ // This is for the case where you flick the airplane mode;
302
+ // you end up getting something like this:
303
+ //Reachability: WR ct-----
304
+ //Reachability: -- -------
305
+ //Reachability: WR ct-----
306
+ //Reachability: -- -------
307
+ // We treat this as 4 UNREACHABLE triggers - really apple should do better than this
308
+
309
+ #define testcase (kSCNetworkReachabilityFlagsConnectionRequired | kSCNetworkReachabilityFlagsTransientConnection)
310
+
311
+ -(BOOL)isReachableWithFlags:(SCNetworkReachabilityFlags)flags
312
+ {
313
+ BOOL connectionUP = YES;
314
+
315
+ if(!(flags & kSCNetworkReachabilityFlagsReachable))
316
+ connectionUP = NO;
317
+
318
+ if( (flags & testcase) == testcase )
319
+ connectionUP = NO;
320
+
321
+ #if TARGET_OS_IPHONE
322
+ if(flags & kSCNetworkReachabilityFlagsIsWWAN)
323
+ {
324
+ // We're on 3G.
325
+ if(!self.reachableOnWWAN)
326
+ {
327
+ // We don't want to connect when on 3G.
328
+ connectionUP = NO;
329
+ }
330
+ }
331
+ #endif
332
+
333
+ return connectionUP;
334
+ }
335
+
336
+ -(BOOL)isReachable
337
+ {
338
+ SCNetworkReachabilityFlags flags;
339
+
340
+ if(!SCNetworkReachabilityGetFlags(self.reachabilityRef, &flags))
341
+ return NO;
342
+
343
+ return [self isReachableWithFlags:flags];
344
+ }
345
+
346
+ -(BOOL)isReachableViaWWAN
347
+ {
348
+ #if TARGET_OS_IPHONE
349
+
350
+ SCNetworkReachabilityFlags flags = 0;
351
+
352
+ if(SCNetworkReachabilityGetFlags(reachabilityRef, &flags))
353
+ {
354
+ // Check we're REACHABLE
355
+ if(flags & kSCNetworkReachabilityFlagsReachable)
356
+ {
357
+ // Now, check we're on WWAN
358
+ if(flags & kSCNetworkReachabilityFlagsIsWWAN)
359
+ {
360
+ return YES;
361
+ }
362
+ }
363
+ }
364
+ #endif
365
+
366
+ return NO;
367
+ }
368
+
369
+ -(BOOL)isReachableViaWiFi
370
+ {
371
+ SCNetworkReachabilityFlags flags = 0;
372
+
373
+ if(SCNetworkReachabilityGetFlags(reachabilityRef, &flags))
374
+ {
375
+ // Check we're reachable
376
+ if((flags & kSCNetworkReachabilityFlagsReachable))
377
+ {
378
+ #if TARGET_OS_IPHONE
379
+ // Check we're NOT on WWAN
380
+ if((flags & kSCNetworkReachabilityFlagsIsWWAN))
381
+ {
382
+ return NO;
383
+ }
384
+ #endif
385
+ return YES;
386
+ }
387
+ }
388
+
389
+ return NO;
390
+ }
391
+
392
+
393
+ // WWAN may be available, but not active until a connection has been established.
394
+ // WiFi may require a connection for VPN on Demand.
395
+ -(BOOL)isConnectionRequired
396
+ {
397
+ return [self connectionRequired];
398
+ }
399
+
400
+ -(BOOL)connectionRequired
401
+ {
402
+ SCNetworkReachabilityFlags flags;
403
+
404
+ if(SCNetworkReachabilityGetFlags(reachabilityRef, &flags))
405
+ {
406
+ return (flags & kSCNetworkReachabilityFlagsConnectionRequired);
407
+ }
408
+
409
+ return NO;
410
+ }
411
+
412
+ // Dynamic, on demand connection?
413
+ -(BOOL)isConnectionOnDemand
414
+ {
415
+ SCNetworkReachabilityFlags flags;
416
+
417
+ if (SCNetworkReachabilityGetFlags(reachabilityRef, &flags))
418
+ {
419
+ return ((flags & kSCNetworkReachabilityFlagsConnectionRequired) &&
420
+ (flags & (kSCNetworkReachabilityFlagsConnectionOnTraffic | kSCNetworkReachabilityFlagsConnectionOnDemand)));
421
+ }
422
+
423
+ return NO;
424
+ }
425
+
426
+ // Is user intervention required?
427
+ -(BOOL)isInterventionRequired
428
+ {
429
+ SCNetworkReachabilityFlags flags;
430
+
431
+ if (SCNetworkReachabilityGetFlags(reachabilityRef, &flags))
432
+ {
433
+ return ((flags & kSCNetworkReachabilityFlagsConnectionRequired) &&
434
+ (flags & kSCNetworkReachabilityFlagsInterventionRequired));
435
+ }
436
+
437
+ return NO;
438
+ }
439
+
440
+
441
+ #pragma mark - reachability status stuff
442
+
443
+ -(NetworkStatus)currentReachabilityStatus
444
+ {
445
+ if([self isReachable])
446
+ {
447
+ if([self isReachableViaWiFi])
448
+ return ReachableViaWiFi;
449
+
450
+ #if TARGET_OS_IPHONE
451
+ return ReachableViaWWAN;
452
+ #endif
453
+ }
454
+
455
+ return NotReachable;
456
+ }
457
+
458
+ -(SCNetworkReachabilityFlags)reachabilityFlags
459
+ {
460
+ SCNetworkReachabilityFlags flags = 0;
461
+
462
+ if(SCNetworkReachabilityGetFlags(reachabilityRef, &flags))
463
+ {
464
+ return flags;
465
+ }
466
+
467
+ return 0;
468
+ }
469
+
470
+ -(NSString*)currentReachabilityString
471
+ {
472
+ NetworkStatus temp = [self currentReachabilityStatus];
473
+
474
+ if(temp == reachableOnWWAN)
475
+ {
476
+ // Updated for the fact that we have CDMA phones now!
477
+ return NSLocalizedString(@"Cellular", @"");
478
+ }
479
+ if (temp == ReachableViaWiFi)
480
+ {
481
+ return NSLocalizedString(@"WiFi", @"");
482
+ }
483
+
484
+ return NSLocalizedString(@"No Connection", @"");
485
+ }
486
+
487
+ -(NSString*)currentReachabilityFlags
488
+ {
489
+ return reachabilityFlags([self reachabilityFlags]);
490
+ }
491
+
492
+ #pragma mark - Callback function calls this method
493
+
494
+ -(void)reachabilityChanged:(SCNetworkReachabilityFlags)flags
495
+ {
496
+ if([self isReachableWithFlags:flags])
497
+ {
498
+ if(self.reachableBlock)
499
+ {
500
+ self.reachableBlock(self);
501
+ }
502
+ }
503
+ else
504
+ {
505
+ if(self.unreachableBlock)
506
+ {
507
+ self.unreachableBlock(self);
508
+ }
509
+ }
510
+
511
+ // this makes sure the change notification happens on the MAIN THREAD
512
+ dispatch_async(dispatch_get_main_queue(), ^{
513
+ [[NSNotificationCenter defaultCenter] postNotificationName:kReachabilityChangedNotification
514
+ object:self];
515
+ });
516
+ }
517
+
518
+ #pragma mark - Debug Description
519
+
520
+ - (NSString *) description;
521
+ {
522
+ NSString *description = [NSString stringWithFormat:@"<%@: %#x>",
523
+ NSStringFromClass([self class]), (unsigned int) self];
524
+ return description;
525
+ }
526
+
527
+ @end