10

Before I installed Xcode 8 and converted project to Swift 3, the following line was fine. Now after conversion it looks like this:

let valueData:Data = Data(bytes: UnsafePointer<UInt8>(&intVal), count: sizeof(NSInteger))

it shows the error

Ambiguous use of 'init'

what is wrong with it in Swift 3? How to fix it?

theDC
  • 5,884
  • 8
  • 49
  • 93

2 Answers2

8

UnsafePointer has initializer for both UnsafePointer and UnsafeMutablePointer, and sizeof was moved to MemoryLayout disambiguate it as:

let valueData = withUnsafePointer(to: &intVal){
    return Data(bytes: $0, count: MemoryLayout<NSInteger>.size)
}
Jans
  • 10,551
  • 3
  • 34
  • 43
  • This answer worked for me (and not the accepted answer). – i4niac Dec 27 '16 at 10:30
  • @i4niac: I have double-checked that both answers work with the current Xcode 8.2.1 (and produce the same result). Please let me know if there is a problem with my answer. How does it not work? Do you get an error or a wrong result? – Martin R Dec 28 '16 at 22:43
  • In my case I have an array of UInt8 and need a pointer to &buffer[offset]. This answer works, but using UnsafeBufferPointer as per the accepted answer does not – Dale Jan 14 '17 at 02:27
6

The easiest way to create Data from a simple value is to go via UnsafeBufferPointer, then you don't need any explicit pointer conversion or size calculation:

var intVal = 1000
let data = Data(buffer: UnsafeBufferPointer(start: &intVal, count: 1))
print(data as NSData) // <e8030000 00000000>

For a more generic approach for conversion from values to Data and back, see for example round trip Swift number types to/from Data.

Community
  • 1
  • 1
Martin R
  • 488,667
  • 78
  • 1,132
  • 1,248
  • Problem for me trying to get a pointer to an element in array &buffer[offset]. This answer fails with "cannot subscript a value of inout[UInt8]". Alternative answer using withUnsafePointer works fine – Dale Jan 14 '17 at 02:30