user2023106
user2023106

Reputation:

Objective-C to swift objectAtIndex:

To teach myself some swift I'm following some old tutorials. Now I've found the following line of code in a Objective C tutorial:

Recipe *recipe = [recipes objectAtIndex:indexPath.row];

I'm trying to rewrite this to swift for a little while but cant seem to get it work. I tried the following:

var recipe: Recipe = recipes[indexPath.row] as Recipe

Full source of my viewController.swift:

import UIKit

class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {

    @IBOutlet weak var tableView: UITableView!
    var recipes: NSArray = []

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.

        let recipe1: [Recipe] = [Recipe(
            name: "Egg Benedict",
            preptime: "30 min",
            imageFile: "egg_benedict.jpg",
            ingredients: ["2 fresh English muffins", "4 eggs", "4 rashers of back bacon", "2 egg yolks", "1 tbsp of lemon juice", "125 g of butter", "salt and pepper"])]

        let recipe2: [Recipe] = [Recipe(
            name: "Mushroom Risotto",
            preptime: "25 min",
            imageFile: "mushroom_risotto.jpg",
            ingredients: ["1 tbsp dried porcini mushrooms", "2 tbsp olive oil", "1 onion, chopped", "2 garlic cloves", "350g/12oz arborio rice", "1.2 litres/2 pints hot vegetable stock", "salt and pepper", "25g/1oz butter"])]

        recipes = [recipe1, recipe2]

    }

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

    func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return recipes.count
    }

    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cellID = "RecipeCell"
        var cell = tableView.dequeueReusableCellWithIdentifier(cellID, forIndexPath: indexPath) as? UITableViewCell

        if cell == nil {
            cell = UITableViewCell(style: .Subtitle, reuseIdentifier: cellID)
            cell!.accessoryType = .DisclosureIndicator
        }



        let recipe = recipes[indexPath.row] as Recipe


        cell?.textLabel?.text = recipe.name
        cell?.detailTextLabel?.text = recipe.preptime

        return cell!
    }
}

My Recipe class:

import Foundation

class Recipe {

    var name: String
    var preptime: String
    var imageFile: String
    var ingredients: NSArray

    init (name: String, preptime: String, imageFile: String = "", ingredients: NSArray = []) {
        self.name = name
        self.preptime = preptime
        self.imageFile = imageFile
        self.ingredients = ingredients
    }
}

That's at least what i think. Create a variable that's part of my Recipe class. Then I assign the each recipe in my recipes array to the rows of my tableView.

Well so far zero errors in my file and I could continue with the following lines:

cell?.textLabel?.text = recipe.name
cell?.detailTextLabel?.text = recipe.preptime

It also finds the name and preptime within the array so everything is working fine. Still zero errors. Then when I launch my application the following errors come up:

 0x108ba88ad:  movq   %rdi, %rax

Well since I'm not an expert at debugging I'm not able to fix it. i know it's that line that's causing me errors because if I disable it my app will run just fine.

So what am I doing wrong?

Upvotes: 0

Views: 837

Answers (2)

Matthias Bauch
Matthias Bauch

Reputation: 90117

When you think you create recipe1, and recipe2, you actually create an array that contains your first recipe and another array that contains the second recipe. You then add both of these arrays to another array.

If you put something in [ and ] it'll be turned into an array containing the thing between the brackets.

let recipe1: [Recipe] = [Recipe()] // an array with a Recipe
             ^      ^   ^        ^
let recipe2: [Recipe] = [Recipe()] // another array with a Recipe
             ^      ^   ^        ^

recipes = [recipe1, recipe2] // an array with two arrays that each contain a Recipe

Remove the array brackets and you are good:

let recipe1 = Recipe(
    name: "Egg Benedict",
    preptime: "30 min",
    imageFile: "egg_benedict.jpg",
    ingredients: ["2 fresh English muffins", "4 eggs", "4 rashers of back bacon", "2 egg yolks", "1 tbsp of lemon juice", "125 g of butter", "salt and pepper"])

Upvotes: 1

LDNZh
LDNZh

Reputation: 1136

There are two solutions:

1) Change line of code to let recipe = recipes[indexPath.row][0] as Recipe in func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell

2) in your viewDidLoad function change your recipes declaration to

   let recipe1 = Recipe(
        name: "Egg Benedict",
        preptime: "30 min",
        imageFile: "egg_benedict.jpg",
        ingredients: ["2 fresh English muffins", "4 eggs", "4 rashers of back bacon", "2 egg yolks", "1 tbsp of lemon juice", "125 g of butter", "salt and pepper"])

    let recipe2 = Recipe(
        name: "Mushroom Risotto",
        preptime: "25 min",
        imageFile: "mushroom_risotto.jpg",
        ingredients: ["1 tbsp dried porcini mushrooms", "2 tbsp olive oil", "1 onion, chopped", "2 garlic cloves", "350g/12oz arborio rice", "1.2 litres/2 pints hot vegetable stock", "salt and pepper", "25g/1oz butter"])

Upvotes: 0

Related Questions