【问题标题】:How can I display an image by an API URL? Swift如何通过 API URL 显示图像?迅速
【发布时间】:2019-09-10 20:56:59
【问题描述】:

我有一个应用程序,它向我显示来自 API 的数据。我做了一个获取数据的服务,其中 URL(string = "") 是 API 的 url:

class Webservice {

    func getAllMatches(completion: @escaping ([Matches.Matchs]?) -> ()) {

        guard let url = URL(string: "API")
            else {
                fatalError("URL is not correct!")
        }
        URLSession.shared.dataTask(with: url) { data, _, _ in

            let matchs = try! JSONDecoder().decode([Matches.Matchs].self, from: data!)
            DispatchQueue.main.async {
                completion(matchs)
            }
        }.resume()
    }

}

然后我制作了一个 ViewModel,其中设置了 API 字段:

class MatchListViewModel: ObservableObject {

    @Published var matches = [MatchViewModel]()


    init() {
        fetchMatch()


    }

    func fetchMatch() {

        Webservice().getAllMatches { matches in

            if let matches = matches {
                self.matches = matches.map(MatchViewModel.init)
            }
        }
    }

}


class MatchViewModel {

    let id = UUID()

    var match: Matches.Matchs

    init(match: (Matches.Matchs)) {
        self.match = match
    }


    var championship: String {
        return self.match.championship.name
    }

    var local_Name: String {
        return self.match.local.name
    }

    var local_Image: String  {
        return self.match.local.image
    }

    var local_goals: Double {
        return self.match.local_goals
    }

    var local_penalty_goals: Double {
        return self.match.local_penalty_goals
    }
    var stadium_Name: String {
        return self.match.stadium.name
    }

}

在API中,有一个显示图像的字段,它包含在一个URL中,我举个例子:

"local":{  
     "slug":"nombre",
     "name":"nombre",
     "short_name":"nombre",
     "image":"https://s3.amazonaws.com/funx-futbol/dashboard/ad.png"
 },

我的问题是:如何通过该 URL 显示该图像? API 查询有效,因为它为我提供了我需要的信息,但我需要通过该链接向我展示图像,但我还没有实现。

感谢阅读!

error

【问题讨论】:

    标签: swift swiftui combine


    【解决方案1】:

    使用这样的加载器来加载数据:

    import Combine
    
    public class DataLoader: ObservableObject {
    
        public let objectWillChange = PassthroughSubject<Data,Never>()
    
        public private(set) var data = Data() {
            willSet {
                objectWillChange.send(newValue)
            }
        }
    
        private let resourseURL: URL?
    
        public init(resourseURL: URL?){
            self.resourseURL = resourseURL
        }
    
        public func loadImage() {
            guard let url = resourseURL else {
                return
            }
    
            URLSession.shared.dataTask(with: url) { (data,_,_) in
                guard let data = data else {
                    return
                }
                DispatchQueue.main.async {
                    self.data = data
                }
            }   .resume()
        }
    }
    

    还有一个这样的结构来显示它:

    import SwiftUI 
    
    struct WebImage: View {
    
        @ObservedObject private var imageLoader: DataLoader
    
        public init(imageURL: URL?) {
            imageLoader = DataLoader(resourseURL: imageURL)
        }
    
        public var body: some View {
            if let uiImage = UIImage(data: self.imageLoader.data) {
                return AnyView(Image(uiImage: uiImage)
                                .resizable()
                                .aspectRatio(contentMode: ContentMode.fit))
            } else {
                return AnyView(Image(systemName: "ellipsis")
                                .onAppear(perform: { self.imageLoader.loadImage() }))
            }
        }
    }
    

    【讨论】:

    • 谢谢,但是当我尝试将“WebImage”放在我的视图中时,我在 forEach 中收到一个错误,错误显示“类型 '_' 没有成员 'id'”。 ://
    • 能否提供出现错误的代码?
    • WebImage 需要一个 URL?到它的初始化程序中,所以你必须像这样声明它: WebImage(imageURL: URL(string: ""))
    【解决方案2】:

    您可以通过 init?(contentsOf:): https://developer.apple.com/documentation/foundation/data/3126626-init 初始化 Data,然后您可以使用该数据通过 init?(data:): https://developer.apple.com/documentation/uikit/uiimage/1624106-init 初始化 UIImage

    如果您这样做,请记住默认情况下,此 Data 初始化程序不会在后台线程上运行,因此您的性能可能会很差,可能您希望将其推送到后台,然后在完成时使用 GCD 来使用结果并更新 UI。

    【讨论】:

      【解决方案3】:

      如果您不想编写任何自定义类,可以使用URLImage 库。它有大量可应用于远程图像的自定义选项。

      您可以通过添加一个 swift 包(steps)将其安装到您的项目中。

      希望对你有帮助。

      编码愉快。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-10-14
        • 1970-01-01
        • 1970-01-01
        • 2016-06-16
        • 1970-01-01
        • 2016-02-10
        • 2021-01-21
        • 2015-04-10
        相关资源
        最近更新 更多