尝试将url传递到SwiftUI中的图像加载器时,结果为零
因此,我试图用JSON中的数据(在本例中,它们是书籍)填充一个列表,JSON包含每本书的一个图像,我四处询问,图像加载器应该是唯一的方法 让我给你看一些代码 这是图像加载器:尝试将url传递到SwiftUI中的图像加载器时,结果为零,swiftui,Swiftui,因此,我试图用JSON中的数据(在本例中,它们是书籍)填充一个列表,JSON包含每本书的一个图像,我四处询问,图像加载器应该是唯一的方法 让我给你看一些代码 这是图像加载器: struct ImageView: View { @ObservedObject var imageLoader:ImageLoader @State var image:UIImage = UIImage() func imageFromData(_ data:Data) -> UIIma
struct ImageView: View {
@ObservedObject var imageLoader:ImageLoader
@State var image:UIImage = UIImage()
func imageFromData(_ data:Data) -> UIImage {
UIImage(data: data) ?? UIImage()
}
init(withURL url:String) {
imageLoader = ImageLoader(urlString:url)
}
var body: some View {
VStack {
Image(uiImage: imageLoader.data != nil ? UIImage(data:imageLoader.data!)! : UIImage())
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width:100, height:100)
}
}
}
class ImageLoader: ObservableObject {
@Published var dataIsValid = false
var data:Data?
init(urlString:String) {
guard let url = URL(string: urlString) else { return }
let task = URLSession.shared.dataTask(with: url) { data, response, error in
guard let data = data else { return }
DispatchQueue.main.async {
self.dataIsValid = true
self.data = data
}
}
task.resume()
}
}
查看正文中VStack
中的第一行:结构的一些视图
,这就是它崩溃的地方,在展开可选值时给了我意外发现的nil
下面是列表的代码
:
let apiUrl = "https://qodyhvpf8b.execute-api.us-east-1.amazonaws.com/test/books"
class BooksViewModel: ObservableObject {
@Published var books: [Book] = [
.init(id: 1, nombre: "Libro 1", autor: "Autor 1", disponibilidad: true, popularidad: 100, imagen: "https://www.google.com.ar"),
.init(id: 2, nombre: "Libro 2", autor: "Autor 2", disponibilidad: false, popularidad: 80, imagen: "https://www.google.com.ar"),
.init(id: 3, nombre: "Libro 3", autor: "Autor 3", disponibilidad: true, popularidad: 60, imagen: "https://www.google.com.ar")
]
func fetchBooks() {
guard let url = URL(string: apiUrl) else { return }
URLSession.shared.dataTask(with: url) { (data, resp, err) in
DispatchQueue.main.async {
do {
self.books = try JSONDecoder().decode([Book].self, from: data!)
} catch {
print("Failed to decode JSON: ", error)
}
}
}.resume()
}
}
struct ContentView: View {
@ObservedObject var booksVM = BooksViewModel()
var body: some View {
NavigationView {
List {
VStack(alignment: .leading) {
ForEach(booksVM.books.sorted { $0.popularidad > $1.popularidad}) { book in
HStack {
ImageView(withURL: book.imagen)
Text(book.nombre)
Spacer()
Text(String(book.popularidad))
}
HStack {
Text(book.autor)
Spacer()
if book.disponibilidad {
Text("Disponible")
} else {
Text("No disponible")
}
}
Spacer()
}
}.padding([.leading, .trailing], 5)
}
.navigationBarTitle("Bienvenido a la librería flux")
.onAppear(perform: self.booksVM.fetchBooks)
}
}
}
HStack
,ImageView(带url:book.imagen)
的第一行应该是传递url字符串的那一行,但我不知道为什么,这没有发生book.imagen
应返回字符串。我不知道是因为它没有返回字符串,还是图像加载程序出了问题。我想不出来。其余的数据都很好
以下是JSON的一部分:
[
{
"id": 1,
"nombre": "The design of every day things",
"autor": "Don Norman",
"disponibilidad": true,
"popularidad": 70,
"imagen": "https://images-na.ssl-images-amazon.com/images/I/410RTQezHYL._SX326_BO1,204,203,200_.jpg"
},
{
"id": 2,
"nombre": "100 años de soledad",
"autor": "Garcia Marquez",
"disponibilidad": false,
"popularidad": 43,
"imagen": "https://images-na.ssl-images-amazon.com/images/I/51egIZUl88L._SX336_BO1,204,203,200_.jpg"
},
{
"id": 3,
"nombre": "El nombre del viento",
"autor": "Patrik Rufus",
"disponibilidad": false,
"popularidad": 80,
"imagen": "https://static.megustaleer.com/images/libros_200_x/EL352799.jpg"
}
]
如果需要更多说明,请告诉我。swiftUI代码没有问题。以下是工作模型示例代码。也许你在你的模特身上遗漏了什么
struct Book: Identifiable, Decodable {
var popularidad: Int = 0
var imagen : String = ""
var nombre : String = ""
var autor : String = ""
var disponibilidad : Bool = false
var id : Int = 0
}
class BooksViewModel: ObservableObject {
@Published var books : [Book] = []
func fetchBooks(){
do {
if let url = Bundle.main.url(forResource: "LocalCache", withExtension: "json")
{
if let string = try String(contentsOf: url).data(using: .utf8)
{
self.books = try JSONDecoder().decode([Book].self, from: string)
}
}
}
catch{}
}
}
swiftUI代码没有问题。以下是工作模型示例代码。也许你在你的模特身上遗漏了什么
struct Book: Identifiable, Decodable {
var popularidad: Int = 0
var imagen : String = ""
var nombre : String = ""
var autor : String = ""
var disponibilidad : Bool = false
var id : Int = 0
}
class BooksViewModel: ObservableObject {
@Published var books : [Book] = []
func fetchBooks(){
do {
if let url = Bundle.main.url(forResource: "LocalCache", withExtension: "json")
{
if let string = try String(contentsOf: url).data(using: .utf8)
{
self.books = try JSONDecoder().decode([Book].self, from: string)
}
}
}
catch{}
}
}
你能和我分享一下你的BooksViewModel
吗?当然可以!补充!你能和我分享一下你的BooksViewModel
吗?当然可以!补充!嘿,谢谢你的回答。我真的需要在结构上添加空字符串作为默认值吗?我加上这些,现在我得到了空白。调试说,book.imagen
返回一个空字符串。您可以从计算机访问地址吗?嘿,谢谢您的回答。我真的需要在结构上添加空字符串作为默认值吗?我加上这些,现在我得到了空白。调试说,book.imagen
返回一个空字符串。您可以从计算机访问地址吗?