user1976727 user1976727 - 7 months ago 21
Swift Question

How do I pass an array of custom objects in Swift

I am trying to make a main menu for an Mac application as a beginning task to learn about Swift. Here is my code, which does not work.

In the AppDelegate

import Foundation
import Cocoa

@NSApplicationMain

class AppDelegate: NSObject, NSApplicationDelegate
{

@IBOutlet weak var window: NSWindow!

//private let mainWindow = NSWindow(frame: NSWindow.mainScreen().bounds)
//let mainWindow = NSWindow()
//let statusItem = NSStatusBar.systemStatusBar().statusItemWithLength(NSSquareStatusItemLength)

func applicationDidFinishLaunching(aNotification: NSNotification)
{
// Insert code here to initialize your application
let menuData = [getMainMenuItems]

//[makeMainMenu, menuData]

}

}


And then in a different project file, named Swift_FileManager

import Foundation
import Cocoa

class menuArrayObject
{
var title: String = ""
var subMenuTitles: [String] = []
}

func getMainMenuItems (menuData:Array<AnyObject>) -> AnyObject
{
//Make a new menu array
var menuData = [AnyObject]()

let arrayObject1 = menuArrayObject()
arrayObject1.title = "Project"
arrayObject1.subMenuTitles = ["New Project","Open Project","Save Project", "Quit Project"]
menuData.append(arrayObject1)

return menuData
}


The code compiles but the function
getMainMenuItems
is never called.

Can somebody shed some light on the (probably very simple) issue here? Thanks in advance

Answer
let menuData = [getMainMenuItems]

This line (probably) isn't doing what you think it's doing. What it's doing is creating an array of [(Array<AnyObject>)->(AnyObject)] type (an array of functions that take an array of AnyObjects as input, and return an AnyObject) – and adding your getMainMenuItems function to it.

It's not calling your function at all.

In order to call a function, you need to use a pair of brackets (), containing the required input. In this case, your getMainMenuItems method expects an array of AnyObjects (although it never appears to actually use them).

For example:

let menuData = getMainMenuItems([/* Insert your objects here */])

Although that being said, I'm not entirely sure that your getMainMenuItems function actually needs an input, as you never use it. I think you're looking for something like this:

func getMainMenuItems() -> [MenuArrayObject] {

    // create an empty array of MenuArrayObjects
    var menuData = [MenuArrayObject]()

    let arrayObject1 = MenuArrayObject()
    arrayObject1.title = "Project"
    arrayObject1.subMenuTitles = ["New Project","Open Project","Save Project", "Quit Project"]
    menuData.append(arrayObject1)

    return menuData
}

Note that the function no longer has an input, and I've replaced AnyObject with [MenuArrayObject]. It's best to be as type specific as you can in Swift, so you should really steer away from AnyObject unless you have good reason to use it.

Now you can just invoke your function like this:

let menuData = getMainMenuItems()

If you're trying to make the function so that it'll add an object to an already existing array, then you can use an inout parameter in your function. This will let you pass an array into your function, which it can modify.

For example:

func getMainMenuItems(inout menuData:[MenuArrayObject]) {

    let arrayObject1 = MenuArrayObject()
    arrayObject1.title = "Project"
    arrayObject1.subMenuTitles = ["New Project","Open Project","Save Project", "Quit Project"]
    menuData.append(arrayObject1)
}

You can then call it like so:

// an existing array of MenuArrayObjects
var menuDataArray = [MenuArrayObject]()

// call function with array – which it will append an element to
getMainMenuItems(&menuDataArray)