简体   繁体   中英

Serialization of Structs to NSData in Swift

I need to save a Swift struct to NSData . I can't conform to NSCoding since it only works for subclasses of NSObject .

I wrote a little protocol with extensions in Swift 2.0 that seems to work in a Playground. It seems a little too easy.

Is there something here I am missing?

The following code can be run in a playground in Xcode 7 Beta 5.

//: Playground - noun: a place where people can play

 import UIKit


protocol Serializable {
    init?(encodedData: NSData)
    var encodedData: NSData { get }
}

extension Serializable {

    var encodedData: NSData {
        var pointer = self
        return NSData(bytes: &pointer, length: sizeof(Self.self))
    }

    init?(encodedData data: NSData) {
        guard
            data.length == sizeof(Self.self)
            else { return nil }

        self = UnsafePointer(data.bytes).memory
    }
}

struct Test: CustomStringConvertible, Serializable {
    let message: String
    let people: [String]
    let color: UIColor

    var description: String {
        return "\(message) + \(people) + \(color)"
    }
}

let structToEncode = Test(message: "Hi!", people: ["me", "someone else"], color: UIColor(red: 0.5, green: 0.2, blue: 0.1, alpha: 0.4))
let encodedData = structToEncode.encodedData
let decodedStruct = Test(encodedData: encodedData)

I've been looking at a serialization solution for Swift too. Instead of inventing your own protocol, take a look at RawRepresentable. It is more generic than what you are doing here in that it isn't tied to NSData. You could serialize to anything as long as your type specifies it in the RawValue type alias.

Another solution is to serialize your data to JSON. I just created a pod that makes this simpler, and it should work for structs, enums, and classes. To use it, you need to implement the ToJSON and FromJSON protocols. Then to serialize and deserialize data, you can use the Aeson.encode and Aeson.decode functions.

I wrote a framework to serialize structs, classes and enums in Swift, though it serializes to plist files (exclusively for convenience, could be any format).

High level notes:

  • Serialization to an intermediate String: AnyObject representation by providing toDictionary() methods via protocol extensions. Nothing you have to do to support this side of things.
  • Deserialization via generics, each type should have an init that (essentially) provides type information about its properties.

Here's a writeup about the framework , and a link to the github repo .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM