Here's another example on OS X: import Foundation
class Outer { class Inner : NSObject, NSCoding { let uuid: Foundation.NSUUID required init?(coder aDecoder: NSCoder) { uuid = aDecoder.decodeObjectForKey("my.uuid") as! Foundation.NSUUID } override init() { uuid = Foundation.NSUUID() } func encodeWithCoder(aCoder: NSCoder) { aCoder.encodeObject(uuid, forKey: "my.uuid") } } } NSKeyedArchiver.archiveRootObject(Outer.Inner(), toFile: "/Users/jrose/Desktop/test-archive") Which results in this archive: { "$version" => 100000 "$objects" => [ 0 => "$null" 1 => { "my.uuid" => <CFKeyedArchiverUID 0x7f8992c0e9d0 [0x7fff7c5acd80]>{value = 2} "$class" => <CFKeyedArchiverUID 0x7f8992c0ec90 [0x7fff7c5acd80]>{value = 4} } 2 => { "NS.uuidbytes" => <67f0b08b c8274f8c b0c78d90 bd4627dc> "$class" => <CFKeyedArchiverUID 0x7f8992c0eda0 [0x7fff7c5acd80]>{value = 3} } 3 => { "$classname" => "NSUUID" "$classes" => [ 0 => "NSUUID" 1 => "NSObject" ] } 4 => { "$classname" => "_TtCC4main5Outer5Inner" "$classes" => [ 0 => "_TtCC4main5Outer5Inner" 1 => "NSObject" ] } ] "$archiver" => "NSKeyedArchiver" "$top" => { "root" => <CFKeyedArchiverUID 0x7f8992c0f0c0 [0x7fff7c5acd80]>{value = 1} } } NSStringFromClass makes pretty names when they fall into the "simple" category, but that's not an arbitrarily extensible transformation, and NSCoding shouldn't have to know anything about it. Jordan > On Dec 23, 2015, at 14:48, Philippe Hausler <phaus...@apple.com> wrote: > > The archiving format encodes the names of the classes in the archive itself. > Here are a few code examples and a quasi readable output from them: > > let uuid = NSUUID() > let data = NSKeyedArchiver.archivedDataWithRootObject(uuid) > let archive = try! NSPropertyListSerialization.propertyListWithData(data, > options: [], format: nil) > print(archive) > > prints the following: > > { > "$archiver" = NSKeyedArchiver; > "$objects" = ( > "$null", > { > "$class" = "<CFKeyedArchiverUID 0x1030025e0 > [0x7fff7ab33bb0]>{value = 2}"; > "NS.uuidbytes" = <797639fe dad74b14 902afab3 c490448b>; > }, > { > "$classes" = ( > NSUUID, > NSObject > ); > "$classname" = NSUUID; > } > ); > "$top" = { > root = "<CFKeyedArchiverUID 0x103002a80 [0x7fff7ab33bb0]>{value = 1}"; > }; > "$version" = 100000; > } > > Note the $classes and $classname objects; which are what tell the internal > implementation of NSKeyedUnarchiver what to construct; moreover you can > create your own classes.. > > // I don’t really think this is a good naming for an application’s class but > hey it might happen... > class NSUUID : NSObject, NSCoding { > let uuid: Foundation.NSUUID > required init?(coder aDecoder: NSCoder) { > uuid = aDecoder.decodeObjectForKey("my.uuid") as! Foundation.NSUUID > } > override init() { > uuid = Foundation.NSUUID() > } > func encodeWithCoder(aCoder: NSCoder) { > aCoder.encodeObject(uuid, forKey: "my.uuid") > } > } > > let uuid = NSUUID() > let data = NSKeyedArchiver.archivedDataWithRootObject(uuid) > let archive = try! NSPropertyListSerialization.propertyListWithData(data, > options: [], format: nil) > print(archive) > > prints the following: > > { > "$archiver" = NSKeyedArchiver; > "$objects" = ( > "$null", > { > "$class" = "<CFKeyedArchiverUID 0x100709630 > [0x7fff7ab33bb0]>{value = 4}"; > "my.uuid" = "<CFKeyedArchiverUID 0x100708e60 > [0x7fff7ab33bb0]>{value = 2}"; > }, > { > "$class" = "<CFKeyedArchiverUID 0x100709740 > [0x7fff7ab33bb0]>{value = 3}"; > "NS.uuidbytes" = <546e5b5e 15c244a1 aa96eb90 30c3f7f6>; > }, > { > "$classes" = ( > NSUUID, > NSObject > ); > "$classname" = NSUUID; > }, > { > "$classes" = ( > "Archiver.NSUUID", > NSObject > ); > "$classname" = "Archiver.NSUUID"; > } > ); > "$top" = { > root = "<CFKeyedArchiverUID 0x100709b70 [0x7fff7ab33bb0]>{value = 1}"; > }; > "$version" = 100000; > } > > Granted this is a questionable name for a class but it illustrates which > class names are encoded where and how they should be interpreted in the > pre-existing archive format; which we will have to figure out some sensible > way of inflating and deflating to/from disk/network etc. > >> On Dec 23, 2015, at 2:37 PM, Jordan Rose <jordan_r...@apple.com >> <mailto:jordan_r...@apple.com>> wrote: >> >> No, we cannot encode things "non-mangled but with the namespace". For any >> type other than top-level non-generic class types, using a non-mangled name >> is not unique. The only correct answer for arbitrary classes is to use >> mangled names, or something that maps one-to-one with mangled names. >> >> Now, Foundation classes are not arbitrary classes, but then I don't see why >> we'd need to use mangled names for those. We can just use the plain old >> Objective-C names that the OS X classes use today. >> >> Jordan >> >>> On Dec 22, 2015, at 10:16, Philippe Hausler via swift-corelibs-dev >>> <swift-corelibs-dev@swift.org <mailto:swift-corelibs-dev@swift.org>> wrote: >>> >>> To clarify the goals: I think it is reasonable for us to have a goal to be >>> able to encode/decode archives from foreign targets; e.g. linux encodes an >>> archive and mac os x decodes or iOS encodes and linux decodes. This will >>> allow for server architecture to transmit binary archives across the wire. >>> This will mean that we will want to have the encoded class names from the >>> application scope to be encoded as the non mangled name but with the >>> namespace. However this presents a problem; Foundation will have a >>> namespace which will need to be inferred both for encoding and decoding. >>> Thankfully there may be a reasonable way to approach this; >>> >>> public class func classNameForClass(cls: AnyClass) -> String? >>> public class func setClassName(codedName: String?, forClass cls: AnyClass) >>> >>> These methods can be used to allow for translation of classes by >>> registering the appropriate classes for a “shortened” name that drops the >>> Foundation/SwiftFoundation namespace prefix during encoding. >>> >>>> On Dec 22, 2015, at 2:45 AM, Luke Howard via swift-corelibs-dev >>>> <swift-corelibs-dev@swift.org <mailto:swift-corelibs-dev@swift.org>> wrote: >>>> >>>> >>>>> On 22 Dec 2015, at 5:50 AM, Jordan Rose <jordan_r...@apple.com >>>>> <mailto:jordan_r...@apple.com>> wrote: >>>>> >>>>> IMHO on Linux NSKeyedArchiver should always use mangled names. If we want >>>>> cross-platform archives, we should set up standard substitutions, but >>>>> given that Swift classes exposed to Objective-C are archived with their >>>>> full names it doesn't make sense to use "half the name" in the archive. >>>> >>>> You mean namespaced but unmangled yes? If so I agree. >>>> >>>> BTW I found a couple of small CF nits: >>>> >>>> * in CFDictionaryGetKeysAndValues(), keybuf and valuebuf are transposed in >>>> the call to CF_SWIFT_FUNCDISPATCHV(NSDictionary.getObjects()) >>>> >>>> * _CFSwiftDictionaryGetKeysAndValues() does not handle keybuf or valbuf >>>> being NULL (either of which are valid when calling >>>> CFDictionaryGetKeysAndValues()) >>>> >>> >>> This is a bit un-related to NSCoding and the transposition is probably a >>> mistake if it is inverted (the CF method should be reversed from the NS >>> method to mimic the objc counterpart) >>> >>>> — Luke >>>> _______________________________________________ >>>> swift-corelibs-dev mailing list >>>> swift-corelibs-dev@swift.org <mailto:swift-corelibs-dev@swift.org> >>>> https://lists.swift.org/mailman/listinfo/swift-corelibs-dev >>>> <https://lists.swift.org/mailman/listinfo/swift-corelibs-dev> >>> >>> _______________________________________________ >>> swift-corelibs-dev mailing list >>> swift-corelibs-dev@swift.org <mailto:swift-corelibs-dev@swift.org> >>> https://lists.swift.org/mailman/listinfo/swift-corelibs-dev >>> <https://lists.swift.org/mailman/listinfo/swift-corelibs-dev> >
_______________________________________________ swift-corelibs-dev mailing list swift-corelibs-dev@swift.org https://lists.swift.org/mailman/listinfo/swift-corelibs-dev