Error[8]: Undefined offset: 8, File: /www/wwwroot/outofmemory.cn/tmp/plugin_ss_superseo_model_superseo.php, Line: 121
File: /www/wwwroot/outofmemory.cn/tmp/plugin_ss_superseo_model_superseo.php, Line: 473, decode(

使用Swift检查互联网连接

为了解决注释中提到的4G问题,我已使用@AshleyMills可达性实现作为参考并重写了Swift 3.1的Reachability:

更新: Xpre 10.1•Swift 4或更高版本


Reachability.swift文件

import Foundationimport SystemConfigurationclass Reachability {    var hostname: String?    var isRunning = false    var isReachableOnWWAN: Bool    var reachability: SCNetworkReachability?    var reachabilityFlags = SCNetworkReachabilityFlags()    let reachabilitySerialQueue = DispatchQueue(label: "ReachabilityQueue")    init(hostname: String) throws {        guard let reachability = SCNetworkReachabilityCreateWithName(nil, hostname) else { throw Network.Error.failedToCreateWith(hostname)        }        self.reachability = reachability        self.hostname = hostname        isReachableonWWAN = true        try start()    }    init() throws {        var zeroAddress = sockaddr_in()        zeroAddress.sin_len = UInt8(MemoryLayout<sockaddr_in>.size)        zeroAddress.sin_family = sa_family_t(AF_INET)        guard let reachability = withUnsafePointer(to: &zeroAddress, { 
extension Reachability {    func start() throws {        guard let reachability = reachability, !isRunning else { return }        var context = SCNetworkReachabilityContext(version: 0, info: nil, retain: nil, release: nil, copyDescription: nil)        context.info = Unmanaged<Reachability>.passUnretained(self).toOpaque()        guard SCNetworkReachabilitySetCallback(reachability, callout, &context) else { stop() throw Network.Error.failedToSetCallout        }        guard SCNetworkReachabilitySetDispatchQueue(reachability, reachabilitySerialQueue) else { stop() throw Network.Error.failedToSetDispatchQueue        }        reachabilitySerialQueue.async { self.flagsChanged() }        isRunning = true    }    func stop() {        defer { isRunning = false }        guard let reachability = reachability else { return }        SCNetworkReachabilitySetCallback(reachability, nil, nil)        SCNetworkReachabilitySetDispatchQueue(reachability, nil)        self.reachability = nil    }    var isConnectedToNetwork: Bool {        return isReachable &&    !isConnectionRequiredAndTransientConnection &&    !(isRunningonDevice && isWWAN && !isReachableOnWWAN)    }    var isReachableViaWiFi: Bool {        return isReachable && isRunningonDevice && !isWWAN    }    /// Flags that indicate the reachability of a network node name or address, including whether a connection is required, and whether some user intervention might be required when establishing a connection.    var flags: SCNetworkReachabilityFlags? {        guard let reachability = reachability else { return nil }        var flags = SCNetworkReachabilityFlags()        return withUnsafeMutablePointer(to: &flags) { SCNetworkReachabilityGetFlags(reachability, UnsafeMutablePointer(
func callout(reachability: SCNetworkReachability, flags: SCNetworkReachabilityFlags, info: UnsafeMutableRawPointer?) {    guard let info = info else { return }    DispatchQueue.main.async {        Unmanaged<Reachability> .fromOpaque(info) .takeUnretainedValue() .flagsChanged()    }}
)) } ? flags : nil } /// compares the current flags with the previous flags and if changed posts a flagsChanged notification func flagsChanged() { guard let flags = flags, flags != reachabilityFlags else { return } reachabilityFlags = flags NotificationCenter.default.post(name: .flagsChanged, object: self) } /// The specified node name or address can be reached via a transient connection, such as PPP. var transientConnection: Bool { return flags?.contains(.transientConnection) == true } /// The specified node name or address can be reached using the current network configuration. var isReachable: Bool { return flags?.contains(.reachable) == true } /// The specified node name or address can be reached using the current network configuration, but a connection must first be established. If this flag is set, the kSCNetworkReachabilityFlagsConnectionOnTraffic flag, kSCNetworkReachabilityFlagsConnectionOnDemand flag, or kSCNetworkReachabilityFlagsIsWWAN flag is also typically set to indicate the type of connection required. If the user must manually make the connection, the kSCNetworkReachabilityFlagsInterventionRequired flag is also set. var connectionRequired: Bool { return flags?.contains(.connectionRequired) == true } /// The specified node name or address can be reached using the current network configuration, but a connection must first be established. Any traffic directed to the specified name or address will initiate the connection. var connectionOnTraffic: Bool { return flags?.contains(.connectionOnTraffic) == true } /// The specified node name or address can be reached using the current network configuration, but a connection must first be established. var interventionRequired: Bool { return flags?.contains(.interventionRequired) == true } /// The specified node name or address can be reached using the current network configuration, but a connection must first be established. The connection will be established "On Demand" by the CFSocketStream programming interface (see CFStream Socket Additions for information on this). Other functions will not establish the connection. var connectionOnDemand: Bool { return flags?.contains(.connectionOnDemand) == true } /// The specified node name or address is one that is associated with a network interface on the current system. var isLocalAddress: Bool { return flags?.contains(.isLocalAddress) == true } /// Network traffic to the specified node name or address will not go through a gateway, but is routed directly to one of the interfaces in the system. var isDirect: Bool { return flags?.contains(.isDirect) == true } /// The specified node name or address can be reached via a cellular connection, such as EDGE or GPRS. var isWWAN: Bool { return flags?.contains(.isWWAN) == true } /// The specified node name or address can be reached using the current network configuration, but a connection must first be established. If this flag is set /// The specified node name or address can be reached via a transient connection, such as PPP. var isConnectionRequiredAndTransientConnection: Bool { return (flags?.intersection([.connectionRequired, .transientConnection]) == [.connectionRequired, .transientConnection]) == true }}
.withMemoryRebound(to: sockaddr.self, capacity: 1) { SCNetworkReachabilityCreateWithAddress(nil,
extension Notification.Name {    static let flagsChanged = Notification.Name("FlagsChanged")}
) } }) else { throw Network.Error.failedToInitializeWith(zeroAddress) } self.reachability = reachability isReachableonWWAN = true try start() } var status: Network.Status { return !isConnectedToNetwork ? .unreachable : isReachableViaWiFi ? .wifi : isRunningonDevice ? .wwan : .unreachable } var isRunningOnDevice: Bool = { #if targetEnvironment(simulator) return false #else return true #endif }() deinit { stop() }}

struct Network {    static var reachability: Reachability!    enum Status: String {        case unreachable, wifi, wwan    }    enum Error: Swift.Error {        case failedToSetCallout        case failedToSetDispatchQueue        case failedToCreateWith(String)        case failedToInitializeWith(sockaddr_in)    }}

import UIKit@UIApplicationMainclass AppDelegate: UIResponder, UIApplicationDelegate {    var window: UIWindow?    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {        do { try Network.reachability = Reachability(hostname: "www.google.com")        }        catch { switch error as? Network.Error { case let .failedToCreateWith(hostname)?:     print("Network error:nFailed to create reachability object With host named:", hostname) case let .failedToInitializeWith(address)?:     print("Network error:nFailed to initialize reachability object With address:", address) case .failedToSetCallout?:     print("Network error:nFailed to set callout") case .failedToSetDispatchQueue?:     print("Network error:nFailed to set DispatchQueue") case .none:     print(error) }        }        return true    }}

import UIKitclass ViewController: UIViewController {    override func viewDidLoad() {        super.viewDidLoad()        NotificationCenter.default .addObserver(self,   selector: #selector(statusManager),   name: .flagsChanged,   object: nil)        updateUserInterface()    }    func updateUserInterface() {        switch Network.reachability.status {        case .unreachable: view.backgroundColor = .red        case .wwan: view.backgroundColor = .yellow        case .wifi: view.backgroundColor = .green        }        print("Reachability Summary")        print("Status:", Network.reachability.status)        print("HostName:", Network.reachability.hostname ?? "nil")        print("Reachable:", Network.reachability.isReachable)        print("Wifi:", Network.reachability.isReachableViaWiFi)    }    @objc func statusManager(_ notification: Notification) {        updateUserInterface()    }}

[+++]

用法

在您的AppDelegate.swift didFinishLaunchingWithOptions方法中对其进行初始化,并处理可能发生的任何错误:

[+++]

和一个视图控制器示例:

[+++]

样例项目



)
File: /www/wwwroot/outofmemory.cn/tmp/route_read.php, Line: 126, InsideLink()
File: /www/wwwroot/outofmemory.cn/tmp/index.inc.php, Line: 166, include(/www/wwwroot/outofmemory.cn/tmp/route_read.php)
File: /www/wwwroot/outofmemory.cn/index.php, Line: 30, include(/www/wwwroot/outofmemory.cn/tmp/index.inc.php)
Error[8]: Undefined offset: 9, File: /www/wwwroot/outofmemory.cn/tmp/plugin_ss_superseo_model_superseo.php, Line: 121
File: /www/wwwroot/outofmemory.cn/tmp/plugin_ss_superseo_model_superseo.php, Line: 473, decode(

使用Swift检查互联网连接

为了解决注释中提到的4G问题,我已使用@AshleyMills可达性实现作为参考并重写了Swift 3.1的Reachability:

更新: Xpre 10.1•Swift 4或更高版本


Reachability.swift文件

import Foundationimport SystemConfigurationclass Reachability {    var hostname: String?    var isRunning = false    var isReachableOnWWAN: Bool    var reachability: SCNetworkReachability?    var reachabilityFlags = SCNetworkReachabilityFlags()    let reachabilitySerialQueue = DispatchQueue(label: "ReachabilityQueue")    init(hostname: String) throws {        guard let reachability = SCNetworkReachabilityCreateWithName(nil, hostname) else { throw Network.Error.failedToCreateWith(hostname)        }        self.reachability = reachability        self.hostname = hostname        isReachableonWWAN = true        try start()    }    init() throws {        var zeroAddress = sockaddr_in()        zeroAddress.sin_len = UInt8(MemoryLayout<sockaddr_in>.size)        zeroAddress.sin_family = sa_family_t(AF_INET)        guard let reachability = withUnsafePointer(to: &zeroAddress, { 
extension Reachability {    func start() throws {        guard let reachability = reachability, !isRunning else { return }        var context = SCNetworkReachabilityContext(version: 0, info: nil, retain: nil, release: nil, copyDescription: nil)        context.info = Unmanaged<Reachability>.passUnretained(self).toOpaque()        guard SCNetworkReachabilitySetCallback(reachability, callout, &context) else { stop() throw Network.Error.failedToSetCallout        }        guard SCNetworkReachabilitySetDispatchQueue(reachability, reachabilitySerialQueue) else { stop() throw Network.Error.failedToSetDispatchQueue        }        reachabilitySerialQueue.async { self.flagsChanged() }        isRunning = true    }    func stop() {        defer { isRunning = false }        guard let reachability = reachability else { return }        SCNetworkReachabilitySetCallback(reachability, nil, nil)        SCNetworkReachabilitySetDispatchQueue(reachability, nil)        self.reachability = nil    }    var isConnectedToNetwork: Bool {        return isReachable &&    !isConnectionRequiredAndTransientConnection &&    !(isRunningonDevice && isWWAN && !isReachableOnWWAN)    }    var isReachableViaWiFi: Bool {        return isReachable && isRunningonDevice && !isWWAN    }    /// Flags that indicate the reachability of a network node name or address, including whether a connection is required, and whether some user intervention might be required when establishing a connection.    var flags: SCNetworkReachabilityFlags? {        guard let reachability = reachability else { return nil }        var flags = SCNetworkReachabilityFlags()        return withUnsafeMutablePointer(to: &flags) { SCNetworkReachabilityGetFlags(reachability, UnsafeMutablePointer(
func callout(reachability: SCNetworkReachability, flags: SCNetworkReachabilityFlags, info: UnsafeMutableRawPointer?) {    guard let info = info else { return }    DispatchQueue.main.async {        Unmanaged<Reachability> .fromOpaque(info) .takeUnretainedValue() .flagsChanged()    }}
)) } ? flags : nil } /// compares the current flags with the previous flags and if changed posts a flagsChanged notification func flagsChanged() { guard let flags = flags, flags != reachabilityFlags else { return } reachabilityFlags = flags NotificationCenter.default.post(name: .flagsChanged, object: self) } /// The specified node name or address can be reached via a transient connection, such as PPP. var transientConnection: Bool { return flags?.contains(.transientConnection) == true } /// The specified node name or address can be reached using the current network configuration. var isReachable: Bool { return flags?.contains(.reachable) == true } /// The specified node name or address can be reached using the current network configuration, but a connection must first be established. If this flag is set, the kSCNetworkReachabilityFlagsConnectionOnTraffic flag, kSCNetworkReachabilityFlagsConnectionOnDemand flag, or kSCNetworkReachabilityFlagsIsWWAN flag is also typically set to indicate the type of connection required. If the user must manually make the connection, the kSCNetworkReachabilityFlagsInterventionRequired flag is also set. var connectionRequired: Bool { return flags?.contains(.connectionRequired) == true } /// The specified node name or address can be reached using the current network configuration, but a connection must first be established. Any traffic directed to the specified name or address will initiate the connection. var connectionOnTraffic: Bool { return flags?.contains(.connectionOnTraffic) == true } /// The specified node name or address can be reached using the current network configuration, but a connection must first be established. var interventionRequired: Bool { return flags?.contains(.interventionRequired) == true } /// The specified node name or address can be reached using the current network configuration, but a connection must first be established. The connection will be established "On Demand" by the CFSocketStream programming interface (see CFStream Socket Additions for information on this). Other functions will not establish the connection. var connectionOnDemand: Bool { return flags?.contains(.connectionOnDemand) == true } /// The specified node name or address is one that is associated with a network interface on the current system. var isLocalAddress: Bool { return flags?.contains(.isLocalAddress) == true } /// Network traffic to the specified node name or address will not go through a gateway, but is routed directly to one of the interfaces in the system. var isDirect: Bool { return flags?.contains(.isDirect) == true } /// The specified node name or address can be reached via a cellular connection, such as EDGE or GPRS. var isWWAN: Bool { return flags?.contains(.isWWAN) == true } /// The specified node name or address can be reached using the current network configuration, but a connection must first be established. If this flag is set /// The specified node name or address can be reached via a transient connection, such as PPP. var isConnectionRequiredAndTransientConnection: Bool { return (flags?.intersection([.connectionRequired, .transientConnection]) == [.connectionRequired, .transientConnection]) == true }}
.withMemoryRebound(to: sockaddr.self, capacity: 1) { SCNetworkReachabilityCreateWithAddress(nil,
extension Notification.Name {    static let flagsChanged = Notification.Name("FlagsChanged")}
) } }) else { throw Network.Error.failedToInitializeWith(zeroAddress) } self.reachability = reachability isReachableonWWAN = true try start() } var status: Network.Status { return !isConnectedToNetwork ? .unreachable : isReachableViaWiFi ? .wifi : isRunningonDevice ? .wwan : .unreachable } var isRunningOnDevice: Bool = { #if targetEnvironment(simulator) return false #else return true #endif }() deinit { stop() }}

struct Network {    static var reachability: Reachability!    enum Status: String {        case unreachable, wifi, wwan    }    enum Error: Swift.Error {        case failedToSetCallout        case failedToSetDispatchQueue        case failedToCreateWith(String)        case failedToInitializeWith(sockaddr_in)    }}

import UIKit@UIApplicationMainclass AppDelegate: UIResponder, UIApplicationDelegate {    var window: UIWindow?    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {        do { try Network.reachability = Reachability(hostname: "www.google.com")        }        catch { switch error as? Network.Error { case let .failedToCreateWith(hostname)?:     print("Network error:nFailed to create reachability object With host named:", hostname) case let .failedToInitializeWith(address)?:     print("Network error:nFailed to initialize reachability object With address:", address) case .failedToSetCallout?:     print("Network error:nFailed to set callout") case .failedToSetDispatchQueue?:     print("Network error:nFailed to set DispatchQueue") case .none:     print(error) }        }        return true    }}

import UIKitclass ViewController: UIViewController {    override func viewDidLoad() {        super.viewDidLoad()        NotificationCenter.default .addObserver(self,   selector: #selector(statusManager),   name: .flagsChanged,   object: nil)        updateUserInterface()    }    func updateUserInterface() {        switch Network.reachability.status {        case .unreachable: view.backgroundColor = .red        case .wwan: view.backgroundColor = .yellow        case .wifi: view.backgroundColor = .green        }        print("Reachability Summary")        print("Status:", Network.reachability.status)        print("HostName:", Network.reachability.hostname ?? "nil")        print("Reachable:", Network.reachability.isReachable)        print("Wifi:", Network.reachability.isReachableViaWiFi)    }    @objc func statusManager(_ notification: Notification) {        updateUserInterface()    }}


用法

在您的AppDelegate.swift didFinishLaunchingWithOptions方法中对其进行初始化,并处理可能发生的任何错误:

[+++]

和一个视图控制器示例:

[+++]

样例项目



)
File: /www/wwwroot/outofmemory.cn/tmp/route_read.php, Line: 126, InsideLink()
File: /www/wwwroot/outofmemory.cn/tmp/index.inc.php, Line: 166, include(/www/wwwroot/outofmemory.cn/tmp/route_read.php)
File: /www/wwwroot/outofmemory.cn/index.php, Line: 30, include(/www/wwwroot/outofmemory.cn/tmp/index.inc.php)
Error[8]: Undefined offset: 10, File: /www/wwwroot/outofmemory.cn/tmp/plugin_ss_superseo_model_superseo.php, Line: 121
File: /www/wwwroot/outofmemory.cn/tmp/plugin_ss_superseo_model_superseo.php, Line: 473, decode(

使用Swift检查互联网连接

为了解决注释中提到的4G问题,我已使用@AshleyMills可达性实现作为参考并重写了Swift 3.1的Reachability:

更新: Xpre 10.1•Swift 4或更高版本


Reachability.swift文件

import Foundationimport SystemConfigurationclass Reachability {    var hostname: String?    var isRunning = false    var isReachableOnWWAN: Bool    var reachability: SCNetworkReachability?    var reachabilityFlags = SCNetworkReachabilityFlags()    let reachabilitySerialQueue = DispatchQueue(label: "ReachabilityQueue")    init(hostname: String) throws {        guard let reachability = SCNetworkReachabilityCreateWithName(nil, hostname) else { throw Network.Error.failedToCreateWith(hostname)        }        self.reachability = reachability        self.hostname = hostname        isReachableonWWAN = true        try start()    }    init() throws {        var zeroAddress = sockaddr_in()        zeroAddress.sin_len = UInt8(MemoryLayout<sockaddr_in>.size)        zeroAddress.sin_family = sa_family_t(AF_INET)        guard let reachability = withUnsafePointer(to: &zeroAddress, { 
extension Reachability {    func start() throws {        guard let reachability = reachability, !isRunning else { return }        var context = SCNetworkReachabilityContext(version: 0, info: nil, retain: nil, release: nil, copyDescription: nil)        context.info = Unmanaged<Reachability>.passUnretained(self).toOpaque()        guard SCNetworkReachabilitySetCallback(reachability, callout, &context) else { stop() throw Network.Error.failedToSetCallout        }        guard SCNetworkReachabilitySetDispatchQueue(reachability, reachabilitySerialQueue) else { stop() throw Network.Error.failedToSetDispatchQueue        }        reachabilitySerialQueue.async { self.flagsChanged() }        isRunning = true    }    func stop() {        defer { isRunning = false }        guard let reachability = reachability else { return }        SCNetworkReachabilitySetCallback(reachability, nil, nil)        SCNetworkReachabilitySetDispatchQueue(reachability, nil)        self.reachability = nil    }    var isConnectedToNetwork: Bool {        return isReachable &&    !isConnectionRequiredAndTransientConnection &&    !(isRunningonDevice && isWWAN && !isReachableOnWWAN)    }    var isReachableViaWiFi: Bool {        return isReachable && isRunningonDevice && !isWWAN    }    /// Flags that indicate the reachability of a network node name or address, including whether a connection is required, and whether some user intervention might be required when establishing a connection.    var flags: SCNetworkReachabilityFlags? {        guard let reachability = reachability else { return nil }        var flags = SCNetworkReachabilityFlags()        return withUnsafeMutablePointer(to: &flags) { SCNetworkReachabilityGetFlags(reachability, UnsafeMutablePointer(
func callout(reachability: SCNetworkReachability, flags: SCNetworkReachabilityFlags, info: UnsafeMutableRawPointer?) {    guard let info = info else { return }    DispatchQueue.main.async {        Unmanaged<Reachability> .fromOpaque(info) .takeUnretainedValue() .flagsChanged()    }}
)) } ? flags : nil } /// compares the current flags with the previous flags and if changed posts a flagsChanged notification func flagsChanged() { guard let flags = flags, flags != reachabilityFlags else { return } reachabilityFlags = flags NotificationCenter.default.post(name: .flagsChanged, object: self) } /// The specified node name or address can be reached via a transient connection, such as PPP. var transientConnection: Bool { return flags?.contains(.transientConnection) == true } /// The specified node name or address can be reached using the current network configuration. var isReachable: Bool { return flags?.contains(.reachable) == true } /// The specified node name or address can be reached using the current network configuration, but a connection must first be established. If this flag is set, the kSCNetworkReachabilityFlagsConnectionOnTraffic flag, kSCNetworkReachabilityFlagsConnectionOnDemand flag, or kSCNetworkReachabilityFlagsIsWWAN flag is also typically set to indicate the type of connection required. If the user must manually make the connection, the kSCNetworkReachabilityFlagsInterventionRequired flag is also set. var connectionRequired: Bool { return flags?.contains(.connectionRequired) == true } /// The specified node name or address can be reached using the current network configuration, but a connection must first be established. Any traffic directed to the specified name or address will initiate the connection. var connectionOnTraffic: Bool { return flags?.contains(.connectionOnTraffic) == true } /// The specified node name or address can be reached using the current network configuration, but a connection must first be established. var interventionRequired: Bool { return flags?.contains(.interventionRequired) == true } /// The specified node name or address can be reached using the current network configuration, but a connection must first be established. The connection will be established "On Demand" by the CFSocketStream programming interface (see CFStream Socket Additions for information on this). Other functions will not establish the connection. var connectionOnDemand: Bool { return flags?.contains(.connectionOnDemand) == true } /// The specified node name or address is one that is associated with a network interface on the current system. var isLocalAddress: Bool { return flags?.contains(.isLocalAddress) == true } /// Network traffic to the specified node name or address will not go through a gateway, but is routed directly to one of the interfaces in the system. var isDirect: Bool { return flags?.contains(.isDirect) == true } /// The specified node name or address can be reached via a cellular connection, such as EDGE or GPRS. var isWWAN: Bool { return flags?.contains(.isWWAN) == true } /// The specified node name or address can be reached using the current network configuration, but a connection must first be established. If this flag is set /// The specified node name or address can be reached via a transient connection, such as PPP. var isConnectionRequiredAndTransientConnection: Bool { return (flags?.intersection([.connectionRequired, .transientConnection]) == [.connectionRequired, .transientConnection]) == true }}
.withMemoryRebound(to: sockaddr.self, capacity: 1) { SCNetworkReachabilityCreateWithAddress(nil,
extension Notification.Name {    static let flagsChanged = Notification.Name("FlagsChanged")}
) } }) else { throw Network.Error.failedToInitializeWith(zeroAddress) } self.reachability = reachability isReachableonWWAN = true try start() } var status: Network.Status { return !isConnectedToNetwork ? .unreachable : isReachableViaWiFi ? .wifi : isRunningonDevice ? .wwan : .unreachable } var isRunningOnDevice: Bool = { #if targetEnvironment(simulator) return false #else return true #endif }() deinit { stop() }}

struct Network {    static var reachability: Reachability!    enum Status: String {        case unreachable, wifi, wwan    }    enum Error: Swift.Error {        case failedToSetCallout        case failedToSetDispatchQueue        case failedToCreateWith(String)        case failedToInitializeWith(sockaddr_in)    }}

import UIKit@UIApplicationMainclass AppDelegate: UIResponder, UIApplicationDelegate {    var window: UIWindow?    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {        do { try Network.reachability = Reachability(hostname: "www.google.com")        }        catch { switch error as? Network.Error { case let .failedToCreateWith(hostname)?:     print("Network error:nFailed to create reachability object With host named:", hostname) case let .failedToInitializeWith(address)?:     print("Network error:nFailed to initialize reachability object With address:", address) case .failedToSetCallout?:     print("Network error:nFailed to set callout") case .failedToSetDispatchQueue?:     print("Network error:nFailed to set DispatchQueue") case .none:     print(error) }        }        return true    }}

import UIKitclass ViewController: UIViewController {    override func viewDidLoad() {        super.viewDidLoad()        NotificationCenter.default .addObserver(self,   selector: #selector(statusManager),   name: .flagsChanged,   object: nil)        updateUserInterface()    }    func updateUserInterface() {        switch Network.reachability.status {        case .unreachable: view.backgroundColor = .red        case .wwan: view.backgroundColor = .yellow        case .wifi: view.backgroundColor = .green        }        print("Reachability Summary")        print("Status:", Network.reachability.status)        print("HostName:", Network.reachability.hostname ?? "nil")        print("Reachable:", Network.reachability.isReachable)        print("Wifi:", Network.reachability.isReachableViaWiFi)    }    @objc func statusManager(_ notification: Notification) {        updateUserInterface()    }}


用法

在您的AppDelegate.swift didFinishLaunchingWithOptions方法中对其进行初始化,并处理可能发生的任何错误:


和一个视图控制器示例:

[+++]

样例项目



)
File: /www/wwwroot/outofmemory.cn/tmp/route_read.php, Line: 126, InsideLink()
File: /www/wwwroot/outofmemory.cn/tmp/index.inc.php, Line: 166, include(/www/wwwroot/outofmemory.cn/tmp/route_read.php)
File: /www/wwwroot/outofmemory.cn/index.php, Line: 30, include(/www/wwwroot/outofmemory.cn/tmp/index.inc.php)
使用Swift检查互联网连接_随笔_内存溢出

使用Swift检查互联网连接

使用Swift检查互联网连接,第1张

使用Swift检查互联网连接

为了解决注释中提到的4G问题,我已使用@AshleyMills可达性实现作为参考并重写了Swift 3.1的Reachability:

更新: Xpre 10.1•Swift 4或更高版本


Reachability.swift文件

import Foundationimport SystemConfigurationclass Reachability {    var hostname: String?    var isRunning = false    var isReachableOnWWAN: Bool    var reachability: SCNetworkReachability?    var reachabilityFlags = SCNetworkReachabilityFlags()    let reachabilitySerialQueue = DispatchQueue(label: "ReachabilityQueue")    init(hostname: String) throws {        guard let reachability = SCNetworkReachabilityCreateWithName(nil, hostname) else { throw Network.Error.failedToCreateWith(hostname)        }        self.reachability = reachability        self.hostname = hostname        isReachableonWWAN = true        try start()    }    init() throws {        var zeroAddress = sockaddr_in()        zeroAddress.sin_len = UInt8(MemoryLayout<sockaddr_in>.size)        zeroAddress.sin_family = sa_family_t(AF_INET)        guard let reachability = withUnsafePointer(to: &zeroAddress, { 
extension Reachability {    func start() throws {        guard let reachability = reachability, !isRunning else { return }        var context = SCNetworkReachabilityContext(version: 0, info: nil, retain: nil, release: nil, copyDescription: nil)        context.info = Unmanaged<Reachability>.passUnretained(self).toOpaque()        guard SCNetworkReachabilitySetCallback(reachability, callout, &context) else { stop() throw Network.Error.failedToSetCallout        }        guard SCNetworkReachabilitySetDispatchQueue(reachability, reachabilitySerialQueue) else { stop() throw Network.Error.failedToSetDispatchQueue        }        reachabilitySerialQueue.async { self.flagsChanged() }        isRunning = true    }    func stop() {        defer { isRunning = false }        guard let reachability = reachability else { return }        SCNetworkReachabilitySetCallback(reachability, nil, nil)        SCNetworkReachabilitySetDispatchQueue(reachability, nil)        self.reachability = nil    }    var isConnectedToNetwork: Bool {        return isReachable &&    !isConnectionRequiredAndTransientConnection &&    !(isRunningonDevice && isWWAN && !isReachableOnWWAN)    }    var isReachableViaWiFi: Bool {        return isReachable && isRunningonDevice && !isWWAN    }    /// Flags that indicate the reachability of a network node name or address, including whether a connection is required, and whether some user intervention might be required when establishing a connection.    var flags: SCNetworkReachabilityFlags? {        guard let reachability = reachability else { return nil }        var flags = SCNetworkReachabilityFlags()        return withUnsafeMutablePointer(to: &flags) { SCNetworkReachabilityGetFlags(reachability, UnsafeMutablePointer(
func callout(reachability: SCNetworkReachability, flags: SCNetworkReachabilityFlags, info: UnsafeMutableRawPointer?) {    guard let info = info else { return }    DispatchQueue.main.async {        Unmanaged<Reachability> .fromOpaque(info) .takeUnretainedValue() .flagsChanged()    }}
)) } ? flags : nil } /// compares the current flags with the previous flags and if changed posts a flagsChanged notification func flagsChanged() { guard let flags = flags, flags != reachabilityFlags else { return } reachabilityFlags = flags NotificationCenter.default.post(name: .flagsChanged, object: self) } /// The specified node name or address can be reached via a transient connection, such as PPP. var transientConnection: Bool { return flags?.contains(.transientConnection) == true } /// The specified node name or address can be reached using the current network configuration. var isReachable: Bool { return flags?.contains(.reachable) == true } /// The specified node name or address can be reached using the current network configuration, but a connection must first be established. If this flag is set, the kSCNetworkReachabilityFlagsConnectionOnTraffic flag, kSCNetworkReachabilityFlagsConnectionOnDemand flag, or kSCNetworkReachabilityFlagsIsWWAN flag is also typically set to indicate the type of connection required. If the user must manually make the connection, the kSCNetworkReachabilityFlagsInterventionRequired flag is also set. var connectionRequired: Bool { return flags?.contains(.connectionRequired) == true } /// The specified node name or address can be reached using the current network configuration, but a connection must first be established. Any traffic directed to the specified name or address will initiate the connection. var connectionOnTraffic: Bool { return flags?.contains(.connectionOnTraffic) == true } /// The specified node name or address can be reached using the current network configuration, but a connection must first be established. var interventionRequired: Bool { return flags?.contains(.interventionRequired) == true } /// The specified node name or address can be reached using the current network configuration, but a connection must first be established. The connection will be established "On Demand" by the CFSocketStream programming interface (see CFStream Socket Additions for information on this). Other functions will not establish the connection. var connectionOnDemand: Bool { return flags?.contains(.connectionOnDemand) == true } /// The specified node name or address is one that is associated with a network interface on the current system. var isLocalAddress: Bool { return flags?.contains(.isLocalAddress) == true } /// Network traffic to the specified node name or address will not go through a gateway, but is routed directly to one of the interfaces in the system. var isDirect: Bool { return flags?.contains(.isDirect) == true } /// The specified node name or address can be reached via a cellular connection, such as EDGE or GPRS. var isWWAN: Bool { return flags?.contains(.isWWAN) == true } /// The specified node name or address can be reached using the current network configuration, but a connection must first be established. If this flag is set /// The specified node name or address can be reached via a transient connection, such as PPP. var isConnectionRequiredAndTransientConnection: Bool { return (flags?.intersection([.connectionRequired, .transientConnection]) == [.connectionRequired, .transientConnection]) == true }}
.withMemoryRebound(to: sockaddr.self, capacity: 1) { SCNetworkReachabilityCreateWithAddress(nil,
extension Notification.Name {    static let flagsChanged = Notification.Name("FlagsChanged")}
) } }) else { throw Network.Error.failedToInitializeWith(zeroAddress) } self.reachability = reachability isReachableonWWAN = true try start() } var status: Network.Status { return !isConnectedToNetwork ? .unreachable : isReachableViaWiFi ? .wifi : isRunningonDevice ? .wwan : .unreachable } var isRunningOnDevice: Bool = { #if targetEnvironment(simulator) return false #else return true #endif }() deinit { stop() }}

struct Network {    static var reachability: Reachability!    enum Status: String {        case unreachable, wifi, wwan    }    enum Error: Swift.Error {        case failedToSetCallout        case failedToSetDispatchQueue        case failedToCreateWith(String)        case failedToInitializeWith(sockaddr_in)    }}

import UIKit@UIApplicationMainclass AppDelegate: UIResponder, UIApplicationDelegate {    var window: UIWindow?    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {        do { try Network.reachability = Reachability(hostname: "www.google.com")        }        catch { switch error as? Network.Error { case let .failedToCreateWith(hostname)?:     print("Network error:nFailed to create reachability object With host named:", hostname) case let .failedToInitializeWith(address)?:     print("Network error:nFailed to initialize reachability object With address:", address) case .failedToSetCallout?:     print("Network error:nFailed to set callout") case .failedToSetDispatchQueue?:     print("Network error:nFailed to set DispatchQueue") case .none:     print(error) }        }        return true    }}

import UIKitclass ViewController: UIViewController {    override func viewDidLoad() {        super.viewDidLoad()        NotificationCenter.default .addObserver(self,   selector: #selector(statusManager),   name: .flagsChanged,   object: nil)        updateUserInterface()    }    func updateUserInterface() {        switch Network.reachability.status {        case .unreachable: view.backgroundColor = .red        case .wwan: view.backgroundColor = .yellow        case .wifi: view.backgroundColor = .green        }        print("Reachability Summary")        print("Status:", Network.reachability.status)        print("HostName:", Network.reachability.hostname ?? "nil")        print("Reachable:", Network.reachability.isReachable)        print("Wifi:", Network.reachability.isReachableViaWiFi)    }    @objc func statusManager(_ notification: Notification) {        updateUserInterface()    }}


用法

在您的AppDelegate.swift didFinishLaunchingWithOptions方法中对其进行初始化,并处理可能发生的任何错误:


和一个视图控制器示例:

样例项目



欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5662452.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-16
下一篇 2022-12-16

发表评论

登录后才能评论

评论列表(0条)

保存