0

I am trying to use a custom property inside a SwiftData model:

import SwiftData
struct Foo {
 var name: String
}
@Model
final class Bar {
 var id: String
 var name: String
 var foo: Foo
 
 init(id: String, name: String) {
 self.id = id
 self.name = name
 self.foo = Foo(name: name)
 }
}

This is just a simplified example, in my real project Foo has many more variables and functions.

I get the following three "No exact matches in call to instance method setValue or getValue" errors:

{
 @storageRestrictions(accesses: _$backingData, initializes: _foo)
 init(initialValue) {
 _$backingData.setValue(forKey: \.foo, to: initialValue)
 _foo = _SwiftDataNoType()
 }
 get {
 _$observationRegistrar.access(self, keyPath: \.foo)
 return self.getValue(forKey: \.foo)
 }
 set {
 _$observationRegistrar.withMutation(of: self, keyPath: \.foo) {
 self.setValue(forKey: \.foo, to: newValue)
 }
 }
}

How can I solve this?

EDIT

Here is my updated code using a computed property, and this compiles:

@Model
final class Bar {
 var id: String
 var name: String
 var foo: Foo {
 return Foo(name: name)
 }
 
 init(id: String, name: String) {
 self.id = id
 self.name = name
 }
}

However, if I try to change the name of foo:

func changeFoo(newName: String) {
 foo.name = newName
}

I get another error:

Cannot assign to property: 'foo' is a get-only property

President Jam
1,3141 gold badge6 silver badges22 bronze badges
asked Oct 23, 2025 at 13:41
4
  • 1
    Why do you expect that SwiftData supports storing instances of some random Foo type? Please read the documentation. How about making Foo conform to Codable? It really depends on what properties Foo has and what their types are. Commented Oct 23, 2025 at 13:58
  • Ok, clear. Unfortunately, Foo is from an external package, and does not conform to Codable. And it has many other properties from the package. I tried making it a computed property, which compiles, but then I cannot make changes to it, even though it is a var. Commented Oct 23, 2025 at 14:15
  • 1
    Well okay you need to declare a setter for the computed property too, e.g. set { self.name = newValue.name }. But why not just conform it to Codable? "From an external package" isn't really an excuse, unless you are anticipating that package will add its own Codable conformance and therefore conflict with yours? Commented Oct 23, 2025 at 14:30
  • 1
    Actually, aren't you creating two sources of truth for "name" here if you used a stored property? What actually is the relationship between self.name and foo.name? If there is only one source of truth (self.name), then you can just use @Transient on the other property to have SwiftData ignore it. Commented Oct 23, 2025 at 14:32

1 Answer 1

0

EDIT:

Although the answer below works, in the end I was able to make Foo from the external package conform to Codable.


Thanks to @Sweeper for pointing me to @Transient.

The following code works for both my example, and real project:

import SwiftData
struct Foo {
 var name: String
}
@Model
final class Bar {
 var id: String
 var name: String
 
 @Transient
 var foo: Foo = .init(name: "")
 
 init(id: String, name: String) {
 self.id = id
 self.name = name
 }
 
 func changeFoo(newName: String) {
 foo.name = newName
 }
}
answered Oct 23, 2025 at 14:44
Sign up to request clarification or add additional context in comments.

1 Comment

Or you could make foo a computed property with a get and set

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

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.