فهرست منبع

Merge branch 'develop'

Ashley Mills 10 سال پیش
والد
کامیت
0266016b74

+ 39 - 2
Reachability.xcodeproj/project.pbxproj

@@ -13,10 +13,35 @@
 		AA7344981BE76820008AFE69 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = AA7344961BE76820008AFE69 /* Main.storyboard */; };
 		AA73449A1BE76820008AFE69 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = AA7344991BE76820008AFE69 /* Assets.xcassets */; };
 		AA7344B11BE76862008AFE69 /* Reachability.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA7344B01BE76862008AFE69 /* Reachability.swift */; };
-		AA7344B21BE76959008AFE69 /* Reachability.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AA7344721BE7678B008AFE69 /* Reachability.framework */; };
 		AA7344B51BE769D6008AFE69 /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = AA7344B31BE769D6008AFE69 /* LaunchScreen.xib */; };
+		CAC230C51BF2180000F6464E /* Reachability.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AA7344721BE7678B008AFE69 /* Reachability.framework */; };
+		CAC230C61BF2180000F6464E /* Reachability.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = AA7344721BE7678B008AFE69 /* Reachability.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
 /* End PBXBuildFile section */
 
+/* Begin PBXContainerItemProxy section */
+		CAC230C71BF2180000F6464E /* PBXContainerItemProxy */ = {
+			isa = PBXContainerItemProxy;
+			containerPortal = AA7344691BE7678B008AFE69 /* Project object */;
+			proxyType = 1;
+			remoteGlobalIDString = AA7344711BE7678B008AFE69;
+			remoteInfo = Reachability;
+		};
+/* End PBXContainerItemProxy section */
+
+/* Begin PBXCopyFilesBuildPhase section */
+		CAC230C91BF2180100F6464E /* Embed Frameworks */ = {
+			isa = PBXCopyFilesBuildPhase;
+			buildActionMask = 2147483647;
+			dstPath = "";
+			dstSubfolderSpec = 10;
+			files = (
+				CAC230C61BF2180000F6464E /* Reachability.framework in Embed Frameworks */,
+			);
+			name = "Embed Frameworks";
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+/* End PBXCopyFilesBuildPhase section */
+
 /* Begin PBXFileReference section */
 		AA7344721BE7678B008AFE69 /* Reachability.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Reachability.framework; sourceTree = BUILT_PRODUCTS_DIR; };
 		AA7344751BE7678B008AFE69 /* Reachability.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Reachability.h; sourceTree = "<group>"; };
@@ -43,7 +68,7 @@
 			isa = PBXFrameworksBuildPhase;
 			buildActionMask = 2147483647;
 			files = (
-				AA7344B21BE76959008AFE69 /* Reachability.framework in Frameworks */,
+				CAC230C51BF2180000F6464E /* Reachability.framework in Frameworks */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
@@ -130,10 +155,12 @@
 				AA73448C1BE76820008AFE69 /* Sources */,
 				AA73448D1BE76820008AFE69 /* Frameworks */,
 				AA73448E1BE76820008AFE69 /* Resources */,
+				CAC230C91BF2180100F6464E /* Embed Frameworks */,
 			);
 			buildRules = (
 			);
 			dependencies = (
+				CAC230C81BF2180000F6464E /* PBXTargetDependency */,
 			);
 			name = ReachabilitySample;
 			productName = ReachabilitySample;
@@ -217,6 +244,14 @@
 		};
 /* End PBXSourcesBuildPhase section */
 
