Swift is born to be a strict and safe language. If you write your code in a Swift way, all types of references or variables will be exactly what they actually are. You are not able to do conversion between types not explicitly convertible. This helps us to avoid lots of bugs. However, in exchange, Swift loses some flexibility at the same time. The shortage will become quite obvious when considering its interoperability with C.

We all want to throw C, but it is not an easy thing in a short time. Some older C APIs and frameworks are still being used everyday. Developers, especially developers relying on lower level frameworks, have to work with C APIs. One not encouraged thing in Swift comes out - pointer. For handling these C APIs, Swift defines a set of rules for accessing and converting these pointers. The most important type is UnsafePointer and its variations. Take an example, it is quite regular for a C API receiving an address as an argument. In Swift, it should be a UnsafePointer<Type>. Say we have this function in C:

void method(const int *num) {

Its Swift version would be:

func method(num: UnsafePointer<CInt>) {

We will take a brief look on UnsafePointer in this tip. For primitive types in C, they are renamed in the same rule in Swift: Adding C before the type name and capitalize the first letter. int, bool and char is converted to CInt, CBool and CChar. In the method above, it requires a pointer to int in C. After converted to Swift, it should be an UnsafePointer to CInt. Note that the original argument contains a const modifier, which indicates it is immutable. So in Swift we are using UnsafePointer, which is also the immutable version. If it is a normal mutable pointer, the corresponding type would be UnsafeMutablePointer.

const Type * UnsafePointer
Type * UnsafeMutablePointer

We use * to get the pointed value of a pointer, while in Swift, it is mapped to a memory property.

Calling these methods is more or less comparable in either C or Swift. We can prefix a & sign to pass a pointer address in:

// C
int a = 123;
method(&a);   // Output 123

// Swift
var a: CInt = 123
method(&a)    // Output 123

If you follow this principle, you are like to be able to handle half of the C API calling in Swift with UnsafePointer.

Another half would be the way to convert between pointer data and actual value. Let's say we need to use CFArray directly to achieve an element of an array, we may use this method in CoreFoundation:

func CFArrayGetValueAtIndex(theArray: CFArray!, idx: CFIndex)
                                                -> UnsafePointer<Void>

Since CFArray could contain any type of object, here we get a pointer to Void, which is equal to void * in C. That cannot be the thing we want in Swift. Swift hates any type but needs a concrete type. A brutal conversion is needed here. By using unsafeBitCast, we can cast a pointer to a value in Swift. The code below shows how to convert it to a CFString object.

let arr = NSArray(object: "meow")
let str = unsafeBitCast(CFArrayGetValueAtIndex(arr, 0), CFString.self)
// str = "meow"

unsafeBitCast will convert the first parameter as the type of the second parameter, without taking care of being or not. That is the reason UnsafePointer is not safe at all. There is no check on the pointer type. We get a chance to manipulate the pointer and memory directly.

Apple gives this pointer type a frightful prefix Unsafe. It is a warning for all developers. When we develop an app, we should prefer to use higher level APIs, which is always safe and efficient. Unless you really know what happens, keep away from Unsafe would be a wise choice.