首页 > 解决方案 > iOS13 网络监视器崩溃

问题描述

因此,我试图在 iOS 13 + 上保持当前状态,同时引入一些 iOS 14 功能。其中一项新功能是监控用户是否失去网络连接。

但是,当我运行以下代码时,我遇到了一个奇怪的错误。

TaView.swift(默认视图)

import SwiftUI


struct TaView: View {
    @StateObject var monitor = Monitor()
    @ObservedObject var location = LocationManager()
    @State var errorDetail = false
  
    
    var lat: String{
        return "\(location.lastKnownLocation?.coordinate.latitude ?? 0.0)"
    }
    
    var lon: String{
        return "\(location.lastKnownLocation?.coordinate.longitude ?? 0.0)"
    }
    
    var state: String{
        return "\(UserSettings().state)"
    }
    
    init() {
//        print(self.data.connected)
        self.location.startUpdating()
    }
    @ObservedObject var userSettings = UserSettings()
    
    
    var body: some View {
        if (self.lat == "0.0" && self.lon == "0.0"){
            LocationDisabled()
        }
        else{
            if #available(iOS 14.0, *) {
                TabView {
                    ContentView()
                        
                        .tabItem {
                            Image(systemName: "dot.radiowaves.left.and.right")
                            Text("Radio")
                        }
                    
                    WinView()
                        .tabItem {
                            Image(systemName: "w.circle")
                            Text("Win")
                        }
                    
                    SettingsView()
                        .tabItem {
                            Image(systemName: "gear")
                            Text("Settings")
                            
                        }
                }.accentColor(Color.red)
                .onAppear(){
                    Timer.scheduledTimer(withTimeInterval: 1, repeats: true) { (timer) in
                        if monitor.score == 0{
                            DispatchQueue.main.asyncAfter(deadline: .now()) {
                                self.errorDetail = true
                            }
                        }
                        
                        //print("this is the score \(monitor.score)")
                    }
                }
                .fullScreenCover(isPresented: self.$errorDetail, content: NetworkOutageView.init)
            } else {
                TabView {
                    ContentView()
                        
                        .tabItem {
                            Image(systemName: "dot.radiowaves.left.and.right")
                            Text("Radio")
                        }
                    
                    WinView()
                        .tabItem {
                            Image(systemName: "w.circle")
                            Text("Win")
                        }
                    
                    SettingsView()
                        .tabItem {
                            Image(systemName: "gear")
                            Text("Settings")
                            
                        }
                }.accentColor(Color.red)
                .onAppear(){
                    Timer.scheduledTimer(withTimeInterval: 1, repeats: true) { (timer) in
                        if monitor.score == 0{
                            DispatchQueue.main.asyncAfter(deadline: .now()) {
                                self.errorDetail = true
                            }
                        }
                        
                        //print("this is the score \(monitor.score)")
                    }
                }
                .sheet(isPresented: self.$errorDetail, content: NetworkOutageView.init)
            }
        }
    }
}


struct LocationDisabled: View {
    @ObservedObject var location = LocationManager()

    init() {
        self.location.startUpdating()
    }
    var body: some View {
        GeometryReader { geo in
        VStack{
            Spacer().frame(maxHeight: 100)
            Image(systemName: "location.fill").resizable().scaledToFit().frame(width: 100).foregroundColor(Color.white)
            
            VStack{
                 Text("Enable Location").font(.system(.largeTitle, design: .rounded)).bold().multilineTextAlignment(.leading).foregroundColor(Color.white)
                 Text("You'll need to enable your location.\nIn order to use access these features").fontWeight(.light).multilineTextAlignment(.center).fixedSize(horizontal: false, vertical: true).padding(.all, 8).foregroundColor(Color.white)
                 Text("\u{2022} Win Prizes\n\n\u{2022} Change Stations\n\n\u{2022} Access Podcasts\n\n\u{2022} Request Songs\n\n\u{2022} And More").bold().multilineTextAlignment(.center).fixedSize(horizontal: false, vertical: true).padding(.all, 8).foregroundColor(Color.white)
                 
                
                Spacer()
                Button(action: {
                     self.location.requestLoc()
                }) {
                    Text("ALLOW LOCATION")
                        .font(.headline)
                        .bold()
                }.buttonStyle(LocationGradientButtonStyle())
                .padding(.bottom, 100)
           }
        
        
        
       // ImageOverlay()
    }.frame(maxWidth: .infinity,maxHeight: .infinity).edgesIgnoringSafeArea(.all).background(
        Image("TooFarWallPaper").resizable().aspectRatio(contentMode: .fill).frame(maxWidth: .infinity,maxHeight: .infinity).edgesIgnoringSafeArea(.all)
        )
    }
    }
}


