How to Use Unsafemutablepointer<Opaquepointer> in Swift

How to use UnsafeMutablePointer OpaquePointer in Swift?

PMPrinter and PMPaper are defined in the PrintCore framework
as pointer to an "incomplete type"

typedef struct OpaquePMPrinter*         PMPrinter;
typedef struct OpaquePMPaper* PMPaper;

Those are imported into Swift as OpaquePointer, and are a bit
cumbersome to use.

The second argument to PMSessionGetCurrentPrinter() is a pointer to
a non-optional PMPrinter variable, and in Swift it must be
initialized before being passed as an inout argument. One possible way
to initialize a null-pointer is to use unsafeBitCast.

The easiest way to get the PMPaper objects from the array seems to
be to use CFArrayGetValueAtIndex() instead of bridging it to a
Swift array. That returns a UnsafeRawPointer which can be converted
to an OpaquePointer.

This worked in my test:

let printInfo = NSPrintInfo.shared()
let printSession = PMPrintSession(printInfo.pmPrintSession())

var currentPrinter = unsafeBitCast(0, to: PMPrinter.self)
PMSessionGetCurrentPrinter(printSession, ¤tPrinter);

var paperListUnmanaged: Unmanaged<CFArray>?
PMPrinterGetPaperList(currentPrinter, &paperListUnmanaged)
guard let paperList = paperListUnmanaged?.takeUnretainedValue() else {
fatalError()
}
for idx in 0..<CFArrayGetCount(paperList) {
let paper = PMPaper(CFArrayGetValueAtIndex(paperList, idx))!
var width = 0.0, height = 0.0
PMPaperGetWidth(paper, &width)
PMPaperGetHeight(paper, &height)
print(width, height)
}

How to use UnsafeMutablePointer in Swift 3?

I recommend you to work with Data rather than NSData in Swift 3.

var keyData = Data(count: 64)
let result = keyData.withUnsafeMutableBytes {mutableBytes in
SecRandomCopyBytes(kSecRandomDefault, keyData.count, mutableBytes)
}

withUnsafeMutableBytes(_:) is declared as a generic method, so, in simple cases such as this, you can use it without specifying element type.

How to Initialize OpaquePointer in Swift

What the compile error is telling you is that the initialiser that takes a bit pattern returns an optional OpaquePointer.

So you either should use it as an optional:

@State var OP: OpaquePointer? = OpaquePointer(bitPattern: 1)

Or if you're a 100% certain the opaque pointer is never nil, you can force unwrap it:

@State var OP: OpaquePointer = OpaquePointer(bitPattern: 1)!

However, if the OpaquePointer fails to initialise, your app will crash.

Please note that a bitPattern of 1 will most certainly fail, since this should point to an address in memory.

A better way to get an OpaquePointer is to derive it from an UnsafePointer or UnsafeMutablePointer, so you're sure the pointer is actually pointing to the thing you want it to.

What are you trying to point to? And do you really need an OpaquePointer? If so, I'd highly advise to not mess with pointers inside your SwiftUI view, do this stuff in a (or multiple) layers 'above' that (so either ViewModel or Model/Data).

Struggling with Opaque Pointers in SQLITE swift

Change var db = OpaquePointer? to var db : OpaquePointer?

Add return nil to the end of the function.

How to to assign the address of a local swift variable to an UnsafeMutablePointer

You're looking for withUnsafeMutablePointer(_: _:). It takes an inout parameter of type T and a block that takes a parameter of type UnsafeMutablePointer<T>. It is used as such:

var i: Int = 0
withUnsafeMutablePointer(&i) { (pointer) in
f(pointer)
}


Related Topics



Leave a reply



Submit