溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

iOS12+中檢測網(wǎng)絡(luò)訪問的方法是什么

發(fā)布時(shí)間:2021-11-05 10:11:54 來源:億速云 閱讀:251 作者:iii 欄目:編程語言

本篇內(nèi)容主要講解“iOS12+中檢測網(wǎng)絡(luò)訪問的方法是什么”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實(shí)用性強(qiáng)。下面就讓小編來帶大家學(xué)習(xí)“iOS12+中檢測網(wǎng)絡(luò)訪問的方法是什么”吧!

多年來,Apple 的 Reachability 示例程序一直被用作 App 中檢測網(wǎng)絡(luò)訪問的基礎(chǔ)代碼。搜索 Cocoapods.org 將會(huì)看到一個(gè)很長的第三方庫列表,這些庫基本上都是基于 Reachability,并考慮了 ARC 的支持或 Swift 的兼容等問題。在 WWDC 2018 上,Apple 介紹了 iOS 12 中的一個(gè)新的框架:Network.framework,該框架包含了一個(gè) NWPathMonitor 類。這個(gè)類為我們提供了一種監(jiān)視網(wǎng)絡(luò)狀態(tài)變化的方法,而無需包含第三方庫或 Apple 示例代碼。

使用

只需簡單導(dǎo)入 Network 框架,便可以使用 NWPathMonitor 類,如下創(chuàng)建一個(gè) NWPathMonitor 實(shí)例:

let monitor = NWPathMonitor()

如果你只對某個(gè)特定網(wǎng)絡(luò)適配器的狀態(tài)變更感興趣,例如 Wi-Fi,則可以使用 init(requiredInterfaceType:) 初始化方法,并提供 NWInterface.InterfaceType 值作為參數(shù),來實(shí)例化 NWPathMonitor 對象,以監(jiān)聽指定類型的網(wǎng)絡(luò)適配器,例如:

let monitor = NWPathMonitor(requiredInterfaceType: .wifi)

您需要確保在某處保留對 NWPathMonitor 對象的引用(例如使用 strong 屬性),否則 ARC 可能會(huì)釋放 NWPathMonitor 對象,從而導(dǎo)致指定的回調(diào)無法被調(diào)用。

可監(jiān)控的網(wǎng)絡(luò)類型包括:

cellularloopbackother (對于虛擬或未確定的網(wǎng)絡(luò)類型)wifiwiredEthernet

要獲取狀態(tài)更改的通知,需要為 pathUpdateHandler 屬性指定一個(gè)回調(diào),該回調(diào)將在網(wǎng)絡(luò)接口發(fā)生狀態(tài)更改時(shí)調(diào)用。例如,你的手機(jī)網(wǎng)絡(luò)從蜂窩網(wǎng)絡(luò)切換到 Wi-Fi 網(wǎng)絡(luò)。然后,每當(dāng)發(fā)生狀態(tài)更改時(shí),將返回一個(gè) NWPath 實(shí)例,可以使用該實(shí)例以確定后續(xù)的操作,如下代碼:

monitor.pathUpdateHandler = { path in  if path.status == .satisfied {    print("Connected")  }}

使用無參初始化方法與使用指定網(wǎng)絡(luò)適配器的初始化方法的不同點(diǎn)是:返回的 NWPathobject 對象的 status 屬性是否是 satisfied。例如,你只想監(jiān)聽蜂窩網(wǎng)絡(luò),而你的手機(jī)連接的是 Wi-Fi 網(wǎng)絡(luò),則當(dāng) Wi-Fi 網(wǎng)絡(luò)狀態(tài)發(fā)生變化時(shí),并不會(huì)調(diào)用回調(diào)方法,并且 path 的 status 也會(huì)保持 unsatisfied 狀態(tài),因?yàn)槭謾C(jī)沒有使用指定的網(wǎng)絡(luò)連接。所以,如果你只想知道是否有網(wǎng)絡(luò)連接,無論是 Wi-Fi 還是蜂窩,則最好使用無參數(shù)的初始化方法。

一個(gè)有趣的問題是,NWPath 在 iOS 12 中是作為 Network 框架的一部分,而實(shí)際上在 iOS 9 中就有它的身影,不過是在 NetworkExtension.framework,兩者之間有一些細(xì)微差別。

可以查詢返回的 NWPath 對象,以查看設(shè)備的網(wǎng)絡(luò)適配器的狀態(tài)信息。另一個(gè)更有趣的屬性是 isExpensive,它標(biāo)識網(wǎng)絡(luò)接口返回的數(shù)據(jù)收費(fèi)是否昂貴,如使用蜂窩數(shù)據(jù)。我們同樣可以查詢是否支持 DNS、IPv4 或 IPv6。我們可以調(diào)用 usesInterfaceType 方法,來查看哪個(gè)接口改變了狀態(tài)并觸發(fā)回調(diào):

let isCellular: Bool = path.usesInterfaceType(.cellular)

使用 NWPathMonitor 有點(diǎn)類似于使用其他 iOS API,例如 CLLocationManager,我們需要調(diào)用 start 方法以便開始接收更新,然后在完成后調(diào)用對應(yīng)的 stop 方法。NWPathMonitor 的 start 方法要求我們?yōu)閷ο筇峁┮粋€(gè)隊(duì)列來執(zhí)行其工作:

let queue = DispatchQueue.global(qos: .background)monitor.start(queue: queue)

