Converter nsmutabledata append to swift

const uint16_t b = 1;
[data appendBytes: &b length: sizeof(b)];

Swift:
let b: UInt16 = 1
var data = Data()
And Noe what?

You can do it like this:

let twoBytes: UInt16 = 1
var data = Data()
withUnsafeBytes(of: twoBytes) { buffer in
  data.append(buffer.bindMemory(to: UInt8.self))
}

Also, you can make a helper method for convenience:

extension Data {
  mutating func append<T>(value: T) {
    Swift.withUnsafeBytes(of: value) { buffer in
      self.append(buffer.bindMemory(to: UInt8.self))
    }
  }
}
var data = Data()
data.append(value: twoBytes)
1 Like

Thanks a lot!

But one more problem, which I cannot find an answer to:

Objective-C:
const char *userP = getlogin();
const size_t userL = strlen(userP) + 1;
[data appendBytes: userP length: userL];

Swift:
let userPopt = getlogin()
guard let userP = userPopt else
{
print("Error no userName")
return
}

let userL = strlen(userP) + 1

and now?

Gerriet

var data = Data()
let stringData = "🦉".data(using: .utf8) ?? Data()
data.append(stringData)
data.append(0)

glessard Guillaume Lessard
March 2
var data = Data()
let stringData = ":owl:".data(using: .utf8) ?? Data()
data.append(stringData)
data.append(0)

This works nicely. Although I had hoped for something more succinct than:

guard let userP = getlogin() else	//	UnsafeMutablePointer<Int8>
{
	let mess = strerror(errno) 
	print("Error no userName errno \(errno) = \(String(describing: mess)))")
	return
}

guard let userS = String(cString: userP, encoding: String.Encoding.utf8) else
{
	print("Error non-Utf8 userName")
	return
}

guard let stringData = userS.data(using: .utf8) else
{
	print("Error cannot make \(userS) into data")
	return
}

data.append(stringData)
data.append(0)

Seems like working with C-stuff is kind of messy.

Guess I will try NSProcessInfo instead.

Anyway, thanks for your help!

Seems like working with C-stuff is kind of messy.

There’s no doubt that working with C APIs is kinda messy, but there are tricks to learn that make it easier. Part of the problem with the most recent code you posted is that it’s round tripping through String, which means a bunch of UTF-8 conversions, which means a bunch of extra checks beyond those done by your C code. You can avoid this in the same way you do in the C code, by treating the C string as a sequence of bytes. For example:

guard let l = getlogin() else {
    … handle the error …
}
data.append(UnsafeBufferPointer(start: l, count: strlen(l) + 1))

Guess I will try NSProcessInfo instead.

Quite.

Share and Enjoy

Quinn “The Eskimo!” @ DTS @ Apple

1 Like