Swift: Make PropertyListDecoder available on Linux

I was happily moving along with a server side swift project in Vapor working with binary property list (bplist) files when my CI job running on Linux suddenly reported:

/app/Sources/App/Models/Foo.swift:77:23: error: use of unresolved identifier 'PropertyListDecoder'
        let decoder = PropertyListDecoder()
                      ^~~~~~~~~~~~~~~~~~~
error: terminated(1): /usr/bin/swift-build-tool -f /app/.build/release.yaml main output:

That’s one of the dangers working on a Mac and deploying on Linux (and one of the beauties of having a CI pipeline). The issue is that PropertyListDecoder does not (yet) exist on Linux.

However, using the info from that issue SR-8259 this is quite simple to fix in the interim:

  • Take the file from swift/PlistEncoder.swift at master · apple/swift · GitHub
  • Insert the following at the top:
    import Foundation
    extension DecodingError {
      internal static func _typeMismatch(at path: [CodingKey], expectation: Any.Type, reality: Any) -> DecodingError {
          let description = "Expected to decode \(expectation) but found \(type(of: reality)) instead."
          return .typeMismatch(expectation, Context(codingPath: path, debugDescription: description))
      }
    }
    let kCFBooleanTrue = NSNumber(booleanLiteral: true)
    let kCFBooleanFalse = NSNumber(booleanLiteral: false)

These additions fix a couple of undeclared symbols that the main file expects.

Simply add the file with the preamble as given to your project and it will compile and run on Linux.