Welcome to the Treehouse Community

The Treehouse Community is a meeting place for developers, designers, and programmers of all backgrounds and skill levels to get support. Collaborate here on code errors or bugs that you need feedback on, or asking for an extra set of eyes on your latest project. Join thousands of Treehouse students and alumni in the community today. (Note: Only Treehouse students can comment or ask questions, but non-students are welcome to browse our conversations.)

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and a supportive community. Start your free trial today.

iOS Build an Interactive Story App with Swift Personalizing the Story Handling Incorrect Input

Alert box is not displaying

Hi Everyone The error as alert is not displaying. Here is my code. I tried my best to put this code but markdown doesnt recognize some code. Sorry for that. Thanks for your time.

ViewController.swift
import UIKit

class ViewController: UIViewController {

    @IBOutlet weak var nameTextField: UITextField!

    override func viewDidLoad() {
        super.viewDidLoad()

        NotificationCenter.default.addObserver(self, selector: #selector(ViewController.keyboardWillShow(_:)), name: Notification.Name.UIKeyboardWillShow, object: nil)

    }

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

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if segue.identifier == "startAdventure" {

            do {
                if let name = nameTextField.text {
                    if name == "" {
                        throw AdventureError.nameNotProvided
                    } else {
                        guard let pageController = segue.destination as? PageController else { return }

                        pageController.page = Adventure.story(withName: name)
                    }
                }
            } catch AdventureError.nameNotProvided {
                let alertController = UIAlertController(title: "Name Not Provided", message: "Provide a name to start the story", preferredStyle: .alert)

                let action = UIAlertAction(title: "OK", style: .default, handler: nil)
                alertController.addAction(action)

                present(alertController, animated: true, completion: nil)
            } catch let error {
                fatalError("\(error.localizedDescription)")
            }
        }
    }

    func keyboardWillShow(_ notification: Notification){
        print("Keyboard will show")
    }


    deinit{
        NotificationCenter.default.removeObserver(self)
    }
}
Page.swift
import Foundation

enum AdventureError: Error{
    case nameNotProvided
}

class Page{
    let story: Story

    typealias Choice = (title: String, page: Page)

    var firstChoice: Choice?
    var secondChoice: Choice?

    init(story: Story){
        self.story = story
    }
}

extension Page{


    func addChoiceWith(title: String, story: Story) -> Page {
        let page = Page(story: story)
        return addChoiceWith(title: title, page: page)
    }

    func addChoiceWith(title: String, page: Page) -> Page{

        switch (firstChoice, secondChoice) {
        case (.some, .some): return self
        case (.none, .none), (.none, .some): firstChoice = (title, page)
        case (.some, .none): secondChoice = (title, page)
        }

        return page
    }
}

struct Adventure {
    static func story(withName name: String) -> Page {
    let returnTrip = Page(story: .returnTrip(name: name))
        let touchdown = returnTrip.addChoiceWith(title: "Stop and Investigate", story: .touchDown)
        let homeward = returnTrip.addChoiceWith(title: "Continue home to Earth", story: .homeward)
        let rover = touchdown.addChoiceWith(title: "Explore the Rover", story: .rover(name: name))
        let crate = touchdown.addChoiceWith(title: "Open the Crate", story: .crate)

        homeward.addChoiceWith(title: "Head back to Mars", page: touchdown)
        let home = homeward.addChoiceWith(title: "Continue Home to Earth", story: .home)

        let cave = rover.addChoiceWith(title: "Explore the Coordinates", story: .cave)
        rover.addChoiceWith(title: "Return to Earth", page: home)

        cave.addChoiceWith(title: "Continue towards faint light", story: .droid(name: name))
        cave.addChoiceWith(title: "Refill the ship and explore the rover", page: rover)

        crate.addChoiceWith(title: "Explore the Rover", page: rover)
        crate.addChoiceWith(title: "Use the key", story: .monster)

        return returnTrip
    }
}

Keyboard is also not showing after successful build.

1 Answer

Xavier D
PLUS
Xavier D
Courses Plus Student 5,840 Points

Hi dipanchokshi ,

I'm using Swift 4 and one thing I did noticed in your code that was missing was the @objc or the @objecMembers keyword for your keyboardWillShow method. In Swift 4, not using these keyword will not expose the method to Objective-C. The @objc is used to exposed individual methods, while @objecMembers will expose the methods in the entire class.

Here's more info on it:

https://www.hackingwithswift.com/example-code/language/how-to-fix-argument-of-selector-refers-to-instance-method-that-is-not-exposed-to-objective-c

If the necessary methods are not exposed, then you would have a hard time running your code, you won't be able to see the alert message in your console, and of course, the key will not show.

After that, if you continue have issues, then the problem probably lies with iOS device that you are testing on. Try running the app on another iOS device, and tap on the text field to see if the keyboard will show. On my physical iPhone 7, I was able to generate the alert message in my console when I tapped the textfield, and the keyboard did show, covering the textfield.

Again, check the settings on the device that you are testing on because if the keyboard did not show, then it's because of that...

...hope this helps!

XD