为什么数组 return 在 Swift 中为空?

Why does the Array return empty in Swift?

我正在尝试向我的 MapKit 添加注释,但是我附加到的数组返回 nil。我之前使用这种方法在之前的 ViewControllers 中填充 CollectionView 并且数组有值,现在如果我打印数组它 returns 0 值,我确信应该有数据,因为它打印在控制台中,但未添加到数组中。请考虑一下?

我的经理Class:

class GoogleMapsAPIManager {

var bloodBanksArray = [BloodBanksModel]()


func fetchCity(latitude: CLLocationDegrees, longitude: CLLocationDegrees, raduis: Double){
    let urlString = "\(K.googleMapsAPI)&location=\(latitude),\(longitude)&radius=\(raduis)&key=\(K.apiKey)"
    print(urlString)
    performRequest(with: urlString)
}

//MARK: - Decoding JSON
func performRequest(with urlString: String){
    if let url = URL(string: urlString) {
        
        let session = URLSession(configuration: .default)
        
        let task = session.dataTask(with: url) { (data, response, error) in
            if error != nil {
                print(error!)
                return
            }
            
            if let safeData = data {
                self.parseJSON(bloodBankData: safeData)
            }
        }
        task.resume()
    }
}

func parseJSON(bloodBankData: Data) {
    let decoder = JSONDecoder()
    
    do {
        let decodedData = try decoder.decode(BloodBanksData.self, from: bloodBankData)
        for i in 0...decodedData.results.count - 1 {
            bloodBanksArray.append(BloodBanksModel(name: decodedData.results[i].name, photo: decodedData.results[i].photos?[0].photoReference ?? "ATtYBwJjqXlw3DMdL74SRtgG_GRA3LkAET6hDJXHWtkQMaOTo1B3Gx9jrDTXFLFabGStSxX8BiYdLAnknF7A9ynw33KKyUh5Oc55A9vXzo_6nd4mnk5Sx-iOqMNaw21dk0C424PWaio9GiogQaKecYxOT1q-bmj30syypZmyxkjF7r3-gFyC", open_now: decodedData.results[i].openingHours?.openNow ?? false, vincinity: decodedData.results[i].vicinity, rating: decodedData.results[i].rating, placeId: decodedData.results[i].placeId, lat: decodedData.results[i].geometry.location.lat, lng: decodedData.results[i].geometry.location.lng))
        }
        
        print("bossins \(bloodBanksArray)")
        
    } catch {
        print(error)
    }
}  
}

型号Class:

struct BloodBanksModel {
    let name: String
    let photo: String
    let open_now: Bool
    let vincinity: String
    let rating: Double
    let placeId: String
    let lat: Double
    let lng: Double
}

数据:

import Foundation

// MARK: - BloodBanksData
struct BloodBanksData: Codable {
    let results: [Result]

    enum CodingKeys: String, CodingKey {
        case results
    }
}

// MARK: - Result
struct Result: Codable {
    let geometry: Geometry
    let name: String
    let openingHours: OpeningHours?
    let photos: [Photo]?
    let rating: Double
    let vicinity: String
    let placeId: String

    enum CodingKeys: String, CodingKey {
        case geometry, name
        case openingHours = "opening_hours"
        case photos
        case rating
        case vicinity
        case placeId = "place_id"
    }
}

// MARK: - Geometry
struct Geometry: Codable {
    let location: Location
}

// MARK: - Location
struct Location: Codable {
    let lat, lng: Double
}

// MARK: - OpeningHours
struct OpeningHours: Codable {
    let openNow: Bool

    enum CodingKeys: String, CodingKey {
        case openNow = "open_now"
    }
}

// MARK: - Photo
struct Photo: Codable {
    let photoReference: String

    enum CodingKeys: String, CodingKey {
        case photoReference = "photo_reference"
    }
}

在我的 ViewController:

override func viewDidLoad() {
        super.viewDidLoad()
        
        //mapView.delegate = self
        
        locationManager.requestWhenInUseAuthorization()
        var currentLocation: CLLocation!
        
        if
            CLLocationManager.authorizationStatus() == .authorizedWhenInUse ||
                CLLocationManager.authorizationStatus() ==  .authorizedAlways
        {
            currentLocation = locationManager.location
            googleMapsAPIManager.fetchCity(latitude: currentLocation.coordinate.latitude, longitude: currentLocation.coordinate.longitude, raduis: 100000.0)
        }
        
        for location in googleMapsAPIManager.bloodBanksArray {
            let annotation = MKPointAnnotation()
            annotation.title = location.name
            annotation.coordinate = CLLocationCoordinate2D(latitude: location.lat, longitude: location.lng)
            annotations.append(annotation)
        }
        mapView.addAnnotations(annotations)
}

正如我在你的 previous question fetchCity 作品中所说 异步 ,你必须添加一个完成处理程序

为了方便起见,我将 fetchCityperformRequestparseJSON() 合并为一个方法。

func fetchCity(latitude: CLLocationDegrees, longitude: CLLocationDegrees, raduis: Double, completion: @escaping () -> Void){
    let urlString = "\(K.googleMapsAPI)&location=\(latitude),\(longitude)&radius=\(raduis)&key=\(K.apiKey)"
    print(urlString)
    if let url = URL(string: urlString) {
        
        let session = URLSession(configuration: .default)
        
        let task = session.dataTask(with: url) { (data, _, error) in
            if let error = error { print(error); return }
            let decoder = JSONDecoder()
            do {
                let decodedData = try decoder.decode(BloodBanksData.self, from: data!)
                for i in 0..<decodedData.results.count {
                    bloodBanksArray.append(BloodBanksModel(name: decodedData.results[i].name, photo: decodedData.results[i].photos?[0].photoReference ?? "ATtYBwJjqXlw3DMdL74SRtgG_GRA3LkAET6hDJXHWtkQMaOTo1B3Gx9jrDTXFLFabGStSxX8BiYdLAnknF7A9ynw33KKyUh5Oc55A9vXzo_6nd4mnk5Sx-iOqMNaw21dk0C424PWaio9GiogQaKecYxOT1q-bmj30syypZmyxkjF7r3-gFyC", open_now: decodedData.results[i].openingHours?.openNow ?? false, vincinity: decodedData.results[i].vicinity, rating: decodedData.results[i].rating, placeId: decodedData.results[i].placeId, lat: decodedData.results[i].geometry.location.lat, lng: decodedData.results[i].geometry.location.lng))
                }
                print("bossins \(bloodBanksArray)")
                completion()
        
            } catch {
                print(error)
            }
        }
        task.resume()
    }
}

并称之为

if CLLocationManager.authorizationStatus() == .authorizedWhenInUse ||
                CLLocationManager.authorizationStatus() ==  .authorizedAlways {
    currentLocation = locationManager.location
    googleMapsAPIManager.fetchCity(latitude: currentLocation.coordinate.latitude, longitude: currentLocation.coordinate.longitude, raduis: 100000.0) {
        for location in googleMapsAPIManager.bloodBanksArray {
            let annotation = MKPointAnnotation()
            annotation.title = location.name
            annotation.coordinate = CLLocationCoordinate2D(latitude: location.lat, longitude: location.lng)
            annotations.append(annotation)
        }
        mapView.addAnnotations(annotations)
    }
}

请注意,Core Location 也是异步工作的。