WWDC2019 Session 204 - use core data for data source with Identifiable protocol
Asked Answered
M

3

7

At WWDC19 session 204 it was shown how to build a UI using Swift 5.1 and the List function. I would like to use Core Data instead of having a data file. The problem is that the core data entity does not conform to the Identifiable protocol.

I've searched extensively on the net and watched several core data videos but they are all out of date. None of them cover Swift 5.1 and the New beta functions (like List).

I create an entity with some fields (name, id -> which is a UUID). I then manually generate the source files shown below:

AccountsMO+CoreDataClass.swift:

import Foundation
import CoreData


public class AccountsMO: NSManagedObject
{

}

And AccountsMO+CoreDataProperties.swift:

import Foundation
import CoreData


extension AccountsMO
{

    @nonobjc public class func fetchRequest() -> NSFetchRequest<AccountsMO>
    {
        return NSFetchRequest<AccountsMO>(entityName: "Accounts")
    }

    @NSManaged public var balance: NSDecimalNumber?
    @NSManaged public var id: UUID
    @NSManaged public var name: String
    @NSManaged public var type: Int16

}

These work but I can't use them in List because they do not conform to the Identifiable protocol. I'm assuming there is some way to add this but I can't find it, either in the core data entity or here.

I load my data in the ContentView file and attempt to use it in the list. Depending on what I try I get either 'unable to infer complex closure return type; add explicit type to disambiguate', OR I get the 'does not conform to Identifiable protocol'.

Manpower answered 20/6, 2019 at 16:7 Comment(0)
G
4

From SwiftUI Tutorials

Lists work with identifiable data. You can make your data identifiable in one of two ways: by calling the identified(by:) method with a key path to a property that uniquely identifies each element, or by making your data type conform to the Identifiable protocol.

Since the AccountsMO type already has the id property required by Identifiable protocol just declare conformance to the Identifiable protocol.

import SwiftUI

extension AccountsMO: Identifiable {

}
Gelya answered 30/6, 2019 at 19:12 Comment(2)
OK I have done that to my class. BUT with this code below:Manpower
var body: some View { NavigationView { List(accounts as [AccountsMO]) {account in accounts Text("name") Text("id") Text("type") Text("balance") }.navigationBarTitle(Text("Accounts")) } I am getting the 'Type of expression is ambiguous without more context' error. I have tried using account.id but it says there is no such value (which there is).Manpower
N
2

The Core Data code generator declares objects as Identifiable (at least as of Xcode 14), as Core Data objects have their own ObjectIdentifier.

AccountsMO+CoreDataProperties.swift:

extension AccountsMO : Identifiable {

}

If you are manually writing Core Data files then you can do the same.

Nepali answered 30/12, 2022 at 18:57 Comment(0)
D
1

Pass Self as id parameter in your SwiftUI List

var entries : [AccountsMO]
List(entries, id : \.self) {_ in

}
Dysgraphia answered 11/1, 2020 at 6:30 Comment(2)
objectID isn't enough. A newly created object has its ID changed when the context is saved. Use \.selfPervious
@Pervious Totally agree.Dysgraphia

© 2022 - 2024 — McMap. All rights reserved.