I’m trying to load the photos into the interface. I checked all of the code and connections
countless times, but it still gave me the same error. I added the code on pages 432-434 which only adds to PhotosViewController.swift and Photo.swift, but the error is coming from PhotoCollectionViewCell.swift. It looks like the code found the photos and started logging the photos into the console but then crashed and never loaded the photos.
Does anybody have ideas? What am I missing? TIA
Here is the error I’ve been getting:
Successfully found 100 photos
2020-08-12 14:58:18.271777-0700 Photorama[64192:4012203] [Storyboard] Unknown class ImageView in Interface Builder file.
2020-08-12 14:58:18.273968-0700 Photorama[64192:4012203] [Storyboard] Unknown class ImageView in Interface Builder file.
2020-08-12 14:58:18.275442-0700 Photorama[64192:4012203] [Storyboard] Unknown class ImageView in Interface Builder file.
…
2020-08-12 14:58:18.334039-0700 Photorama[64192:4012203] [Storyboard] Unknown class ImageView in Interface Builder file.
2020-08-12 14:58:18.335395-0700 Photorama[64192:4012203] [Storyboard] Unknown class ImageView in Interface Builder file.
Fatal error: Unexpectedly found nil while implicitly unwrapping an Optional value: file /Users/sarahchang/Desktop/Summer Projects/Photorama/Photorama/PhotoCollectionViewCell.swift, line 20
2020-08-12 14:58:18.584343-0700 Photorama[64192:4012203] Fatal error: Unexpectedly found nil while implicitly unwrapping an Optional value: file /Users/sarahchang/Desktop/Summer Projects/Photorama/Photorama/PhotoCollectionViewCell.swift, line 20
(lldb)
Photo.swift
import Foundation
class Photo: Codable {
let title: String
let remoteURL: URL?
let photoID: String
let dateTaken: Date?
enum CodingKeys: String, CodingKey {
case title
case remoteURL = "url_z"
case photoID = "id"
case dateTaken = "date_taken"
}
}
extension Photo: Equatable {
static func == (lhs: Photo, rhs: Photo) -> Bool {
// Two Photos are the same if they have the same photoID
return lhs.photoID == rhs.photoID
}
}
PhotosViewController.swift
import UIKit
class PhotosViewController: UIViewController, UICollectionViewDelegate {
@IBOutlet var collectionView: UICollectionView!
var store: PhotoStore!
let photoDataSource = PhotoDataSource()
override func viewDidLoad() {
super.viewDidLoad()
collectionView.dataSource = photoDataSource
collectionView.delegate = self
store.fetchInterestingPhotos {
(photosResult) in
switch photosResult {
case let .success(photos):
print("Successfully found \(photos.count) photos")
self.photoDataSource.photos = photos
case let .failure(error):
print("Error fetching interesting photos: \(error)")
self.photoDataSource.photos.removeAll()
}
self.collectionView.reloadSections(IndexSet(integer: 0))
}
}
func collectionView(_ collectionView: UICollectionView,
willDisplay cell: UICollectionViewCell,
forItemAt indexPath: IndexPath) {
let photo = photoDataSource.photos[indexPath.row]
// Download the image data, which could take some time
store.fetchImage(for: photo) { (result) -> Void in
// The index path for the photo might have changed between the
// time the request started and finished, so find the most
// recent index path
guard let photoIndex = self.photoDataSource.photos.firstIndex(of: photo),
case let .success(image) = result else {
return
}
let photoIndexPath = IndexPath(item: photoIndex, section: 0)
// When the request finishes, find the current cell for this photo
if let cell = self.collectionView.cellForItem(at: photoIndexPath)
as? PhotoCollectionViewCell {
cell.update(displaying: image)
}
}
}
}
PhotoCollectionViewCell
import UIKit
class PhotoCollectionViewCell: UICollectionViewCell {
@IBOutlet var imageView: UIImageView!
@IBOutlet var spinner: UIActivityIndicatorView!
func update(displaying image: UIImage?) {
if let imageToDisplay = image {
spinner.stopAnimating()
imageView.image = imageToDisplay
} else {
spinner.startAnimating()
imageView = nil
}
}
}