iOS13 网络监视器崩溃
Posted
技术标签:
【中文标题】iOS13 网络监视器崩溃【英文标题】:Network monitor crashing in iOS13 【发布时间】:2021-05-13 07:30:21 【问题描述】:所以我试图在 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("\u2022 Win Prizes\n\n\u2022 Change Stations\n\n\u2022 Access Podcasts\n\n\u2022 Request Songs\n\n\u2022 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
我想知道如何解决这个问题?
【问题讨论】:
我无法重现此错误,您是否在Simulator
上运行,这对我来说工作正常,在 iOS 14.4
和 Xcode 12.4
上进行了测试
是的,它适用于 iOS14+ 但不适用于 iOS 13.6
请注意,此代码无法在iOS 13.6
上运行,因为您使用的是@StateObject
属性包装器,该包装器可从iOS 14.0
及更高版本获得。
尝试改用@ObservedObject
。
那么想知道解决这个问题的解决方案是什么,使其向后兼容
【参考方案1】:
将@StateObject
更改为ObservedObject
效果很好。
注意:在检查@availability
(进行向后兼容时)时,您并不总是需要在if
和else
中再次编写相同的代码,您只需为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
、iOS13.3.1
和iOS 14.4.2
测试
【讨论】:
以上是关于iOS13 网络监视器崩溃的主要内容,如果未能解决你的问题,请参考以下文章