카카오톡 먹통 이후 드디어 작업물을 새롭게 기록할 수 있게 되었네요! (짝짝짝)
이번에 구현해본 것은 네트워크 모니터를 활용해 연결 상태를 유저에게 피드백해주는 기능입니다.
모든 어플에 구현되어 있는 필수 기능입니다.
메세지를 보여주는 형태는 유튜브 앱에서 사용되는 스타일로 만들어 봤습니다.
1. NWPathMonitor()로 Network Monitor를 작성해줍니다.
import Foundation
import Network
import SwiftUI
class NetworkMonitor: ObservableObject {
@Published var isConnected: Bool = true
@Published var showAlert: Bool = false
let monitor = NWPathMonitor()
let queue = DispatchQueue(label: "Monitor")
init() {
monitor.pathUpdateHandler = { [weak self] path in
DispatchQueue.main.async {
if path.status == .satisfied { <-- 연결상태
withAnimation {
self?.isConnected = true
}
DispatchQueue.main.asyncAfter(deadline: .now() + 5) {
withAnimation {
self?.showAlert = false
}
}
} else {
withAnimation {
self?.isConnected = false
self?.showAlert = true
}
}
}
}
monitor.start(queue: queue)
}
}
init() 안의 함수는 연결상태에 따라서 동작하게 될 코드입니다.
기본적으로 isConnected를 업데이트해주고, 인터넷이 다시 연결되었을 시 "인터넷에 다시 연결됨" 메세지와 함께 초록색으로 변경시켜주고 5초간 유저에게 보여준 후 메시지창이 사라져야 하기 때문에 showAlert 프로퍼티도 업데이트해줬습니다.
withAnimation은 모든 동작들에 애니메이션 효과를 부여해줍니다.
2. 앱 전체에서 사용하길 원했기 때문에 부모 뷰에 EnvironmentObject로 추가해주었습니다.
import SwiftUI
@main
struct SwiftUICoinApp: App {
@StateObject private var viewModel = HomeViewModel()
@StateObject private var monitor = NetworkMonitor() <-- 네트워크 모니터
@State private var isNavigationBarHidden: Bool = true
var body: some Scene {
WindowGroup {
NavigationView {
VStack {
MyTabView()
.navigationBarTitle("Hidden Title")
.navigationBarHidden(self.isNavigationBarHidden)
.onAppear {
self.isNavigationBarHidden = true
}
if !monitor.isConnected || monitor.showAlert {
NetworkMissingView() <-- 메세지뷰를 넣어주었습니다.
}
}
}
.environmentObject(viewModel)
.environmentObject(monitor) <-- 모든 자식뷰가 Monitor에 엑세스 할 수 있습니다.
.navigationViewStyle(StackNavigationViewStyle())
}
}
}
3. AlertView를 생성해줍니다.
import SwiftUI
struct NetworkMissingView: View {
@EnvironmentObject var monitor: NetworkMonitor <-- EnvironmentObject를 통해 상태가 모든 뷰와 공유됩니다.
var body: some View {
Text(monitor.isConnected ? "인터넷에 다시 연결됨" : "연결되지 않음")
.frame(width: UIScreen.main.bounds.width)
.font(.footnote)
.background((monitor.isConnected ? Color.theme.green : Color.black).ignoresSafeArea())
.foregroundColor(Color.white)
.animation(.easeInOut, value: monitor.showAlert)
}
}
struct NetworkMissingVIew_Previews: PreviewProvider {
static var previews: some View {
NetworkMissingView()
.previewLayout(.sizeThatFits)
}
}
유튜브 스타일 네트워크 모니터 완료입니다!
그런데 한가지 문제가 있습니다..
저의 경우 구현 초기에는 원할하게 되었다가 어느 순간부터는 잘 작동하지 않는 모습을 보여주고 있는데요.
검색하여보니 저와 비슷한 문제가 종종 발생하는 것을 알 수 있었고, 시뮬레이터에 문제가 있는 것이 아닌가 생각하고 있습니다.
스택오버플로우의 댓글들도 시뮬레이터에 문제가 있는 것 같다고 얘기를 해주고 있습니다.
SwiftUI, Xcode에 자잘한 버그가 너무 많아요...ㅠㅠ
추후 실제 기기에서 테스트해보고 또 다른 이슈 혹은 개선사항이 발견되면 업데이트하겠습니다!
비슷한 문제를 다루는 글:
구현 참고:
'Project > SwiftUI 블록와이드' 카테고리의 다른 글
[SwiftUI Project] 텍스트필드 글자 수 제한하기 (문제 해결 과정) (0) | 2022.10.19 |
---|---|
[SwiftUI Project] 뉴스기사 URL 공유 버튼 만들기 (0) | 2022.10.19 |
[SwiftUI Project] 몇시간 전, 몇일 전 상대적 시간 구하기 RelativeDateTimeFormatter (0) | 2022.10.14 |
[SwiftUI Project] 예외처리: StatusCode에 따라서 안내글 띄우기 (0) | 2022.10.14 |
[SwiftUI Project] 예외처리: Json Data -> CoreData 백업하기 (0) | 2022.10.14 |
댓글