3

I create a dictionary in Swift:

var type:String
var content:[UInt8]
let dict = NSMutableDictionary()
dict.setValue(type, forKey: "type")
dict.setValue(content, forKey: "content")

I get an error: Cannot convert value of type [UInt8] to expected argument type 'AnyObject?', but if I change the content type as [UInt], it will work fine. Why?

In fact, I want to define a byte array as in Java, so I want to use [UInt8], anyone could help me?

Arnaud
  • 7,259
  • 10
  • 50
  • 71
fcbflying
  • 693
  • 1
  • 7
  • 23
  • @Russell Yes, already tried and got failed. – fcbflying Dec 11 '15 at 06:19
  • 1
    You are creating an NSDictionary, which cannot store arrays of instrinsic types, it can only store NSArrays and NSArrays can only store object types, so you will need to store an array of NSNumbers and box the UInt8 into an NSNumber before storing it in the array or use a native Swift dictionary which can store an array of UInt8 – Paulw11 Dec 11 '15 at 06:21
  • Int/UInt (and Float/Double) are automatically bridged to NSNumber, but the fixed-size integer types like UInt8 are not. – Martin R Dec 11 '15 at 06:22
  • @Paulw I tried this with native swift dictinary, but still failed. var dict = Dictionary() dict["type"] = type dict["content"] = content – fcbflying Dec 11 '15 at 06:26
  • @Martin But I need a UInt8 array, so how to handle this? I am a ios newbie. – fcbflying Dec 11 '15 at 06:28
  • If you need a UInt8 array then you will need to box/unbox the NSNumbers yourself - with `NSNumber(unsignedChar:)` and `content[0].unsignedCharValue` – Paulw11 Dec 11 '15 at 06:31

1 Answers1

4

you can use Swift native types

var dict: Dictionary<String,Array<UInt8>> = [:]
dict["first"]=[1,2,3]
print(dict) // ["first": [1, 2, 3]]

i recommend you to use native Swift type as much as you can ... Please, see Martins's notes to you question, it is very useful!

if the case is you want to store there any value, just define you dictionary as the proper type

var dict: Dictionary<String,Array<Any>> = [:]
dict["first"]=[1,2,3]
class C {
}
dict["second"] = ["alfa", Int(1), UInt(1), C()]
print(dict) // ["first": [1, 2, 3], "second": ["alfa", 1, 1, C]]

to see, that the type of the value is still well known, you can check it

dict["second"]?.forEach({ (element) -> () in
    print(element, element.dynamicType)
})

/*
alfa String
1 Int
1 UInt
C C
*/

if you want to store Any value, you are free to do it ...

var type:String = "test"
var content:[UInt8] = [1,2,3,4]
var dict: Dictionary<String,Any> = [:]
dict["type"] = type
dict["content"] = content
dict.forEach { (element) -> () in // ["content": [1, 2, 3, 4], "type": "test"]
    print("key:", element.0, "value:", element.1, "with type:", element.1.dynamicType)
    /*
    key: content value: [1, 2, 3, 4] with type: Array<UInt8>
    key: type value: test with type: String
    */
}
user3441734
  • 16,722
  • 2
  • 40
  • 59
  • Of course what you did is right, but for your dictionary can only put UInt8 array as value, it can not put other types(String,Int etc.). I need a dictionary that can put string value, int value and UInt8 array value. – fcbflying Dec 11 '15 at 08:23
  • it is up to you, what do you want to store in your dictionary ... see my update – user3441734 Dec 11 '15 at 08:35
  • what I want like this: var type:String = "test" var content:[UInt8] = [1,2,3,4] var dict: Dictionary> = [:] dict["type"] = type dict["content"] = content – fcbflying Dec 11 '15 at 08:43
  • what you did is any type in the Array, I want multiple types of the dictionary value – fcbflying Dec 11 '15 at 08:44
  • so, do you want to store Any value in you dictionary? see my 'final' example :-) – user3441734 Dec 11 '15 at 09:13
  • Yes, that is what I want. But unfortunately this Generic constraint of Dictionary is not suitable for SwiftyJSON: JSON(dict). But I think it is another question ^_^. Thanks a lot. – fcbflying Dec 11 '15 at 09:24