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

发布于:2017-01-02 18:59,阅读数:1726,点赞数:5


> 这是一款基于Swift3.0的数据流操作库 > > 项目在[「GitHub」](https://github.com/trmbhs/EMDataStream)中开源,可在`iOS`、`macOS`和`Linux`中通用。 > > 本库依赖于[「EMFileStream」](https://github.com/trmbhs/EMFileStream),博文:[「基于 stdio 的 Swift 文件流操作库」](https://blog.yuusann.com/posts/article/16011) # 引言 前几天开源了一个文件流操作库`EMFileStream`,可以以文件流形式归档和读取对象,自定义的第三方对象,只需实现`EMFileStreamReadable`和`EMFileStreamWriteable`协议后也可以归档到文件流。今天来归档一个内存流操作库,可以将对象归档到二进制数据中。 为什么要写这个呢,不是有`NSCoding`协议吗?其实`NSCoding`在`Swift`中使用有许多限制。例如在使用`Swift`开发服务端时,`iOS`客户端Client和`Linux`服务端Service有同一个类A,用同一个源文件`A.swift`。但此时在`iOS`中这个类的签名其实是`Client.A`,服务端里叫`Service.A`,如果使用`NSCoding`,在`iOS`中归档,传到`Linux`中其实是无法解档的。虽然内容结构完全一样,但是`NSCoding`包含了类相关的信息,是不同的类是用不了的,因此我基于`EMFileStream`,写了一个归档到`Data`的库。 `EMDataStream`依赖于`EMFileStream`,使用时请把这两个都克隆下来,地址在文章开头。 # 使用 使用方法和`EMFileStream`几乎一样。 封装中维护了一个`Array<UInt8>`,用索引号来实现类似流的操作。主要的属性有: ```swift //流索引在的位置 open var position: Int { get } //现在的数据的长度 open var limit: Int { get } //流索引指针 open var mptr: UnsafeMutablePointer<UInt8> { get } ``` 方法也和`EMFileStream`类似,这里有个例子: ```swift 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`实现了`EMDataStreamReadable`和`EMDataStreamWriteable`协议后,就可以使用`readObject()`和`write(object:)`方法进行归档解档了。 ```swift 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](//cdn.blog.yuusann.com/img/posts/17001-1.jpg) # 结语 同样也是一个简单的工具库,Have fun! 😆


评论:0条


返回列表

返回主页