Swift 4 Int32至[UInt8]

时间:2018-09-29 15:17:06

标签: swift swift4

我试图将字节从整数转换为[UInt8]以通过有线协议发送它们。虽然我找到了适用于Swift 2/3的答案,但没有一种解决方案适用于Swift 4。

以下代码段用于为小消息大小(仅以网络字节顺序Int32大小为前缀的原始字符串数据)编码消息:

func send(message: String) {
    let messageSize = message.utf8.count
    let encodedMessageSize = Int32(messageSize).bigEndian
    let frameSize = messageSize + 4

    var buffer: [UInt8] = Array()
    buffer.append(0)
    buffer.append(0)
    buffer.append(0)
    buffer.append(UInt8(messageSize))
    buffer.append(contentsOf: message.utf8)
    outputStream.write(buffer, maxLength: frameSize)
}

我也尝试过直接使用原始指针,但也无法使Swift 4沿该途径工作。

总体任务是编码和构成由整数和字符串组成的消息。编码会将所有内容转换为字符串,并在每个字符串的末尾添加一个null。该框架只是在消息前加上网络字节顺序Int32大小。我无法更改协议,但愿意考虑实现此目的的其他方法。

欢呼

[EDIT]使用@MartinR的代码(带有@Hamish的建议)更新了代码。同时也使整体任务有所进展。

func encodeMessagePart(_ message: String) -> [UInt8] {
    var buffer: [UInt8] = Array(message.utf8)
    buffer.append(0)
    return buffer
}

func encodeMessagePart(_ message: Int) -> [UInt8] {
    return encodeMessagePart("\(message)")
}

func frameMessage(_ buffer: [UInt8]) -> [UInt8] {
    let bufferSize = buffer.count
    var encodedBufferSize = Int32(bufferSize).bigEndian
    let encodedBufferSizeData = withUnsafeBytes(of: &encodedBufferSize) { Data($0) }

    var frame: [UInt8] = Array()
    frame.append(contentsOf: encodedBufferSizeData)
    frame.append(contentsOf: buffer)
    return frame
}

func sendMessage(_ buffer: [UInt8]) {
    let frame = frameMessage(buffer)
    outputStream.write(frame, maxLength: frame.count)
}

func sendMessage(_ message: String) {
    let encodedPart = encodeMessagePart(message)
    sendMessage(encodedPart)
}

//    func sendMessage(_ messages: Encodable...) {
//        var buffer: [UInt8] = Array()
//        for message in messages {
//            let b = encodeMessagePart(message)
//            buffer.append(contentsOf: b)
//        }
//        sendMessage(buffer)
//    }

1 个答案:

答案 0 :(得分:2)

您可以使用

从整数创建一个Data
let encodedMessageSize = Int32(messageSize).bigEndian
let data = withUnsafeBytes(of: encodedMessageSize) { Data($0) }

(在4.2之前的Swift版本中,您必须编写

var encodedMessageSize = Int32(messageSize).bigEndian
let data = withUnsafeBytes(of: &encodedMessageSize) { Data($0) }

相反。)

然后可以使用

将数据附加到数组
buffer.append(contentsOf: data)

或者,您可以使用data缓冲区代替数组:

func send(message: String) {
    let messageSize = message.utf8.count
    let encodedMessageSize = Int32(messageSize).bigEndian

    var data = withUnsafeBytes(of: encodedMessageSize) { Data($0) }
    data.append(Data(message.utf8))

    let amountWritten = data.withUnsafeBytes { [count = data.count] in
        outputStream.write($0, maxLength: count)
    }
}

最后请注意,write()方法写入的字节数可能少于 提供(例如通过网络连接),因此您应始终检查 返回值。