Swift is Apple’s newest programming language, which is also now open source and can be compiled to run on many different platforms.

  • ARKit + 3D printing: STL files in AR


    Ever since ARKit was released, I’ve had the idea to build an app that would let people preview models for 3D printing in an AR Scene. It would allow the user to place their objects in the AR environment, and then be able to manipulate and rotate them in a realistic manner. For this post, I’ll be using the interlocking card holders I designed for Settlers of Catan as a demo. (They lock together to form a Monopoly-style bank for all of the resource and development cards.)

    There’s a number of things on my to-do list for the app:

    1. iCloud Drive integration & File type associations for loading files via the share sheet.
    2. User-configurable scaling & orientation, since some STL files may use different units/coordinate systems.
    3. Fallback for non-ARKit devices to a simple Metal-based view mode with one model centered onscreen. This should give us the ability to support iPhone 5s, iPad Air iPad mini 2, and newer, even if ARKit is not available. [1]
    4. Plane detection: display a light transparent grid on planes (user-configurable), and mainly for debugging.
    5. Plane projection: When a user taps the screen, that tap’s vector should be extended to intersect with a detected plane, if one exists. The object would be placed relative to that projected coordinate to simulate real-world interaction.
    6. Shaders: Realistic shading for the printer’s filament layers based on the normal vectors for each polygon. Normal vectors for a polygon that is parallel to the vertical axis should be shaded with lines on the x = z plane, to simulate an individual layer. All other triangles should be shaded based on the y-value and the configured layer height (about 0.3mm).
    7. Model downscaling: Simplify complicated models if individual polygons are so small they will not be noticed, to improve performance.

    Getting Started

    To start, I created an ARKit & Metal/Swift starter project using XCode. In an earlier proof-of-concept, I was utilizing SceneKit based on one of Apple’s demos, but it didn’t grant me the control over the models and display I was looking for in any obvious way. STLs files contain just vertex information, and no color or textures, so they’d appear white inside of SceneKit. I have some experience using OpenGL so I decided to take this opportunity to explore Apple’s Metal for the task since it’d give me the most control over the scene and rendering pipeline. Most of the colorization and lighting can then be done inside of the shaders independent of the model logic in swift.

    Luckily, iOS’ Model I/O library supports all sorts of formats and allowed me to easily load the raw STL file into a Mesh that can be drawn in the metal pipeline. I ran into a few issues:

    • Model coordinate systems are different.
      • As it turns out, ARKit’s coordinate system is defined in meters, and the STL file output by Autodesk’s Inventor appears to have its units set to centimeters. Applying a scale transform to the transformation matrix for the model’s anchor fixed this.
    • Model rotation is inconsistent.
      • For the example model, it needed to be rotated 90° across the X-axis
      • This is mainly due to the axes of the original CAD model being incorrectly aligned with their real-world counterparts. From what I remember, this is a problem with many STL models that exist depending on what software created them.
      • As a result, this will need to be a user-configurable setting per-model.
    • Apple’s demo has the Z-axis inverted, causing our models to be flipped vs. their real-world counterparts!
      • However, disabling this transform causes lighting to be calculated incorrectly with the default shaders and uniform settings.
      • Since we’ll be re-doing the Metal shaders later, it shouldn’t be too much of an issue.
      • From the starter template:
    // Flip Z axis to convert geometry from right handed to left handed
    // We will need to remove this.
    var coordinateSpaceTransform = matrix_identity_float4x4
    coordinateSpaceTransform.columns.2.z = -1.0

    Current Progress

    read more

  • Swift Errors

    Here, I explore Swift’s error handling system and how it relates to NSError, and propose a simple extension to the Error protocol that allows for improved debugging.

    As a refresher, the Objective-C style NSError class contains an error code and domain. In Swift, we don’t have this. Error is instead an (empty) protocol. The error “domain” is simply the whatever type conforms to the error protocol. But what about the error codes? In some situations, it may be necessary to have a generic error handler and report meaningful debug information to the developer. While error codes still exist, but are a little more difficult to analyze at first glance.

    Let’s say you’re following Apple’s documentation and you build a custom error enum that looks something like this:

    enum HTTPError : Error {
        case badRequest
        case unauthorized
        case forbidden
        case notFound
        case internalServerError 

    Not terrible, but if we want to get a human-readable description of the error when it’s thrown, you’d get something like this:

    The key HTTPError.notFound.localizedDescription returns the string:

    “The operation couldn’t be completed. (HTTPError error 3.)”

    That’s not too helpful. “error 3” doesn’t obviously relate to the original error enum at first glance. As it turns out, the error code is equal to the error’s zero-based index in the enum, which seems to be swift’s default (internal) enum behavior. So the above enum actually represents is this:

    enum HTTPError : Int, Error {
        case badRequest = 0
        case unauthorized = 1
        case forbidden = 2
        case notFound = 3 
        case internalServerError = 4

    While this isn’t too hard to figure out, it’s not very explicit. If we have a large enum with a ton of cases it’s not efficient to waste developer time in order to trace the error back to the correct one. Additionally, if we add a new case in the middle of the list somewhere, all of the error codes following it will be altered. There is a solution to this problem: If we make our enum a RawRepresentable Int enum, we can then customize our error codes to our liking. This makes it much more explicit and easier for debugging, and ensures they are preserved in between versions.

    enum HTTPError : Int, Error {
        case badRequest = 400
        case unauthorized = 401
        case forbidden = 403
        case notFound = 404
        case internalServerError = 500

    HTTPError.notFound.localizedDescription now returns the following value:

    “The operation couldn’t be completed. (HTTPError error 404.)”

    This is a bit better, now we can easily trace an error back to the enum that it’s declared in from the string description. If we decide to add a new response code, it won’t affect the error codes for the rest of them.

    Can we improve this more? As it turns out, we can fetch the error code for any Error instance by casting to NSError. Additionally, if we use swift’s String(describing:) initializer, we can get a string representing the enum key that represents the error. We can then create an extension that produces error codes in the format “ErrorType.errorCase (code ##)”.

    // (Swift 4) Extension to Error that allows for better debugging info than localizedDescription.
    // https://www.richinfante.com/2018/01/25/demystifying-swift-errors
    extension Error {
        var debugDescription: String {
            return "\(String(describing: type(of: self))).\(String(describing: self)) (code \((self as NSError).code))"

    Using our custom extension, we can now get more information about the error. The key HTTPError.notFound.debugDescription returns the string:

    “HTTPError.notFound (code 404)”

    This is much clearer for debugging and more explicit about what error was thrown. This helps a lot if we’re sending error information to a crash reporter and we can add extra information about what happened.

    Non-integer enums

    As it turns out, the default swift behavior for error codes returns if you use a non-integer enum.

    enum AnotherError : String, Error {
        case bad = "Something Bad Happened"
        case terrible = "Something Terrible Happened"
        case critical = "Error level is critical"

    Running AnotherError.critical.localizedDescription returns:

    “The operation couldn’t be completed. (AnotherError error 2.)”

    Side note which may be useful: Although we shouldn’t rely on hash values being the same between different executions of the same program, it appears that a swift enum’s hashValue is set to the index of the item in the enum, regardless of its actual Raw type. So in our AnotherError example above, the AnotherError.critical.hashValue is equal to: (AnotherError.critical as NSError).code

    Other Types

    In Swift 4, Error is defined as an empty protocol. The only requirement for try/catch ing a value is that the thrown value conforms to the Error protocol. So, what If we make other classes conform to Error?

    class CustomError : Error {}
    CustomError().localizedDescription // = "The operation couldn’t be completed. (CustomError error 1.)"

    It appears that the error code is always “1” for custom class implementations.

    We could also make a type such as String conform to the Error protocol, and then throw it. It’s probably not a good idea for production use, but it’s an interesting use of the try/catch mechanism. If we do this, the error behavior is similar to a custom class.

    extension String : Error {}
    func playMovie() throws -> Never {
        throw "Han shot first"
    do {
        try playMovie()
    } catch let error as String {
        // Prints "Han shot first"
        print((error as Error).debugDescription)
        // Prints "String.Han shot first (code 1)"

    read more

  • Using Swift DispatchGroups

    Swift’s DispatchGroups are useful for doing stuff after a group of asynchronous operations. In my Day Planner app, I’ve got to load items from the iOS calendars (where some of the APIs return asynchronously). Using a DispatchGroup allows me to efficiently wait for all the data to reload and then update the user interface to reflect the changes.

    let dispatchGroup = DispatchGroup()
    for item in self.items {
      // Signal that we're entering a new execution block
      item.loadAsync {
        // Signal that we've finished.
    dispatchGroup.notify(queue: .main, execute: {
      // Do something with the data, once all of the loadAsync calls have finished.

    read more