Cannot use instance member within property initializer

I've been trying to use the example from this session to tweak the default SwiftData template, allowing for syncing of the data across devices. When I added the following code, I get the above error:

@main
struct ItemApp: App {
    let items = ModelConfiguration(schema: Schema([Item.self]), url: URL(filePath: "/path/to/item.store"),  cloudKitContainerIdentifier: "iCloud.com.app.Item")
    let container = try ModelContainer(for: items). // ERROR HERE

    
    var body: some Scene {
        WindowGroup {
            ContentView()
        }
        .modelContainer(container)
    }
}

Cannot use instance member 'items' within property initializer; property initializers run before 'self' is available

Any pointers would be helpful.

  • I noticed the same! The code the session uses at 6:58 isn’t working. The .modelContainer(for: [Trip.self, BucketListItem.self, LivingAccommodation.self]) code you’ve mentioned in the other comment is only for simple cases, and not really something to achieve the customization like yours …

Add a Comment

Replies

You could replace the let contained by a computed var, something like this

var container : ModelContainer {  // I suppose it is this type
  let cont = try ModelContainer(for: items)
  return cont 
}

You could call

    let items = ModelConfiguration(schema: Schema([Item.self]), url: URL(filePath: "/path/to/item.store"),  cloudKitContainerIdentifier: "iCloud.com.app.Item")

in the computed var if you don't need items elsewhere.

Or create an explicit init.

Or set in .onAppear

  • Interesting, Downloaded the project from the session and it does not match what was in the presentation,

    @main struct TripsApp: App { var body: some Scene { WindowGroup { ContentView() } .modelContainer(for: [Trip.self, BucketListItem.self, LivingAccommodation.self]) } }

    Is thow they do it, guess I need to go thru the project in more detail. btw, the var example above also fails with the message "No exact matches in call to initializer"

  • Sometimes, between the time they prepare the demo and the time the API is published, some changes may occur…

  • Yeah, also I found an online tutorial (already ;) ) that shows the issue for my syncing was that the Items was not optional. Changing it to optional, allowed me to remove all the above code and just use the default template as is. So since what I am trying to do is pretty simple, I will stick with

    WindowGroup { ContentView() } .modelContainer(for: Item.self) }

    As that seems to work.

Add a Comment

To make it explicit, this works:

@main
struct SwiftDataFlashCardSample: App {
   let container: ModelContainer
   
   init() {
      let schema = Schema([Card.self])
      let config = ModelConfiguration(schema: schema, cloudKitContainerIdentifier: "iCloud.org.your.name")
      var contain: ModelContainer? = nil
      do {
         contain = try ModelContainer(for: schema, config)
      } catch {
         print("couldn't create ModelContainer()")
      }
      self.container = contain!
   }
   var body: some Scene {
      WindowGroup {
         ContentView()
      }
      .modelContainer(container)
   }
}

and, as normal, add Capabilities iCloud.cloudKit and BackgroundModes.Remote notifications.