IOS-1469 move reachability to pEpIOSToolbook IOS-1469
authorAlejandro Gelos <agp@pep.security>
Mon, 18 Mar 2019 11:12:42 +0100
branchIOS-1469
changeset 8016c7c6910a6614
parent 8015 6de02130d308
child 8019 159aee7fd2c5
IOS-1469 move reachability to pEpIOSToolbook
pEpForiOS.xcodeproj/project.pbxproj
pEpForiOS/Util/Reachability/NetworkReachability.swift
pEpForiOS/Util/Reachability/NetworkReachabilityProtocol.swift
pEpForiOS/Util/Reachability/ReachabilityUtils.swift
pEpForiOS/Util/Reachability/ReachabilityUtilsProtocol.swift
pEpForiOSTests/TestUtils/ReachabilityUtilsTest/NetworkReachibilityMock.swift
pEpForiOSTests/TestUtils/ReachabilityUtilsTest/ReachabilityUtilsTests.swift
subModules/pEpIOSToolbox/pEpIOSToolbox.xcodeproj/project.pbxproj
subModules/pEpIOSToolbox/pEpIOSToolbox/Other/Reachability/NetworkReachability.swift
subModules/pEpIOSToolbox/pEpIOSToolbox/Other/Reachability/NetworkReachabilityProtocol.swift
subModules/pEpIOSToolbox/pEpIOSToolbox/Other/Reachability/ReachabilityUtils.swift
subModules/pEpIOSToolbox/pEpIOSToolbox/Other/Reachability/ReachabilityUtilsProtocol.swift
subModules/pEpIOSToolbox/pEpIOSToolboxTests/Other/ReachabilityUtilsTest/NetworkReachibilityMock.swift
subModules/pEpIOSToolbox/pEpIOSToolboxTests/Other/ReachabilityUtilsTest/ReachabilityUtilsTests.swift
     1.1 --- a/pEpForiOS.xcodeproj/project.pbxproj	Mon Mar 18 10:54:14 2019 +0100
     1.2 +++ b/pEpForiOS.xcodeproj/project.pbxproj	Mon Mar 18 11:12:42 2019 +0100
     1.3 @@ -229,12 +229,6 @@
     1.4  		220DCE371E0AB5CC002FE716 /* MessageSubjectCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 220DCE331E0AB5CC002FE716 /* MessageSubjectCell.swift */; };
     1.5  		222B35581DF96389007A1F82 /* Capability.swift in Sources */ = {isa = PBXBuildFile; fileRef = 222B35571DF96389007A1F82 /* Capability.swift */; };
     1.6  		228038681DC9DE6D00F1CB45 /* TextfieldResponder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 228038671DC9DE6D00F1CB45 /* TextfieldResponder.swift */; };
     1.7 -		37A3D61F221429DA00E11415 /* NetworkReachibilityMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37A3D61E221429DA00E11415 /* NetworkReachibilityMock.swift */; };
     1.8 -		37A3D6222214338300E11415 /* NetworkReachabilityProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37A3D6212214338300E11415 /* NetworkReachabilityProtocol.swift */; };
     1.9 -		37A3D6242214372B00E11415 /* NetworkReachability.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37A3D6232214372B00E11415 /* NetworkReachability.swift */; };
    1.10 -		37A3D6262215695400E11415 /* ReachabilityUtilsProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37A3D6252215695400E11415 /* ReachabilityUtilsProtocol.swift */; };
    1.11 -		37FE82E92211D290008F8CF4 /* ReachabilityUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37FE82E82211D290008F8CF4 /* ReachabilityUtils.swift */; };
    1.12 -		37FE82ED22132B23008F8CF4 /* ReachabilityUtilsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37FE82EC22132B23008F8CF4 /* ReachabilityUtilsTests.swift */; };
    1.13  		43040A531E9776220083DED8 /* AttachmentSummaryView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43040A521E9776220083DED8 /* AttachmentSummaryView.swift */; };
    1.14  		4304FD001EBB8EBB0086DADA /* LanguageListViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4304FCFE1EBB8C5A0086DADA /* LanguageListViewController.swift */; };
    1.15  		4307C4701ED81F3100A276A4 /* DefaultImapSyncDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4307C46F1ED81F3100A276A4 /* DefaultImapSyncDelegate.swift */; };
    1.16 @@ -821,12 +815,6 @@
    1.17  		220DCE331E0AB5CC002FE716 /* MessageSubjectCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MessageSubjectCell.swift; sourceTree = "<group>"; };
    1.18  		222B35571DF96389007A1F82 /* Capability.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Capability.swift; sourceTree = "<group>"; };
    1.19  		228038671DC9DE6D00F1CB45 /* TextfieldResponder.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TextfieldResponder.swift; sourceTree = "<group>"; };
    1.20 -		37A3D61E221429DA00E11415 /* NetworkReachibilityMock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkReachibilityMock.swift; sourceTree = "<group>"; };
    1.21 -		37A3D6212214338300E11415 /* NetworkReachabilityProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkReachabilityProtocol.swift; sourceTree = "<group>"; };
    1.22 -		37A3D6232214372B00E11415 /* NetworkReachability.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkReachability.swift; sourceTree = "<group>"; };
    1.23 -		37A3D6252215695400E11415 /* ReachabilityUtilsProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReachabilityUtilsProtocol.swift; sourceTree = "<group>"; };
    1.24 -		37FE82E82211D290008F8CF4 /* ReachabilityUtils.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReachabilityUtils.swift; sourceTree = "<group>"; };
    1.25 -		37FE82EC22132B23008F8CF4 /* ReachabilityUtilsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReachabilityUtilsTests.swift; sourceTree = "<group>"; };
    1.26  		43040A521E9776220083DED8 /* AttachmentSummaryView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AttachmentSummaryView.swift; sourceTree = "<group>"; };
    1.27  		4304FCFE1EBB8C5A0086DADA /* LanguageListViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LanguageListViewController.swift; sourceTree = "<group>"; };
    1.28  		4307C46F1ED81F3100A276A4 /* DefaultImapSyncDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = DefaultImapSyncDelegate.swift; path = ../DefaultImapSyncDelegate.swift; sourceTree = "<group>"; };
    1.29 @@ -1316,7 +1304,6 @@
    1.30  		151F71EB202A06750057C74D /* TestUtils */ = {
    1.31  			isa = PBXGroup;
    1.32  			children = (
    1.33 -				37A3D61D2214292B00E11415 /* ReachabilityUtilsTest */,
    1.34  				151F71F6202A06750057C74D /* CdAccount+TestUtils.swift */,
    1.35  				151F71F3202A06750057C74D /* CdMessage+TestUtils.swift */,
    1.36  				151F71F1202A06750057C74D /* CoreDataDrivenTestBase.swift */,
    1.37 @@ -1876,26 +1863,6 @@
    1.38  			name = Cells;
    1.39  			sourceTree = "<group>";
    1.40  		};
    1.41 -		37A3D61D2214292B00E11415 /* ReachabilityUtilsTest */ = {
    1.42 -			isa = PBXGroup;
    1.43 -			children = (
    1.44 -				37FE82EC22132B23008F8CF4 /* ReachabilityUtilsTests.swift */,
    1.45 -				37A3D61E221429DA00E11415 /* NetworkReachibilityMock.swift */,
    1.46 -			);
    1.47 -			path = ReachabilityUtilsTest;
    1.48 -			sourceTree = "<group>";
    1.49 -		};
    1.50 -		37A3D6202214333200E11415 /* Reachability */ = {
    1.51 -			isa = PBXGroup;
    1.52 -			children = (
    1.53 -				37A3D6252215695400E11415 /* ReachabilityUtilsProtocol.swift */,
    1.54 -				37FE82E82211D290008F8CF4 /* ReachabilityUtils.swift */,
    1.55 -				37A3D6212214338300E11415 /* NetworkReachabilityProtocol.swift */,
    1.56 -				37A3D6232214372B00E11415 /* NetworkReachability.swift */,
    1.57 -			);
    1.58 -			path = Reachability;
    1.59 -			sourceTree = "<group>";
    1.60 -		};
    1.61  		4304FCFD1EBB8C2C0086DADA /* LanguageList */ = {
    1.62  			isa = PBXGroup;
    1.63  			children = (
    1.64 @@ -2308,7 +2275,6 @@
    1.65  				4362398D1EAE08F400BD2EB9 /* Extensions */,
    1.66  				B740B7571E4B1B80002585E1 /* MimeTypes */,
    1.67  				43306EBC1FE125950045DD00 /* OAuth2 */,
    1.68 -				37A3D6202214333200E11415 /* Reachability */,
    1.69  				43980EF91CBD415700A7FC3C /* AppConfig.swift */,
    1.70  				43C6F35A1CBE7496006A2A18 /* ConnectionManager.swift */,
    1.71  				A1B50A811CD26FF100B1A997 /* Constants.swift */,
    1.72 @@ -3229,7 +3195,6 @@
    1.73  				5D039AA21D0EEA3700AD59EC /* DecryptMessagesOperation.swift in Sources */,
    1.74  				439AAC561F21D0CC0018A29E /* CdFolder+Pantomime.swift in Sources */,
    1.75  				4351C2D51F4441190053381F /* latex.c in Sources */,
    1.76 -				37A3D6262215695400E11415 /* ReachabilityUtilsProtocol.swift in Sources */,
    1.77  				43498CDB200CF20F006DC947 /* LoginViewModelLoginErrorDelegate.swift in Sources */,
    1.78  				1560D1721F6FD1F600A75B39 /* FetchOlderImapMessagesService.swift in Sources */,
    1.79  				15874BC42127493E00A3A4A6 /* SettingsCellViewModel.swift in Sources */,
    1.80 @@ -3240,7 +3205,6 @@
    1.81  				15874BC62127493E00A3A4A6 /* SettingsTableViewController.swift in Sources */,
    1.82  				B740B75F1E4B1C46002585E1 /* MimeTypeUtil.swift in Sources */,
    1.83  				1555E97C1FD587A300BF8E0E /* Message+IMAP.swift in Sources */,
    1.84 -				37A3D6242214372B00E11415 /* NetworkReachability.swift in Sources */,
    1.85  				002375D320DCDC7300663961 /* FullMessageCell+SecureWebViewControllerDelegate.swift in Sources */,
    1.86  				4351C2C91F4441190053381F /* buffer.c in Sources */,
    1.87  				434B5D191DDF67E400BEDEF0 /* CdMessage+Extension.swift in Sources */,
    1.88 @@ -3514,7 +3478,6 @@
    1.89  				43A6E0581E57400E005BEE69 /* RatingReEvaluator.swift in Sources */,
    1.90  				49C34AF620E4F649009D11CC /* CellDetailTransition.swift in Sources */,
    1.91  				492EF92A20C18C6C004EAE14 /* DisplayedMessage.swift in Sources */,
    1.92 -				37A3D6222214338300E11415 /* NetworkReachabilityProtocol.swift in Sources */,
    1.93  				15AA6016207CD71D00D57DB4 /* ImapFlags+Pantomime.swift in Sources */,
    1.94  				B70A3A9322089D5000EDCE61 /* Log+ASL.swift in Sources */,
    1.95  				49228A5520D4035100A51E9D /* DetailCellSegue.swift in Sources */,
    1.96 @@ -3523,7 +3486,6 @@
    1.97  				00FD0CE82102014C00BA0C56 /* PrimarySplitViewcontroller+ScreenComposerProtocol.swift in Sources */,
    1.98  				434E5A1B20DB9C4600D7F88A /* EmailListViewModel+MessageFolderDelegate.swift in Sources */,
    1.99  				431E58F61ED57F6500EFA77F /* AccountVerificationServiceProtocol.swift in Sources */,
   1.100 -				37FE82E92211D290008F8CF4 /* ReachabilityUtils.swift in Sources */,
   1.101  				152A39E821905C3E00D9F8E4 /* RecipientCellViewModel.swift in Sources */,
   1.102  				43A26FBF1E041BF200AF0B84 /* ImapSyncOperation.swift in Sources */,
   1.103  				152A39CE21905C3E00D9F8E4 /* ComposeHelpers.swift in Sources */,
   1.104 @@ -3664,13 +3626,11 @@
   1.105  				1569AEA520E14DC3002102A0 /* ReUploadTest.swift in Sources */,
   1.106  				00262058217DE97100DDAFB5 /* AccountSettingsViewModelTest.swift in Sources */,
   1.107  				004422C82179E3C500BDF6DF /* SettingsCellViewModelTest.swift in Sources */,
   1.108 -				37A3D61F221429DA00E11415 /* NetworkReachibilityMock.swift in Sources */,
   1.109  				150707DC21006CD000AA213F /* ComposeUtilTest.swift in Sources */,
   1.110  				15D439A5216F7E0E00EB3933 /* AccountPickerViewModelTest.swift in Sources */,
   1.111  				1574D07D2114696B00FEDC93 /* URL+MailToTest.swift in Sources */,
   1.112  				43C273DD21C9024A002EB4C8 /* LoggerTest.swift in Sources */,
   1.113  				4356FFEC21356CB600804089 /* ReplyAllPossibleCheckerTest.swift in Sources */,
   1.114 -				37FE82ED22132B23008F8CF4 /* ReachabilityUtilsTests.swift in Sources */,
   1.115  				430C80E01D0EADC200CD4582 /* PepAdapterTests.swift in Sources */,
   1.116  				00DF2C3B2164C53F004EBA6C /* FolderViewModelTest.swift in Sources */,
   1.117  				5DEBAA481DE59C3B00FAE12C /* NetworkServiceTests.swift in Sources */,
     2.1 --- a/pEpForiOS/Util/Reachability/NetworkReachability.swift	Mon Mar 18 10:54:14 2019 +0100
     2.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.3 @@ -1,22 +0,0 @@
     2.4 -//
     2.5 -//  NetworkReachability.swift
     2.6 -//  pEp
     2.7 -//
     2.8 -//  Created by Alejandro Gelos on 13/02/2019.
     2.9 -//  Copyright © 2019 p≡p Security S.A. All rights reserved.
    2.10 -//
    2.11 -
    2.12 -import Foundation
    2.13 -import SystemConfiguration
    2.14 -
    2.15 -class NetworkReachability: NetworkReachabilityProtocol {
    2.16 -    init(){}
    2.17 -    
    2.18 -    func networkReachabilityGetFlags(_ target: SCNetworkReachability, _ flags: UnsafeMutablePointer<SCNetworkReachabilityFlags>) -> Bool {
    2.19 -        return SCNetworkReachabilityGetFlags(target, flags)
    2.20 -    }
    2.21 -    
    2.22 -    @discardableResult func networkReachabilitySetCallback(_ target: SCNetworkReachability, _ callout: SCNetworkReachabilityCallBack?, _ context: UnsafeMutablePointer<SCNetworkReachabilityContext>?) -> Bool {
    2.23 -        return SCNetworkReachabilitySetCallback(target, callout, context)
    2.24 -    }
    2.25 -}
     3.1 --- a/pEpForiOS/Util/Reachability/NetworkReachabilityProtocol.swift	Mon Mar 18 10:54:14 2019 +0100
     3.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.3 @@ -1,15 +0,0 @@
     3.4 -//
     3.5 -//  NetworkReachabilityProtocol.swift
     3.6 -//  pEp
     3.7 -//
     3.8 -//  Created by Alejandro Gelos on 13/02/2019.
     3.9 -//  Copyright © 2019 p≡p Security S.A. All rights reserved.
    3.10 -//
    3.11 -
    3.12 -import Foundation
    3.13 -import SystemConfiguration
    3.14 -
    3.15 -protocol NetworkReachabilityProtocol: class {
    3.16 -    func networkReachabilityGetFlags(_ target: SCNetworkReachability, _ flags: UnsafeMutablePointer<SCNetworkReachabilityFlags>) -> Bool
    3.17 -    @discardableResult func networkReachabilitySetCallback(_ target: SCNetworkReachability, _ callout: SCNetworkReachabilityCallBack?, _ context: UnsafeMutablePointer<SCNetworkReachabilityContext>?) -> Bool
    3.18 -}
     4.1 --- a/pEpForiOS/Util/Reachability/ReachabilityUtils.swift	Mon Mar 18 10:54:14 2019 +0100
     4.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.3 @@ -1,185 +0,0 @@
     4.4 -//
     4.5 -//  ReachabilityUtils.swift
     4.6 -//  pEp
     4.7 -//
     4.8 -//  Created by Alejandro Gelos on 11/02/2019.
     4.9 -//  Copyright © 2019 p≡p Security S.A. All rights reserved.
    4.10 -
    4.11 -import Foundation
    4.12 -import SystemConfiguration
    4.13 -
    4.14 -public protocol ReachabilityDelegate: class {
    4.15 -    /// Called every time internet connection status changes. Also the first time startNotifier() is call
    4.16 -    ///
    4.17 -    /// - Parameter status: connected for connected to internet, otherwise notConnected
    4.18 -    func didChangeReachability(status: Reachability.Connection)
    4.19 -    func didFailToStartNotifier(error: Reachability.ReachabilityError)
    4.20 -}
    4.21 -
    4.22 -///  This service allow an application to determine whether or not you have a working internet
    4.23 -///  connection.
    4.24 -///  Reachability supports asynchronous model. You get the internet connection status, in the
    4.25 -///  completion block by calling the getConnectionStatus(completion:failure:) function. You can also
    4.26 -///  call startNotifier() function, to start getting changes in internet connection status, on
    4.27 -///  ReachabilityDelegate, didChangeReachability(status:) function. The client must implement
    4.28 -///  ReachabilityDelegate to get new internet connection status. When startNotifier is call,
    4.29 -///  ReachabilityDelegate didChangeReachability(status:) will be call with the current internet
    4.30 -///  connection status.
    4.31 -///
    4.32 -/// # How to use:
    4.33 -///
    4.34 -/// # Start listening to new states
    4.35 -/// * instantiate Reachability class and retain it, ex: let <yourReachability> = Reachability()
    4.36 -/// * set ReachabilityDelegate to you (to get ReachabilityDelegate calls)
    4.37 -/// * implement ReachabilityDelegate (to get new connection states)
    4.38 -/// * call yourReachability.startNotifier() (start updating reachability status with delegate)
    4.39 -/// * call yourReachability.stopNotifier() (to stop updating)
    4.40 -///
    4.41 -/// # Get current state
    4.42 -/// * instantiate Reachability class
    4.43 -/// * call yourReachability.getConnectionStatus(
    4.44 -///    completion: { result in ...},
    4.45 -///    failure: { error in ...})
    4.46 -public final class Reachability: ReachabilityUtilsProtocol {
    4.47 -    public enum Connection: String {
    4.48 -        case notConnected, connected
    4.49 -    }
    4.50 -    
    4.51 -    /// ReachabilityError types
    4.52 -    ///
    4.53 -    /// - failToGetReachabilityState: failt to get reachability state
    4.54 -    public enum ReachabilityError: Error {
    4.55 -        case failToGetReachabilityState
    4.56 -    }
    4.57 -
    4.58 -    public weak var delegate: ReachabilityDelegate?
    4.59 -    
    4.60 -    private var notifierRunning = false
    4.61 -    private var networkReachability: NetworkReachabilityProtocol
    4.62 -    private let reachabilityRef: SCNetworkReachability
    4.63 -    private let reachabilitySerialQueue: DispatchQueue
    4.64 -    
    4.65 -    var flags: SCNetworkReachabilityFlags? {
    4.66 -        didSet {
    4.67 -            callDelegateDidChangeReachibilityIfNeeded(newFlags: flags, oldFlags: oldValue)
    4.68 -        }
    4.69 -    }
    4.70 -    
    4.71 -    /// Get intense of Reachability, to check internet status
    4.72 -    public required init?() {
    4.73 -        var zeroAddress = sockaddr()
    4.74 -        zeroAddress.sa_len = UInt8(MemoryLayout<sockaddr>.size)
    4.75 -        zeroAddress.sa_family = sa_family_t(AF_INET)
    4.76 -        guard let ref = SCNetworkReachabilityCreateWithAddress(nil, &zeroAddress) else { return nil }
    4.77 -        
    4.78 -        self.reachabilityRef = ref
    4.79 -        self.networkReachability = NetworkReachability()
    4.80 -        self.reachabilitySerialQueue =
    4.81 -            DispatchQueue(label: "pep.reachability", qos: .default, target: nil)
    4.82 -    }
    4.83 -    
    4.84 -    convenience init?(networkReachability: NetworkReachabilityProtocol) {
    4.85 -        self.init()
    4.86 -        self.networkReachability = networkReachability
    4.87 -    }
    4.88 -    
    4.89 -    deinit {
    4.90 -        stopNotifier()
    4.91 -    }
    4.92 -    
    4.93 -    /// Get current connection status
    4.94 -    ///
    4.95 -    /// - Parameters:
    4.96 -    ///   - completion: connected and not connected to internet
    4.97 -    ///   - failure: failToGetReachabilityState when failed to get internet status
    4.98 -    public func getConnectionStatus(completion: @escaping ((Connection)->()),
    4.99 -                                       failure: @escaping ((ReachabilityError) -> ()) ) {
   4.100 -        setReachabilityFlags(
   4.101 -            completion: { [weak self] flags in
   4.102 -                guard let `self` = self else { return }
   4.103 -                let connectionStatud = self.getConnectionStatus(fromFlags: flags)
   4.104 -                completion(connectionStatud)},
   4.105 -            failure: { error in
   4.106 -                failure(error)
   4.107 -        })
   4.108 -    }
   4.109 -    
   4.110 -    /// Start updating internet connection state through ReachabilityDelegate
   4.111 -    public func startNotifier() {
   4.112 -        guard !notifierRunning else { return }
   4.113 -        
   4.114 -        let callback: SCNetworkReachabilityCallBack = { (reachability, flags, info) in
   4.115 -            guard let info = info else { return }
   4.116 -            
   4.117 -            let reachability = Unmanaged<Reachability>.fromOpaque(info).takeUnretainedValue()
   4.118 -            reachability.flags = flags
   4.119 -        }
   4.120 -        
   4.121 -        var context = SCNetworkReachabilityContext(version: 0, info: nil, retain: nil, release: nil,
   4.122 -                                                   copyDescription: nil)
   4.123 -        context.info = UnsafeMutableRawPointer(Unmanaged<Reachability>.passUnretained(self).toOpaque())
   4.124 -        if !networkReachability.networkReachabilitySetCallback(reachabilityRef, callback, &context) {
   4.125 -            stopNotifier()
   4.126 -            delegate?.didFailToStartNotifier(error: .failToGetReachabilityState)
   4.127 -        }
   4.128 -        
   4.129 -        if !SCNetworkReachabilitySetDispatchQueue(reachabilityRef, reachabilitySerialQueue) {
   4.130 -            stopNotifier()
   4.131 -            delegate?.didFailToStartNotifier(error: .failToGetReachabilityState)
   4.132 -        }
   4.133 -        
   4.134 -        // Perform an initial check
   4.135 -        setReachabilityFlags(
   4.136 -            completion: { [weak self] flags in
   4.137 -                self?.flags = flags },
   4.138 -            failure: { [weak self] error in
   4.139 -                self?.stopNotifier()
   4.140 -                self?.delegate?.didFailToStartNotifier(error: error)
   4.141 -        })
   4.142 -        notifierRunning = true
   4.143 -    }
   4.144 -    
   4.145 -    /// Stop updating reachable value
   4.146 -    public func stopNotifier() {
   4.147 -        defer { notifierRunning = false }
   4.148 -        
   4.149 -        networkReachability.networkReachabilitySetCallback(reachabilityRef, nil, nil)
   4.150 -        SCNetworkReachabilitySetDispatchQueue(reachabilityRef, nil)
   4.151 -    }
   4.152 -}
   4.153 -
   4.154 -
   4.155 -// MARK: - Private methods
   4.156 -private extension Reachability {
   4.157 -    private func setReachabilityFlags(completion: @escaping ((SCNetworkReachabilityFlags)->()),
   4.158 -                                         failure: @escaping ((ReachabilityError) -> ()) ) {
   4.159 -        reachabilitySerialQueue.async { [weak self] in
   4.160 -            guard let `self` = self else { return }
   4.161 -            var flags = SCNetworkReachabilityFlags()
   4.162 -            guard self.networkReachability.networkReachabilityGetFlags(self.reachabilityRef, &flags) else {
   4.163 -                failure(.failToGetReachabilityState)
   4.164 -                return
   4.165 -            }
   4.166 -             completion(flags)
   4.167 -        }
   4.168 -    }
   4.169 -    
   4.170 -    private func getConnectionStatus(fromFlags: SCNetworkReachabilityFlags) -> Connection {
   4.171 -        return fromFlags.contains(.reachable) ? .connected : .notConnected
   4.172 -    }
   4.173 -    
   4.174 -    private func callDelegateDidChangeReachibilityIfNeeded(newFlags: SCNetworkReachabilityFlags?,
   4.175 -                                                           oldFlags: SCNetworkReachabilityFlags?){
   4.176 -        guard let newFlags = newFlags else { return }
   4.177 -        let newState = getConnectionStatus(fromFlags: newFlags)
   4.178 -        
   4.179 -        guard let oldFlags = oldFlags else {
   4.180 -            delegate?.didChangeReachability(status: newState)
   4.181 -            return
   4.182 -        }
   4.183 -        
   4.184 -        let oldState = getConnectionStatus(fromFlags: oldFlags)
   4.185 -        if newState == oldState { return }
   4.186 -        delegate?.didChangeReachability(status: newState)
   4.187 -    }
   4.188 -}
     5.1 --- a/pEpForiOS/Util/Reachability/ReachabilityUtilsProtocol.swift	Mon Mar 18 10:54:14 2019 +0100
     5.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.3 @@ -1,18 +0,0 @@
     5.4 -//
     5.5 -//  ReachibilityUtilsProtocol.swift
     5.6 -//  pEp
     5.7 -//
     5.8 -//  Created by Alejandro Gelos on 14/02/2019.
     5.9 -//  Copyright © 2019 p≡p Security S.A. All rights reserved.
    5.10 -//
    5.11 -
    5.12 -import Foundation
    5.13 -
    5.14 -protocol ReachabilityUtilsProtocol {
    5.15 -    var delegate: ReachabilityDelegate? {get set}
    5.16 -    
    5.17 -    func getConnectionStatus(completion: @escaping ((Reachability.Connection)->()),
    5.18 -                                failure: @escaping ((Reachability.ReachabilityError) -> ()) )
    5.19 -    func startNotifier()
    5.20 -    func stopNotifier()
    5.21 -}
     6.1 --- a/pEpForiOSTests/TestUtils/ReachabilityUtilsTest/NetworkReachibilityMock.swift	Mon Mar 18 10:54:14 2019 +0100
     6.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.3 @@ -1,56 +0,0 @@
     6.4 -//
     6.5 -//  NetworkReachibilityMock.swift
     6.6 -//  pEpForiOSTests
     6.7 -//
     6.8 -//  Created by Alejandro Gelos on 13/02/2019.
     6.9 -//  Copyright © 2019 p≡p Security S.A. All rights reserved.
    6.10 -//
    6.11 -
    6.12 -import XCTest
    6.13 -import SystemConfiguration
    6.14 -@testable import pEpForiOS
    6.15 -
    6.16 -
    6.17 -class YesInternetReachabilityMock: NetworkReachabilityProtocol {
    6.18 -    let callback: SCNetworkReachabilityCallBack = { (reachability, flags, info) in
    6.19 -        guard let info = info else { return }
    6.20 -        
    6.21 -        let reachability = Unmanaged<Reachability>.fromOpaque(info).takeUnretainedValue()
    6.22 -        reachability.flags = [SCNetworkReachabilityFlags.reachable]
    6.23 -    }
    6.24 -    
    6.25 -    func networkReachabilityGetFlags(_ target: SCNetworkReachability,
    6.26 -                                     _ flags: UnsafeMutablePointer<SCNetworkReachabilityFlags>)
    6.27 -        -> Bool {
    6.28 -        flags.pointee = [SCNetworkReachabilityFlags.reachable]
    6.29 -        return true
    6.30 -    }
    6.31 -    
    6.32 -    @discardableResult func networkReachabilitySetCallback(_ target: SCNetworkReachability,
    6.33 -                                                           _ callout: SCNetworkReachabilityCallBack?,
    6.34 -                                     _ context: UnsafeMutablePointer<SCNetworkReachabilityContext>?)
    6.35 -        -> Bool {
    6.36 -        return SCNetworkReachabilitySetCallback(target, callback, context)
    6.37 -    }
    6.38 -}
    6.39 -
    6.40 -class NoInternetReachabilityMock: NetworkReachabilityProtocol {
    6.41 -    let callback: SCNetworkReachabilityCallBack = { (reachability, flags, info) in
    6.42 -        guard let info = info else { return }
    6.43 -        
    6.44 -        let reachability = Unmanaged<Reachability>.fromOpaque(info).takeUnretainedValue()
    6.45 -        reachability.flags = []
    6.46 -    }
    6.47 -    
    6.48 -    func networkReachabilityGetFlags(_ target: SCNetworkReachability,
    6.49 -                                     _ flags: UnsafeMutablePointer<SCNetworkReachabilityFlags>)
    6.50 -        -> Bool {
    6.51 -        flags.pointee = []
    6.52 -        return true
    6.53 -    }
    6.54 -    
    6.55 -    @discardableResult func networkReachabilitySetCallback(_ target: SCNetworkReachability, _ callout: SCNetworkReachabilityCallBack?, _ context: UnsafeMutablePointer<SCNetworkReachabilityContext>?)
    6.56 -        -> Bool {
    6.57 -        return SCNetworkReachabilitySetCallback(target, callback, context)
    6.58 -    }
    6.59 -}
     7.1 --- a/pEpForiOSTests/TestUtils/ReachabilityUtilsTest/ReachabilityUtilsTests.swift	Mon Mar 18 10:54:14 2019 +0100
     7.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     7.3 @@ -1,134 +0,0 @@
     7.4 -//
     7.5 -//  ReachabilityUtilsTests.swift
     7.6 -//  pEpForiOSTests
     7.7 -//
     7.8 -//  Created by Alejandro Gelos on 12/02/2019.
     7.9 -//  Copyright © 2019 p≡p Security S.A. All rights reserved.
    7.10 -//
    7.11 -
    7.12 -import XCTest
    7.13 -@testable import pEpForiOS
    7.14 -
    7.15 -class ReachibilityUtilsTests: XCTestCase {
    7.16 -    
    7.17 -    private var yesReachability: Reachability?
    7.18 -    private var noReachability:  Reachability?
    7.19 -    private let yesInternetNetworkReachibilityMock = YesInternetReachabilityMock()
    7.20 -    private let noInternetLocalNetworkReachibilityMock = NoInternetReachabilityMock()
    7.21 -    
    7.22 -    override func setUp() {
    7.23 -        yesReachability = Reachability(networkReachability: yesInternetNetworkReachibilityMock)
    7.24 -        noReachability  = Reachability(networkReachability: noInternetLocalNetworkReachibilityMock)
    7.25 -    }
    7.26 -    
    7.27 -    override func tearDown() {
    7.28 -        yesReachability = nil
    7.29 -        noReachability  = nil
    7.30 -        super.tearDown()
    7.31 -    }
    7.32 -    
    7.33 -    func testInit() {
    7.34 -        // Given
    7.35 -        // When
    7.36 -        let reachibility = Reachability()
    7.37 -        
    7.38 -        //Then
    7.39 -        XCTAssertNotNil(reachibility)
    7.40 -    }
    7.41 -    
    7.42 -    func testGetConnectionStatusYesInternet() {
    7.43 -        // Given
    7.44 -        guard let yesReachability = yesReachability else {
    7.45 -            XCTFail()
    7.46 -            return
    7.47 -        }
    7.48 -        // When
    7.49 -        yesReachability.getConnectionStatus(
    7.50 -            completion: { result in
    7.51 -                // Then
    7.52 -                XCTAssertTrue(result == Reachability.Connection.connected)
    7.53 -        },
    7.54 -            failure: { error in
    7.55 -                XCTFail()
    7.56 -        })
    7.57 -    }
    7.58 -    
    7.59 -    func testGetConnectionStatusNoInternet() {
    7.60 -        guard let noReachability = noReachability else {
    7.61 -            XCTFail()
    7.62 -            return
    7.63 -        }
    7.64 -        // When
    7.65 -        noReachability.getConnectionStatus(
    7.66 -            completion: { result in
    7.67 -                // Then
    7.68 -                XCTAssertFalse(result == Reachability.Connection.connected)
    7.69 -        },
    7.70 -            failure: { error in
    7.71 -                XCTFail()
    7.72 -        })
    7.73 -    }
    7.74 -    
    7.75 -    func testStartNotifierYesInternet(){
    7.76 -        // Given
    7.77 -        guard let yesReachability = yesReachability else {
    7.78 -            XCTFail()
    7.79 -            return
    7.80 -        }
    7.81 -        let exp = expectation(description: "delegate called for connected")
    7.82 -        let expectedConnected = Reachability.Connection.connected
    7.83 -        let testDelegate = ReachibilityUtilsTestsDelegate(withExp: exp,
    7.84 -                                                          withExpectedConnected: expectedConnected)
    7.85 -        yesReachability.delegate = testDelegate
    7.86 -        
    7.87 -        // When
    7.88 -        yesReachability.startNotifier()
    7.89 -        
    7.90 -        // Then
    7.91 -        waitForExpectations(timeout: TestUtil.waitTime)
    7.92 -    }
    7.93 -    
    7.94 -    func testStartNotifierNoInternet(){
    7.95 -        // Given
    7.96 -        guard let noReachability = noReachability else {
    7.97 -            XCTFail()
    7.98 -            return
    7.99 -        }
   7.100 -        let exp = expectation(description: "delegate called for no connected")
   7.101 -        let expectedNotConnected = Reachability.Connection.notConnected
   7.102 -        let testDelegate = ReachibilityUtilsTestsDelegate(withExp: exp,
   7.103 -                                                          withExpectedConnected: expectedNotConnected)
   7.104 -        noReachability.delegate = testDelegate
   7.105 -        
   7.106 -        // When
   7.107 -        noReachability.startNotifier()
   7.108 -        
   7.109 -        // Then
   7.110 -        waitForExpectations(timeout: TestUtil.waitTime)
   7.111 -    }
   7.112 -}
   7.113 -
   7.114 -// MARK: - ReachabilityDelegate
   7.115 -class ReachibilityUtilsTestsDelegate {
   7.116 -    let exp: XCTestExpectation
   7.117 -    var expedConnected: Reachability.Connection
   7.118 -    
   7.119 -    init(withExp exp: XCTestExpectation, withExpectedConnected expedConnected: Reachability.Connection) {
   7.120 -        self.exp = exp
   7.121 -        self.expedConnected = expedConnected
   7.122 -    }
   7.123 -}
   7.124 -
   7.125 -// MARK: - ReachabilityDelegate
   7.126 -extension ReachibilityUtilsTestsDelegate: ReachabilityDelegate{
   7.127 -    func didFailToStartNotifier(error: Reachability.ReachabilityError) {
   7.128 -        XCTFail()
   7.129 -        exp.fulfill()
   7.130 -    }
   7.131 -    
   7.132 -    func didChangeReachability(status: Reachability.Connection) {
   7.133 -        // Then
   7.134 -        XCTAssertEqual(status, expedConnected)
   7.135 -        exp.fulfill()
   7.136 -    }
   7.137 -}
     8.1 --- a/subModules/pEpIOSToolbox/pEpIOSToolbox.xcodeproj/project.pbxproj	Mon Mar 18 10:54:14 2019 +0100
     8.2 +++ b/subModules/pEpIOSToolbox/pEpIOSToolbox.xcodeproj/project.pbxproj	Mon Mar 18 11:12:42 2019 +0100
     8.3 @@ -7,6 +7,12 @@
     8.4  	objects = {
     8.5  
     8.6  /* Begin PBXBuildFile section */
     8.7 +		37904562223FA486006DAB3B /* NetworkReachabilityProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3790455E223FA486006DAB3B /* NetworkReachabilityProtocol.swift */; };
     8.8 +		37904563223FA486006DAB3B /* ReachabilityUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3790455F223FA486006DAB3B /* ReachabilityUtils.swift */; };
     8.9 +		37904564223FA486006DAB3B /* NetworkReachability.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37904560223FA486006DAB3B /* NetworkReachability.swift */; };
    8.10 +		37904565223FA486006DAB3B /* ReachabilityUtilsProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37904561223FA486006DAB3B /* ReachabilityUtilsProtocol.swift */; };
    8.11 +		37904569223FA52B006DAB3B /* NetworkReachibilityMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37904567223FA52B006DAB3B /* NetworkReachibilityMock.swift */; };
    8.12 +		3790456A223FA52B006DAB3B /* ReachabilityUtilsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37904568223FA52B006DAB3B /* ReachabilityUtilsTests.swift */; };
    8.13  		B70A3A5522005BD400EDCE61 /* Date+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = B70A3A5422005BD400EDCE61 /* Date+Extension.swift */; };
    8.14  		B70A3A5722005BE300EDCE61 /* NSRegularExpression+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = B70A3A5622005BE300EDCE61 /* NSRegularExpression+Extension.swift */; };
    8.15  		B70A3A7322006B9F00EDCE61 /* SystemUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = B70A3A7222006B9E00EDCE61 /* SystemUtils.swift */; };
    8.16 @@ -47,6 +53,12 @@
    8.17  /* End PBXContainerItemProxy section */
    8.18  
    8.19  /* Begin PBXFileReference section */
    8.20 +		3790455E223FA486006DAB3B /* NetworkReachabilityProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NetworkReachabilityProtocol.swift; sourceTree = "<group>"; };
    8.21 +		3790455F223FA486006DAB3B /* ReachabilityUtils.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ReachabilityUtils.swift; sourceTree = "<group>"; };
    8.22 +		37904560223FA486006DAB3B /* NetworkReachability.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NetworkReachability.swift; sourceTree = "<group>"; };
    8.23 +		37904561223FA486006DAB3B /* ReachabilityUtilsProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ReachabilityUtilsProtocol.swift; sourceTree = "<group>"; };
    8.24 +		37904567223FA52B006DAB3B /* NetworkReachibilityMock.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NetworkReachibilityMock.swift; sourceTree = "<group>"; };
    8.25 +		37904568223FA52B006DAB3B /* ReachabilityUtilsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ReachabilityUtilsTests.swift; sourceTree = "<group>"; };
    8.26  		B70A3A5422005BD400EDCE61 /* Date+Extension.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Date+Extension.swift"; sourceTree = "<group>"; };
    8.27  		B70A3A5622005BE300EDCE61 /* NSRegularExpression+Extension.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NSRegularExpression+Extension.swift"; sourceTree = "<group>"; };
    8.28  		B70A3A7222006B9E00EDCE61 /* SystemUtils.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SystemUtils.swift; sourceTree = "<group>"; };
    8.29 @@ -115,11 +127,32 @@
    8.30  		15175EDA221E9F4C00C91DB8 /* Other */ = {
    8.31  			isa = PBXGroup;
    8.32  			children = (
    8.33 +				37904566223FA52B006DAB3B /* ReachabilityUtilsTest */,
    8.34  				B7DB7F8322144E4E003968DA /* SortedSetTest.swift */,
    8.35  			);
    8.36  			path = Other;
    8.37  			sourceTree = "<group>";
    8.38  		};
    8.39 +		3790455D223FA486006DAB3B /* Reachability */ = {
    8.40 +			isa = PBXGroup;
    8.41 +			children = (
    8.42 +				3790455E223FA486006DAB3B /* NetworkReachabilityProtocol.swift */,
    8.43 +				3790455F223FA486006DAB3B /* ReachabilityUtils.swift */,
    8.44 +				37904560223FA486006DAB3B /* NetworkReachability.swift */,
    8.45 +				37904561223FA486006DAB3B /* ReachabilityUtilsProtocol.swift */,
    8.46 +			);
    8.47 +			path = Reachability;
    8.48 +			sourceTree = "<group>";
    8.49 +		};
    8.50 +		37904566223FA52B006DAB3B /* ReachabilityUtilsTest */ = {
    8.51 +			isa = PBXGroup;
    8.52 +			children = (
    8.53 +				37904567223FA52B006DAB3B /* NetworkReachibilityMock.swift */,
    8.54 +				37904568223FA52B006DAB3B /* ReachabilityUtilsTests.swift */,
    8.55 +			);
    8.56 +			path = ReachabilityUtilsTest;
    8.57 +			sourceTree = "<group>";
    8.58 +		};
    8.59  		B70A3A5222005A7600EDCE61 /* Foundation */ = {
    8.60  			isa = PBXGroup;
    8.61  			children = (
    8.62 @@ -195,6 +228,7 @@
    8.63  		B7DB7FEC221B086A003968DA /* Other */ = {
    8.64  			isa = PBXGroup;
    8.65  			children = (
    8.66 +				3790455D223FA486006DAB3B /* Reachability */,
    8.67  				B7DB7F4F22130DE9003968DA /* Weak.swift */,
    8.68  				B70A3A75220091D400EDCE61 /* Logger.swift */,
    8.69  				B75390852212E20500B1FCF9 /* Collection+Extensions.swift */,
    8.70 @@ -314,12 +348,15 @@
    8.71  			buildActionMask = 2147483647;
    8.72  			files = (
    8.73  				B7465DC622119EB1008A1708 /* Array+SortingAndSearching.swift in Sources */,
    8.74 +				37904563223FA486006DAB3B /* ReachabilityUtils.swift in Sources */,
    8.75  				B7911ECC21F8B46600D7F66F /* GCD.swift in Sources */,
    8.76  				B7A46C54220C73BE0027CCB5 /* String+Extensions.swift in Sources */,
    8.77  				B7A46C58220DA6190027CCB5 /* String+Email.swift in Sources */,
    8.78 +				37904565223FA486006DAB3B /* ReachabilityUtilsProtocol.swift in Sources */,
    8.79  				B7A46C62220DCEA80027CCB5 /* NSAttributedString+Parsing.swift in Sources */,
    8.80  				B7465DE72211E969008A1708 /* CGRect+Util.swift in Sources */,
    8.81  				B7465DCC2211BEEA008A1708 /* Tuple.swift in Sources */,
    8.82 +				37904562223FA486006DAB3B /* NetworkReachabilityProtocol.swift in Sources */,
    8.83  				B7A46C50220C1F0C0027CCB5 /* MiscUtil.swift in Sources */,
    8.84  				B70A3A7322006B9F00EDCE61 /* SystemUtils.swift in Sources */,
    8.85  				B7936E3D220DD8F5003B39E6 /* NSAttributedString+Extensions.swift in Sources */,
    8.86 @@ -334,6 +371,7 @@
    8.87  				B70A3A5722005BE300EDCE61 /* NSRegularExpression+Extension.swift in Sources */,
    8.88  				B7465DBE22119D3A008A1708 /* Thread+Extension.swift in Sources */,
    8.89  				B7DB7F5022130DE9003968DA /* Weak.swift in Sources */,
    8.90 +				37904564223FA486006DAB3B /* NetworkReachability.swift in Sources */,
    8.91  				B7A46C52220C732E0027CCB5 /* Data+Extensions.swift in Sources */,
    8.92  				B7465DE32211C890008A1708 /* CGImageSource+Extension.swift in Sources */,
    8.93  				B7465DE12211C6E9008A1708 /* UIImage+GIF.swift in Sources */,
    8.94 @@ -345,7 +383,9 @@
    8.95  			isa = PBXSourcesBuildPhase;
    8.96  			buildActionMask = 2147483647;
    8.97  			files = (
    8.98 +				3790456A223FA52B006DAB3B /* ReachabilityUtilsTests.swift in Sources */,
    8.99  				B7DB7F8422144E4E003968DA /* SortedSetTest.swift in Sources */,
   8.100 +				37904569223FA52B006DAB3B /* NetworkReachibilityMock.swift in Sources */,
   8.101  			);
   8.102  			runOnlyForDeploymentPostprocessing = 0;
   8.103  		};
     9.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     9.2 +++ b/subModules/pEpIOSToolbox/pEpIOSToolbox/Other/Reachability/NetworkReachability.swift	Mon Mar 18 11:12:42 2019 +0100
     9.3 @@ -0,0 +1,22 @@
     9.4 +//
     9.5 +//  NetworkReachability.swift
     9.6 +//  pEp
     9.7 +//
     9.8 +//  Created by Alejandro Gelos on 13/02/2019.
     9.9 +//  Copyright © 2019 p≡p Security S.A. All rights reserved.
    9.10 +//
    9.11 +
    9.12 +import Foundation
    9.13 +import SystemConfiguration
    9.14 +
    9.15 +class NetworkReachability: NetworkReachabilityProtocol {
    9.16 +    init(){}
    9.17 +    
    9.18 +    func networkReachabilityGetFlags(_ target: SCNetworkReachability, _ flags: UnsafeMutablePointer<SCNetworkReachabilityFlags>) -> Bool {
    9.19 +        return SCNetworkReachabilityGetFlags(target, flags)
    9.20 +    }
    9.21 +    
    9.22 +    @discardableResult func networkReachabilitySetCallback(_ target: SCNetworkReachability, _ callout: SCNetworkReachabilityCallBack?, _ context: UnsafeMutablePointer<SCNetworkReachabilityContext>?) -> Bool {
    9.23 +        return SCNetworkReachabilitySetCallback(target, callout, context)
    9.24 +    }
    9.25 +}
    10.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    10.2 +++ b/subModules/pEpIOSToolbox/pEpIOSToolbox/Other/Reachability/NetworkReachabilityProtocol.swift	Mon Mar 18 11:12:42 2019 +0100
    10.3 @@ -0,0 +1,15 @@
    10.4 +//
    10.5 +//  NetworkReachabilityProtocol.swift
    10.6 +//  pEp
    10.7 +//
    10.8 +//  Created by Alejandro Gelos on 13/02/2019.
    10.9 +//  Copyright © 2019 p≡p Security S.A. All rights reserved.
   10.10 +//
   10.11 +
   10.12 +import Foundation
   10.13 +import SystemConfiguration
   10.14 +
   10.15 +protocol NetworkReachabilityProtocol: class {
   10.16 +    func networkReachabilityGetFlags(_ target: SCNetworkReachability, _ flags: UnsafeMutablePointer<SCNetworkReachabilityFlags>) -> Bool
   10.17 +    @discardableResult func networkReachabilitySetCallback(_ target: SCNetworkReachability, _ callout: SCNetworkReachabilityCallBack?, _ context: UnsafeMutablePointer<SCNetworkReachabilityContext>?) -> Bool
   10.18 +}
    11.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    11.2 +++ b/subModules/pEpIOSToolbox/pEpIOSToolbox/Other/Reachability/ReachabilityUtils.swift	Mon Mar 18 11:12:42 2019 +0100
    11.3 @@ -0,0 +1,185 @@
    11.4 +//
    11.5 +//  ReachabilityUtils.swift
    11.6 +//  pEp
    11.7 +//
    11.8 +//  Created by Alejandro Gelos on 11/02/2019.
    11.9 +//  Copyright © 2019 p≡p Security S.A. All rights reserved.
   11.10 +
   11.11 +import Foundation
   11.12 +import SystemConfiguration
   11.13 +
   11.14 +public protocol ReachabilityDelegate: class {
   11.15 +    /// Called every time internet connection status changes. Also the first time startNotifier() is call
   11.16 +    ///
   11.17 +    /// - Parameter status: connected for connected to internet, otherwise notConnected
   11.18 +    func didChangeReachability(status: Reachability.Connection)
   11.19 +    func didFailToStartNotifier(error: Reachability.ReachabilityError)
   11.20 +}
   11.21 +
   11.22 +///  This service allow an application to determine whether or not you have a working internet
   11.23 +///  connection.
   11.24 +///  Reachability supports asynchronous model. You get the internet connection status, in the
   11.25 +///  completion block by calling the getConnectionStatus(completion:failure:) function. You can also
   11.26 +///  call startNotifier() function, to start getting changes in internet connection status, on
   11.27 +///  ReachabilityDelegate, didChangeReachability(status:) function. The client must implement
   11.28 +///  ReachabilityDelegate to get new internet connection status. When startNotifier is call,
   11.29 +///  ReachabilityDelegate didChangeReachability(status:) will be call with the current internet
   11.30 +///  connection status.
   11.31 +///
   11.32 +/// # How to use:
   11.33 +///
   11.34 +/// # Start listening to new states
   11.35 +/// * instantiate Reachability class and retain it, ex: let <yourReachability> = Reachability()
   11.36 +/// * set ReachabilityDelegate to you (to get ReachabilityDelegate calls)
   11.37 +/// * implement ReachabilityDelegate (to get new connection states)
   11.38 +/// * call yourReachability.startNotifier() (start updating reachability status with delegate)
   11.39 +/// * call yourReachability.stopNotifier() (to stop updating)
   11.40 +///
   11.41 +/// # Get current state
   11.42 +/// * instantiate Reachability class
   11.43 +/// * call yourReachability.getConnectionStatus(
   11.44 +///    completion: { result in ...},
   11.45 +///    failure: { error in ...})
   11.46 +public final class Reachability: ReachabilityUtilsProtocol {
   11.47 +    public enum Connection: String {
   11.48 +        case notConnected, connected
   11.49 +    }
   11.50 +    
   11.51 +    /// ReachabilityError types
   11.52 +    ///
   11.53 +    /// - failToGetReachabilityState: failt to get reachability state
   11.54 +    public enum ReachabilityError: Error {
   11.55 +        case failToGetReachabilityState
   11.56 +    }
   11.57 +
   11.58 +    public weak var delegate: ReachabilityDelegate?
   11.59 +    
   11.60 +    private var notifierRunning = false
   11.61 +    private var networkReachability: NetworkReachabilityProtocol
   11.62 +    private let reachabilityRef: SCNetworkReachability
   11.63 +    private let reachabilitySerialQueue: DispatchQueue
   11.64 +    
   11.65 +    var flags: SCNetworkReachabilityFlags? {
   11.66 +        didSet {
   11.67 +            callDelegateDidChangeReachibilityIfNeeded(newFlags: flags, oldFlags: oldValue)
   11.68 +        }
   11.69 +    }
   11.70 +    
   11.71 +    /// Get intense of Reachability, to check internet status
   11.72 +    public required init?() {
   11.73 +        var zeroAddress = sockaddr()
   11.74 +        zeroAddress.sa_len = UInt8(MemoryLayout<sockaddr>.size)
   11.75 +        zeroAddress.sa_family = sa_family_t(AF_INET)
   11.76 +        guard let ref = SCNetworkReachabilityCreateWithAddress(nil, &zeroAddress) else { return nil }
   11.77 +        
   11.78 +        self.reachabilityRef = ref
   11.79 +        self.networkReachability = NetworkReachability()
   11.80 +        self.reachabilitySerialQueue =
   11.81 +            DispatchQueue(label: "pep.reachability", qos: .default, target: nil)
   11.82 +    }
   11.83 +    
   11.84 +    convenience init?(networkReachability: NetworkReachabilityProtocol) {
   11.85 +        self.init()
   11.86 +        self.networkReachability = networkReachability
   11.87 +    }
   11.88 +    
   11.89 +    deinit {
   11.90 +        stopNotifier()
   11.91 +    }
   11.92 +    
   11.93 +    /// Get current connection status
   11.94 +    ///
   11.95 +    /// - Parameters:
   11.96 +    ///   - completion: connected and not connected to internet
   11.97 +    ///   - failure: failToGetReachabilityState when failed to get internet status
   11.98 +    public func getConnectionStatus(completion: @escaping ((Connection)->()),
   11.99 +                                       failure: @escaping ((ReachabilityError) -> ()) ) {
  11.100 +        setReachabilityFlags(
  11.101 +            completion: { [weak self] flags in
  11.102 +                guard let `self` = self else { return }
  11.103 +                let connectionStatud = self.getConnectionStatus(fromFlags: flags)
  11.104 +                completion(connectionStatud)},
  11.105 +            failure: { error in
  11.106 +                failure(error)
  11.107 +        })
  11.108 +    }
  11.109 +    
  11.110 +    /// Start updating internet connection state through ReachabilityDelegate
  11.111 +    public func startNotifier() {
  11.112 +        guard !notifierRunning else { return }
  11.113 +        
  11.114 +        let callback: SCNetworkReachabilityCallBack = { (reachability, flags, info) in
  11.115 +            guard let info = info else { return }
  11.116 +            
  11.117 +            let reachability = Unmanaged<Reachability>.fromOpaque(info).takeUnretainedValue()
  11.118 +            reachability.flags = flags
  11.119 +        }
  11.120 +        
  11.121 +        var context = SCNetworkReachabilityContext(version: 0, info: nil, retain: nil, release: nil,
  11.122 +                                                   copyDescription: nil)
  11.123 +        context.info = UnsafeMutableRawPointer(Unmanaged<Reachability>.passUnretained(self).toOpaque())
  11.124 +        if !networkReachability.networkReachabilitySetCallback(reachabilityRef, callback, &context) {
  11.125 +            stopNotifier()
  11.126 +            delegate?.didFailToStartNotifier(error: .failToGetReachabilityState)
  11.127 +        }
  11.128 +        
  11.129 +        if !SCNetworkReachabilitySetDispatchQueue(reachabilityRef, reachabilitySerialQueue) {
  11.130 +            stopNotifier()
  11.131 +            delegate?.didFailToStartNotifier(error: .failToGetReachabilityState)
  11.132 +        }
  11.133 +        
  11.134 +        // Perform an initial check
  11.135 +        setReachabilityFlags(
  11.136 +            completion: { [weak self] flags in
  11.137 +                self?.flags = flags },
  11.138 +            failure: { [weak self] error in
  11.139 +                self?.stopNotifier()
  11.140 +                self?.delegate?.didFailToStartNotifier(error: error)
  11.141 +        })
  11.142 +        notifierRunning = true
  11.143 +    }
  11.144 +    
  11.145 +    /// Stop updating reachable value
  11.146 +    public func stopNotifier() {
  11.147 +        defer { notifierRunning = false }
  11.148 +        
  11.149 +        networkReachability.networkReachabilitySetCallback(reachabilityRef, nil, nil)
  11.150 +        SCNetworkReachabilitySetDispatchQueue(reachabilityRef, nil)
  11.151 +    }
  11.152 +}
  11.153 +
  11.154 +
  11.155 +// MARK: - Private methods
  11.156 +private extension Reachability {
  11.157 +    private func setReachabilityFlags(completion: @escaping ((SCNetworkReachabilityFlags)->()),
  11.158 +                                         failure: @escaping ((ReachabilityError) -> ()) ) {
  11.159 +        reachabilitySerialQueue.async { [weak self] in
  11.160 +            guard let `self` = self else { return }
  11.161 +            var flags = SCNetworkReachabilityFlags()
  11.162 +            guard self.networkReachability.networkReachabilityGetFlags(self.reachabilityRef, &flags) else {
  11.163 +                failure(.failToGetReachabilityState)
  11.164 +                return
  11.165 +            }
  11.166 +             completion(flags)
  11.167 +        }
  11.168 +    }
  11.169 +    
  11.170 +    private func getConnectionStatus(fromFlags: SCNetworkReachabilityFlags) -> Connection {
  11.171 +        return fromFlags.contains(.reachable) ? .connected : .notConnected
  11.172 +    }
  11.173 +    
  11.174 +    private func callDelegateDidChangeReachibilityIfNeeded(newFlags: SCNetworkReachabilityFlags?,
  11.175 +                                                           oldFlags: SCNetworkReachabilityFlags?){
  11.176 +        guard let newFlags = newFlags else { return }
  11.177 +        let newState = getConnectionStatus(fromFlags: newFlags)
  11.178 +        
  11.179 +        guard let oldFlags = oldFlags else {
  11.180 +            delegate?.didChangeReachability(status: newState)
  11.181 +            return
  11.182 +        }
  11.183 +        
  11.184 +        let oldState = getConnectionStatus(fromFlags: oldFlags)
  11.185 +        if newState == oldState { return }
  11.186 +        delegate?.didChangeReachability(status: newState)
  11.187 +    }
  11.188 +}
    12.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    12.2 +++ b/subModules/pEpIOSToolbox/pEpIOSToolbox/Other/Reachability/ReachabilityUtilsProtocol.swift	Mon Mar 18 11:12:42 2019 +0100
    12.3 @@ -0,0 +1,18 @@
    12.4 +//
    12.5 +//  ReachibilityUtilsProtocol.swift
    12.6 +//  pEp
    12.7 +//
    12.8 +//  Created by Alejandro Gelos on 14/02/2019.
    12.9 +//  Copyright © 2019 p≡p Security S.A. All rights reserved.
   12.10 +//
   12.11 +
   12.12 +import Foundation
   12.13 +
   12.14 +protocol ReachabilityUtilsProtocol {
   12.15 +    var delegate: ReachabilityDelegate? {get set}
   12.16 +    
   12.17 +    func getConnectionStatus(completion: @escaping ((Reachability.Connection)->()),
   12.18 +                                failure: @escaping ((Reachability.ReachabilityError) -> ()) )
   12.19 +    func startNotifier()
   12.20 +    func stopNotifier()
   12.21 +}
    13.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    13.2 +++ b/subModules/pEpIOSToolbox/pEpIOSToolboxTests/Other/ReachabilityUtilsTest/NetworkReachibilityMock.swift	Mon Mar 18 11:12:42 2019 +0100
    13.3 @@ -0,0 +1,56 @@
    13.4 +//
    13.5 +//  NetworkReachibilityMock.swift
    13.6 +//  pEpForiOSTests
    13.7 +//
    13.8 +//  Created by Alejandro Gelos on 13/02/2019.
    13.9 +//  Copyright © 2019 p≡p Security S.A. All rights reserved.
   13.10 +//
   13.11 +
   13.12 +import XCTest
   13.13 +import SystemConfiguration
   13.14 +@testable import pEpForiOS
   13.15 +
   13.16 +
   13.17 +class YesInternetReachabilityMock: NetworkReachabilityProtocol {
   13.18 +    let callback: SCNetworkReachabilityCallBack = { (reachability, flags, info) in
   13.19 +        guard let info = info else { return }
   13.20 +        
   13.21 +        let reachability = Unmanaged<Reachability>.fromOpaque(info).takeUnretainedValue()
   13.22 +        reachability.flags = [SCNetworkReachabilityFlags.reachable]
   13.23 +    }
   13.24 +    
   13.25 +    func networkReachabilityGetFlags(_ target: SCNetworkReachability,
   13.26 +                                     _ flags: UnsafeMutablePointer<SCNetworkReachabilityFlags>)
   13.27 +        -> Bool {
   13.28 +        flags.pointee = [SCNetworkReachabilityFlags.reachable]
   13.29 +        return true
   13.30 +    }
   13.31 +    
   13.32 +    @discardableResult func networkReachabilitySetCallback(_ target: SCNetworkReachability,
   13.33 +                                                           _ callout: SCNetworkReachabilityCallBack?,
   13.34 +                                     _ context: UnsafeMutablePointer<SCNetworkReachabilityContext>?)
   13.35 +        -> Bool {
   13.36 +        return SCNetworkReachabilitySetCallback(target, callback, context)
   13.37 +    }
   13.38 +}
   13.39 +
   13.40 +class NoInternetReachabilityMock: NetworkReachabilityProtocol {
   13.41 +    let callback: SCNetworkReachabilityCallBack = { (reachability, flags, info) in
   13.42 +        guard let info = info else { return }
   13.43 +        
   13.44 +        let reachability = Unmanaged<Reachability>.fromOpaque(info).takeUnretainedValue()
   13.45 +        reachability.flags = []
   13.46 +    }
   13.47 +    
   13.48 +    func networkReachabilityGetFlags(_ target: SCNetworkReachability,
   13.49 +                                     _ flags: UnsafeMutablePointer<SCNetworkReachabilityFlags>)
   13.50 +        -> Bool {
   13.51 +        flags.pointee = []
   13.52 +        return true
   13.53 +    }
   13.54 +    
   13.55 +    @discardableResult func networkReachabilitySetCallback(_ target: SCNetworkReachability, _ callout: SCNetworkReachabilityCallBack?, _ context: UnsafeMutablePointer<SCNetworkReachabilityContext>?)
   13.56 +        -> Bool {
   13.57 +        return SCNetworkReachabilitySetCallback(target, callback, context)
   13.58 +    }
   13.59 +}
    14.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    14.2 +++ b/subModules/pEpIOSToolbox/pEpIOSToolboxTests/Other/ReachabilityUtilsTest/ReachabilityUtilsTests.swift	Mon Mar 18 11:12:42 2019 +0100
    14.3 @@ -0,0 +1,134 @@
    14.4 +//
    14.5 +//  ReachabilityUtilsTests.swift
    14.6 +//  pEpForiOSTests
    14.7 +//
    14.8 +//  Created by Alejandro Gelos on 12/02/2019.
    14.9 +//  Copyright © 2019 p≡p Security S.A. All rights reserved.
   14.10 +//
   14.11 +
   14.12 +import XCTest
   14.13 +@testable import pEpForiOS
   14.14 +
   14.15 +class ReachibilityUtilsTests: XCTestCase {
   14.16 +    
   14.17 +    private var yesReachability: Reachability?
   14.18 +    private var noReachability:  Reachability?
   14.19 +    private let yesInternetNetworkReachibilityMock = YesInternetReachabilityMock()
   14.20 +    private let noInternetLocalNetworkReachibilityMock = NoInternetReachabilityMock()
   14.21 +    
   14.22 +    override func setUp() {
   14.23 +        yesReachability = Reachability(networkReachability: yesInternetNetworkReachibilityMock)
   14.24 +        noReachability  = Reachability(networkReachability: noInternetLocalNetworkReachibilityMock)
   14.25 +    }
   14.26 +    
   14.27 +    override func tearDown() {
   14.28 +        yesReachability = nil
   14.29 +        noReachability  = nil
   14.30 +        super.tearDown()
   14.31 +    }
   14.32 +    
   14.33 +    func testInit() {
   14.34 +        // Given
   14.35 +        // When
   14.36 +        let reachibility = Reachability()
   14.37 +        
   14.38 +        //Then
   14.39 +        XCTAssertNotNil(reachibility)
   14.40 +    }
   14.41 +    
   14.42 +    func testGetConnectionStatusYesInternet() {
   14.43 +        // Given
   14.44 +        guard let yesReachability = yesReachability else {
   14.45 +            XCTFail()
   14.46 +            return
   14.47 +        }
   14.48 +        // When
   14.49 +        yesReachability.getConnectionStatus(
   14.50 +            completion: { result in
   14.51 +                // Then
   14.52 +                XCTAssertTrue(result == Reachability.Connection.connected)
   14.53 +        },
   14.54 +            failure: { error in
   14.55 +                XCTFail()
   14.56 +        })
   14.57 +    }
   14.58 +    
   14.59 +    func testGetConnectionStatusNoInternet() {
   14.60 +        guard let noReachability = noReachability else {
   14.61 +            XCTFail()
   14.62 +            return
   14.63 +        }
   14.64 +        // When
   14.65 +        noReachability.getConnectionStatus(
   14.66 +            completion: { result in
   14.67 +                // Then
   14.68 +                XCTAssertFalse(result == Reachability.Connection.connected)
   14.69 +        },
   14.70 +            failure: { error in
   14.71 +                XCTFail()
   14.72 +        })
   14.73 +    }
   14.74 +    
   14.75 +    func testStartNotifierYesInternet(){
   14.76 +        // Given
   14.77 +        guard let yesReachability = yesReachability else {
   14.78 +            XCTFail()
   14.79 +            return
   14.80 +        }
   14.81 +        let exp = expectation(description: "delegate called for connected")
   14.82 +        let expectedConnected = Reachability.Connection.connected
   14.83 +        let testDelegate = ReachibilityUtilsTestsDelegate(withExp: exp,
   14.84 +                                                          withExpectedConnected: expectedConnected)
   14.85 +        yesReachability.delegate = testDelegate
   14.86 +        
   14.87 +        // When
   14.88 +        yesReachability.startNotifier()
   14.89 +        
   14.90 +        // Then
   14.91 +        waitForExpectations(timeout: TestUtil.waitTime)
   14.92 +    }
   14.93 +    
   14.94 +    func testStartNotifierNoInternet(){
   14.95 +        // Given
   14.96 +        guard let noReachability = noReachability else {
   14.97 +            XCTFail()
   14.98 +            return
   14.99 +        }
  14.100 +        let exp = expectation(description: "delegate called for no connected")
  14.101 +        let expectedNotConnected = Reachability.Connection.notConnected
  14.102 +        let testDelegate = ReachibilityUtilsTestsDelegate(withExp: exp,
  14.103 +                                                          withExpectedConnected: expectedNotConnected)
  14.104 +        noReachability.delegate = testDelegate
  14.105 +        
  14.106 +        // When
  14.107 +        noReachability.startNotifier()
  14.108 +        
  14.109 +        // Then
  14.110 +        waitForExpectations(timeout: TestUtil.waitTime)
  14.111 +    }
  14.112 +}
  14.113 +
  14.114 +// MARK: - ReachabilityDelegate
  14.115 +class ReachibilityUtilsTestsDelegate {
  14.116 +    let exp: XCTestExpectation
  14.117 +    var expedConnected: Reachability.Connection
  14.118 +    
  14.119 +    init(withExp exp: XCTestExpectation, withExpectedConnected expedConnected: Reachability.Connection) {
  14.120 +        self.exp = exp
  14.121 +        self.expedConnected = expedConnected
  14.122 +    }
  14.123 +}
  14.124 +
  14.125 +// MARK: - ReachabilityDelegate
  14.126 +extension ReachibilityUtilsTestsDelegate: ReachabilityDelegate{
  14.127 +    func didFailToStartNotifier(error: Reachability.ReachabilityError) {
  14.128 +        XCTFail()
  14.129 +        exp.fulfill()
  14.130 +    }
  14.131 +    
  14.132 +    func didChangeReachability(status: Reachability.Connection) {
  14.133 +        // Then
  14.134 +        XCTAssertEqual(status, expedConnected)
  14.135 +        exp.fulfill()
  14.136 +    }
  14.137 +}