7

I have been playing around with Swift. I have had multiple errors with types, especially working with Swift and my old Objective-C classes. The problem with this method is: I am expecting an array made of NSDictionarys in Objective-C.

var curArr:[Dictionary<String, AnyObject>] = self.getItemsForCurrentStack()
var arrToReturn:[(Dictionary<String, AnyObject?>)] = []
for obj in curArr{
    arrToReturn.append(["image": UIImage(named: obj["imageName"] as! String), "color": UIColor(red:obj["colorDic"]!["red"] as! CGFloat, green:obj["colorDic"]!["green"] as! CGFloat, blue:obj["colorDic"]!["blue"] as! CGFloat, alpha:1.0), "percentage": obj["percantage"]])
}
return arrToReturn

This returns Dictionaries (which are NSDictionaries) in Swift. But the last line throws me an error:

Dictionary' is not identical to 'AnyObject'

I've tried using as! [AnyObject]

But that throws another error:

'AnyObject' is not a subtype of 'Dictionary'

I don't get the second error, since this doesn't have to be a subtype, but the other way around. Any ideas on how to solve this? I didn't find an answer for several hours of googleing and researching.

nhgrif
  • 61,578
  • 25
  • 134
  • 173
user2456014
  • 355
  • 1
  • 4
  • 13
  • var arrToReturn:[String:AnyObject] = [] or var arrToReturn:[AnyObject] = [] if you want to return an array of AnyObjects – Leo Dabus Apr 18 '15 at 21:09

3 Answers3

9

Dictionary is a struct in Swift, whereas AnyObject is

/// The protocol to which all classes implicitly conform.

Depending what you're trying to do, you may want to use Any in your code, or cast your dictionary to NSDictionary using as NSDictionary.


Edit after your clarification:

If you split up the append call from the dictionary itself, you see a better error message:

So, the issue is that your dictionary contains some Optional values, but Optional is a struct and not convertible to Obj-C. You can fix by casting to UIImage! and AnyObject! (ImplicitlyUnwrappedOptional), or by using as!.

jtbandes
  • 115,675
  • 35
  • 233
  • 266
  • If I do this by `var arrToReturn:[NSDictionary] = [] for obj in curArr{ arrToReturn.append(["image": UIImage(named: obj["imageName"] as! String), "color": UIColor(red:obj["colorDic"]!["red"] as! CGFloat, green:obj["colorDic"]!["green"] as! CGFloat, blue:obj["colorDic"]!["blue"] as! CGFloat, alpha:1.0), "percentage": obj["percantage"]] as! NSDictionary) }`, I get the error: `Cannot invoke 'append' with an argument list of type '(NSDictionary)'` – user2456014 Apr 18 '15 at 21:26
  • Using Any is not possible because this method is generated by Xcode and cannot be changed because it expects an NSArray in Objective-C code. – user2456014 Apr 18 '15 at 22:12
  • 1
    What version of Xcode are you using? It works for me. – jtbandes Apr 18 '15 at 22:26
  • I'm using Xcode 6.3, so the latest official version. The whole playground I am testing this in: http://fs2.directupload.net/images/150419/gcgqk9t9.png – user2456014 Apr 18 '15 at 22:46
1

Your code works fine in playground, without compile or runtime errors. Here is what I added to populate curArr:

var curArr:[Dictionary<String, AnyObject>] = [
    [
        "imageName" : "photo.jpg",
        "colorDic" : ["red" : 1.0, "green" : 0.0, "blue" : 0.0],
        "percentage" : 0.5
    ]
]

With all this forced unwrapping I think you just have to make sure that what self.getItemsForCurrentStack() returns is indeed what you expect.

Result in playground:

[
 "percentage": {Some 5.0e+-1}, 
 "image": nil, 
 "color": {Some r 1,0 g 0,0 b 0,0 a 1,0}
]

My recommendation would be to refactor into objects - that would make your code so much more readable!

Mundi
  • 79,884
  • 17
  • 117
  • 140
  • The problem is not that code, but the return statement, returning arrToReturn where an Array of NSDictionaries or other objects is expected. – user2456014 Apr 18 '15 at 22:09
0

In Swift 3

code:

var curArr:[Dictionary<String, Any>] = [
[
        "imageName" : "photo.jpg",
        "colorDic" :[
            "red" : 1.0,
            "green" : 0.0,
            "blue" : 0.0
        ],
        "percentage" : 0.5
    ]
]

enter image description here

Claudio Silva
  • 3,743
  • 1
  • 26
  • 27