+/* Begin PBXTargetDependency section */
+		CAC230C81BF2180000F6464E /* PBXTargetDependency */ = {
+			isa = PBXTargetDependency;
+			target = AA7344711BE7678B008AFE69 /* Reachability */;
+			targetProxy = CAC230C71BF2180000F6464E /* PBXContainerItemProxy */;
+		};
+/* End PBXTargetDependency section */
+
 /* Begin PBXVariantGroup section */
 		AA7344961BE76820008AFE69 /* Main.storyboard */ = {
 			isa = PBXVariantGroup;
@@ -367,6 +402,7 @@
 			isa = XCBuildConfiguration;
 			buildSettings = {
 				ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+				EMBEDDED_CONTENT_CONTAINS_SWIFT = YES;
 				INFOPLIST_FILE = ReachabilitySample/Info.plist;
 				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
 				PRODUCT_BUNDLE_IDENTIFIER = uk.co.joylordsystems.ReachabilitySample;
@@ -378,6 +414,7 @@
 			isa = XCBuildConfiguration;
 			buildSettings = {
 				ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+				EMBEDDED_CONTENT_CONTAINS_SWIFT = YES;
 				INFOPLIST_FILE = ReachabilitySample/Info.plist;
 				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
 				PRODUCT_BUNDLE_IDENTIFIER = uk.co.joylordsystems.ReachabilitySample;

+ 65 - 90
Reachability/Reachability.swift

@@ -25,6 +25,8 @@ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 POSSIBILITY OF SUCH DAMAGE.
 */
 
+// Reachability.swift version 2.2beta2
+
 import SystemConfiguration
 import Foundation
 
@@ -68,7 +70,6 @@ public class Reachability: NSObject {
     }
 
     // MARK: - *** Public properties ***
-
     public var whenReachable: NetworkReachable?
     public var whenUnreachable: NetworkUnreachable?
     public var reachableOnWWAN: Bool
@@ -83,7 +84,6 @@ public class Reachability: NSObject {
                 return .ReachableViaWWAN
             }
         }
-
         return .NotReachable
     }
 
@@ -91,6 +91,8 @@ public class Reachability: NSObject {
         return "\(currentReachabilityStatus)"
     }
 
+    private var previousFlags: SCNetworkReachabilityFlags?
+    
     // MARK: - *** Initialisation methods ***
     
     required public init(reachabilityRef: SCNetworkReachability) {
@@ -139,7 +141,7 @@ public class Reachability: NSObject {
     // MARK: - *** Notifier methods ***
     public func startNotifier() throws {
 
-        if notifierRunning { return }
+        guard !notifierRunning else { return }
         
         var context = SCNetworkReachabilityContext(version: 0, info: nil, retain: nil, release: nil, copyDescription: nil)
         context.info = UnsafeMutablePointer(Unmanaged.passUnretained(self).toOpaque())
@@ -154,77 +156,70 @@ public class Reachability: NSObject {
             throw ReachabilityError.UnableToSetDispatchQueue
         }
 
+        // Perform an intial check
+        let flags = reachabilityFlags
+        reachabilityChanged(flags)
+        
         notifierRunning = true
     }
-    
 
     public func stopNotifier() {
-        if let reachabilityRef = reachabilityRef {
-            SCNetworkReachabilitySetCallback(reachabilityRef, nil, nil)
-            SCNetworkReachabilitySetDispatchQueue(reachabilityRef, nil)
-        }
-        notifierRunning = false
-    }
+        defer { notifierRunning = false }
+        guard let reachabilityRef = reachabilityRef else { return }
 
+        SCNetworkReachabilitySetCallback(reachabilityRef, nil, nil)
+        SCNetworkReachabilitySetDispatchQueue(reachabilityRef, nil)
+    }
+    
     // MARK: - *** Connection test methods ***
     public func isReachable() -> Bool {
-        return isReachableWithTest({ (flags: SCNetworkReachabilityFlags) -> (Bool) in
-            return self.isReachableWithFlags(flags)
-        })
+        let flags = reachabilityFlags
+        return isReachableWithFlags(flags)
     }
 
     public func isReachableViaWWAN() -> Bool {
-
-        if isRunningOnDevice {
-            return isReachableWithTest() { flags -> Bool in
-                // Check we're REACHABLE
-                if self.isReachable(flags) {
-
-                    // Now, check we're on WWAN
-                    if self.isOnWWAN(flags) {
-                        return true
-                    }
-                }
-                return false
-            }
-        }
-        return false
+        
+        let flags = reachabilityFlags
+        
+        // Check we're not on the simulator, we're REACHABLE and check we're on WWAN
+        return isRunningOnDevice && isReachable(flags) && isOnWWAN(flags)
     }
 
     public func isReachableViaWiFi() -> Bool {
-
-        return isReachableWithTest() { flags -> Bool in
-
-            // Check we're reachable
-            if self.isReachable(flags) {
-
-                if self.isRunningOnDevice {
-                    // Check we're NOT on WWAN
-                    if self.isOnWWAN(flags) {
-                        return false
-                    }
-                }
-                return true
-            }
-
+        
+        let flags = reachabilityFlags
+        
+        // Check we're reachable
+        if !isReachable(flags) {
             return false
         }
+        
+        // Must be on WiFi if reachable but not on an iOS device (i.e. simulator)
+        if !isRunningOnDevice {
+            return true
+        }
+        
+        // Check we're NOT on WWAN
+        return !isOnWWAN(flags)
     }
 
     // MARK: - *** Private methods ***
     private var isRunningOnDevice: Bool = {
         #if (arch(i386) || arch(x86_64)) && os(iOS)
             return false
-            #else
+        #else
             return true
         #endif
-        }()
+    }()
 
     private var notifierRunning = false
     private var reachabilityRef: SCNetworkReachability?
     private let reachabilitySerialQueue = dispatch_queue_create("uk.co.ashleymills.reachability", DISPATCH_QUEUE_SERIAL)
 
     private func reachabilityChanged(flags: SCNetworkReachabilityFlags) {
+        
+        guard previousFlags != flags else { return }
+        
         if isReachableWithFlags(flags) {
             if let block = whenReachable {
                 block(self)
@@ -236,47 +231,30 @@ public class Reachability: NSObject {
         }
 
         notificationCenter.postNotificationName(ReachabilityChangedNotification, object:self)
+
+        previousFlags = flags
     }
 
     private func isReachableWithFlags(flags: SCNetworkReachabilityFlags) -> Bool {
 
-        let reachable = isReachable(flags)
-
-        if !reachable {
+        if !isReachable(flags) {
             return false
         }
-
+        
         if isConnectionRequiredOrTransient(flags) {
             return false
         }
-
+        
         if isRunningOnDevice {
             if isOnWWAN(flags) && !reachableOnWWAN {
                 // We don't want to connect when on 3G.
                 return false
             }
         }
-
+        
         return true
     }
-
-    private func isReachableWithTest(test: (SCNetworkReachabilityFlags) -> (Bool)) -> Bool {
-
-        if let reachabilityRef = reachabilityRef {
-            
-            var flags = SCNetworkReachabilityFlags(rawValue: 0)
-            let gotFlags = withUnsafeMutablePointer(&flags) {
-                SCNetworkReachabilityGetFlags(reachabilityRef, UnsafeMutablePointer($0))
-            }
-            
-            if gotFlags {
-                return test(flags)
-            }
-        }
-
-        return false
-    }
-
+    
     // WWAN may be available, but not active until a connection has been established.
     // WiFi may require a connection for VPN on Demand.
     private func isConnectionRequired() -> Bool {
@@ -284,23 +262,20 @@ public class Reachability: NSObject {
     }
 
     private func connectionRequired() -> Bool {
-        return isReachableWithTest({ (flags: SCNetworkReachabilityFlags) -> (Bool) in
-            return self.isConnectionRequired(flags)
-        })
+        let flags = reachabilityFlags
+        return isConnectionRequired(flags)
     }
 
     // Dynamic, on demand connection?
     private func isConnectionOnDemand() -> Bool {
-        return isReachableWithTest({ (flags: SCNetworkReachabilityFlags) -> (Bool) in
-            return self.isConnectionRequired(flags) && self.isConnectionOnTrafficOrDemand(flags)
-        })
+        let flags = reachabilityFlags
+        return isConnectionRequired(flags) && isConnectionOnTrafficOrDemand(flags)
     }
 
     // Is user intervention required?
     private func isInterventionRequired() -> Bool {
-        return isReachableWithTest({ (flags: SCNetworkReachabilityFlags) -> (Bool) in
-            return self.isConnectionRequired(flags) && self.isInterventionRequired(flags)
-        })
+        let flags = reachabilityFlags
+        return isConnectionRequired(flags) && isInterventionRequired(flags)
     }
 
     private func isOnWWAN(flags: SCNetworkReachabilityFlags) -> Bool {
@@ -343,19 +318,19 @@ public class Reachability: NSObject {
     }
 
     private var reachabilityFlags: SCNetworkReachabilityFlags {
-        if let reachabilityRef = reachabilityRef {
-            
-            var flags = SCNetworkReachabilityFlags(rawValue: 0)
-            let gotFlags = withUnsafeMutablePointer(&flags) {
-                SCNetworkReachabilityGetFlags(reachabilityRef, UnsafeMutablePointer($0))
-            }
-            
-            if gotFlags {
-                return flags
-            }
+        
+        guard let reachabilityRef = reachabilityRef else { return SCNetworkReachabilityFlags() }
+        
+        var flags = SCNetworkReachabilityFlags()
+        let gotFlags = withUnsafeMutablePointer(&flags) {
+            SCNetworkReachabilityGetFlags(reachabilityRef, UnsafeMutablePointer($0))
+        }
+        
+        if gotFlags {
+            return flags
+        } else {
+            return SCNetworkReachabilityFlags()
         }
-
-        return []
     }
 
     override public var description: String {

+ 16 - 0
ReachabilitySample/Base.lproj/Main.storyboard

@@ -25,16 +25,32 @@
                                 <color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
                                 <nil key="highlightedColor"/>
                             </label>
+                            <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="5EE-X2-pKr">
+                                <rect key="frame" x="275.5" y="242" width="49" height="24"/>
+                                <animations/>
+                                <fontDescription key="fontDescription" type="system" pointSize="20"/>
+                                <color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
+                                <nil key="highlightedColor"/>
+                            </label>
                         </subviews>
                         <animations/>
                         <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
                         <constraints>
+                            <constraint firstItem="UBQ-2c-x8L" firstAttribute="top" secondItem="5EE-X2-pKr" secondAttribute="bottom" constant="8" symbolic="YES" id="CuO-ho-b10"/>
                             <constraint firstAttribute="centerY" secondItem="UBQ-2c-x8L" secondAttribute="centerY" id="K7q-cv-Lfi"/>
+                            <constraint firstItem="5EE-X2-pKr" firstAttribute="centerX" secondItem="UBQ-2c-x8L" secondAttribute="centerX" id="MZr-wz-ELn"/>
                             <constraint firstItem="UBQ-2c-x8L" firstAttribute="leading" secondItem="8bC-Xf-vdC" secondAttribute="leadingMargin" constant="20" id="YBI-sa-7Z9"/>
+                            <constraint firstItem="5EE-X2-pKr" firstAttribute="top" secondItem="y3c-jy-aDJ" secondAttribute="bottom" constant="225" id="pMO-lY-Wq8"/>
                             <constraint firstAttribute="trailingMargin" secondItem="UBQ-2c-x8L" secondAttribute="trailing" constant="20" id="xcC-HE-ZUz"/>
                         </constraints>
+                        <variation key="default">
+                            <mask key="constraints">
+                                <exclude reference="pMO-lY-Wq8"/>
+                            </mask>
+                        </variation>
                     </view>
                     <connections>
+                        <outlet property="hostNameLabel" destination="5EE-X2-pKr" id="qt8-ZE-mUg"/>
                         <outlet property="networkStatus" destination="UBQ-2c-x8L" id="vop-Uf-5Ev"/>
                     </connections>
                 </viewController>

+ 1 - 1
ReachabilitySample/Info.plist

@@ -15,7 +15,7 @@
 	<key>CFBundlePackageType</key>
 	<string>APPL</string>
 	<key>CFBundleShortVersionString</key>
-	<string>2.1-beta1</string>
+	<string>2.2-beta2</string>
 	<key>CFBundleSignature</key>
 	<string>????</string>
 	<key>CFBundleVersion</key>

+ 37 - 19
ReachabilitySample/ViewController.swift

@@ -9,19 +9,37 @@
 import UIKit
 import Reachability
 
-let useClosures = false
-
 class ViewController: UIViewController {
 
     @IBOutlet weak var networkStatus: UILabel!
+    @IBOutlet weak var hostNameLabel: UILabel!
     
     var reachability: Reachability?
     
     override func viewDidLoad() {
         super.viewDidLoad()
 
+        // Start reachability without a hostname intially
+        setupReachability(useHostName: false, useClosures: true)
+        startNotifier()
+
+        // After 5 seconds, stop and re-start reachability, this time using a hostname
+        let dispatchTime = dispatch_time(DISPATCH_TIME_NOW, Int64(UInt64(5) * NSEC_PER_SEC))
+        dispatch_after(dispatchTime, dispatch_get_main_queue()) {
+            self.stopNotifier()
+            self.setupReachability(useHostName: true, useClosures: true)
+            self.startNotifier()
+        }
+    }
+    
+    func setupReachability(useHostName useHostName: Bool, useClosures: Bool) {
+        let hostName = "google.com"
+        hostNameLabel.text = useHostName ? hostName : "No host name"
+        
+        print("--- set up with host name: \(hostNameLabel.text!)")
+
         do {
-            let reachability = try Reachability.reachabilityForInternetConnection()
+            let reachability = try useHostName ? Reachability(hostname: hostName) : Reachability.reachabilityForInternetConnection()
             self.reachability = reachability
         } catch ReachabilityError.FailedToCreateWithAddress(let address) {
             networkStatus.textColor = UIColor.redColor()
@@ -39,7 +57,10 @@ class ViewController: UIViewController {
         } else {
             NSNotificationCenter.defaultCenter().addObserver(self, selector: "reachabilityChanged:", name: ReachabilityChangedNotification, object: reachability)
         }
-        
+    }
+    
+    func startNotifier() {
+        print("--- start notifier")
         do {
             try reachability?.startNotifier()
         } catch {
@@ -47,27 +68,17 @@ class ViewController: UIViewController {
             networkStatus.text = "Unable to start\nnotifier"
             return
         }
-        
-        // Initial reachability check
-        if let reachability = reachability {
-            if reachability.isReachable() {
-                updateLabelColourWhenReachable(reachability)
-            } else {
-                updateLabelColourWhenNotReachable(reachability)
-            }
-        }
     }
     
-    deinit {
-
+    func stopNotifier() {
+        print("--- stop notifier")
         reachability?.stopNotifier()
-        
-        if (!useClosures) {
-            NSNotificationCenter.defaultCenter().removeObserver(self, name: ReachabilityChangedNotification, object: nil)
-        }
+        NSNotificationCenter.defaultCenter().removeObserver(self, name: ReachabilityChangedNotification, object: nil)
+        reachability = nil
     }
     
     func updateLabelColourWhenReachable(reachability: Reachability) {
+        print("\(reachability.description) - \(reachability.currentReachabilityString)")
         if reachability.isReachableViaWiFi() {
             self.networkStatus.textColor = UIColor.greenColor()
         } else {
@@ -78,6 +89,8 @@ class ViewController: UIViewController {
     }
 
     func updateLabelColourWhenNotReachable(reachability: Reachability) {
+        print("\(reachability.description) - \(reachability.currentReachabilityString)")
+
         self.networkStatus.textColor = UIColor.redColor()
         
         self.networkStatus.text = reachability.currentReachabilityString
@@ -93,6 +106,11 @@ class ViewController: UIViewController {
             updateLabelColourWhenNotReachable(reachability)
         }
     }
+    
+    deinit {
+        stopNotifier()
+    }
+
 }