🪶
Cannot convert value of type 'String' to expected argument type 'URL?'
AsyncImageを使ってエラーでつまる(−_−;)
前のページから、String型のプロパティを受け取って、表示するだけなのだが、なぜかできない???
詳細ページを作っていたときのソースコード
import SwiftUI
struct ShopDetailView: View {
var shop: Shop
var body: some View {
NavigationView {
VStack(alignment: .leading, spacing: 10) {
AsyncImage(url: shop.imageUrl)
Text("お店の名前: \(shop.shop_name)")
}
.padding()
.navigationBarTitle(shop.shopname, displayMode: .inline)
}
}
}
🤖AIに質問してみる
エラーの原因は、AsyncImageがURL型を期待しているのに対し、shop.imageUrlがString型であることです。この問題を解決するために、StringをURLに変換する必要があります。
import SwiftUI
struct ShopDetailView: View {
var shop: Shop
var body: some View {
NavigationView {
ScrollView {
VStack(alignment: .leading, spacing: 10) {
// get shop image url
if let url = URL(string: shop.imageUrl) {
AsyncImage(url: url) { phase in
switch phase {
// loading...
case .empty:
ProgressView()
case .success(let image):
image
.resizable()
.aspectRatio(contentMode: .fit)
.frame(height: 200)
case .failure:
Image(systemName: "photo")
.resizable()
.aspectRatio(contentMode: .fit)
.frame(height: 200)
// error
@unknown default:
EmptyView()
}
}
} else {
Image(systemName: "photo")
.resizable()
.aspectRatio(contentMode: .fit)
.frame(height: 200)
}
Text("お店の名前: \(shop.shop_name)")
}
.padding()
}
.navigationBarTitle(shop.shop_name, displayMode: .inline)
}
}
}
上記に記載のコードでは、if let を使用して、nilでないかチェックする処理をしています。
what is if let?
if letは、オプショナル型の値がnilでない場合にその値を取り出し、そのスコープ内で利用します。値がnilの場合、elseブロックが実行されます。
例:
if let someString = b {
// 値があるときは、この処理を実行する
print("Optional Value \(b)")
} else if b == nil {
// 値がnilのときは、この処理を実行する
print("b is nil")
} else {
print("b has a value")
}
今回だと、値がnil
でなければ、画像を表示することができます。表示に時間がかかるときは、ローディングが表示されます。画像がなかったら仮のイメージを表示します。
まとめ
今回は、AsyncImageを使ってハマったエラーについて記事を書きました。Stringの値を渡すだけと思いきやまさか、nil
でないかチェックが必要なんですね。Dartでもnullでないかチェックしてますが......
Discussion