EMDataStream —— 一款 Swift 3.0 的数据流归档库

发布于: 2017-01-02 18:59
阅读: 1035
评论: 0
喜欢: 5

这是一款基于Swift3.0的数据流操作库

项目在「GitHub」中开源,可在iOSmacOSLinux中通用。

本库依赖于「EMFileStream」,博文:「基于 stdio 的 Swift 文件流操作库」

引言

前几天开源了一个文件流操作库EMFileStream,可以以文件流形式归档和读取对象,自定义的第三方对象,只需实现EMFileStreamReadableEMFileStreamWriteable协议后也可以归档到文件流。今天来归档一个内存流操作库,可以将对象归档到二进制数据中。

为什么要写这个呢,不是有NSCoding协议吗?其实NSCodingSwift中使用有许多限制。例如在使用Swift开发服务端时,iOS客户端Client和Linux服务端Service有同一个类A,用同一个源文件A.swift。但此时在iOS中这个类的签名其实是Client.A,服务端里叫Service.A,如果使用NSCoding,在iOS中归档,传到Linux中其实是无法解档的。虽然内容结构完全一样,但是NSCoding包含了类相关的信息,是不同的类是用不了的,因此我基于EMFileStream,写了一个归档到Data的库。

EMDataStream依赖于EMFileStream,使用时请把这两个都克隆下来,地址在文章开头。

使用

使用方法和EMFileStream几乎一样。

封装中维护了一个Array<UInt8>,用索引号来实现类似流的操作。主要的属性有:

//流索引在的位置
open var position: Int { get }
//现在的数据的长度
open var limit: Int { get }
//流索引指针
open var mptr: UnsafeMutablePointer<UInt8> { get }

方法也和EMFileStream类似,这里有个例子:

import Foundation
import EMDataStream

class Student: EMDataStreamReadable, EMDataStreamWriteable {
    
    var name: String
    var age: Int
    var source: Float
    var memo: String
    
    init(name: String, age: Int, source: Float, memo: String) {
        self.name = name
        self.age = age
        self.source = source
        self.memo = memo
    }
    
    public required init(stream: EMDataStream) throws {
        self.name = try stream.readString(withSize: 20)
        self.age = try stream.readInt()
        self.source = try stream.readFloat()
        self.memo = try stream.readString(withSize: 100)
    }
    
    func emObjectWrite(withStream stream: EMDataStream) throws {
        try stream.write(string: name, writeSize: 20)
        try stream.write(int: age)
        try stream.write(float: source)
        try stream.write(string: memo, writeSize: 100)
    }
}

Student实现了EMDataStreamReadableEMDataStreamWriteable协议后,就可以使用readObject()write(object:)方法进行归档解档了。

do {
    //创建对象
    let student = Student.init(name: "Sark", age: 20, source: 78.9, memo: "Memo..........")
    //对象写入流
    let stream = EMDataStream.init()
    try stream.write(object: student)
    //流转成Data后重新构造输出流
    let streamOut = EMDataStream.init(data: stream.toData())
    //读出对象
    let stundentOut: Student = try streamOut.readObject()
    //这里的类型必须标明,否则无法通过泛型推断类型
    print(stundentOut)
} catch {
    print(error)
}

测试结果: 17001-1

结语

同样也是一个简单的工具库,Have fun! 😆


Thanks for reading.

All the best wishes for you! 💕