admin管理员组文章数量:1316030
I have been using AsyncImage for my project which gets the images using urls. I thought AsyncImage is the best way to go since SwiftUI provides a ready to use component for it.
However, if a image load fails, then I am getting a common error and not a detailed error message of why the url request failed (eg: no permissions to access URL or some other reason).
The reason I am constantly seeing is The operation couldn’t be completed. (SwiftUI.(unknown context at $1d2600574).LoadingError error 1.)
Executable code:
import SwiftUI
class Foo {
var title: String
var url: String
var image: Image?
init(title: String, url: String, image: Image? = nil) {
self.title = title
self.url = url
self.image = image
}
}
struct ContentViewA: View {
@State var showSheetA: Bool = false
var body: some View {
VStack {
Text("This is main view")
}
.onAppear{
showSheetA = true
}
.sheet(isPresented: $showSheetA) {
SheetViewA()
}
}
}
struct SheetViewA: View {
@State var data = [
Foo(title: "Image E", url: ".jpg123", image: nil)
]
@State var panelDetent: PresentationDetent = .medium
var body: some View {
NavigationStack {
VStack {
ScrollView(.horizontal, showsIndicators: false) {
HStack(alignment: .center, spacing: 10) {
ForEach(data, id: \.title) { item in
if let urlObject = URL(string: item.url) {
AsyncImage(url: urlObject,
scale: 1.0,
transaction: Transaction(animation: .spring(response: 0.5, dampingFraction: 0.65, blendDuration: 0.025)),
content: { renderPhoto(phase: $0, item: item) })
} else {
/// Note: Shows placeholder view
EmptyView()
}
}
}
.background(Color.gray.opacity(0.2))
.padding(.leading, 0)
.padding(.trailing, 16)
.frame(maxWidth: .infinity, minHeight: 65, maxHeight: 65, alignment: .topLeading)
}
}
.padding([.top, .bottom], 150.0)
.presentationDetents([.medium, .large], selection: $panelDetent)
}
}
@ViewBuilder
private func renderPhoto(phase: AsyncImagePhase, item: Foo) -> some View {
switch phase {
case .success(let image):
let _ = print("Success state")
case .failure(let error):
let _ = print("%%% detailed error is - \(error.localizedDescription) %%%%")
case .empty:
let _ = print("Empty state")
@unknown default:
EmptyView()
}
}
}
Is there a way to get detailed error message using AsycnImage? Or will I have to get images using the old URLSession request method? I need to display detailed error message on the UI.
I have been using AsyncImage for my project which gets the images using urls. I thought AsyncImage is the best way to go since SwiftUI provides a ready to use component for it.
However, if a image load fails, then I am getting a common error and not a detailed error message of why the url request failed (eg: no permissions to access URL or some other reason).
The reason I am constantly seeing is The operation couldn’t be completed. (SwiftUI.(unknown context at $1d2600574).LoadingError error 1.)
Executable code:
import SwiftUI
class Foo {
var title: String
var url: String
var image: Image?
init(title: String, url: String, image: Image? = nil) {
self.title = title
self.url = url
self.image = image
}
}
struct ContentViewA: View {
@State var showSheetA: Bool = false
var body: some View {
VStack {
Text("This is main view")
}
.onAppear{
showSheetA = true
}
.sheet(isPresented: $showSheetA) {
SheetViewA()
}
}
}
struct SheetViewA: View {
@State var data = [
Foo(title: "Image E", url: "https://t3.ftcdn/jpg/10/08/34/50/360_F_1008345045_VOe4ziz83vb6d3E3X6KI00qHyLd32D4l.jpg123", image: nil)
]
@State var panelDetent: PresentationDetent = .medium
var body: some View {
NavigationStack {
VStack {
ScrollView(.horizontal, showsIndicators: false) {
HStack(alignment: .center, spacing: 10) {
ForEach(data, id: \.title) { item in
if let urlObject = URL(string: item.url) {
AsyncImage(url: urlObject,
scale: 1.0,
transaction: Transaction(animation: .spring(response: 0.5, dampingFraction: 0.65, blendDuration: 0.025)),
content: { renderPhoto(phase: $0, item: item) })
} else {
/// Note: Shows placeholder view
EmptyView()
}
}
}
.background(Color.gray.opacity(0.2))
.padding(.leading, 0)
.padding(.trailing, 16)
.frame(maxWidth: .infinity, minHeight: 65, maxHeight: 65, alignment: .topLeading)
}
}
.padding([.top, .bottom], 150.0)
.presentationDetents([.medium, .large], selection: $panelDetent)
}
}
@ViewBuilder
private func renderPhoto(phase: AsyncImagePhase, item: Foo) -> some View {
switch phase {
case .success(let image):
let _ = print("Success state")
case .failure(let error):
let _ = print("%%% detailed error is - \(error.localizedDescription) %%%%")
case .empty:
let _ = print("Empty state")
@unknown default:
EmptyView()
}
}
}
Is there a way to get detailed error message using AsycnImage? Or will I have to get images using the old URLSession request method? I need to display detailed error message on the UI.
Share Improve this question asked Jan 29 at 22:56 tech_humantech_human 7,16617 gold badges75 silver badges134 bronze badges 3 |1 Answer
Reset to default 1Here is my test code that prints the error
and error.localizedDescription
,
giving very little info to a user, just LoadingError
.
Included is a test fetching the image (which does not exist) using URLSession
.
The data/info your get seems to give you more information (File Not Found),
but this is just because the server sends you this info.
Note, casting the error to URLError
and DecodingError
return nil
, because this is not the
type of error you get this time, but you may well get something next time.
struct Foo {
var title: String
var url: String
var image: Image?
init(title: String, url: String, image: Image? = nil) {
self.title = title
self.url = url
self.image = image
}
}
struct ContentView: View {
@State private var showSheetA: Bool = false
var body: some View {
Text("This is main view")
Button("show sheet") {
showSheetA = true
}.buttonStyle(.bordered)
.sheet(isPresented: $showSheetA) {
SheetViewA()
}
}
}
struct SheetViewA: View {
@State private var data = [
Foo(title: "Image E", url: "https://t3.ftcdn/jpg/10/08/34/50/360_F_1008345045_VOe4ziz83vb6d3E3X6KI00qHyLd32D4l.jpg123", image: nil)
]
@State private var panelDetent: PresentationDetent = .medium
var body: some View {
NavigationStack {
VStack {
ScrollView(.horizontal, showsIndicators: false) {
HStack(alignment: .center, spacing: 10) {
ForEach(data, id: \.title) { item in
if let urlObject = URL(string: item.url) {
AsyncImage(url: urlObject,
scale: 1.0,
transaction: Transaction(animation: .spring(response: 0.5, dampingFraction: 0.65, blendDuration: 0.025)),
content: { renderPhoto(phase: $0, item: item) })
} else {
/// Note: Shows placeholder view
EmptyView()
}
}
}
.background(Color.gray.opacity(0.2))
.padding(.leading, 0)
.padding(.trailing, 16)
.frame(maxWidth: .infinity, minHeight: 65, maxHeight: 65, alignment: .topLeading)
}
}
.padding([.top, .bottom], 150.0)
.presentationDetents([.medium, .large], selection: $panelDetent)
// for testing
.task {
await getImage()
}
}
}
@ViewBuilder
private func renderPhoto(phase: AsyncImagePhase, item: Foo) -> some View {
switch phase {
case .success(let image):
let _ = print("Success state")
case .failure(let error):
let _ = print("%%% error is - \(error) %%%%")
let _ = print("%%% localizedDescription error is - \(error.localizedDescription)")
let _ = print("%%% ---> URLError error is - \(error as? URLError) %%%%")
let _ = print("%%% ---> DecodingError error is - \(error as? DecodingError) %%%%")
case .empty:
let _ = print("Empty state")
@unknown default:
EmptyView()
}
}
// for testing
func getImage() async {
guard let url = URL(string: "https://t3.ftcdn/jpg/10/08/34/50/360_F_1008345045_VOe4ziz83vb6d3E3X6KI00qHyLd32D4l.jpg123") else {
print("bad URL")
return
}
do {
let (data, _) = try await URLSession.shared.data(from: url)
print("\n---> URLSession data: \(String(data: data, encoding: .utf8) as AnyObject)\n")
} catch {
print("\n---> URLSession error: \(error)\n")
}
}
}
Note, the server returns a html result:
<html>
<head>
</head>
<body>
<h1>File Not Found</h1>
</body>
</html>
When AsyncImage
tries to make sense of this, it concludes that this
cannot be loaded (because this is not an image).
本文标签: iosDetailed error from AsyncImage in SwiftUIStack Overflow
版权声明:本文标题:ios - Detailed error from AsyncImage in SwiftUI? - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1741993704a2409618.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
case .failure
you can try casting the error, for example:if let urlError = error as? URLError {...}
orif let decodingError = error as? DecodingError {...}
etc... to try to get more info from the returned error. If you use aURLSession
instead of theAsyncImage
you get what you would if you used your browser, that is, a html withFile Not Found
. Note, you should usestruct Foo
and have@State private var
– workingdog support Ukraine Commented Jan 29 at 23:31localizedDescription
. Just printerror
directly. – Sweeper Commented Jan 30 at 7:59