當(dāng)我們完成監(jiān)聽狀態(tài)的變化時(shí),我們只需在調(diào)用 cancel() 方法。請注意,目前在 NWPathMonitor 上調(diào)用 cancel 后,我們無法再次啟動(dòng)監(jiān)聽,而是需要實(shí)例化一個(gè)新的 NWPathMonitor 實(shí)例。請注意,如果在調(diào)用 start() 之前訪問 NWPathMonitor 的 currentPath 屬性,將返回 nil。實(shí)際上,如果你打印返回到更新回調(diào)的 path,如下所示:

monitor.pathUpdateHandler = { path in  print(path)}

則會(huì)打印以下內(nèi)容:

Optional(satisfied (Path is satisfied), interface: en0, scoped, ipv4, ipv6, dns)

這表明此處返回的 NWPaths 和 currentPath 屬性是可選項(xiàng),盡管 API 沒有明確說明(我們可以推斷返回的 NWPath 引用是橋接到 Swift 的 Objective-C 指針)。

Captive Portals

Captive Portal 是在公共 Wi-Fi 熱點(diǎn)連接時(shí)顯示的網(wǎng)頁,通常用于在授權(quán)訪問 Internet(或訪問其他網(wǎng)絡(luò)資源)之前強(qiáng)制登錄、注冊或支付。在之前的一篇博客中,我談到了從 App 開發(fā)的的角度來看,Reachability 看起來好像沒什么問題,但實(shí)際上由于有 Captive Portals,它并不能很好完成任務(wù)。這可能導(dǎo)致 App 無法正常工作甚至于崩潰 -- 因?yàn)?App 可能期望從 RESTful API 中獲取一些 JSON 數(shù)據(jù),卻從 Captive Portals 獲取到了一些 HTML。

我之前很好奇 NWPathMonitor 在檢測網(wǎng)絡(luò)連接方面是否比 Reachability 有所改進(jìn)。NWPath.Status 枚舉確實(shí)提供了三種情況 -- satisfied、 unsatisfied 和 requiresConnection。不幸的是,Network.framework 的開發(fā)者文檔并未提供這些枚舉值的使用說明,而如果我們查看 NetworkExtension.framework 文檔,其中的 NWPathStatus 對象提供了 satisfiable 枚舉值,里面有一些相關(guān)文檔描述:

The path is not currently satisfied, but may become satisfied upon a connection attempt. This can be due to a service, such as a VPN or a cellular data connection not being activated.

requiresConnection 枚舉值似乎類似于 NWPathStatus 對象的 satisfiable 值。好消息是 NWPathMonitor 通常只在 captive portal 協(xié)商之后通知 path 被設(shè)置為 satisfiable 狀態(tài),即在彈出 web view 且用戶登錄后。而在沒有彈出 captive portal 的情況下,將向用戶顯示一個(gè) Action Sheet,提供了 Use Without Internet 和 Use Other Network 選項(xiàng)。如果用戶選擇了 Use Without Internet,則 NWPathMonitor 返回的 path 的狀態(tài)是 satisfied,即便實(shí)際上并沒有連網(wǎng)。

通過使用 Charles 做的一些實(shí)驗(yàn),我發(fā)現(xiàn)除非選擇 Use Without Internet,否則在初始化 Wi-Fi 網(wǎng)絡(luò)連接的同時(shí)中斷連接的情況下,NWPathMonitor 沒有報(bào)告 NWPath 的 Status 被置為 statisfied。但是,如果網(wǎng)絡(luò)連接已恢復(fù),但隨后被刪除,則并不能檢測到這種變更,并且 path 的狀態(tài)未依然是 satisfied。如果用戶僅在火車或酒店上支付一小時(shí)的互聯(lián)網(wǎng)訪問費(fèi)用,這種情況是可能發(fā)生的。

Connectivity

Connectivity 是一個(gè) MIT 許可的開源框架,其目的是復(fù)用 iOS 現(xiàn)有的檢測 captive portal 的方法。它允許在 iOS 8+ 上使用 Reachability 準(zhǔn)確檢測真正的 Internet 連接,這意味著在無法使用 NWPathMonitor 時(shí),我們可以使用這個(gè)方法。并且在 iOS 12 上,Connectivity 使用了 NWPathMonitor 來提供更高的準(zhǔn)確度。

Connectivity 已經(jīng)提供了對 NWPathMonitor 的支持,可用于 iOS 12+ 系統(tǒng)。如果 framework 屬性設(shè)置為 network,則會(huì)使用 Network 框架來替代 SystemConfiguration 框架(Reachability),以監(jiān)聽網(wǎng)絡(luò)適配器的狀態(tài)變更。

let connectivity = Connectivity()connectivity.framework = .network

在網(wǎng)絡(luò)適配器中的狀態(tài)更改后,Connectivity 會(huì)執(zhí)行大量檢查以確定 Internet 訪問是否可用。另外還有一個(gè)輪詢選項(xiàng),可以用來輪詢網(wǎng)絡(luò)是否可用,即使?fàn)顟B(tài)并未發(fā)生改變??梢酝ㄟ^設(shè)置 isPollingEnabled = true 并將 pollingInterval 設(shè)置為適當(dāng)?shù)臅r(shí)間值來實(shí)現(xiàn)這一點(diǎn)。

到此,相信大家對“iOS12+中檢測網(wǎng)絡(luò)訪問的方法是什么”有了更深的了解,不妨來實(shí)際操作一番吧!這里是億速云網(wǎng)站,更多相關(guān)內(nèi)容可以進(jìn)入相關(guān)頻道進(jìn)行查詢,關(guān)注我們,繼續(xù)學(xué)習(xí)!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

ios
AI