-2

I have a main VC, which displays data added by a user, and a VC where the user inputs the data.

What I am trying to do is pass the image from the adding VC to the main VC.

Currently, I get the SIGABRT error when I press save, and the following error message:

2016-04-14 08:07:23.207 On The Go[27697:2680635] -[On_The_Go.Agenda setImage:]: unrecognized selector sent to instance 0x7faf03063900 2016-04-14 08:07:23.212 On The Go[27697:2680635] * Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[On_The_Go.Agenda setImage:]: unrecognized selector sent to instance 0x7faf03063900' * First throw call stack: ( 0 CoreFoundation 0x000000010442bd85 exceptionPreprocess + 165 1 libobjc.A.dylib 0x0000000106897deb objc_exception_throw + 48 2 CoreFoundation 0x0000000104434d3d -[NSObject(NSObject) doesNotRecognizeSelector:] + 205 3 CoreFoundation 0x000000010437acfa ___forwarding_ + 970 4 CoreFoundation 0x000000010437a8a8 _CF_forwarding_prep_0 + 120 5 On The Go 0x0000000103e97e11 _TFC9On_The_Go22AddTableViewController4savefCSo15UIBarButtonItemT_ + 4897 6 On The Go 0x0000000103e9842a _TToFC9On_The_Go22AddTableViewController4savefCSo15UIBarButtonItemT_ + 58 7 UIKit 0x000000010531da8d -[UIApplication sendAction:to:from:forEvent:] + 92 8 UIKit 0x000000010572b067 -[UIBarButtonItem(UIInternal) _sendAction:withEvent:] + 152 9 UIKit 0x000000010531da8d -[UIApplication sendAction:to:from:forEvent:] + 92 10 UIKit 0x0000000105490e67 -[UIControl sendAction:to:forEvent:] + 67 11 UIKit 0x0000000105491143 -[UIControl _sendActionsForEvents:withEvent:] + 327 12 UIKit 0x00000001054912be -[UIControl _sendActionsForEvents:withEvent:] + 706 13 UIKit 0x0000000105490263 -[UIControl touchesEnded:withEvent:] + 601 14 UIKit 0x000000010539099f -[UIWindow _sendTouchesForEvent:] + 835 15 UIKit 0x00000001053916d4 -[UIWindow sendEvent:] + 865 16 UIKit 0x000000010533cdc6 -[UIApplication sendEvent:] + 263 17 UIKit 0x0000000105316553 _UIApplicationHandleEventQueue + 6660 18 CoreFoundation 0x0000000104351301 CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION + 17 19 CoreFoundation 0x000000010434722c __CFRunLoopDoSources0 + 556 20 CoreFoundation 0x00000001043466e3 __CFRunLoopRun + 867 21 CoreFoundation 0x00000001043460f8 CFRunLoopRunSpecific + 488 22 GraphicsServices 0x0000000109efbad2 GSEventRunModal + 161 23 UIKit 0x000000010531bf09 UIApplicationMain + 171 24 On The Go 0x0000000103e9b672 main + 114 25 libdyld.dylib 0x000000010736492d start + 1 26 ??? 0x0000000000000001 0x0 + 1 ) libc++abi.dylib: terminating with uncaught exception of type NSException (lldb)

My code is:

Main VC:

import UIKit
import CoreData

class MainTableViewController: UITableViewController, NSFetchedResultsControllerDelegate, UISearchResultsUpdating {

var content:[Agenda] = []
var fetchResultController:NSFetchedResultsController!
var searchController:UISearchController!
var searchResults:[Agenda] = []

override func viewDidLoad() {
    super.viewDidLoad()

    let fetchRequest = NSFetchRequest(entityName: "Agenda")
    let sortDescriptor = NSSortDescriptor(key: "subject", ascending: true)
    fetchRequest.sortDescriptors = [sortDescriptor]

    if let managedObjectContext = (UIApplication.sharedApplication().delegate as? AppDelegate)?.managedObjectContext {

        fetchResultController = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: managedObjectContext, sectionNameKeyPath: nil, cacheName: nil)
        fetchResultController.delegate = self

        do {
            try fetchResultController.performFetch()
            content = fetchResultController.fetchedObjects as! [Agenda]
        } catch {
            print(error)
        }
    }

    tableView.estimatedRowHeight = 76.0
    tableView.rowHeight = UITableViewAutomaticDimension

    searchController = UISearchController(searchResultsController: nil)
    tableView.tableHeaderView = searchController.searchBar
    searchController.searchResultsUpdater = self
    searchController.dimsBackgroundDuringPresentation = false

    searchController.searchBar.placeholder = "Search items..."
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}

// MARK: - Table view data source

override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
    return 1
}

