Zmey Zmey - 4 months ago 34
Swift Question

Converting array of C strings to Swift string array

In Swift 3, C function with signature

const char *f()
is mapped to
UnsafePointer<Int8>! f()
on import. It's result can be converted to a Swift string as:

let swiftString = String(cString: f())


The question is, how a NULL terminated C array of C strings can be mapped to Swift array of strings?

The original C signature:

const char **f()


Imported Swift signature:

UnsafeMutablePointer<UnsafePointer<Int8>?>! f()


Swift array of strings:

let stringArray: [String] = ???

Answer

There is no built-in method as far as I know. You have to iterate over the returned pointer array, converting C strings to Swift Strings, until a nil pointer is found:

if var ptr = f() {
    var strings: [String] = []
    while let s = ptr.pointee {
        strings.append(String(cString: s))
        ptr += 1
    }
    // Now p.pointee == nil.

    print(strings)
}

Remark: If f() is guaranteed to return a non-NULL result then you can annotate it as

const char * _Nullable * _Nonnull f();

which would be imported to Swift as

public func f() -> UnsafeMutablePointer<UnsafePointer<Int8>?>

and you can get rid of the outer optional binding.

Comments