2016-08-08 60 views
12

Ich habe eine protobuf v2 in Swift und ich versuche, es an einen anderen Protobuf anhängen. Das ist, was ich versuche:Wie fügt man Protokollpuffer in Swift an?

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 

Es scheint, ich bin wie ich die Daten korrumpieren, weil ich diesen Fehler beim Lesen zurück:

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

Vielleicht ist es meine Lektüre zurück die Werte falsch ist, hier ist das, was ich tue die beigefügten Daten aus dem Speicher zu lesen:

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 
    } 
    } 
} 

Und hier ist meine protobuf Nachricht:

Was ist die korrekte Methode, Daten an einen vorhandenen Protobuf anzuhängen, anstatt die Array-Elemente einzeln analysieren zu müssen, den Protobuf anzuhängen und dann das gesamte Array wieder in Bytes umzuwandeln?

+0

Vielleicht fehlt mir ein Trennzeichen? – TruMan1

Antwort

5

Ihr Leseabschnitt ist in Ordnung. Beim Verketten von Proto-Objekten fehlen Begrenzungszeichen. Berechnen und fügen Sie dem Stream und dann dem Proto-Objekt zuerst ein Trennzeichen hinzu. dann mach es für jedes Proto-Objekt.

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 
+0

Vielen Dank, es hat funktioniert !! Das Hinzufügen der Byte-Größe als Präfix für das Trennzeichen war der Schlüssel. – TruMan1