YSMessagePack 是一个用 swift 编写的 messagePack 打包/解包器(swift 3 兼容)。它旨在易于使用。YSMessagePack 包括以下功能
1.6
YSMessagePack/Classes
下的文件添加到您的项目中YSMessagePack', '~> 1.6.0'
” 添加到 podfile 中let exampleInt: Int = 1
let exampleStr: String = "Hello World"
let exampleArray: [Int] = [1, 2, 3, 4, 5, 6]
let bool: Bool = true
// To pack items, just put all of them in a single array
// and call the `pack(items:)` function
//this will be the packed data
let msgPackedBytes: NSData = pack(items: [true, foo, exampleInt, exampleStr, exampleArray])
// Now your payload is ready to send!!!
但如果我们有一些自定义数据结构要发送怎么办?
//To make your struct / class packable
struct MyStruct: Packable { //Confirm to this protocol
var name: String
var index: Int
func packFormat() -> [Packable] { //protocol function
return [name, index] //pack order
}
func msgtype() -> MsgPackTypes {
return .Custom
}
}
let exampleInt: Int = 1
let exampleStr: String = "Hello World"
let exampleArray: [Int] = [1, 2, 3, 4, 5]
let bool: Bool = true
let foo = MyStruct(name: "foo", index: 626)
let msgPackedBytes = pack(items: [bool, foo, exampleInt, exampleStr, exampleArray])
或者您还可以单独打包它们并将它们手动添加到字节数组中(这也更便宜)
let exampleInt: Int = 1
let exampleStr: String = "Hello World"
let exampleArray: [Int] = [1, 2, 3, 4, 5, 6]
//Now pack them individually
let packedInt = exampleInt.packed()
//if you didn't specific encoding, the default encoding will be ASCII
#if swift(>=3)
let packedStr = exampleStr.packed(withEncoding: NSASCIIStringEncoding)
#else
let packedStr = exampleStr.packed(withEncoding: .ascii)
#endif
let packedArray = exampleArray.packed()
//You can use this operator +^ the join the data on rhs to the end of data on lhs
let msgPackedBytes: NSData = packedInt +^ packedStr +^ packedArray
YSMessagePack 提供了多种不同方式和选项进行解包,包括异步解包,请参阅示例项目以获取详细信息。
解包消息打包字节数组相当简单
do {
//The unpack method will return an array of NSData which each element is an unpacked object
let unpackedItems = try msgPackedBytes.itemsUnpacked()
//instead of casting the NSData to the type you want, you can call these `.castTo..` methods to do the job for you
let int: Int = unpackedItems[2].castToInt()
//Same as packing, you can also specify the encoding you want to use, default is ASCII
let str: String = unpackedItem[3].castToString()
let array: NSArray = unpackedItems[4].castToArray()
} catch let error as NSError{
NSLog("Error occurs during unpacking: %@", error)
}
//Remember how to pack your struct? Here is a better way to unpack a stream of bytes formatted in specific format
let testObj1 = MyStruct(name: "TestObject1", index: 1)
let testObj2 = MyStruct(name: "TestObject2", index: 2)
let testObj3 = MyStruct(name: "TestObject3", index: 3)
let packed = packCustomObjects(testObj1, testObj2, testObj3) //This is an other method that can pack your own struct easier
let nobjsInOneGroup = 2
try! packed.unpackByGroupsWith(nobjsInOneGroup) {
(unpackedData, isLast) -> Bool
//you can also involve additional args like number of groups to unpack
guard let name = unpackedData[0].castToString() else {return false} //abort unpacking hen something wrong
let index = unpackedData[1]
let testObj = MyStruct(name: name, index: index) // assembly
return true //proceed unpacking, or return false to abort
}
如果您不想解包消息打包字节数组中包含的每一项,您也可以指定要解包的数量,如果您想保留剩余的字节,可以在 returnRemainingBytes
参数中放置 true
,剩余的字节将存储在 NSData
数组的末尾。
do {
//Unpack only 2 objects, and we are not interested in remaining bytes
let unpackedItems = try msgPackedBytes.itemsUnpacked(specific_amount: 2, returnRemainingBytes: false)
print(unpackedItems.count) //will print 2
} catch let error as NSError{
NSLog("Error occurs during unpacking: %@", error)
}