场景:
我正在玩访问和显示远程图像,以了解Combine的各种通知标记/协议。
一个目标:
访问错误的URL应该立即显示Alert()。
现实:
警报显示之后,然后显示第二个请求。
这是主(调用)视图:
import Combine
import SwiftUI
struct ContentView: View {
@EnvironmentObject var settings: MySettings
@State private var url: String = "https://garbage.com" // ...purposely set to display alert.
@State private var image: URLImage = URLImage()
@State private var angelFish: Image = Image("QueenAngelfish")
@State private var isPresented = false
var body: some View {
ZStack {
Color.green
NavigationView {
VStack {
Button(action: {
self.url = "garbage.com"
self.isPresented = self.image.imageLoader.isPresented
self.image.imageLoader.load(url: URL(string: self.url)!)
}) {
Text("Get An Image")
}
angelFish
.resizable()
.frame(width: 300,height: 200,alignment: .center)
.padding()
image
.alert(isPresented: $isPresented,content: { () -> Alert in
Alert(title: Text(verbatim: "Unable to Acquire Image."))
})
}.navigationBarTitle(Text(settings.name))
}
}
}
}
这是访问引擎:
import Combine
import SwiftUI
enum ImageURLError: Error {
case dataIsnotAnImage
}
struct URLImage: View {
@EnvironmentObject var settings: MySettings
@ObservedObject var imageLoader: ImageLoader
var placeholder: Image
init() {
self.placeholder = Image(systemName: "photo")
self.imageLoader = ImageLoader()
}
var body: some View {
VStack {
imageLoader.image == nil ?
placeholder : Image(uiImage: imageLoader.image!)
Button(action: {
self.settings.name = "Happy Thanks Giving"
self.settings.isPresented = true
},label: {
Text("Touch Me")
})
}
}
}
// =====================================================================================================
class ImageLoader: ObservableObject {
let id: String = UUID().uuidString
var didChange = PassthroughSubject<Void,Never>()
@Published var isPresented = false
@Published var image: UIImage? {
didSet {
DispatchQueue.main.async {
self.didChange.send()
}
}
}
// ---------------------------------------------------------------------------
func load(url: URL) {
print("Hello Ric: ",#function)
URLSession.shared.dataTask(with: url) { data,_,error in
DispatchQueue.main.async {
if error != nil {
self.isPresented = true
self.didChange.send() // ...attempting to activate alert().
return
}
self.image = UIImage(data: data!)
}
}.resume()
}
}
由于URL错误,此代码有意创建一个错误。
我试图通过将布尔值“ isPresented”标志作为“ @Published”变量传递来立即通知调用例程
预期结果:
显示的警报。
实际结果:
警报将在首次尝试之后显示。
问题:如何执行即时警报显示?