swift - 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
我想知道如何解决这个问题?
解决方案
改成@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
推荐阅读
- django - 你能写一个查询来根据修改Django中的外键在另一个表中查找一个值吗?
- c# - 日期时间转换为 yyyy/M/d 无论如何都转换为 M/d/yyyy
- android - 是否可以在不显示 URL 的情况下从我的应用程序打开 Web 浏览器?
- laravel - Laravel5.6“在null上调用成员函数delete()”,删除表中的一行
- vb.net - 用VB在DataTable中求和双打?
- delphi - Delphi TidHTTP web 服务安全用户名token
- javascript - 对象值中的Javascript传递函数
- python - Keras 服装回调。生成精确召回时,_flow_index 出现错误
- express - 如何找出访问者在我的网站上停留的时间(持续时间)
- perl - 计算特定子字符串之间的匹配