App Development with Swift – Lesson 4.6 – Edit crashing app

Dear all,

I am again here with an evolution of the previous project I had posted.

Now I get to edit, add, save new Emojis (urrah!) … safe that … once more … following instructions does not work …

I also tried to be creative and think with my head instead of blindly following things but then, the app crashes when I select a row to try to edit it and, moreover, when I create a new emoji and click the save button, I do come back to the previous screen but nothing has been saved.

Building succeeds but, as I have learned on my skin, it doesn’t mean absolutely anything …

If you have the book, the place where I finally got stuck is in chapter 4.6 at the paragraph ‘Save Emoji’ but I am going to post here the code as clearly as I can.


This is the error I get:

2018-04-19 21:44:27.396639+0200 EmojiDictionary[36531:3201882] [MC] Reading from private effective user settings.

Could not cast value of type ‘UINavigationController’ (0x108b55400) to ‘EmojiDictionary.AddEditEmojiTableViewController’ (0x106464af8).

2018-04-19 21:44:41.581369+0200 EmojiDictionary[36531:3201882] Could not cast value of type ‘UINavigationController’ (0x108b55400) to ‘EmojiDictionary.AddEditEmojiTableViewController’ (0x106464af8).

Document outline:












import UIKit
class AddEditEmojiTableViewController: UITableViewController {
    var emoji : Emoji?
    @IBOutlet weak var symbolTextField: UITextField!
    @IBOutlet weak var nameTextField: UITextField!
    @IBOutlet weak var descriptionTextField: UITextField!
    @IBOutlet weak var usageTextField: UITextField!
    @IBOutlet weak var saveButton: UIBarButtonItem!
    override func viewDidLoad() {
        if let emoji = emoji {
            symbolTextField.text = emoji.symbol
            nameTextField.text =
            descriptionTextField.text = emoji.description
            usageTextField.text = emoji.usage

    @IBAction func textEditingChanged(_ sender: UITextField) {
    override func didReceiveMemoryWarning() {
    func updateSaveButtonState() {
        let symbolText = symbolTextField.text ?? ""
        let nameText = nameTextField.text ?? ""
        let descriptionText = descriptionTextField.text ?? ""
        let usageText = usageTextField.text ?? ""
        saveButton.isEnabled = !symbolText.isEmpty && !nameText.isEmpty && !descriptionText.isEmpty && !usageText.isEmpty
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        super.prepare(for: segue, sender: sender)

        guard segue.identifier == "saveUnwind" else { return }

        let symbol = symbolTextField.text ?? ""
        let name = nameTextField.text ?? ""
        let description = descriptionTextField.text ?? ""
        let usage = usageTextField.text ?? ""
        emoji = Emoji(symbol: symbol, name: name, description: description, usage: usage)



import UIKit
class EmojiTableViewController: UITableViewController {
    override func viewDidLoad() {
        navigationController?.navigationBar.prefersLargeTitles = true
    override func didReceiveMemoryWarning() {
    var emojis: [Emoji] = [
        Emoji(symbol: "  ", name: "Grinning Face", description: "A typical smiley face.", usage: "happiness"),
        Emoji(symbol: "  ", name: "Confused Face", description: "A confused, puzzled face", usage: "unsure what to think; displeasure"),
        Emoji(symbol: "  ", name: "Heart Eyes", description: "A smiley face with hearts for eyes.", usage: "love of something; attractive"),
        Emoji(symbol: "  ♂️", name: "Police Officer", description: "A police officer wearing a blue cap with a gold badge.", usage: "person of authority"),
        Emoji(symbol: "  ", name: "Turtle", description: "A cute turtle", usage: "Something slow"),
        Emoji(symbol: "  ", name: "Elephant", description: "A gray elephant", usage: "good memory"),
        Emoji(symbol: "  ", name: "Spaghetti", description: "A plate of spaghetti.", usage: "spaghetti"),
        Emoji(symbol: "  ", name: "Die", description: "A single die.", usage: "taking a risk, chance; game"),
        Emoji(symbol: "⛺️", name: "Tent", description: "A small tent.", usage: "camping"),
        Emoji(symbol: "  ", name: "Stack of Books", description: "Three colored books stacked on each other.", usage: "homework, studying"),
        Emoji(symbol: "  ", name: "Broken Heart", description: "A red, broken heart.", usage: "extreme sadness"),
        Emoji(symbol: "  ", name: "Snore", description: "Three blue 'z's.", usage: "tired, sleepiness"),
        Emoji(symbol: "  ", name: "Checkered Flag", description: "A black-and-white checkered flag.", usage: "completion")
    override func numberOfSections(in tableView: UITableView) -> Int {
        return 1
    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        if section == 0 {
            return emojis.count
        } else {
            return 0
    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "EmojiCell", for: indexPath) as! EmojiTableViewCell
        let emoji = emojis[indexPath.row]
        cell.update(with: emoji)
        cell.showsReorderControl = true
        return cell
override func tableView(_ tableView: UITableView, moveRowAt fromIndexPath: IndexPath, to: IndexPath) {
        let moveEmoji = emojis.remove(at: fromIndexPath.row)
        emojis.insert(moveEmoji, at: to.row)
@IBAction func editButtonTapped(_ sender: UIBarButtonItem) {
        let tableViewEditingMode = tableView.isEditing
        tableView.setEditing(!tableViewEditingMode, animated: true)
override func tableView(_ tableView: UITableView, editingStyleForRowAt indexPath: IndexPath) -> UITableViewCellEditingStyle {
        return .delete

    override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
        if editingStyle == .delete {
            emojis.remove(at: indexPath.row)
            tableView.deleteRows(at: [indexPath], with: .automatic)
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if segue.identifier == "EditEmoji" {
            let indexPath = tableView.indexPathForSelectedRow!
            let emoji = emojis[indexPath.row]
            let addEditEmojiTableViewController = segue.destination as! AddEditEmojiTableViewController
            addEditEmojiTableViewController.emoji = emoji

    @IBAction func unwindToEmojiTableView(segue: UIStoryboardSegue) {
        guard segue.identifier == "saveUnwind" else { return }
        let sourceViewController = segue.source as! AddEditEmojiTableViewController
        if let emoji = sourceViewController.emoji {
            if let selectedIndexPath = tableView.indexPathForSelectedRow {
                emojis[selectedIndexPath.row] = emoji
                tableView.reloadRows(at: [selectedIndexPath], with: .none)
            } else {
                let newIndexPath = IndexPath(row: emojis.count, section: 0)
                tableView.insertRows(at: [newIndexPath], with: .automatic)


Please do notice that the last IBAction (line84) has an empty circle at its left.

There was no instruction to connect it in the book nor any attempt from my part ever succeeded in connecting it to what I thought was logical.

Unfortunately I cannot post images here (why?) to help you see the instructions without having to browse the book.

Please let me know if and where I am wrong here.

Thank you so much!

Powered by WPeMatico


You may also like...

Comments are closed.