0

On my MapViewController, I am able to successfully download all the records from CloudKit and place them in their locations as pins with (title and subtitle).

When I tried to create thumbnail images for each pin when you click on it. I get the error message:

Could not cast value of type 'Foodie.CustomPointAnnotation' (0x7f85dff41b00) to 'Foodie.Place' (0x1077b5fa0).

Here is the viewForAnnotation method:

  func mapView(mapView: MKMapView, viewForAnnotation annotation: MKAnnotation) -> MKAnnotationView?
  {
    var pinView = mapView.dequeueReusableAnnotationViewWithIdentifier(Constants.PinIdentifier)

    if pinView == nil
    {
      pinView = MKAnnotationView(annotation: annotation, reuseIdentifier: Constants.PinIdentifier)
      pinView?.canShowCallout = true
    }

    pinView!.annotation = annotation
    (annotation as! Place).loadMapImage { image in
      if image != nil
      {
        UIGraphicsBeginImageContext(CGSize(width: 30, height: 30))
        image.drawInRect(CGRectMake(0, 0, 30, 30))
        let smallImage = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        let imView = UIImageView(image: smallImage)
        pinView?.leftCalloutAccessoryView = imView
      }
    }

    let customPointAnnotation = annotation as! CustomPointAnnotation
    pinView!.image = UIImage(named: customPointAnnotation.pinCustomImageName)

    return pinView
  }

Here is my model (Place):

import UIKit
import CloudKit
import MapKit

let placeName = "name"
let placeAddress = "address"
let placeComment = "comment"
let placePhoto = "photo"
let placeRating = "rating"
let placeLocation = "location"

class Place
{
  var name: String
  var address: String
  var comment: String?
  var photo: UIImage?
  var rating: Int
  var location: CLLocation?
  var identifier: String
  var record: CKRecord!

  init(record: CKRecord)
  {
    self.record = record
    self.name = record.valueForKey(placeName) as! String
    self.address = record.valueForKey(placeAddress) as! String
    self.comment = record.valueForKey(placeComment) as? String

    if let photoAsset = record.valueForKey(placePhoto) as? CKAsset
    {
      self.photo = UIImage(data: NSData(contentsOfURL: photoAsset.fileURL)!)
    }

    self.rating = record.valueForKey(placeRating) as! Int
    self.location = record.valueForKey(placeLocation) as? CLLocation

    self.identifier = record.recordID.recordName
  }

  // MARK: Map Annotation

  var coordinate: CLLocationCoordinate2D? {
    get {
      return location!.coordinate
    }
  }

  var title: String! {
    get {
      return name
    }
  }

  var subtitle: String! {
    get {
      return address
    }
  }

  func loadMapImage(completion: (image: UIImage!) -> ())
  {
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0))
    {
      var image: UIImage!
      if let mapImage = self.record.objectForKey(placePhoto) as? CKAsset
      {
        image = UIImage(data: NSData(contentsOfURL: mapImage.fileURL)!)
      }
      completion(image: image)
    }
  }

}

Any idea what I did wrong? Thanks in advance.

rmaddy
  • 314,917
  • 42
  • 532
  • 579
ckraider
  • 335
  • 5
  • 19

1 Answers1

0

For the cast to work, the annotation has to actually be a Place object or a subclass of Place. There's no automagical translation of something that isn't a Place to a Place.

Probably the best solution is to create an initialiser for Place that takes a CustomPointAnnotation as a parameter.

JeremyP
  • 84,577
  • 15
  • 123
  • 161
  • Thanks for your suggestion. What's the safest way to add that initializer? Are you referring in the viewForAnnotation method? I am trying to avoid changing the model much since many VCs depend on it. I'm still new to Swift/programming. – ckraider Jan 18 '16 at 15:29