Good afternoon. I am working on my final year project, in my project I am using Google Maps API to show results in CollectionView.
If I test print the array, result is successful and I get the data displayed. Sometimes the app works perfectly, If I run it, it goes through and working, 75% of the times I get Fatal error: Index out of range: file Swift/ContiguousArrayBuffer.swift, line 444.
Any help is so much appreciated and thank you so much.
    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
    enum CodingKeys: String, CodingKey {
        case geometry, name
        case openingHours = "opening_hours"
        case photos
        case rating
        case vicinity
    }
}
// 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"
    }
}
My Model:
import Foundation
struct BloodBanksModel {
    let name: String
    let photo: String
    let open_now: Bool
    let longitude: Double
    let latitude: Double
    let vincinity: String
    let rating: Double
}
My Manager class:
import Foundation
class BloodBanksManager {
    var bloodBanksArray = [BloodBanksModel]()
    
    
    //MARK: - Decoding JSON
    func performRequest(){
        if let url = URL(string: "https://maps.googleapis.com/maps/api/place/nearbysearch/json?location=XX,XX&radius=1000.0&rankby=prominence&sensor=true&key=XXXXX&keyword=blood") {
            
            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 ?? decodedData.results[0].photos![0].photoReference, open_now: decodedData.results[i].openingHours?.openNow ?? false, longitude: decodedData.results[i].geometry.location.lng, latitude: decodedData.results[i].geometry.location.lat, vincinity: decodedData.results[i].vicinity, rating: decodedData.results[i].rating))
            }
            
        } catch {
            print(error)
        }
    }
    
}
My View Controller:
   var bloodBanksManager = BloodBanksManager()
    override func viewDidLoad() {
            super.viewDidLoad()
    ...
    bloodBanksManager.performRequest()
    ...
    }
// MARK: - UICollectionViewDataSource Methods
extension LandingViewController: UICollectionViewDataSource {
    func numberOfSections(in collectionView: UICollectionView) -> Int {
        return 1
    }
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return 3
    }
    
    
    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: K.BloodBanks.bloodBankCellIdentifier, for: indexPath) as! BloodBanksCell
 cell.bloodBankName.text = self.bloodBanksManager.bloodBanksArray[indexPath.row].name
        cell.bloodBankImageView.sd_setImage(with: URL(string: "https://maps.googleapis.com/maps/api/place/photo?photoreference=\(bloodBanksManager.bloodBanksArray[indexPath.row].photo)&sensor=false&maxheight=1000&maxwidth=1000&key=XXX"), placeholderImage: #imageLiteral(resourceName: "bloodbank4"))
        
        return cell
    }
    
}