[Swift] Network 상태 체크하기

민경준·2022년 6월 13일
0

Declaration

swift에서 개발을 하다보면 꼭 필요한것이 네트워크 상태 체크입니다. 네트워크 상태 체크를 어떻게 하는것이 좋을지 고민하다 찾아보니 방법은 의외로 간단 했습니다.

우선 swift에는 Network라는 기본 라이브러리가 있는데 이것을 이용해주면 됩니다. 이것을 이용하면 현재 네트워크의 상태, 종류 등.. 다양한 정보들을 알 수 있습니다. 기본적으로 어떻게 사용하는지 하나씩 알아보도록 합시다.


How To Use

첫번째로 네트워크 상태를 항상 체크할 수 있는 monitor 객체와 이것에 필요한 DispatchQueue가 필요합니다.

import Network

private let queue: DispatchQueue = DispatchQueue.global()
private let monitor: NWPathMonitor = NWPathMonitor()

다음으로는 네트워크 상태가 업데이트 됐을 때 어떤 동작을 할지에 대한 updateHandler를 정의하도록 합시다.
여기서 리턴값으로 NWPath라는 객체를 던져주는데 해당 객체에는 네트워크 인터페이스에 대한 값을 가지고 있지 않지만 정보는 갖고 있어서 어떤 타입을 사용하고 있는지 함수로 전달받을 수 있습니다.
(왜 이렇게 해뒀는지는 개인적으로 의문...)

self.monitor.pathUpdateHandler = { path in
    /// NWPath의 usesInterfaceType 함수를 통해서 어떤 InterfaceType을 사용하는지 유추해야 한다.
    if path.usesInterfaceType(.wifi) {
    	print("Network Type: Wifi")
    } else
    if path.usesInterfaceType(.cellular) {
    	print("Network Type: Cellular")
    } else {
    	print("Network Type: Other Type")
    }
}

세번째로는 이제 위에서 선언해둔 DispatchQueue를 가지고 상태체크를 시작하도록 해주면 완성입니다.
끝낼 때는 cancel() 함수를 사용하면 됩니다.

self.monitor.start(queue: self.queue)

self.monitor.cancel()

Applied

그리고 이걸 응용하여 어플리케이션이 시작할때 모니터링을 동시에 같이 시작하고 상태가 바뀔때마다 Notification을 통해 상태값을 받을 수 있도록 코드를 짜봤습니다.

우선 Singleton을 통해 외부에서 하나의 객체를 가지고 사용하도록 했습니다. 그리고 상태 알림을 받을 NotificationName을 선언 해 두었습니다.

final class NetworkHelper {
	public static let `default`: NetworkHelper = NetworkHelper()
    public static let statusDidChanged = Notification.Name("NetworkStatusDidChanged")
}

다음으로는 pathUpdateHandler가 호출 될 때마다 Notification으로 상태를 알려주면 되겠죠?
그리고 다른 클래스에서 상태 값을 받을 때는 NWPath객체를 통해 핸들링을 해주면 될거 같습니다.

self.monitor.pathUpdateHandler = { path in
    NotificationCenter.default.post(name: NetworkHelper.statusDidChanged, object: path)
}
class OtherClass {
    NotificationCenter.default.addObserver(self, selector: #selector(self.networkStatusHandler(_:)), name: NetworkHelper.statusDidChanged, object: nil)

    @objc
    fileprivate func networkStatusHandler(_ notification: Notification) {
        guard let path = notification.object as? NWPath else { return }
        print("NETWORK DID CHANGED")
    }
}

마지막으로 상태 체크 시작 및 종료에 대한 함수를 선언해서 SceneDelegate에서 호출하도록 합니다.

final class NetworkHelper {
	.
    .
    .
    
    public func start() {
        self.monitor.start(queue: self.queue)
    }

    public func stop() {
        self.monitor.cancel()
    }
}


@available(iOS 13.0, *)
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
    func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
        NetworkHelper.default.start()
    }
}
profile
iOS Developer 💻

0개의 댓글