Notice
Recent Posts
Recent Comments
Link
«   2024/11   »
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
Archives
Today
Total
관리 메뉴

개발자의 삽질

[iOS] 네트워크 연결 상태 확인하기! 본문

iOS

[iOS] 네트워크 연결 상태 확인하기!

uniqueimaginate 2022. 2. 13. 00:51

https://www.hackingwithswift.com/example-code/networking/how-to-check-for-internet-connectivity-using-nwpathmonitor

 

How to check for internet connectivity using NWPathMonitor - free Swift 5.4 example code and tips

Was this page useful? Let us know! 1 2 3 4 5

www.hackingwithswift.com


이번에는 네트워크 연결 상태를 확인하자!

앱을 개발할 때, 네트워크 연결 상태에 따라 UI 변경을 주는 경우가 있다!

아래는 그 예시이다!

1번 사진: 네트워크에 연결 되어 있는 상태, 2번 사진: 네트워크 연결을 끊었을 때, 3번 사진: 네트워크 재연결이 되었을 때

이와 비슷하게 네트워크 상태에 따라 UI 변경을 해보자!

일단 스토리 보드에 라벨이 하나있는 ViewController를 만들자!

그 후 ViewController.swift 를 아래의 코드로 두자

import UIKit
import Network

class ViewController: UIViewController {
    
    let monitor = NWPathMonitor()
    @IBOutlet weak var label: UILabel!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        monitor.pathUpdateHandler = { path in
            if path.status == .satisfied {
                
                DispatchQueue.main.async {
                    self.label.text = "We're connected!"
                }
            } else {
                
                DispatchQueue.main.async {
                    self.label.text = "No connection."
                }
                
            }
        }
        
        let queue = DispatchQueue(label: "Monitor")
        monitor.start(queue: queue)
    }
    
    deinit {
        monitor.cancel()
    }
}

위와 같이 두면 아래의 영상처럼 네트워크 변화를 반영해서 라벨의 문자열을 변경할 수 있다!

그럼 이제 카카오톡 처럼 UI에 변화를 줘보자!

import UIKit
import Network

class ViewController: UIViewController {
    
    let monitor = NWPathMonitor()
    @IBOutlet weak var label: UILabel!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        monitor.pathUpdateHandler = { path in
            if path.status == .satisfied {
                
                // 이 곳은 메인 스레드가 아니기 때문에
                // UI 변화를 하기 위해서는 DispatchQueue.main.async 를 호출해야 한다.
                DispatchQueue.main.async {
                    self.label.text = "We're connected!"
                    self.removeCustomUI()
                }
            } else {
                
                // 위와 같은 이유로 DispatchQueue.main.async 사용
                DispatchQueue.main.async {
                    self.label.text = "No connection."
                    self.addCustomUI()
                }
            }
        }
        
        let queue = DispatchQueue(label: "Monitor")
        monitor.start(queue: queue)
    }
    
    func addCustomUI(){
        // 상태표시줄 높이를 구한다.
        guard let statusBarHeight = view.window?.windowScene?.statusBarManager?.statusBarFrame.height else { return }
        
        // 상태표시줄의 높이를 갖는 빈 네모를 만든다.
        let view = UIView(frame: CGRect(x: 0, y: 0, width: Int(UIScreen.main.bounds.width), height: Int(statusBarHeight)))
        view.backgroundColor = UIColor.black
        view.alpha = 0
        view.tag = 99
        
        // 라벨을 만든다.
        let label = UILabel(frame: CGRect(x: 0, y: Int(statusBarHeight), width: Int(UIScreen.main.bounds.width), height: 10))
        label.backgroundColor = UIColor.black
        label.alpha = 0
        label.font = UIFont.systemFont(ofSize: 10)
        label.textColor = UIColor.white
        label.textAlignment = .center
        label.text = "네트워크 연결이 끊어졌습니다"
        label.tag = 100
        // 위의 2개 뷰들은 추가 될 때 모두 alpha = 0 으로 둬서 투명하게 한다.
        // 추후에 애니메이션을 통해 불투명하게 바꿔줄 것이다.
        
        // addSubview 함수는 애니메이션을 통해 작용하지 않는다.
        self.view.addSubview(view)
        self.view.addSubview(label)
        
        // 추가 될 때 애니메이션으로 alpha 값에 변화를 준다.
        UIView.animate(withDuration: 1, delay: 0, options: .curveEaseIn, animations: {
            view.alpha = 0.6
            label.alpha = 0.6
        }, completion: nil)
    }
    
    func removeCustomUI(){
        // 추가한 뷰를 삭제할 때는 태그로 찾는다.
        guard let label = self.view.viewWithTag(100) as? UILabel else { return }
        guard let view = self.view.viewWithTag(99) else { return }
        
        label.text = "네트워크가 연결되었습니다."
        UIView.animate(withDuration: 1, delay: 2, options: .curveEaseOut, animations: {
                label.alpha = 0
                view.alpha = 0
        }, completion: nil)
        
        // 위에 animate 의 completion에 써야 되지만
        // 이상하게 되질 않아서 아래의 asyncAfter을 사용해야 했다.
        DispatchQueue.main.asyncAfter(deadline: .now() + 3.0) {
            view.removeFromSuperview()
            label.removeFromSuperview()
        }
    }
    
    deinit {
        monitor.cancel()
    }
}

위의 코드는 아래와 같이 보여준다.

 

2번째 코드는 수정가능성이 높다. 코드를 좀 더 짧게 할 여지가 있고

현재시점에서는 addSubView, removeFromSuperView이 애니메이션으로 하지 못해서 alpha값만 변경했기 때문이다.

그래도 작동은 충분히 잘된다!

Comments