Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/image-processing/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
从url异步加载SwiftUI中的多个图像_Swift_Xcode_Image_Swiftui_Imageurl - Fatal编程技术网

从url异步加载SwiftUI中的多个图像

从url异步加载SwiftUI中的多个图像,swift,xcode,image,swiftui,imageurl,Swift,Xcode,Image,Swiftui,Imageurl,我正在尝试编写一个代码,从url加载多个图像(介于5到10之间)。我使用AudioDB api(加载的图像是艺术家的照片)。问题是只显示最后一张图像。在ContentView中,我有一个ForEach,它可以加载5到10个ArtistImage(s)结构。我知道所有图像数据都已加载(在ImageFetcher var imageData中,将设置I put print(新值),并显示已加载的数据(例如:148273字节等)。只是无法理解为什么只显示最后一个图像 struct ArtistImag

我正在尝试编写一个代码,从url加载多个图像(介于5到10之间)。我使用AudioDB api(加载的图像是艺术家的照片)。问题是只显示最后一张图像。在ContentView中,我有一个ForEach,它可以加载5到10个ArtistImage(s)结构。我知道所有图像数据都已加载(在ImageFetcher var imageData中,将设置I put print(新值),并显示已加载的数据(例如:148273字节等)。只是无法理解为什么只显示最后一个图像

struct ArtistImage: View {

var imageURL: URL?

@ObservedObject private var imageFetcher: ImageFetcher

init(imageURL: String) {
    self.imageURL = URL(string: imageURL)

    imageFetcher = ImageFetcher(imageURL: self.imageURL)
}

var body: some View {

    if let uiImage = UIImage(data: imageFetcher.imageData) {
        return AnyView(Image(uiImage: UIImage(data: self.imageFetcher.imageData)!)
            .renderingMode(.original)
            .resizable()
            .cornerRadius(10))
    } else {
        return AnyView(Text("Loading...")
            .onAppear(perform: { self.imageFetcher.getImage() }))
    }
}
以及下面的ImageFetcher类:

class ImageFetcher: ObservableObject  {

public let objectWillChange = PassthroughSubject<Data,Never>()

public private(set) var imageData = Data() {
    willSet {
        print(newValue)        // it tells me all images are loaded
        objectWillChange.send(newValue)
    }
}
var imageURL: URL?

public init(imageURL: URL?) {
    self.imageURL = imageURL
}

func getImage() {

    guard let url = imageURL else { return }

    URLSession.shared.dataTask(with: url) { (data, _, _) in
        guard let data = data else {
            return
        }
        DispatchQueue.main.async {
            self.imageData = data

        }
    }.resume()
}
}

网络管理器类:

class NetworkManager: ObservableObject {

@Published var artistsDB = [Artist]()

func createArtistsDatabase() {

    let artistsNames: [String] = ["Madonna", "Metallica","Coldplay","Toto","Kraftwerk","Depeche%20Mode"]
    for ar in artistsNames {
        findArtistBy(name: ar)
    }
}

func findArtistBy(id: String = "", name: String = "") {
    var url: URL?

    if id != "" {
        guard let urlID = URL.getArtistByID(id: id) else { return }
        url = urlID

    } else {
        guard let urlName = URL.getArtistByName(name: name) else { return }
        url = urlName

    }
    let urlRequest = URLRequest(url: url!)
    let task = URLSession.shared.dataTask(with: urlRequest) { data,response,error in

        if error != nil || data == nil {
            print("Client error")
            return
        }
        guard let response = response as? HTTPURLResponse, (200...299).contains(response.statusCode) else {
            print("Server error")
            return
        }
        guard let mime = response.mimeType, mime == "application/json" else {
            print("Wrong mime type")
            return
        }
        guard let dataToDecode = data else { return }

        do {
            let decoder = JSONDecoder()
            let dataJSONed = try decoder.decode(DBArtist.self, from: dataToDecode)
            DispatchQueue.main.async {
                print(dataJSONed.artist[0])
                self.artistsDB.append(dataJSONed.artist[0])
            }
        } catch {
            print("Error while decoding!")
        }

    }
    task.resume()
}
URL扩展名:

extension URL {
static func getArtistByID(id: String) -> URL? {
    return URL(string: "https://theaudiodb.com/api/v1/json/1/artist.php?i=\((id))")
}
static func getArtistByName(name: String) ->URL? {
    print("https://www.theaudiodb.com/api/v1/json/1/search.php?s=\(name)")
    return URL(string: "https://www.theaudiodb.com/api/v1/json/1/search.php?s=\(name)")
}
}


是否显示ContentView代码?是的,我刚刚更新了第一篇文章。您可以共享NetworkManager吗?当然,刚刚添加。好的,我刚刚发现问题:在NetworkManager中,我将新项目添加到数组中(新艺术家到艺术家数组),这导致不断更新/刷新观察到的数据库(ArtistDB)。我将其更改为将所有数据收集到临时数组,并在收集到所有数据时将其复制到ArtistDB,从而只触发一次UI更新。
extension URL {
static func getArtistByID(id: String) -> URL? {
    return URL(string: "https://theaudiodb.com/api/v1/json/1/artist.php?i=\((id))")
}
static func getArtistByName(name: String) ->URL? {
    print("https://www.theaudiodb.com/api/v1/json/1/search.php?s=\(name)")
    return URL(string: "https://www.theaudiodb.com/api/v1/json/1/search.php?s=\(name)")
}