So I have the function collectionView: cellForItemAtIndexPath
here:
func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCellWithReuseIdentifier("cellID", forIndexPath: indexPath)
print("Creating collection view number: \(indexPath.row)")
// Configure the cell
cell.backgroundColor = UIColor.lightGrayColor()
let thing = Mirror(reflecting: annotation?.photos!)
print(thing.subjectType)
print(annotation?.photos![indexPath.row])
return cell
}
Here is the declaration of my annotation object and photo object
class CustomAnnotation : NSManagedObject, MKAnnotation {
@NSManaged var latitude: NSNumber
@NSManaged var longitude : NSNumber
@NSManaged var title : String?
@NSManaged var subtitle: String?
@NSManaged var photos : [Photo]?
var coordinate = CLLocationCoordinate2D()
override init(entity: NSEntityDescription, insertIntoManagedObjectContext context : NSManagedObjectContext?) {
super.init(entity: entity, insertIntoManagedObjectContext: context)
}
init(coordinate : CLLocationCoordinate2D, context: NSManagedObjectContext) {
let entity = NSEntityDescription.entityForName("CustomAnnotation", inManagedObjectContext: context)!
super.init(entity: entity, insertIntoManagedObjectContext: context)
self.longitude = coordinate.longitude
self.latitude = coordinate.latitude
print(photos)
}
func setCoordinate() {
self.coordinate.longitude = CLLocationDegrees(self.longitude)
self.coordinate.latitude = CLLocationDegrees(self.latitude)
}
}
class Photo : NSManagedObject {
@NSManaged var imagePath : String
@NSManaged var customAnnotation : CustomAnnotation
override init(entity: NSEntityDescription, insertIntoManagedObjectContext context: NSManagedObjectContext?) {
super.init(entity: entity, insertIntoManagedObjectContext: context)
}
init(imagePath: String, context : NSManagedObjectContext) {
let entity = NSEntityDescription.entityForName("Photo", inManagedObjectContext: context)!
super.init(entity: entity, insertIntoManagedObjectContext: context)
self.imagePath = imagePath
}
}
This is how I am saving the Photos object that has an inverse many-one relationship with the CustomAnnotation class
if (annotation?.photos)!.isEmpty {
// Load photos
print("downloading photos")
dispatch_async(dispatch_get_main_queue()) {
FlickrClient.sharedInstance().getFlickrImages(self) {(result, success, errorString) in
if success {
print("loading photos")
// Use the inverse relationship to save the data
for photoURL in result as! [String] {
let photo = Photo(imagePath: photoURL, context: self.sharedContext)
photo.customAnnotation = self.annotation!
print(photo.imagePath)
}
dispatch_async(dispatch_get_main_queue()) {
self.collectionView!.reloadData()
}
CoreDataStackManager.sharedInstance().saveContext()
}
else {
self.showAlert("Error", message: errorString!, confirmButton: "OK")
}
}
}
}
Here is the logs for what happens when it crashes:
Creating collection view number: 0
Optional <Array<Photo>>
2015-12-27 00:15:07.046 VirtualTourist[10413:1965722] -[_NSFaultingMutableSet objectAtIndex:]: unrecognized selector sent to instance 0x7f956d4d8cf0
2015-12-27 00:15:07.058 VirtualTourist[10413:1965722] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[_NSFaultingMutableSet objectAtIndex:]: unrecognized selector sent to instance 0x7f956d4d8cf0'
I don't understand why print(annotation?.photos![indexPath.row])
crashes my program. I've read online and it says that this is a result of the object being an NSSet
but annotation?.photo!
is an Array
.So I'm kind of stuck, any hints?
I have solved it so because in my data model I chose the photos relationship in the CustomAnnotation entity to be unordered, a NSSet
is always returned even though the in the class definition the photos
variable is an Array
.
All I needed to do was to set the Arranged to Ordered:
And everything works, an Array
is returned instead of NSSet
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With