UPGRADE YOUR SKILLS: Learn advanced Swift and SwiftUI on Hacking with Swift+! >>

keyPath issues

Forums > macOS

In a Document app for MacOS using latests non-beta tools.

This works:

   Table(transactions) {
   TableColumn("Payee") { transaction in
          Text("\(transaction.payee ?? "no payee")")
      }
   }

But this column version does not:

   Table(transactions) {TableColunn("Payee", value: \.payee)

The error is about the .payee keyPath "Key path value type 'String?' cannot be converted to contextual type 'String'"

payee is an optional property of the @Model class TheTransaction. The class has an init and also code to make it codeable (for JSON import).

If the model is in a standard struct there is no problem and both work, although the former is not not sortable.

The goal is to list all the transactions in a Table, sortable by any column. Straighforward when not using SwiftData.

Anyone have an example of presenting SwiftData in a Table and eligible for sorting?

3      

Hi,

You could add a computed property to your Model unwrapping the optional and use that as your keyPath,

var payee: String?

var unwrappedPayee: String {
    payee ?? "no payee"
}
TableColumn("Payee", value: \.unwrappedPayee)

3      

Yes that does compile, but isn't it just the same as making the var non-optional (which also works).

3      

Sorry i misunderstood your question; The only way i've been able to display and sort a Table from SwiftData is using a computed property to sort after the query and displaying the sorted version in the table, here's an example using a Model i took from apple:

struct ContentView: View {
    @Environment(\.modelContext) private var modelContext
    @Query private var people: [Person]

    @State var sortOrder = [KeyPathComparator(\Person.givenName)]
    @State var id = UUID()

    var sortedPeople: [Person] {
        people.sorted(using: sortOrder)
    }

    var body: some View {
        NavigationStack {
            Table(sortedPeople, sortOrder: $sortOrder) {
                TableColumn("Given Name", value: \.givenName)
                TableColumn("Family Name", value: \.familyName)
                TableColumn("E-Mail Address", value: \.emailAddress)
            }
            .id(id)
            .onChange(of: sortOrder) {
                id = UUID()
            }
            .toolbar(content: {
                ToolbarItem {
                    Button("Add Example") {
                        try? modelContext.delete(model: Person.self)

                        let person1 = Person(givenName: "Juan", familyName: "Chavez", emailAddress: "juanchavez@icloud.com")
                        modelContext.insert(person1)

                        let person2 = Person(givenName: "Mei", familyName: "Chen", emailAddress: "meichen@icloud.com")
                        modelContext.insert(person2)

                        let person3 = Person(givenName: "Tom", familyName: "Clark", emailAddress: "tomclark@icloud.com")
                        modelContext.insert(person3)

                        let person4 = Person(givenName: "Gita", familyName: "Kumar", emailAddress: "gitakumar@icloud.com")
                        modelContext.insert(person4)
                    }
                }
            })
        }
    }
}

@Model
class Person: Identifiable {
    let givenName: String
    let familyName: String
    let emailAddress: String
    let id = UUID()

    var fullName: String { givenName + " " + familyName }

    init(givenName: String, familyName: String, emailAddress: String) {
        self.givenName = givenName
        self.familyName = familyName
        self.emailAddress = emailAddress
    }
}

4      

Updated the code inside the sortedPeople to use .sorted(using: ) instead of the mess of a switch.

4      

TAKE YOUR SKILLS TO THE NEXT LEVEL If you like Hacking with Swift, you'll love Hacking with Swift+ – it's my premium service where you can learn advanced Swift and SwiftUI, functional programming, algorithms, and more. Plus it comes with stacks of benefits, including monthly live streams, downloadable projects, a 20% discount on all books, and free gifts!

Find out more

Sponsor Hacking with Swift and reach the world's largest Swift community!

Reply to this topic…

You need to create an account or log in to reply.

All interactions here are governed by our code of conduct.

 
Unknown user

You are not logged in

Log in or create account
 

Link copied to your pasteboard.