9

Note: - This question was originally posted while Xcode 15 was in beta. With the final release of Xcode 15, the compiler gives a much clearer error stating:

A default value requires a fully qualified domain named value


The original question:

I've narrowed down this issue to a simple model class with one property with a enum type. If I attempt to give the property a default value, the code won't compile any more:

enum SomeEnum: Hashable, Codable {
    case one
    case two
}

@Model
class SomeClass {
    var value: SomeEnum = .two

    init() {
    }
}

This results in the error:

type 'Any?' has no member 'two'

If you dig into the actual log, you can see a bit more info:

@__swiftmacro_8Sample39SomeClass5ModelfMm_.swift:15:34: error: type 'Any?' has no member 'two'
    ("value", \SomeClass.value, .two, nil)
                                ~^~~
/.../Sample.swift:117:1: note: in expansion of macro 'Model' here
class SomeClass {
^~~~~~~~~~~~~~~~~
/.../Sample.swift:117:1: note: in expansion of macro 'Model' here
class SomeClass {
^~~~~~~~~~~~~~~~~

If you right click on @Model and select "Expand Macro", you see:

@Model
class SomeClass {
    var value: SomeEnum = .two

    init() {
    }

    @Transient
    private var _$backingData: any SwiftData.BackingData<SomeClass> = SwiftData.DefaultBackingData(for: SomeClass.self)
    
    public var backingData: any SwiftData.BackingData<SomeClass> {
        get {
            _$backingData
        }
        set {
            _$backingData = newValue
        }
    }
    
    static func schemaMetadata() -> [(String, AnyKeyPath, Any?, Any?)] {
      return [
        ("value", \SomeClass.value, .two, nil) // <-- Error here
      ]
    }
    
    required init(backingData: any SwiftData.BackingData<SomeClass>) {
      self.backingData = backingData
    }
    
    @Transient
    private let _$observationRegistrar = Observation.ObservationRegistrar()

}

The error appears to be coming from inside the schemaMetadata() function.

What's the fix for this?

0

1 Answer 1

24

Note: This answer applies to both Xcode 15 beta and the release version of Xcode 15. Of course the updated compiler error in the release version of Xcode 15 makes this answer much more obvious than it was during the beta.


Turns out this can be resolved by changing the line:

var value: SomeEnum = .two

to:

var value: SomeEnum = SomeEnum.two

or

var value = SomeEnum.two

Either of those two changes results in the schemaMetadata() line being updated to:

("value", \SomeClass.value, SomeEnum.two, nil)

which makes the compiler happy.

Or you can move the initial value from the property and put it in the init:

var value: SomeEnum

init(value: SomeEnum = .two) {
    self.value = value
}

This seems like a bug in the SwiftData macros that it can't properly expand .two to SomeEnum.two when generating the schemaMetadata() function.

Sign up to request clarification or add additional context in comments.

3 Comments

Interesting, a similar issue was reported here for using .init
@JoakimDanielson Seems related but the error message is quite different. I searched both SwiftData tags with "enum" and the error before posting to avoid a duplicate.
It's no duplicate but just similar behaviour

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.