0

I'm relatively new to Swift and have yet to master the safety aspects of optionals.

I have a dictionary of type [String: [SCNNode]]. A given molecule will have multiple components as elements in an [SCNNode]. For that molecule I retrieve this array of components and assign each element to a local SCNNode to be displayed, manipulated and animated.

    let components = moleculeDictionary["aceticAcid"]     // the array of components
        // [baseMolecule, hydrogenCharge, oxygenCharge, ionizingH, ionizedBond, bonds]

    atomsNode_1 = components![0]            // baseMolecule
    baseNode.addChildNode(atomsNode_1)

    atomsNode_5 = components![3]            // ionizingH
    atomsNode_1.addChildNode(atomsNode_5)

   // etc.

In an attempt to optionally bind this, the compiler seems happy with this.

    if let node = components?[0]  {          // baseMolecule
        baseNode.addChildNode(node)
    }

I'm unclear on the ?. My reading on this suggests we're unwrapping in such a way that we don't care if there's a nil. But does that make this optional binding any better that the forced unwrapping above? Or is this "optional chaining"? Should I be looking instead to just do a check when I assign components? Should I even be concerened about safety here? The only "upsteam" test I've done is for the presence of the dictionary archive before assigning it to moleculeDictionary.

I will have hundreds of these assignments so I'd like to get this right. Suggestions on the best way to handle this are welcome!

Thanks, Byrne

bpedit
  • 1,176
  • 8
  • 22
  • Force unwrapping will crash your app. Optionally unwrapping just means the code won't run. – Abizern Feb 26 '16 at 17:27
  • Meaning that the ? is "optional unwrapping" as used here? – bpedit Feb 26 '16 at 17:54
  • Yes it is. Basically if the value can be unwrapped bind it to a variable and perform the code in the braces. – Abizern Feb 26 '16 at 17:56
  • A variable instead of a constant? So you think the approach of my last code snippet is sound? Thanks! Edit: Oops, missed your response below... – bpedit Feb 26 '16 at 18:29

1 Answers1

1

In my opinion, you should be worried about safety in Swift. Given your code above I would rewrite it in the first pass as:

guard let components = moleculeDictionary["aceticAcid"] where components.count > 3 else { // handle the case where there is no value for this key, or not enough nodes }

// Now I know that I have the correct number of components I don't need to  force unwrap:

atomsNode_1 = components[0]            // baseMolecule
baseNode.addChildNode(atomsNode_1)

atomsNode_5 = components[3]            // ionizingH
atomsNode_1.addChildNode(atomsNode_5)

That's the first first pass. The second pass would be to make sure that I have values for all the components would be to write a struct to contain the SCNNode values so that I either had a value or a nil for each node, you could then build up your node structure accordingly.

Edited to add

Here's an indication of the second pass - which really needs more domain knowledge than I have, but it's a start.

It seems you build up the molecules from [[SCNNode]] (an array of arrays of SCNNodes where the position of each subarray is significant. It's worth putting this into it's own structure such that:

struct Molecule {
    let baseMolecule: [SCNNode]?
    let hydrogenCharge: [SCNNode]?
    let oxygenCharge: [SCNNode]?
    let ionizingH: [SCNNode]?
    let ionizedBond: [SCNNode]?
    let bonds: [SCNNode]?

    // Other methods can be written to build up atom nodes from within the struct which handle the cases where the component array is nil
}
Abizern
  • 146,289
  • 39
  • 203
  • 257
  • Thanks much! I understand the first pass and will use it. I like the added aspect of confirming the count. I'm lost on implementing the "second pass". (I've never had recourse to use struct's.) – bpedit Feb 26 '16 at 18:47
  • The "first pass" suggestion works well. I suspect that gets me to a 90% safety level which I'll settle for until I can parse the "second pass" specifics. I now know the dictionary member loaded and that it had the proper number of components. Thanks again. – bpedit Feb 26 '16 at 20:01
  • Thanks for the edit. My dictionary values are each just one array, I've corrected my post. I guess this means omiting the brackets within the structure but maintaining the order of the node tree members. – bpedit Feb 28 '16 at 14:44