Type-Safe Columns

Define columns using Swift's type system for compile-time safety and cleaner code.

Benefits

The typed API uses DataTableColumn to define how your model properties map to table columns. This approach provides:

  • Compile-time safety - Catch typos and type mismatches at build time
  • Clean syntax - Use key paths instead of manual array conversion
  • Automatic diffing - Enable smooth animated updates via Identifiable

Basic Key Path Columns

struct Person: Identifiable {
    let id: Int
    let name: String
    let age: Int
    let city: String
}

let columns: [DataTableColumn<Person>] = [
    .init("Name", \.name),
    .init("Age", \.age),
    .init("City", \.city)
]

Custom Value Extraction

For computed or formatted values, provide a closure:

let columns: [DataTableColumn<Person>] = [
    .init("Name", \.name),
    .init("Age") { $0.age },                          // Returns Int directly
    .init("Location") { "\($0.city), \($0.country)" } // Returns String directly
]

Formatting Numbers

let columns: [DataTableColumn<Product>] = [
    .init("Product", \.name),
    .init("Price") { "$\(String(format: "%.2f", $0.price))" },
    .init("Discount") { "\(Int($0.discount * 100))%" },
    .init("Final") {
        let final = $0.price * (1 - $0.discount)
        return "$\(String(format: "%.2f", final))"
    }
]

DataTableValueType

Under the hood, each cell value is a DataTableValueType. The type affects sorting behavior:

public enum DataTableValueType {
    case string(String)
    case int(Int)
    case float(Float)
    case double(Double)
}
  • .string values sort alphabetically
  • Numeric types sort numerically

Explicit Type Control

For computed values where you need specific sorting behavior:

// Computed numeric with numeric sorting: 2 < 9 < 10
.init("Total Score") { .int($0.points + $0.bonus) }

// Formatted string with alphabetical sorting: "10" < "2" < "9"
.init("ID") { String($0.id) }

For simple properties, use keypaths instead - they preserve the correct type automatically.

Best Practices

1. Define Columns Once

class EmployeeListVC: UIViewController {
    let columns: [DataTableColumn<Employee>] = [
        .init("Name", \.name),
        .init("Role", \.role)
    ]

    func updateData(_ employees: [Employee]) {
        dataTable.setData(employees, animatingDifferences: true)
    }
}

2. Format for Readability

// Good - formatted strings
.init("Revenue") { "$\($0.revenue.formatted())" }
.init("Growth") { "\(String(format: "%.1f", $0.growth))%" }

// Avoid - raw numbers
.init("Revenue", \.revenue)  // Shows "1234567.89"