29

I have a receipt validation class that is deprecated since Swift 3 has released. I fixed some issues, but I still have many ...

Here is the GitHub source code I used : https://gist.github.com/baileysh9/4386ea92b047d97c7285#file-parsing_productids-swift and https://gist.github.com/baileysh9/eddcba49d544635b3cf5

  1. First Error :

        var p = UnsafePointer<UInt8>(data.bytes)
    

Compiler throws : Cannot invoke initializer for type UnsafePointer(UInt8) with an argument list of type UnsafeRawPointer

  1. Second error

    while (ptr < end)
    

Binary operators < cannot be applied to two UnsafePointer(UInt8) operands

Thank you very much in advance :)

EDIT

Thanks to LinShiwei answer I found a solution to UnsafePointer declaration. It compiles but not tested yet (because other errors avoid me to test) :

 func getProductIdFromReceipt(_ data:Data) -> String?
{
  let tempData: NSMutableData = NSMutableData(length: 26)!
  data.withUnsafeBytes {
        tempData.replaceBytes(in: NSMakeRange(0, data.count), withBytes: $0)
    }

    var p: UnsafePointer? = tempData.bytes.assumingMemoryBound(to: UInt8.self)
GrayFox
  • 824
  • 2
  • 10
  • 27

3 Answers3

47
  1. In Swift 3, you cannot init an UnsafePointer using an UnsafeRawPointer.

    You can use assumingMemoryBound(to:) to convert an UnsafeRawPointer into an UnsafePointer<T>. Like this:

    var ptr = data.bytes.assumingMemoryBound(to: UInt8.self)
    
  2. Use debugDescription or distance(to:) to compare two pointer.

    while(ptr.debugDescription < endPtr.debugDescription)
    

    or

    while(ptr.distance(to:endPtr) > 0)
    
LinShiwei
  • 1,042
  • 14
  • 17
  • Okay thank you, this helped :) ! I Edit my question to add my new code because it is a bit more complex – GrayFox Oct 07 '16 at 15:03
  • @GrayFox What's the problem? – LinShiwei Oct 09 '16 at 15:19
  • data.bytes.assumingMemoryBound(to: UInt8.self) doesn't work because 'bytes' throws a compiler error : "needs to use UnsafeBytes instead of bytes". I added the entire block into EDIT section ;). Now, this works but I have other new errors in device.identifierForVendor.getBytes(UnsafeMutablePointer(mutableData!.mutableBytes)) which is : "Cannot invoke init of type UnsafeMutablePointer with argument list of type UnsafeMutableRawPointer" .... – GrayFox Oct 10 '16 at 12:17
  • Using `assumingMemoryBound(to:)` again to convert `UnsafeMutableRawPointer` into `UnsafeMutablePointer` :) – LinShiwei Oct 11 '16 at 05:22
0

It is possible to put a regular pointer sign i C & in front of a Int8 array or Uint8 array to make a pointer to supply a C-function input. Like the &aBuffer array below (but the data array must copied locally first, to keep control of the storage of the data storage until finished with the operation, you get an error else). Here in a routine handling dropInteraction data (delivering a byte array):

func interpretInstanceData(filename: String, Buffer: [UInt8]) -> String {
    var aBuffer = Buffer
    let sInstanceData = String(cString: Ios_C_InterpretInstanceData(filename, &aBuffer, Int32(aBuffer.count)))

The question is slightly old. But googling for a solution on the topic of converting a swift byte array to a C-pointer (what else is UnsafePointer< UInt8 >). This question made a hit. But I think this answer is helpful for later editions of Swift (that I use). Would have worked even then. Worked in any kind of use needing a pointer from swift (just make the array of right type first).

Jan Bergström
  • 736
  • 6
  • 15
-1

May have recently changed to just this, without the ".bytes." part:

var p: UnsafePointer = data.assumingMemoryBound(to: UInt8.self)

from the original:

var p = UnsafePointer<UInt8>(data.bytes)
brw59
  • 502
  • 4
  • 19