Swift Standard Library: transcode

Swift Standard Library: transcode

The {swift}transcode{/swift} function lets to convert strings from one Unicode encoding to another, for example {swift}UTF16{/swift} to {swift}UTF8{/swift}.

The definition you get when you command-click on the function is quite intimidating:

/*
func transcode<         Input : GeneratorType,
                       Output : SinkType,
                InputEncoding : UnicodeCodecType,
               OutputEncoding : UnicodeCodecType
    where 

       InputEncoding.CodeUnit == InputEncoding.CodeUnit,
      OutputEncoding.CodeUnit == OutputEncoding.CodeUnit>

                (inputEncoding: InputEncoding.Type,
                outputEncoding: OutputEncoding.Type, 
                         input: Input, 
                        output: Output, 
                  #stopOnError: Bool) -> (Bool)
*/

It is also incorrect; a type constraint with the same type expression on both sides of the {swift}=={/swift} sign is not much of a constraint.

/*
func transcode<         Input : GeneratorType,
                       Output : SinkType,
                InputEncoding : UnicodeCodecType,
               OutputEncoding : UnicodeCodecType
    where

       InputEncoding.CodeUnit == GeneratorType.Element
      OutputEncoding.CodeUnit == SinkType.Element>

                (inputEncoding: InputEncoding.Type,
                outputEncoding: OutputEncoding.Type,
                         input: Input,
                        output: Output,
                  #stopOnError: Bool) -> (Bool)
*/

In plain English, what these constraints are saying is that we need an input
source (a {swift}GeneratorType{/swift}) that generates elements that are compatible with
our input {swift}UnicodeCodecType{/swift} and an output {swift}SinkType{/swift} that can consume the output of our output encoder.

The following code takes the UTF32 codepoint for the “Grinning Face with Smiling Eyes”
emoji (I’m not kidding that is its official name!) and converts it to UTF8.

import UIKit
/*
GRINNING FACE WITH SMILING EYES
U+1f601
UTF8: 0xF0 0x9F 0x98 0x81
*/
let grin = UnicodeScalar(0x1f601)
String(Character(grin))

let inputArray : [UInt32] = [ grin.value ]
let input = inputArray.generate()
var outputArray : [UInt8] = []
var output = SinkOf<UInt8>({ outputArray.append($0) })

let error = transcode(UTF32.self, UTF8.self,
inputArray.generate(), output, stopOnError: true)

let utf8HexArray = outputArray.map { String(format: "%02x", $0) }
utf8HexArray

The values obtained seem to agree with the values I found on the ‘net, but we can verify using Cocoa to construct a string from the UTF8 values

let utf8String = NSString(bytes: outputArray, length: countElements(outputArray), encoding: NSUTF8StringEncoding)
utf8String

In the playground for this tutorial the above code will print the emoji.

Download the Playground

The source for this and all other playgrounds in this series can be found on Github in the SwiftStandardLibraryPlaygrounds repository.


About idz

A professional software engineer dabbling in iOS app development.
This entry was posted in Swift, Swift Standard Library and tagged , , , , , , . Bookmark the permalink.

One Response to Swift Standard Library: transcode

  1. Pingback: EVERYTHING YOU WANT – Swift resources | swiftioscodetutorial

Leave a Reply