Hello:
I have this piece of code that seems very straightforward but three errors persist and I can't figure out why.
lines 6, 7, 21 raise errors but I thought that the variable was declared on lines 6 and 7!
import Cocoa
class ViewController: NSViewController {
privatevar overviewViewController: OverviewController?
privatevar detailViewController: DetailViewController?
privatevar products = [Product]() //Unresolved Identifier 'Product'
var selectedProduct: Product? //Undeclared iidentifier 'Product'
@IBActionfunc valueChanged(_ sender: NSPopUpButton) {
detailViewController?.selectedProduct = selectedProduct
iflet bookTitle = sender.selectedItem?.title,
let index = products.index(where: {$0.title == bookTitle}) {
selectedProduct = products[index]
}
overviewViewController?.selectedProduct = selectedProduct
}
@IBOutletweakvar productsButton: NSPopUpButton!
overridefunc viewDidLoad() {
super.viewDidLoad()
iflet filePath = Bundle.main.path(forResource: "Products", ofType: "plist") {
products = Product.productsList(filePath) //Unresolved Identifier 'Product'
}
//1
productsButton.removeAllItems()
//2
for product in products {
productsButton.addItem(withTitle: product.title)
}
//3
selectedProduct = products[0]
productsButton.selectItem(at: 0)// Do any additional setup after loading the view.
}
overridevar representedObject: Any? {
didSet {
// Update the view, if already loaded.
}
}
overridefunc prepare(for segue: NSStoryboardSegue, sender: Any?) {
guardlet tabViewController = segue.destinationController
as? NSTabViewController else { return }
for controller in tabViewController.children {
iflet controller = controller as? OverviewController {
overviewViewController = controller
overviewViewController?.selectedProduct = selectedProduct
}
elseiflet controller = controller as? DetailViewController {
detailViewController = controller
detailViewController?.selectedProduct = selectedProduct
}
}
}
}
You have defined Product struct inside a ViewController (in fact inside viewDidLoad) and try to use in another: it is not visible there.
Just get it out of the class, that will work.
import Cocoa
struct Product {
let title: String
let audience: String
let descriptionText: String
let price: NSNumber
var image: NSImage? {
get {
let i = NSImage(named: imageName)
return i
}
}
fileprivate let imageName: String
static func productsList(_ fileName: String) -> [Product] {
var products = [Product]()
if let productList = NSArray(contentsOfFile: fileName) as? [[String: Any]] {
for dict in productList {
if let product = Product(dictionary: dict) {
products.append(product)
}
}
}
return products
}
init?(dictionary: [String: Any]) {
guard let title = dictionary["Name"] as? String,
let audience = dictionary["Audience"] as? String,
let descriptionText = dictionary["Description"] as? String,
let price = dictionary["Price"] as? NSNumber,
let imageName = dictionary["Imagename"] as? String else {
return nil
}
self.title = title
self.audience = audience
self.descriptionText = descriptionText
self.price = price
self.imageName = imageName
}
}
class Products: NSViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do view setup here.
}
}Take care to naming:
dictionary["Imagename"]
Is it Imagename or mageName for the key ?
You could simplify the writing or image computed property:
var image: UIImage? {
return UIImage(named: imageName)
}