How to Represent Dictionary as NSValue in Swift 3?

382 views Asked by At

I have the following Dictionary:

let example: [String: (Int, Int)] = ["test": (0, 1)]

I need to store this as an NSData variable, and to do that it must first be converted to an NSValue, which I try to do as follows:

let nsval = NSValue().getValue(example as! UnsafeMutableRawPointer)

Only to be met with the error:

Cannot convert value of type 'Void' (aka '()') to specified type 'NSValue'

I've seen SO answers that suggest using:

let test = UnsafeMutablePointer.load(example)

But that also yields the error:

Type 'UnsafeMutablePointer<_>' has no member 'load'

So then, how is one to convert a dictionary to an NSValue in Swift 3?

2

There are 2 answers

0
Joe Daniels On BEST ANSWER

In theory, if you really want to turn a swift Tuple into a data object, you could do this.

var x:(Int, Int) = (4, 2)

var bytes:Data = withUnsafeBytes(of: &x){ g in
    var d = Data()
    for x in g {
        d.append(x)
    }

    return d
}

heres the reverse:

var y:(Int, Int) = (0,0)
bytes.withUnsafeBytes { (x:UnsafePointer<(Int, Int)>) in
    y = x.pointee
}

print(y) // prints (4, 2)

Beware: this is the path to the dark side.

2
Joe Daniels On

not all swift types are compatible with Foundation classes. So you cannot construct an NSValue containing the type [String: (Int, Int)] you can, however start out with an NSDictionary. Ditch the tuple and choose a type thats compatible with objc. then you can change type of let example: to NSDictionary. use that with the NSValue methods.

That said, if you're trying to turn general objc types into an NSData for general serialization purposes, you're going to get more milage out of the NSKeyedArchiver/NSKeyedUnarchiver methods like .archivedData(withRootObject: Any) -> Data (though they still don't support tuples.)