1

I am developing a macOS application. i have a problem with a tableView that load an array of products from a web server. The products are correctly received by the app (i see them in console). But i have these problems: 1) i can't see my products text descriptions in my tableView cells; 2) when i click on a single cell the app crash with this error message:

 fatal error: Index out of range

Here is my code:

import Cocoa
import AppKit


class Controller: NSViewController {

@IBOutlet var tableViewa: NSTableView!
var products = [Product]()   

override func viewDidLoad() {
    super.viewDidLoad()
    title = "Table list"

    tableViewa.reloadData()
   } 

override func viewDidAppear() {
    reload()
    tableViewa.backgroundColor = NSColor.red
    tableViewa.allowsEmptySelection = true
    tableViewa.gridColor = NSColor.red

}
func reload() {
    products = []
    tableViewa.reloadData()
    tableViewa.backgroundColor = NSColor.red
   Products.store.requestProducts{success, products in
        if success {
            self.products = products!

            self.tableViewa.reloadData()

        }else {
            print("download failed")
        }
        self.tableViewa.reloadData()   
    }
}


extension MasterViewController: NSTableViewDataSource, NSTableViewDelegate {

func numberOfRows(in atableView: NSTableView) -> Int {
    print("products number: \(products.count)")
 return products.count
}

func tableViewSelectionDidChange(_ notification: Notification) {
        let tas = IndexPath(item: products.count, section: 0)
        let Cell = tableViewa.makeView(withIdentifier:  NSUserInterfaceItemIdentifier(rawValue: "Cell"),owner: tas ) as! ProductCell

        let product = products[(tas as NSIndexPath).item]//here crash my app
        Cell.product = product
    }

func tableView(_ tableView: NSTableView, shouldSelectRow row: Int) -> Bool {
    return true
}

func tableView(_ tableView: NSTableView, cellForRowAt indexPath: IndexPath)  -> NSTableCellView{
    let Cell = tableViewa.makeView(withIdentifier:  NSUserInterfaceItemIdentifier(rawValue: "Cell"),owner: indexPath ) as! ProCell
    let product = products[(indexPath as NSIndexPath).item]
     Cell.product = product
     Cell.textField?.stringValue = array.item.1

    return Cell


}

}
Swift1
  • 349
  • 1
  • 4
  • 22
  • 1
    `let tas = IndexPath(item: products.count, section: 0)` and `let product = products[(tas as NSIndexPath).item]`. Let's say that products has ONE item. then `products.count` returns `1`. So `let product = products[(tas as NSIndexPath).item]` becomes `let product = products[1]`. But the item is at index `0`, not one, so you'll get an out of range. – Larme Jan 29 '18 at 13:20
  • so how can i avoid this error? – Swift1 Jan 29 '18 at 21:44
  • See there: https://stackoverflow.com/a/29200067/1801544 Your `tas` is `selected`. – Larme Jan 29 '18 at 22:40
  • this no works for me...because if i declare let product = products[(selected as NSIndexPath).row] Xcode gives me this error: Cannot convert value of type 'Int' to type 'NSIndexPath' in coercion – Swift1 Jan 29 '18 at 23:32
  • Nobody knows what ProductCell is. – El Tomato Jan 30 '18 at 00:54
  • 1
    `let product = products[selected]` instead? – Larme Jan 30 '18 at 09:21
  • I tried...if i declare let product = products[selected] Xcode gives me this error: Cannot subscript a value of type '[SKProduct]' with an index of type '[Int]' – Swift1 Jan 30 '18 at 13:01
  • 1
    I'm totally confused. ***NS**TableView* doesn't know sections in `(NS)IndexPath` and there is no method `cellForRowAt` in `NSTableViewDataSource`. Are you really talking about macOS? And – like iOS – **never** use `makeView(withIdentifier` outside of `viewForColumn:row` – vadian Jan 30 '18 at 21:35

1 Answers1

2

How ya doing?

You can use the IndexPath init

init(row: Int, section: Int)

instead

init(item: Int, section: Int)

After that you recover the row that way

let product = products[(tas as NSIndexPath).row]

Explanation:

The item parameter is used to identify an item in a section from collection view and row to table view

jlima
  • 31
  • 3
  • Thank you for the help, but i get this error: Value of type 'NSIndexPath' has no member 'row' – Swift1 Jan 29 '18 at 21:36
  • 1
    Very weird. Take a look on this link https://developer.apple.com/documentation/foundation/nsindexpath – jlima Jan 29 '18 at 21:48
  • i see. Could be i declared in a bad way the init? I made this:extension NSIndexPath { init(row: Int, section: Int) { self.init(row: 1, section: 0) } } – Swift1 Jan 29 '18 at 21:53
  • i tried in different ways but i get ever the same error: "Value of type 'NSIndexPath' has no member 'row'" – Swift1 Jan 29 '18 at 23:47
  • 1
    Are you accessing like this (tas as NSIndexPath).row? Try with IndexPath instead NSIndexPath – jlima Jan 30 '18 at 12:35
  • i tried now...i get the same error "Value of type 'IndexPath' has no member 'row'" – Swift1 Jan 30 '18 at 12:56
  • 1
    Hey I can see whats is wrong on your code. In this line `let tas = IndexPath(item: products.count, section: 0)` you pass the `products.count` but the count always will greater than you products index. Did you get it? – jlima Jan 30 '18 at 16:22
  • and so i should write item: products.count - 1? – Swift1 Jan 30 '18 at 16:39
  • 1
    You can do this it will work! But I don't know what do you want for your logic – jlima Jan 30 '18 at 16:53
  • Fantastic! the problem was just that missing "-1" now my app doesn't crash if i select a row. – Swift1 Jan 30 '18 at 21:22