struct LocationGradientButtonStyle: ButtonStyle {
    func makeBody(configuration: Self.Configuration) -> some SwiftUI.View {
        configuration.label
            .foregroundColor(Color.white)
            .padding()
            .background(LinearGradient(gradient: Gradient(colors: [Color.blue, Color.purple]), startPoint: .topLeading, endPoint: .bottomTrailing))
            .cornerRadius(15.0)
    }
}

struct SaveGradientButtonStyle: ButtonStyle {
    func makeBody(configuration: Self.Configuration) -> some SwiftUI.View {
        configuration.label
            .foregroundColor(Color.black)
            .padding()
            .background(LinearGradient(gradient: Gradient(colors: [Color.green, Color.green]), startPoint: .topLeading, endPoint: .bottomTrailing))
            .cornerRadius(15.0)
    }
}

Monitor.swift

import Network
import SwiftUI

// An enum to handle the network status
enum NetworkStatus: String {
    case connected
    case disconnected
}

class Monitor: ObservableObject {
    private let monitor = NWPathMonitor()
    private let queue = DispatchQueue(label: "Monitor")

    @Published var score = 0
    @Published var status: NetworkStatus = .connected
  
    init() {
        monitor.pathUpdateHandler = { [weak self] path in
            guard let self = self else { return }

            // Monitor runs on a background thread so we need to publish
            // on the main thread
            DispatchQueue.main.async {
                if path.status == .satisfied {
                    print("We're connected!")
                    self.status = .connected
                    self.score = 1
                  

                } else {
                    print("No connection.")
                    self.score = 0
                    self.status = .disconnected
                }
            }
        }
        monitor.start(queue: queue)
    }
}

错误是

Thread 1: signal SIGABRT

我想知道如何解决这个问题?

监视器出错。

标签: swiftxcodeswiftui

解决方案


改成@StateObject效果ObservedObject很好。

注意:您并不总是需要再次编写相同的代码,if并且else在检查时@availability(进行向后兼容性时),您只需为 a 创建一个变量View并重用它,就像在这种情况下我们重用tabViewContent.

struct TaView: View {
    @ObservedObject var monitor = Monitor()
    
    @ObservedObject var location = LocationManager()
    @State var errorDetail = false
    
    
    var lat: String{
        return "\(location.lastKnownLocation?.coordinate.latitude ?? 0.0)"
    }
    
    var lon: String{
        return "\(location.lastKnownLocation?.coordinate.longitude ?? 0.0)"
    }
    
    var state: String{
        return "\(UserSettings().state)"
    }
    
    init() {
        //        print(self.data.connected)
        self.location.startUpdating()
    }
    @ObservedObject var userSettings = UserSettings()
    
    var tabViewContent: some View {
        TabView {
            ContentView()
                
                .tabItem {
                    Image(systemName: "dot.radiowaves.left.and.right")
                    Text("Radio")
                }
            
            WinView()
                .tabItem {
                    Image(systemName: "w.circle")
                    Text("Win")
                }
            
            SettingsView()
                .tabItem {
                    Image(systemName: "gear")
                    Text("Settings")
                    
                }
        }.accentColor(Color.red)
        .onAppear(){
            Timer.scheduledTimer(withTimeInterval: 1, repeats: true) { (timer) in
                if monitor.score == 0{
                    self.errorDetail = true
                } else {
                    self.errorDetail = false
                    
                }
                
                //print("this is the score \(monitor.score)")
            }
        }
    }
    
    var body: some View {
        if (self.lat == "0.0" && self.lon == "0.0"){
            LocationDisabled()
        }
        else{
            if #available(iOS 14.0, *) {
                tabViewContent
                    .fullScreenCover(isPresented: self.$errorDetail, content: NetworkOutageView.init)
            } else {
                tabViewContent
                    .sheet(isPresented: self.$errorDetail, content: NetworkOutageView.init)
            }
        }
    }
}

Xcode 12.4, oniOS13.3.1和测试iOS 14.4.2


推荐阅读