swift - 如何在 Swift 中附加 Protocol Buffer ?

标签 swift swift2 protocol-buffers nsdata bytebuffer

我有一个 protobuf v2 in Swift我正在尝试将它附加到另一个 protobuf。这就是我正在尝试的:

let attachment = getAttachment(id: 987) //From cloud database
var protosData = NSMutableData(data: attachment)

items.forEach { //Some struct array of values
  guard let proto = try? MyProtoBuf.Builder()
      .setEpochMillis($0.date.epochMilliseconds)
      .setValue($0.value)
      .build() else { return }

  protosData.appendData(proto.data())
}

saveAttachment(protosData) //Store to cloud

我好像在破坏数据,因为我在回读时遇到了这个错误:

malloc: *** mach_vm_map(size=2749415424) failed (error code=3)
*** error: can't allocate region
*** set a breakpoint in malloc_error_break to debug

也许是我读回的值不正确,这是我从存储中读取附加数据的操作:

extension GeneratedMessageProtocol {

  static func getStreamData(data: NSData) -> [Self] {
    var messages = [Self]()
    do {
        let inStream = NSInputStream(data:data)
        inStream.open()
        defer { inStream.close() }
        while inStream.hasBytesAvailable {
            var sizeBuffer: [UInt8] = [0,0,0,0]
            inStream.read(&sizeBuffer, maxLength: sizeBuffer.count)
            let data = NSData(bytes: sizeBuffer, length: sizeBuffer.count)
            let messageSize = data.uint32.littleEndian
            var buffer = Array<UInt8>(count: Int(messageSize), repeatedValue: 0)
            inStream.read(&buffer, maxLength: Int(messageSize))
            let messageData = NSData(bytes: buffer, length:Int(messageSize))
            messages.append(try self.parseFromData(messageData))
        }
    }
    catch {

    }
    return messages
  }
}

extension NSData {

  var uint32: UInt32 {
    get {
        var number: UInt32 = 0
        self.getBytes(&number, length: sizeof(UInt32))
        return number
    }
  }
}

这是我的 protobuf 消息:

syntax = "proto2";

message MyProtoBuf {
    optional uint64 epochMillis = 1;
    optional uint32 value = 2;
}

将数据附加到现有 protobuf 而不是逐一解析数组项、附加 protobuf,然后将整个数组转换回字节的正确方法是什么?

最佳答案

你的阅读部分没问题。链接原型(prototype)对象时缺少分隔符。首先计算并向流添加分隔符,然后向原型(prototype)对象添加分隔符。然后为每个原型(prototype)对象执行此操作。

let attachment = getAttachment(id: 987)         //From cloud database
var arr: [UInt32] = [UInt32(attachment.length)] //Assuming attachment is NSData type
let delimiter = NSData(bytes: arr, length: arr.count * sizeof(UInt32))

let protosData = NSMutableData(data: delimiter)
protosData.appendData(attachment)

items.forEach {                                 //Some struct array of values
  guard let proto = try? MyProtoBuf.Builder()
      .setEpochMillis($0.date.epochMilliseconds)
      .setValue($0.value)
      .build() else { return }

  var array: [UInt32] = [UInt32(proto.data().length)]
  let delimit = NSData(bytes: array, length: arr.count * sizeof(UInt32))

  protosData.appendData(delimit)
  protosData.appendData(proto.data())
}

saveAttachment(protosData)                      //Store to cloud

关于swift - 如何在 Swift 中附加 Protocol Buffer ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38838799/

相关文章:

java - 自定义 protobuf CodeGenerator 的问题

swift !类型运算符

swift - 如何使用 Swift 将图像值传递给 ImageSlideshow

swift2 - swift : Instance member cannot be used on type

c++ - Google Protocol Buffers,在提供的流对象中向后重新定位 IO 头

c++ - 您能否将相同的 protobuf 消息静态链接到多个 DLL - 然后让这些 DLL 协同工作?

ios - Swift 从网络获取数据

swift - 关于调用时和方法内使用方法参数名称的 Doc 声明

ios - SKPhysicsJointFixed 没有将两个节点绑定(bind)在一起

ios - 在 Swift 中更改 UITabBar selectedItem