override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    if searchController.active {
        return searchResults.count
    } else {
        return content.count
    }
}

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

    let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as! MainTableViewCell

    // Configure the cell...
    let agenda = (searchController.active) ? searchResults[indexPath.row] : content[indexPath.row]

    cell.subjectLabel.text = agenda.subject
    cell.deadlineLabel.text = agenda.deadline
    cell.iconImageView.image = UIImage(data: agenda.image!)

    if agenda.urgent == true {
        cell.urgentImageView.image = UIImage(named: "urgent")
        cell.urgentImageView.image = cell.urgentImageView.image!.imageWithRenderingMode(UIImageRenderingMode.AlwaysTemplate)
        cell.urgentImageView.tintColor = UIColor(red: 212.0/255.0, green: 106.0/255.0, blue: 106.0/255.0, alpha: 1.0)
    } else {
        cell.urgentImageView.image = nil
    }

    cell.subjectLabel.lineBreakMode = NSLineBreakMode.ByWordWrapping
    cell.subjectLabel.numberOfLines = 999
    cell.deadlineLabel.lineBreakMode = NSLineBreakMode.ByWordWrapping
    cell.deadlineLabel.numberOfLines = 999

    cell.subjectLabel.sizeToFit()
    cell.deadlineLabel.sizeToFit()

    cell.subjectLabel.translatesAutoresizingMaskIntoConstraints = false

    return cell
}

override func tableView(tableView: UITableView, editActionsForRowAtIndexPath indexPath: NSIndexPath) -> [UITableViewRowAction]? {

    let shareAction = UITableViewRowAction(style: UITableViewRowActionStyle.Default, title: "Share", handler: { (action, indexPath) -> Void in

        let defaultText = "I've got to " + self.content[indexPath.row].subject
        let activityController = UIActivityViewController(activityItems: [defaultText], applicationActivities: nil)
        self.presentViewController(activityController, animated: true, completion: nil)
    })

    let deleteAction = UITableViewRowAction(style: UITableViewRowActionStyle.Default, title: "Delete", handler: { (action, indexPath) -> Void in

        if let managedObjectContext = (UIApplication.sharedApplication().delegate as? AppDelegate)?.managedObjectContext {

            let itemToDelete = self.fetchResultController.objectAtIndexPath(indexPath) as! Agenda
            managedObjectContext.deleteObject(itemToDelete)

            do {
                try managedObjectContext.save()
            } catch {
                print(error)
            }
        }
    })

    shareAction.backgroundColor = UIColor(red: 28.0/255.0, green: 165.0/255.0, blue: 253.0/255.0, alpha: 1.0)
    deleteAction.backgroundColor = UIColor(red: 202.0/255.0, green: 202.0/255.0, blue: 203.0/255.0, alpha: 1.0)

    return [deleteAction, shareAction]
}

override func tableView(tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool {
    if searchController.active {
        return false
    } else {
        return true
    }
}

func controllerWillChangeContent(controller: NSFetchedResultsController) {
    tableView.beginUpdates()
}

func controller(controller: NSFetchedResultsController, didChangeObject anObject: AnyObject, atIndexPath indexPath: NSIndexPath?, forChangeType type: NSFetchedResultsChangeType, newIndexPath: NSIndexPath?) {

    switch type {
        case .Insert:
            if let _newIndexPath = newIndexPath {
                tableView.insertRowsAtIndexPaths([_newIndexPath], withRowAnimation: .Fade)
            }

        case .Delete:
            if let _indexPath = indexPath {
                tableView.deleteRowsAtIndexPaths([_indexPath], withRowAnimation: .Fade)
            }

        case .Update:
            if let _indexPath = indexPath {
                tableView.reloadRowsAtIndexPaths([_indexPath], withRowAnimation: .Fade)
            }

        default:
            tableView.reloadData()
    }

    content = controller.fetchedObjects as! [Agenda]
}

func controllerDidChangeContent(controller: NSFetchedResultsController) {
    tableView.endUpdates()
}

func filterContentForSearchText(searchText: String) {
    searchResults = content.filter({ (content:Agenda) -> Bool in
    let nameMatch = content.subject.rangeOfString(searchText, options: NSStringCompareOptions.CaseInsensitiveSearch)
    let deadlineMatch = content.deadline.rangeOfString(searchText, options: NSStringCompareOptions.CaseInsensitiveSearch)
    return nameMatch != nil || deadlineMatch != nil
    })
}

func updateSearchResultsForSearchController(searchController: UISearchController) {
    if let searchText = searchController.searchBar.text {
        filterContentForSearchText(searchText)
        tableView.reloadData()
    }
}

@IBAction func unwindToHomeScreen(segue: UIStoryboardSegue) {
}
}

Adding VC:

import UIKit
import CoreData

