In Swift a String
structure is also treated as a class object like when using the NSCoder
encodeObject(_:forKey:)
method. I do know that String
is directly bridged with the objective-c class, NSString
, but is there a way to make a custom struct
that behaves similarly? Perhaps bridge it to a custom class? I want to be able to do something like this:
struct SortedArray <Value: Comparable> {}
// Would I need to create a bridge between
// SortedArray and NSSortedArray? Can I even do that?
class NSSortedArray <Value: Comparable> : NSObject, NSCoding {
required init?(coder aDecoder: NSCoder) {}
func encodeWithCoder(aCoder: NSCoder) {}
}
class MyClass : NSObject, NSCoding {
private var objects: SortedArray<String> = SortedArray<String>()
required init?(coder aDecoder: NSCoder) {
guard let objects = aDecoder.decodeObjectForKey("objects") as? SortedArray<String> else { return nil }
self.objects = objects
}
func encodeWithCoder(aCoder: NSCoder) {
aCoder.encodeObject(objects, forKey: "objects")
}
}
Ultimately, the bridging between
String
andNSString
is quite simple.NSString
only has 2 instance variables (The string pointernxcsptr
, and the lengthnxcslen
).String
uses_StringCore
, which only has 3 properties (_baseAddress
,_countAndFlags
, and_owner
). The conversion back and forth is hard coded, and called explicitly by the compiler. There's no automatic system implemented for generating classes out of structs, or vice versa.You'll have to implement a
struct
/class
pair (like withString
andNSString
), and implement initializers that construct one from the other.I found a working, elegant solution that works with an
_ObjectiveCBridgeable
struct
that can be encoded byNSCoder
; thanks to the reference that Martin R provided. Here is the library code I wrote for anyone interested. I can now do something like this:SortedArray.swift
NSSortedArray.swift
NSCoder.swift
This isn't currently possible. SE-0058 will address it, but is deferred out of Swift 3. A final implementation of SE-0058 would be hoped to handle more than just ObjC bridging; for example allowing C++ or .NET bridging as well in a more generic solution.