A parser for FAA Digital Obstacle File (DOF) data.
SwiftDOF parses FAA Digital Obstacle File (DOF) data, which can be downloaded from https://www.faa.gov/air_traffic/flight_info/aeronav/digital_products/dof/.
The data is parsed into Codable structs that can be used in your Swift project.
SwiftDOF follows these design principles:
Domain-restricted data: Restrictive enums are favored over open types like Strings wherever possible, ensuring type safety and catching errors at compile time.
Foundation integration: The library uses
Foundationtypes wherever possible, such asMeasurements instead of raw numeric types for physical values.Strict parsing: The parser throws errors for any malformed or invalid data rather than silently accepting it. This ensures data integrity and makes debugging easier. All parsing errors are reported via either thrown exceptions or the
errorCallbackparameter.
The DOF format is documented at https://www.faa.gov/air_traffic/flight_info/aeronav/digital_products/dof/media/DOF_README_09-03-2019.pdf.
- Swift 6.2+
- macOS 26+, iOS 26+, watchOS 26+, tvOS 26+, or visionOS 26+
Add SwiftDOF to your Package.swift:
dependencies:[.package(url:"https://github.com/RISCfuture/SwiftDOF", from:"1.0.0")]Then add it to your target:
.target(
name:"YourTarget",
dependencies:["SwiftDOF"])import SwiftDOF
// Load from a local file
letdof=tryDOF(data:Data(contentsOf: fileURL))
// Or load asynchronously from a URL
letdof=tryawaitDOF(url: fileURL)// Get total count
print("Total obstacles: \(dof.count)")
// Look up by OAS number
iflet obstacle = dof.obstacle(for:"01-001307"){print("\(obstacle.type) at \(obstacle.city), \(obstacle.state ??"")")print("Height: \(obstacle.heightFtAGL) ft AGL")}
// Filter by state
lettexasObstacles= dof.obstacles(in:"TX")
// Iterate over all obstacles
forobstaclein dof {
// ...
}// Heights as Measurement<UnitLength>
letheightAGL= obstacle.heightAGL // e.g., 500 ft
letheightMeters= heightAGL.converted(to:.meters)
// Coordinates as Measurement<UnitAngle>
letlat= obstacle.latitude
letlon= obstacle.longitude
// Or as CoreLocation coordinate
letcoordinate= obstacle.coreLocationSwiftDOF uses strict parsing and reports all errors. There are two ways to handle parsing errors:
1. Catch thrown errors for fatal issues (invalid format, missing headers):
do{letdof=tryDOF(data: fileData)}catchlet error as DOFError{switch error {case.invalidFormat(let formatError):print("Invalid format: \(formatError)")case.parseError(let field,let value,let line):print("Failed to parse \(field) '\(value)' at line \(line)")case.lineTooShort(let expected,let actual,let line):print("Line \(line) has \(actual) chars, expected \(expected)")case.invalidEncoding:print("File contains invalid encoding")default:print("Error: \(error)")}}2. Use the error callback to handle per-line errors while continuing to parse valid data:
varparseErrors:[(Error,Int)]=[]letdof=tryDOF(data: fileData){ error, lineNumber in
parseErrors.append((error, lineNumber))print("Warning: \(error) at line \(lineNumber)")}print("Parsed \(dof.count) obstacles with \(parseErrors.count) errors")The error callback is invoked for each line that fails to parse, allowing you to collect warnings while still loading the rest of the file. This is useful for handling DOF files that may contain occasional malformed records.
Online API documentation and tutorials are available at https://riscfuture.github.io/SwiftDOF/documentation/swiftdof/.
DocC documentation is available, including tutorials and API documentation. For Xcode documentation, you can run
swift package generate-documentation --target SwiftDOFto generate a docarchive at
.build/plugins/Swift-DocC/outputs/SwiftDOF.doccarchive. You can open this
docarchive file in Xcode for browseable API documentation. Or, within Xcode,
open the SwiftDOF package in Xcode and choose Build Documentation from the
Product menu.
SwiftDOF has comprehensive unit tests, which can be run with swift test.
The SwiftDOF_E2E target is a command-line tool for testing DOF parsing:
# Download and parse current FAA DOF cycle
swift run SwiftDOF_E2E
# Parse a local file
swift run SwiftDOF_E2E -i /path/to/DOF.DAT
# Parse from a URL
swift run SwiftDOF_E2E -i https://aeronav.faa.gov/Obst_Data/DOF_251221.zip
# Output as JSON
swift run SwiftDOF_E2E -f json > obstacles.jsonOptions:
-i, --input <path|url>: Path or URL to DOF file (.dat or .zip). Defaults to current FAA cycle.-f, --format <summary|json>: Output format. Defaults to summary.