Your custom initializer cannot initialize the immutable property. If you want it to be immutable then, instead of creating a custom initializer, just initialize in one of the required or designated initializer.
Like this,
class AddBook: UIViewController {
@IBOutlet weak var bookAuthor: UITextField!
@IBOutlet weak var bookTitle: UITextField!
let bookStore: BookStore
required init(coder aDecoder: NSCoder) {
fatalError("Cannot be instantiated from storyboard")
}
override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?) {
bookStore = BookStore()
super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
}
@IBAction func saveNewBook(sender: AnyObject) {
let author = self.bookAuthor.text!
let title = self.bookTitle.text!
bookStore.addBook(author, title: title)
}
}
Or this,
class AddBook: UIViewController {
@IBOutlet weak var bookAuthor: UITextField!
@IBOutlet weak var bookTitle: UITextField!
let bookStore: BookStore
required init(coder aDecoder: NSCoder) {
bookStore = BookStore()
super.init(coder: aDecoder)
}
override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?) {
fatalError("Cannot be instantiated from code")
}
@IBAction func saveNewBook(sender: AnyObject) {
let author = self.bookAuthor.text!
let title = self.bookTitle.text!
bookStore.addBook(author, title: title)
}
}
But, in your case, you want it to be immutable as you are using let bookStore: BookStore but if you were not using storyboard you could simply throw fatal exception from the required initializer and use your own initializer like this,
class AddBook: UIViewController {
@IBOutlet weak var bookAuthor: UITextField!
@IBOutlet weak var bookTitle: UITextField!
let bookStore: BookStore
init(bookStore: BookStore) {
self.bookStore = bookStore
super.init(nibName: nil, bundle: nil)
}
required init(coder aDecoder: NSCoder) {
fatalError("cannot be initialized from storyboard")
}
@IBAction func saveNewBook(sender: AnyObject) {
let author = self.bookAuthor.text!
let title = self.bookTitle.text!
bookStore.addBook(author, title: title)
}
}
let book = AddBook(bookStore: BookStore())
Now, that you need to have the required initializer, you have to make the property mutable such that you can set it from custom initializer like this,
class AddBook: UIViewController {
@IBOutlet weak var bookAuthor: UITextField!
@IBOutlet weak var bookTitle: UITextField!
var bookStore: BookStore!
init(bookStore: BookStore) {
self.bookStore = bookStore
super.init(nibName: nil, bundle: nil)
}
required init(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
@IBAction func saveNewBook(sender: AnyObject) {
let author = self.bookAuthor.text!
let title = self.bookTitle.text!
bookStore.addBook(author, title: title)
}
}
let book = ... // initialized from storyboard or using performSegueWithIdentifier:
book.bookStore = BookStore()
The main philosophy here is, no two initializer can initialize the immutable properties. Only one can do, so either use required initializer to instantiate it or make required initializer unusable or then make the property mutable such that you can have two initializer and both can initialize it.
self.bookStoreto something before you callsuper.init