Search code examples
cswiftswift2unsafe-pointerssecure-transport

How do I convert my swift class to an UnsafePointer like the __bridge in objective-c


I'm trying to implement a swift bridge to the SecureTransport C libraries. I 'think' I can pass in anything as the connection as long as I know how to read stuff from it in my sslReadCallback/sslWriteCallback implementations. This is the assumption I'm working with. This seems to be the case when I view the definition of SSLConnectionRef:

/* Opaque reference to an I/O connection (socket, endpoint, etc.) */
public typealias SSLConnectionRef = UnsafePointer<Void>

So I just need to turn my class into UnsafePointer. Unfortunately the compiler doesn't like my attempts. Can any one give me tips?

func startSSLProcess()
{
    self.sslContext = SSLCreateContext(kCFAllocatorDefault, SSLProtocolSide.ClientSide, SSLConnectionType.StreamType)
    if let sslContext = self.sslContext
    {
        SSLSetIOFuncs(sslContext, sslReadCallback, sslWriteCallback)
        SSLSetConnection(sslContext, UnsafePointer(self)) // <-- error
        SSLSetSessionOption(sslContext, SSLSessionOption.BreakOnClientAuth, true)
        SSLHandshake(sslContext)
    }
}

In GCDAsyncSocket, it does this:

status = SSLSetConnection(sslContext, (__bridge SSLConnectionRef)self);

and

SubZeroGCDAsyncSocket *asyncSocket = (__bridge SubZeroGCDAsyncSocket *)connection;

.. to unwrap. Whats the swift equivalent of this?

Thanks very much!


Solution

  • The answer was here:

    How to cast self to UnsafeMutablePointer<Void> type in swift

    So now I do the following:

    func startSSLProcess()
    {
        self.sslContext = SSLCreateContext(kCFAllocatorDefault, SSLProtocolSide.ClientSide, SSLConnectionType.StreamType)
        if let sslContext = self.sslContext
        {
            SSLSetIOFuncs(sslContext, sslReadCallback, sslWriteCallback)
            SSLSetConnection(sslContext, UnsafePointer(Unmanaged.passUnretained(self).toOpaque()))
            SSLSetSessionOption(sslContext, SSLSessionOption.BreakOnClientAuth, true)
            SSLHandshake(sslContext)
        }
    }
    

    And I unwrap like this:

        let transportWrapper:SecureTransportWrapper = Unmanaged<SecureTransportWrapper>.fromOpaque(COpaquePointer(connection)).takeUnretainedValue()
    

    Substitute your own type for SecureTransportWrapper.