Brandon
Brandon

Reputation: 2427

Swift NSMutableData append Byte

I'm trying to append one byte to an NSMutable data variable in swift and I'm looking for an easier way. The relevant objective-c code would be:

NSMutableData *data = [[NSMutableData alloc] init];
uint8_t number = 255;
[data appendBytes:&number length:2];

I haven't found that I can do something similar in Swift. What does work is to first create an array of Byte values and then pass that in. For example:

    var data = NSMutableData()
    let value: Byte = 0xFF
    let byte: [Byte] = [value]
    data.appendBytes(byte, length: 1)

    //this works too and is a little simpler
    data.appendBytes([value] as [Byte], length: 1)

Is there a simpler way or am I missing something? The doc specifies that it needs an UnsafePointer and an UnsafePointer can be created with a Word (typealias for Int), so the following works

    var word: Word = 255
    data.appendBytes(UnsafePointer(bitPattern: word), length: 4)

But that's not really what I want - I want a Byte (UInt8). Any suggestions?

Upvotes: 3

Views: 8720

Answers (1)

vacawama
vacawama

Reputation: 154691

According to Using Swift with Cocoa and Objective-C, when a function is declared as taking a UnsafePointer argument, it can accept any of the following:

  • nil, which is passed as a null pointer

  • An UnsafePointer, UnsafeMutablePointer, or AutoreleasingUnsafeMutablePointer value, which is converted to UnsafePointer if necessary

  • An in-out expression whose operand is an lvalue of type Type, which is passed as the address of the lvalue

  • A [Type] value, which is passed as a pointer to the start of the array, and lifetime-extended for the duration of the call

The third bullet means you can do:

var value: Byte = 0xFF    // must be var, let will not work
data.appendBytes(&value, length: 1)

Note: You must use var here and not let because it must be an lvalue.

If you find yourself adding a single byte frequently, you could extend NSMutableData:

extension NSMutableData {
    func appendByte(var b: Byte) {
        self.appendBytes(&b, length: 1)
    }
}

var data = NSMutableData()
data.appendByte(255)

Edit (Swift 3):

extension NSMutableData {
  func appendByte(_ i: Int8) {
    var i = i
    self.append(&i, length: 1)
  }
}

var data = NSMutableData()
data.appendByte(255)

Upvotes: 7

Related Questions