class AddTableViewController: UITableViewController {

// MARK: - Table view data source

@IBOutlet var photoImageView:UIImageView!
@IBOutlet var subjectTextField:UITextField!
@IBOutlet var deadlineTextField:UITextField!
@IBOutlet var yesButton:UIButton!
@IBOutlet var noButton:UIButton!

var urgent = true
var content:Agenda!
var imageName:String = ""

override func viewDidLoad() {
    super.viewDidLoad()

    tableView.tableFooterView = UIView(frame: CGRectZero)
    title = "Add an item"

    photoImageView.image = UIImage(named: imageName)
    photoImageView.image = photoImageView.image!.imageWithRenderingMode(UIImageRenderingMode.AlwaysTemplate)
    photoImageView.tintColor = UIColor.whiteColor()

    if imageName == "cup" {
        photoImageView.backgroundColor = UIColor(red: 137.0/255.0, green: 72.0/255.0, blue: 0.0/255.0, alpha: 1.0)
    } else if imageName == "transport" {
        photoImageView.backgroundColor = UIColor.blueColor()
    } else if imageName == "beach" {
        photoImageView.backgroundColor = UIColor.yellowColor()
    } else if imageName == "weather" {
        photoImageView.backgroundColor = UIColor(red: 255.0/255.0, green: 122.0/255.0, blue: 255.0/255.0, alpha: 1.0)
    } else if imageName == "gear" {
        photoImageView.backgroundColor = UIColor(red: 106.0/255.0, green: 207.0/255.0, blue: 255.0/255.0, alpha: 1.0)
    } else if imageName == "money" {
        photoImageView.backgroundColor = UIColor(red: 110.0/255.0, green: 110.0/255.0, blue: 110.0/255.0, alpha: 1.0)
    } else if imageName == "technology-1" {
        photoImageView.backgroundColor = UIColor.orangeColor()
    } else if imageName == "web" {
        photoImageView.backgroundColor = UIColor(red: 255.0/255.0, green: 114.0/255.0, blue: 110.0/255.0, alpha: 1.0)
    } else if imageName == "people" {
        photoImageView.backgroundColor = UIColor(red: 104.0/255.0, green: 251.0/255.0, blue: 208.0/255.0, alpha: 1.0)
    } else if imageName == "nature" {
        photoImageView.backgroundColor = UIColor(red: 110.0/255.0, green: 118.0/255.0, blue: 255.0/255.0, alpha: 1.0)
    } else if imageName == "draw" {
        photoImageView.backgroundColor = UIColor.purpleColor()
    } else if imageName == "technology" {
        photoImageView.backgroundColor = UIColor(red: 131.0/255.0, green: 249.0/255.0, blue: 2.0/255.0, alpha: 1.0)
    } else if imageName == "screen" {
        photoImageView.backgroundColor = UIColor(red: 135.0/255.0, green: 134.0/255.0, blue: 135.0/255.0, alpha: 1.0)
    } else if imageName == "shop" {
        photoImageView.backgroundColor = UIColor(red: 210.0/255.0, green: 120.0/255.0, blue: 255.0/255.0, alpha: 1.0)
    } else if imageName == "arrow" {
        photoImageView.backgroundColor = UIColor.blackColor()
    }

    navigationItem.backBarButtonItem = UIBarButtonItem(title: "", style: .Plain, target: nil, action: nil)
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}

@IBAction func save(sender:UIBarButtonItem) {

    let subject = subjectTextField.text
    let deadline = deadlineTextField.text
    let icon = UIImage(named: imageName)

    if subject == "" || deadline == "" || icon == "" {
        let alertController = UIAlertController(title: "Oops!", message: "Not all of the fields have been filled in. Please fill them in before proceeding.", preferredStyle: UIAlertControllerStyle.Alert)
        alertController.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.Default, handler: nil))
        self.presentViewController(alertController, animated: true, completion: nil)

        return
    }

    if let managedObjectContext = (UIApplication.sharedApplication().delegate as? AppDelegate)?.managedObjectContext {

        content = NSEntityDescription.insertNewObjectForEntityForName("Agenda", inManagedObjectContext: managedObjectContext) as! Agenda
        content.subject = subject!
        content.deadline = deadline!
        content.urgent = urgent

        if let iconImage = photoImageView.image {
            content.image = UIImagePNGRepresentation(iconImage)
        }

        do {
            try managedObjectContext.save()
        } catch {
            print(error)
            return
        }
    }

    dismissViewControllerAnimated(true, completion: nil)
}

@IBAction func toggleUrgentButton(sender: UIButton) {

    if sender == yesButton {
        urgent = true
        yesButton.backgroundColor = UIColor(red: 170.0/255.0, green: 240.0/255.0, blue: 255.0/255.0, alpha: 1.0)
        noButton.backgroundColor = UIColor.lightGrayColor()
    } else if sender == noButton {
        urgent = false
        yesButton.backgroundColor = UIColor.lightGrayColor()
        noButton.backgroundColor = UIColor(red: 170.0/255.0, green: 240.0/255.0, blue: 255.0/255.0, alpha: 1.0)
    }
}

@IBAction func unwindToIcon(segue: UIStoryboardSegue) {
}
}

My class (Agenda):

import Foundation
import CoreData

class Agenda:NSManagedObject {

@NSManaged var subject:String
@NSManaged var deadline:String
@NSManaged var urgent:NSNumber?
@NSManaged var image:NSData?
} 

The image gets chosen from another VC, but if you need that code, feel free to ask.

I want to get the image into the main VC's iconImageView.

Annabelle Sykes
  • 263
  • 6
  • 17

1 Answers1

0

OK so just to check. You're using the Binary Data option for image in the Core Data model right?

If so you can store an image if you also click allows external storage and use agenda.image = UIImagePNGRepresentation(image) or JPG instead of PNG for jpegs

How to store an image in core data

Community
  • 1
  • 1
Magoo
  • 2,552
  • 1
  • 23
  • 43