ios - URL session 下载任务完成 block 从未被调用

标签 ios swift google-places-api nsurlsession nsurlsessiondownloadtask

我正在向 Google Places API 发出网络请求,以根据特定坐标获取附近的地点,然后运行任务来获取这些地点的照片。

我能够通过第一个任务成功获取地点详细信息,而当检索照片的第二个任务运行时,它的完成 block 永远不会输入,导致没有照片,因为我观察到放置了断点。

urlString 是正确的,我的 apiKey 工作正常,因为第一个任务再次返回正确的响应,并且我有能够执行 Web 请求的地点的照片引用。任何指导将不胜感激,因为我承认迷失了 - 如果需要可以提供更多细节。

以下是网络调用,改编自 ray wenderlich 的 guide .

typealias PlacesCompletion = ([Place]) -> Void
typealias PhotoCompletion = (UIImage?) -> Void

class DataProvider {
    private var photoCache: [String: UIImage] = [:]
    private var placesTask: URLSessionDataTask?
    private var session: URLSession {
        return URLSession.shared
    }

//FIRST WEB REQUEST
func fetchPlacesNearCoordinate(_ coordinate: CLLocationCoordinate2D, radius: Double, types: [String], completion: @escaping PlacesCompletion) -> Void {
    var urlString = "https://maps.googleapis.com/maps/api/place/nearbysearch/json?location=\(coordinate.latitude),\(coordinate.longitude)&radius=\(radius)&rankby=prominence&sensor=true&key=\(googleApiKey)"
    let typesString = "restaurant"
    urlString += "&type=\(typesString)"
    urlString = urlString.addingPercentEncoding(withAllowedCharacters: CharacterSet.urlQueryAllowed) ?? urlString

    guard let url = URL(string: urlString) else {
        completion([])
        return
    }

    if let task = placesTask, task.taskIdentifier > 0 && task.state == .running {
        task.cancel()
    }

    DispatchQueue.main.async {
        UIApplication.shared.isNetworkActivityIndicatorVisible = true
    }

    placesTask = session.dataTask(with: url) { data, response, error in
        var placesArray: [Place] = []
        defer {
            DispatchQueue.main.async {
                UIApplication.shared.isNetworkActivityIndicatorVisible = false
                completion(placesArray)
            }
        }
        guard let data = data,
            let json = try? JSON(data: data, options: .mutableContainers),
            let results = json["results"].arrayObject as? [[String: Any]] else {
                return
        }
        results.forEach {
            let place = Place(dictionary: $0, acceptedTypes: types)
            placesArray.append(place)                

            if let reference = place.photoReference {
                //SECOND WEB REQUEST CALL
                self.fetchPhotoFromReference(reference) { image in
                    place.photo = image
                }
            }
        }
    }
    placesTask?.resume()
}



//SECOND WEB REQUEST
func fetchPhotoFromReference(_ reference: String, completion: @escaping PhotoCompletion) -> Void {
    if let photo = photoCache[reference] {
        completion(photo)
    } else {
        let urlString = "https://maps.googleapis.com/maps/api/place/photo?maxwidth=200&maxheight=200&photoreference=\(reference)&key=\(googleApiKey)"
        guard let url = URL(string: urlString) else {
            completion(nil)
            return
        }

        DispatchQueue.main.async {
            UIApplication.shared.isNetworkActivityIndicatorVisible = true
        }

        session.downloadTask(with: url) { url, response, error in                
            var downloadedPhoto: UIImage? = nil
            defer {
                DispatchQueue.main.async {
                    UIApplication.shared.isNetworkActivityIndicatorVisible = false
                    completion(downloadedPhoto)
                }
            }
            guard let url = url else {
                return
            }
            guard let imageData = try? Data(contentsOf: url) else {
                return
            }
            downloadedPhoto = UIImage(data: imageData)
            self.photoCache[reference] = downloadedPhoto
            }
            .resume()
    }
}
}

最佳答案

尝试删除 session.download(with: url) block 。为了从 url 下载数据,您所需要的只是 let imageData = try?数据(contentsOf:url)

此外,您没有给出 let imageData = 尝试吗? Data(contentsOf: url) 执行时间。您进行调用,然后立即尝试使用 downloadedPhoto = UIImage(data: imageData) 行中的结果。

关于ios - URL session 下载任务完成 block 从未被调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53403253/

相关文章:

ios - 动态tableHeaderView无法正常工作

ios - 如果负载中缺少锁定 key ,推送通知是否会显示

ios - 适用于 iOS 的 Google Places API 与 Google Places Web 服务

ios - 如果正在编辑一个文本字段,如何暂时禁用所有文本字段的用户交互?

ios - 下载图片未显示 iOS Swift

ios - 用核心图形绘制正方形和子弹箭头

iOS Google Places API : "This IP, site or mobile application is not authorized to use this API key"

iOS:如何禁用 tableview 中的反弹效果?

ios - UIImage 遍历像素非常低效?

android - Google 地方自动完成给出 "Cannoat load results !"