I'm new to iOS development and also Swift. I'm working on a project consisting of a menu that leads to my various experimentations with the iOS SDK.I've written the menu titles and segueIdentifiers in a plist and I'm populating an array of NavigationItem in viewDidLoad().Is the following code idiomatic, particularly in the way it handles optional values? What might be better?override func viewDidLoad() {        super.viewDidLoad()        let path = NSBundle.mainBundle().pathForResource(NavigationMenu, ofType: plist)        if path == nil{            NSLog(Unable to locate file : NavigationMenu.plist)            return        }        let items = NSArray(contentsOfFile: path!)        if items == nil {            NSLog(Navigation menu items could not be read from plist.)            return        }        for var i = 0 ; i < items!.count ; i++ {            let item : NSDictionary = items!.objectAtIndex(i) as! NSDictionary            navigationItems.append(NavigationItem(                name:(item.objectForKey(name) as! String),                andSegueIdentifier: (item.objectForKey(segueIdentifier) as! String)                ))        }    }
Idiomatic way of handling optional values in Swift
ios;swift
A better way to handle optional values is optional binding:if let path = NSBundle.mainBundle().pathForResource(NavigationMenu, ofType: plist) {    // do something with `path`} else {    NSLog(Unable to locate file : NavigationMenu.plist)}which tests and unwraps the optional result as a single action.Inside the if-block, path is the unwrapped String.You can do the same with the items:if let path = NSBundle.mainBundle().pathForResource(NavigationMenu, ofType: plist) {    if let items = NSArray(contentsOfFile: path) {        // do something with `items` ...    } else {        NSLog(Navigation menu items could not be read from plist.)    }} else {    NSLog(Unable to locate file : NavigationMenu.plist)}As of Swift 1.2, multiple optional bindings can be combined ina single if-statement, which reduces the number of nested if-levels:if    let path = NSBundle.mainBundle().pathForResource(NavigationMenu, ofType: plist),    let items = NSArray(contentsOfFile: path) {        // do something with `items` ...} else {    NSLog(Unable to load NavigationMenu)}The downside is that you have only a common else-block for theerror condition and cannot distinguish which of the optional bindingsfailed.Instead of objectAtIndex() and objectForKey() you can use subscripting for NSArray and NSDictionary:for var i = 0 ; i < items!.count ; i++ {    let item = items![i] as! NSDictionary    let navItem = NavigationItem(name: item[name] as! String,        andSegueIdentifier: item[segueIdentifier] as! String)    navigationItems.append(navItem)}But a better way is to cast the NSArray to a Swift array of Swift dictionaries in the first step.Then you can use array enumeration and don't need any casts later:if    let path = NSBundle.mainBundle().pathForResource(NavigationMenu, ofType: plist),    let items = NSArray(contentsOfFile: path) as? [[String : String]] {        for item in items {            let navItem = NavigationItem(name: item[name]!, andSegueIdentifier: item[segueIdentifier]!)            navigationItems.append(navItem)        }} else {    NSLog(Unable to load NavigationMenu)}This assumes that values for the name and segueIdentifier arepresent (and will crash at runtime otherwise). Alternatively, useoptional binding again:for item in items {    if let name = item[name], ident = item[segueIdentifier] {        let navItem = NavigationItem(name: name, andSegueIdentifier: ident)        navigationItems.append(navItem)    } else {        NSLog(Invalid navigation item)    }}Finally, you could replace the inner loop by a map() operation:if    let path = NSBundle.mainBundle().pathForResource(NavigationMenu, ofType: plist),    let items = NSArray(contentsOfFile: path) as? [[String : String]] {        navitationItems = map(items) {            NavigationItem(name: $0[name]!, andSegueIdentifier: $0[segueIdentifier]!)        }} else {    NSLog(Unable to load NavigationMenu)}