<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>network monitor &#8211; 隨心所欲</title>
	<atom:link href="https://doeverythingiwant.com/tag/network-monitor/feed/" rel="self" type="application/rss+xml" />
	<link>https://doeverythingiwant.com</link>
	<description>iOS Developer 的隨筆記錄</description>
	<lastBuildDate>Sun, 20 Oct 2024 14:25:19 +0000</lastBuildDate>
	<language>zh-TW</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=7.0</generator>

<image>
	<url>https://doeverythingiwant.com/wp-content/uploads/2025/08/cropped-0802.png</url>
	<title>network monitor &#8211; 隨心所欲</title>
	<link>https://doeverythingiwant.com</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>[iOS] Network Monitor</title>
		<link>https://doeverythingiwant.com/ios-network-monitor/</link>
					<comments>https://doeverythingiwant.com/ios-network-monitor/#respond</comments>
		
		<dc:creator><![CDATA[艾普利]]></dc:creator>
		<pubDate>Sun, 20 Oct 2024 14:25:17 +0000</pubDate>
				<category><![CDATA[寫程式]]></category>
		<category><![CDATA[iOS]]></category>
		<category><![CDATA[network monitor]]></category>
		<category><![CDATA[SwiftUI]]></category>
		<guid isPermaLink="false">https://doeverythingiwant.com/?p=2361</guid>

					<description><![CDATA[Photo by Frederik Lipfert on U&#8230;]]></description>
										<content:encoded><![CDATA[
<p class="has-text-align-center wp-block-paragraph">Photo by <a href="https://unsplash.com/@frederikli?utm_content=creditCopyText&amp;utm_medium=referral&amp;utm_source=unsplash" target="_blank" rel="noopener">Frederik Lipfert</a> on <a href="https://unsplash.com/photos/a-person-holding-an-iphone-in-their-hand-y67dwfB2AiM?utm_content=creditCopyText&amp;utm_medium=referral&amp;utm_source=unsplash" target="_blank" rel="noopener">Unsplash</a></p>



<p class="wp-block-paragraph">在iOS12之前想要偵測網路狀態的話，大家都會使用 Reachability 這套官方工具，且有 <a href="https://developer.apple.com/library/archive/samplecode/Reachability/Introduction/Intro.html" data-type="link" data-id="https://developer.apple.com/library/archive/samplecode/Reachability/Introduction/Intro.html" target="_blank" rel="noreferrer noopener">Demo Code</a> 可以直接使用，所以只要說到偵測網路第一時間一定會想到使用 Reachability。</p>



<p class="wp-block-paragraph">在 iOS 12之後官方推出了 <a href="https://developer.apple.com/documentation/network" target="_blank" rel="noreferrer noopener">Network Kit</a> 其中有很多與網路相關的服務，期中一個就可以用來偵測網路狀態，程式碼比過去少又比較清楚，配合現在官方主推的 SwiftUI 也很好用。</p>



<span id="more-2361"></span>



<h2 class="wp-block-heading">Monitor</h2>



<h3 class="wp-block-heading">Create Publisher</h3>



<p class="wp-block-paragraph">像這樣的Monitor 是建議獨立建立一個 Class 來處理，不要放在其他的Class 裡面</p>



<div class="hcb_wrap"><pre class="prism line-numbers lang-swift" data-lang="Swift"><code>import Network

class NetworkMonitor: ObservableObject {
    
    @Published private(set) var isConnected: Bool = false
    @Published private(set) var networkType: NWInterface.InterfaceType? = .other
}</code></pre></div>



<p class="wp-block-paragraph">首先，記得要 <code>import Network</code>，為了能讓SwiftUI 使用記得要Conform <code>ObservableObject</code></p>



<p class="wp-block-paragraph"><code>isConnected</code> 就是在確認是否為連線狀態，<code>networkType</code> 就是屬於那一種連線類型，官方有分為 <code>wifi</code>、<code>cellular</code>…等等，詳細分類可以參考 <a href="https://developer.apple.com/documentation/network/nwinterface/interfacetype" target="_blank" rel="noreferrer noopener">NWInterface.InterfaceType</a> 的說明。</p>



<h3 class="wp-block-heading">Create Monitor</h3>



<div class="hcb_wrap"><pre class="prism line-numbers lang-swift" data-lang="Swift"><code>let networkMonitor = NWPathMonitor()
let workQueue = DispatchQueue(label: &quot;NetworkMonitor&quot;)</code></pre></div>



<p class="wp-block-paragraph">接著往下建立 Monitor ，在Network Kit 裡有一個Class 是 <a href="https://developer.apple.com/documentation/network/nwpathmonitor" data-type="link" data-id="https://developer.apple.com/documentation/network/nwpathmonitor" target="_blank" rel="noreferrer noopener">NWPathMonitor</a> ，它就是用來偵測網路狀態的，上述這樣的寫法表示要偵測所有型態的網路，有需要的話也可以指定想要偵測的網路型態。</p>



<p class="wp-block-paragraph">一般來說偵測網路的動作一定不可以影響到主線程的運行，因此我們需要新增一條負責偵測網路用的 <code>DispatchQueue</code>，名稱可以自訂，這裡是稱它為 <code>NetworkMonitor</code>。</p>



<h3 class="wp-block-heading">Create Path update handler</h3>



<div class="hcb_wrap"><pre class="prism line-numbers lang-swift" data-lang="Swift"><code>networkMonitor.pathUpdateHandler = { [weak self] path in
    self?.isConnected = path.status == .satisfied
    self?.networkType = path.availableInterfaces.first?.type
}</code></pre></div>



<p class="wp-block-paragraph">當網路狀態改變的時候，可以在 <code>pathUpdateHandler</code> 這個 Closure 取得資訊，會回傳 <code>NWPath</code> 這個物件，它有網路狀態的相關資訊。</p>



<h3 class="wp-block-heading">Start</h3>



<div class="hcb_wrap"><pre class="prism line-numbers lang-swift" data-lang="Swift"><code>networkMonitor.start(queue: workQueue)</code></pre></div>



<p class="wp-block-paragraph">最後再開始偵測，記得指定先前設定好的Queue</p>



<p class="wp-block-paragraph">完整的程式如下</p>



<div class="hcb_wrap"><pre class="prism line-numbers lang-swift" data-lang="Swift"><code>class NetworkMonitor: ObservableObject {
    
    @Published private(set) var isConnected: Bool = false
    @Published private(set) var networkType: NWInterface.InterfaceType? = .other
    
    let networkMonitor = NWPathMonitor()
    let workQueue = DispatchQueue(label: &quot;NetworkMonitor&quot;)
    
    init() {
        
        networkMonitor.pathUpdateHandler = { [weak self] path in
            self?.isConnected = path.status == .satisfied
            self?.networkType = path.availableInterfaces.first?.type
        }
        
        networkMonitor.start(queue: workQueue)
    }
}</code></pre></div>



<h3 class="wp-block-heading">View</h3>



<p class="wp-block-paragraph">接著就可以將這個NetworkMonitor 放到View 上使用，以下是一個簡單的範例</p>



<div class="hcb_wrap"><pre class="prism line-numbers lang-swift" data-lang="Swift"><code>struct ContentView: View {
    
    @StateObject var networkMonitor = NetworkMonitor()
    
    var body: some View {
        VStack {
            Label {
                Text(networkMonitor.isConnected ? &quot;Connected&quot; : &quot;Disconnected&quot;)
            } icon: {
                Image(systemName: networkMonitor.isConnected ? &quot;network&quot; : &quot;network.slash&quot;)
                    .foregroundStyle(networkMonitor.isConnected ? .green : .red)
            }

        }
        .padding()
    }
}</code></pre></div>



<p class="wp-block-paragraph">當然，App 應該只會有一個 Network Monitor ，這個時候可以使用 <code>EnvironmentObject</code> 的方式來傳遞 Network Monitor，寫法可以參考以下方式，當然要從哪裡開始建立 Network Monitor 都可以依照個人需求，理論上應該是App 開啟時就需要做偵測啦，記得使用 <code>.environmentObject()</code>來讓其他畫面可以使用 <code>EnvironmentObject</code> 方式讀取到 Network Monitor。</p>



<div class="hcb_wrap"><pre class="prism line-numbers lang-swift" data-lang="Swift"><code>@main
struct NetworkDemoApp: App {
    
    @StateObject var networkMonitor = NetworkMonitor()
    
    var body: some Scene {
        WindowGroup {
            ContentView()
                .environmentObject(networkMonitor)
        }
    }
}</code></pre></div>



<div class="hcb_wrap"><pre class="prism line-numbers lang-swift" data-lang="Swift"><code>struct ContentView: View {
    
    @EnvironmentObject var networkMonitor: NetworkMonitor
    
    var body: some View {
        VStack {
            Label {
                Text(networkMonitor.isConnected ? &quot;Connected&quot; : &quot;Disconnected&quot;)
            } icon: {
                Image(systemName: networkMonitor.isConnected ? &quot;network&quot; : &quot;network.slash&quot;)
                    .foregroundStyle(networkMonitor.isConnected ? .green : .red)
            }

        }
        .padding()
    }
}</code></pre></div>



<p class="wp-block-paragraph">最後，祝大家 Coding 愉快!!</p>



<p class="wp-block-paragraph"></p>
]]></content:encoded>
					
					<wfw:commentRss>https://doeverythingiwant.com/ios-network-monitor/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
