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

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


> 这是一款基于Swift3.0的数据流操作库
>
> 项目在[「GitHub」](https://github.com/trmbhs/EMDataStream)中开源,可在`iOS`、`macOS`和`Linux`中通用。
>
> 本库依赖于[「EMFileStream」](https://github.com/trmbhs/EMFileStream),博文:[「基于 stdio 的 Swift 文件流操作库」](http://www.enumsblog.com/post?pid=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.yuusann.com/img/posts/17001-1.png)

# 结语

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


评论:0条


返回列表

返回归档

返回主页