如何在SwiftUI中使用URL显示Google Place Photos?

时间:2019-12-11 16:47:33

标签: swift uiimage google-places-api swiftui combine

因此,我正在尝试使用Google的Places API提供的photo_references在SwiftUI中显示照片,但是遇到了我似乎无法解决的问题。

据我了解,为了访问Google地方照片,需要使用照片参考和API密钥创建一个URL。 Info here

我目前能够正确地从Google请求所有必要的信息,并创建正确的URL来获取特定照片。但是,当我尝试使用URL显示返回的图像时,我的应用程序将不会显示该图像,而是显示我的占位符/备份选项,以防Google图像无法加载。

-

下面列出了更多代码详细信息:

我在教程here

之后对代码进行了建模

我创建并传递的示例网址: (不包括我针对此问题的api密钥)

https://maps.googleapis.com/maps/api/place/photo?maxwidth=200&photoreference=CnRtAAAATLZNl354RwP_9UKbQ_5Psy40texXePv4oAlgP4qNEkdIrkyse7rPXYGd9D_Uj1rVsQdWT4oRz4QrYAJNpFX7rzqqMlZw2h2E2y5IKMUZ7ouD_SlcHxYq1yL4KbKUv3qtWgTK0A6QbGh87GB3sscrHRIQiG2RrmU_jF4tENr9wGS_YxoUSSDrYjWmrNfeEHSGSc3FyhNLlBU&key=YOUR_API_KEY

ImageViewWidget.view -这是处理请求和显示Google Place Photos的视图:

import SwiftUI
import Foundation
import Combine


class ImageLoader: ObservableObject {
    var didChange = PassthroughSubject<Data, Never>()

    var data = Data() {
        didSet {
            didChange.send(data)
        }
    }

    init(imageUrl: String) {
        // implementation
        guard let url = URL(string: imageUrl) else { return }
        URLSession.shared.dataTask(with: url) { (data, _, _) in
            guard let data = data else { return }

            DispatchQueue.main.async {
                self.data = data
                print("imageLoader.data - ", data)
            }
        }.resume()
    }
}


struct ImageViewWidget: View {

    @ObservedObject var imageLoader: ImageLoader

    init(imageUrl: String) {
        imageLoader = ImageLoader(imageUrl: imageUrl)
        print("imageUrl - ", imageUrl)
    }

    var body: some View {
        Image(uiImage: (imageLoader.data.count == 0) ? UIImage(named: "turtlerock")! : UIImage(data: imageLoader.data)!)
            .resizable()
            .frame(width: 55, height: 55)
            .cornerRadius(6)
    }
}

MarkerInfoWindow.view -这是我的应用程序中调用 ImageViewWidget.view 的文件/视图:

import SwiftUI
import UIKit


struct MarkerInfoWindow: View {


    var placedata: [String: Any]
    var placetypedata: [String]


    var body: some View {

        HStack {
            Text("4")
                    VStack(alignment: .leading) {
                        HStack {
//This is where i call ImageViewWidget vvv
                            ImageViewWidget(imageUrl: placedata["photo_reference"] as! String)

                            VStack(alignment: .leading) {
                                HStack {
                                    Text(placedata["name"] as! String)
                                        .font(.system(size: 16))
                                        .bold()
                                    Spacer()
                                    Text("10am-10pm")
                                    .font(.system(size: 12))
                                }
                                HStack {
                                    Text("⭐ \(placedata["rating"] as! String)")
                                        .font(.system(size: 14))
                                        .foregroundColor(Color(UIColor.systemYellow))
                                    Text("$ \(placedata["price_level"]! as! String)")
                                        .font(.system(size: 14))
                                        .foregroundColor(Color(UIColor.systemGreen))
                                }
                                HStack {
                                Text(placetypedata[0])
                                    .font(.system(size: 14))
                                }
                            }
                            Spacer()

                        }

                    }
                    Spacer()

                }


    }

}

我已经验证了传入的网址是正确的,因为将其粘贴到浏览器中后,图像可以正确显示。但是,当我运行我的应用程序时,它会继续显示在上面的 MarkerInfoWindow.view 文件底部定义的“ turtlerock”图像,而不是我所请求的图像。话虽这么说,

有人知道我的应用程序为什么不显示我请求的Google Place Photos,而是显示我的故障安全选项的原因吗?

编辑: 我认为显示“ turtlerock”图像是因为我的imageLoader.data最初是空的,但是ImageViewWidget不会更新为正确的图像,因为它没有拾取对imageLoader.data的更改。我可能是错的,但是我希望有更多经验的人能找到帮助有用的答案

0 个答案:

没有答案