8
   let orch = NSUserDefaults().dictionaryForKey("orch_array")?[orchId] as? [String:String]
   orch[appleId]

Errors on the orch[appleId] line with:

Cannot subscript a value of type '[String : String]?' with an index of type 'String'

WHY?

Question #2:

   let orch = NSUserDefaults().dictionaryForKey("orch_array")?[orchId] as! [String:[String:String]]
   orch[appleId] = ["type":"fuji"] 

Errors with: "Cannot assign the result of this expression"

hunterp
  • 15,716
  • 18
  • 63
  • 115
  • 1
    possible duplicate of [Cannot subscript a value of type '\[NSObject : AnyObject\]?' with an index of type 'String'](http://stackoverflow.com/questions/29994541/cannot-subscript-a-value-of-type-nsobject-anyobject-with-an-index-of-type) – Sergey Kuryanov May 03 '15 at 23:14

1 Answers1

22

The error is because you're trying to use the subscript on an optional value. You're casting to [String: String] but you're using the conditional form of the casting operator (as?). From the documentation:

This form of the operator will always return an optional value, and the value will be nil if the downcast was not possible. This enables you to check for a successful downcast.

Therefore orch is of type [String: String]?. To solve this you need to:

1. use as! if you know for certain the type returned is [String: String]:

// You should check to see if a value exists for `orch_array` first.
if let dict: AnyObject = NSUserDefaults().dictionaryForKey("orch_array")?[orchId] {
    // Then force downcast.
    let orch = dict as! [String: String]
    orch[appleId] // No error
}

2. Use optional binding to check if orch is nil:

if let orch = NSUserDefaults().dictionaryForKey("orch_array")?[orchId] as? [String: String] {
    orch[appleId] // No error
}

Hope that helps.

ABakerSmith
  • 22,759
  • 9
  • 68
  • 78
  • @abakersmith Thank you, and now, if I get slightly more complex, why can't I [orchId] as! [String: [String:String] and then it won't let me orch["id"] = ["type":"fuji"] – hunterp May 03 '15 at 23:15
  • Could you post that as an edit to your question? It's a bit hard to following without proper formatting. – ABakerSmith May 03 '15 at 23:17
  • That error is because you've declared `orch` as a constant (with `let`). If you use `var` instead you'll be able to edit its contents. – ABakerSmith May 03 '15 at 23:20
  • Is there any benefit to doing it the first way? Seems like the second way does exactly the same thing except shorter and safer. – John Montgomery Apr 14 '17 at 16:02