我试图将字节从整数转换为[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)
// }
答案 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()
方法写入的字节数可能少于
提供(例如通过网络连接),因此您应始终检查
返回值。