'Bundle' does not conform to expected element type 'SchemaMappingProvider' #251

Closed
opened 2025-12-29 18:24:57 +01:00 by adam · 7 comments
Owner

Originally created by @iby on GitHub (Jan 10, 2019).

The Local Store Setting Up example suggests:

let migrationProgress = CoreStore.addStorage(
    SQLiteStore(
        fileName: "MyStore.sqlite",
        configuration: "Config2", // optional. Use entities from the "Config2" configuration in the .xcdatamodeld file
        migrationMappingProviders: [Bundle.main], // optional. The bundles that contain required .xcmappingmodel files
        localStorageOptions: .recreateStoreOnModelMismatch // optional. Provides settings that tells the DataStack how to setup the persistent store
    ),
    completion: { /* ... */ }
)

But apparently Bundle is not (no longer?) compatible with SchemaMappingProvider.

Originally created by @iby on GitHub (Jan 10, 2019). The [Local Store Setting Up example](https://github.com/JohnEstropia/CoreStore/blob/8c30ec3a3d01159f7869700374d03c6a86bcdfec/README.md#local-store) suggests: ```swift let migrationProgress = CoreStore.addStorage( SQLiteStore( fileName: "MyStore.sqlite", configuration: "Config2", // optional. Use entities from the "Config2" configuration in the .xcdatamodeld file migrationMappingProviders: [Bundle.main], // optional. The bundles that contain required .xcmappingmodel files localStorageOptions: .recreateStoreOnModelMismatch // optional. Provides settings that tells the DataStack how to setup the persistent store ), completion: { /* ... */ } ) ``` But apparently `Bundle` is not (no longer?) compatible with `SchemaMappingProvider`.
adam added the question label 2025-12-29 18:24:57 +01:00
adam closed this issue 2025-12-29 18:24:58 +01:00
Author
Owner

@JohnEstropia commented on GitHub (Jan 10, 2019):

I've probably missed updating a documentation somewhere.

If your .xcmappingmodel files are within the Bundle, you can omit the migrationMappingProviders argument altogether.

You can also use InferredSchemaMappingProvider to be explicit (but this will always be the fallback regardless, or you can also use XcodeSchemaMappingProvider if you need to set specifically which Bundle to load .xcmappingmodel from for each target version.

@JohnEstropia commented on GitHub (Jan 10, 2019): I've probably missed updating a documentation somewhere. If your *.xcmappingmodel* files are within the `Bundle`, you can omit the `migrationMappingProviders` argument altogether. You can also use `InferredSchemaMappingProvider` to be explicit (but this will always be the fallback regardless, or you can also use `XcodeSchemaMappingProvider` if you need to set specifically which `Bundle` to load *.xcmappingmodel* from for each target version.
Author
Owner

@iby commented on GitHub (Jan 10, 2019):

Great! I thought it might be the case. For some reason it fails doesn't discover mapping models in non-main bundle, though my data stack explicitly provides the bundle. Looks like data stack uses the explicit bundle for schema models, but not for mapping models. Can this be the case? Adding mapping models into the main bundle fixes it, or using explicit XcodeSchemaMappingProvider, which is a little painful.

@iby commented on GitHub (Jan 10, 2019): Great! I thought it might be the case. For some reason it fails doesn't discover mapping models in non-main bundle, though my data stack explicitly provides the bundle. Looks like data stack uses the explicit bundle for schema models, but not for mapping models. Can this be the case? Adding mapping models into the main bundle fixes it, or using explicit `XcodeSchemaMappingProvider`, which is a little painful.
Author
Owner

@iby commented on GitHub (Jan 10, 2019):

Ignore this for now, there's something odd going on with the build cache. Will retest and confirm or close. 👍

@iby commented on GitHub (Jan 10, 2019): Ignore this for now, there's something odd going on with the build cache. Will retest and confirm or close. 👍
Author
Owner

@JohnEstropia commented on GitHub (Jan 10, 2019):

Looks like data stack uses the explicit bundle for schema models, but not for mapping models. Can this be the case?

Yes, they do load from bundles separately as schema models are per-stack, and mapping models are per-store (you can have different mapping models for different files, for example).

That said, InferredSchemaMappingProvider will always be used as a fallback if no other mappings are found. And if you check the source code of InferredSchemaMappingProvider you'll find that it loads NSMappingModels from Bundle.allBundles.

Let me know if you resolve the issue on your side

@JohnEstropia commented on GitHub (Jan 10, 2019): > Looks like data stack uses the explicit bundle for schema models, but not for mapping models. Can this be the case? Yes, they do load from bundles separately as schema models are per-stack, and mapping models are per-store (you can have different mapping models for different files, for example). That said, `InferredSchemaMappingProvider` will always be used as a fallback if no other mappings are found. And if you check the source code of `InferredSchemaMappingProvider` you'll find that it loads `NSMappingModel`s from `Bundle.allBundles`. Let me know if you resolve the issue on your side
Author
Owner

@iby commented on GitHub (Jan 10, 2019):

No, all looks good, must have overlooked something. Thanks for looking into this!

@iby commented on GitHub (Jan 10, 2019): No, all looks good, must have overlooked something. Thanks for looking into this!
Author
Owner

@iby commented on GitHub (Jan 10, 2019):

I figured out the earlier issue, might be helpful for others who want to store models along with code in a separate framework. That framework might not be present in Bundle.allBundles when InferredSchemaMappingProvider searches for mappings, so the only workaround is to explicitly provide it with XcodeSchemaMappingProvider.

It seems the DataStack doesn't store the bundle reference, but it would be very useful to pass it along into InferredSchemaMappingProvider when needed to explicitly be search first instead of going through all bundles. Alternatively searching Bundle.allFrameworks would solve this issue, but would add a potentially huge overhead.

@iby commented on GitHub (Jan 10, 2019): I figured out the earlier issue, might be helpful for others who want to store models along with code in a separate framework. That framework might not be present in `Bundle.allBundles` when `InferredSchemaMappingProvider` searches for mappings, so the only workaround is to explicitly provide it with `XcodeSchemaMappingProvider`. It seems the `DataStack` doesn't store the bundle reference, but it would be very useful to pass it along into `InferredSchemaMappingProvider` when needed to explicitly be search first instead of going through all bundles. Alternatively searching `Bundle.allFrameworks` would solve this issue, but would add a potentially huge overhead.
Author
Owner

@JohnEstropia commented on GitHub (Jan 11, 2019):

Glad the issue was sorted out :)

It seems the DataStack doesn't store the bundle reference, but it would be very useful to pass it along into InferredSchemaMappingProvider when needed to explicitly be search first instead of going through all bundles.

Bundles being set separately for the DataStack and the SQLiteStore is by design. The DataStack's model is based on the newest schema, while the LocalStorage's model is based on the user's current version (which may be any version since the app's first release). That said, I should explain this better in the source documentation for DataStack.init's bundle argument.

Alternatively searching Bundle.allFrameworks would solve this issue, but would add a potentially huge overhead.

The overhead would be relatively fine (you are already doing a migration anyway). The issue with using Bundle.allFrameworks by default is more about security. You wouldn't want a model to be accidentally loaded from a compromised 3rd party library.

I'll close this issue as it looks like things are behaving as they were intended to. I would update the docs and maybe provide more helpful error logs when models cannot be found.

@JohnEstropia commented on GitHub (Jan 11, 2019): Glad the issue was sorted out :) > It seems the DataStack doesn't store the bundle reference, but it would be very useful to pass it along into InferredSchemaMappingProvider when needed to explicitly be search first instead of going through all bundles. Bundles being set separately for the DataStack and the SQLiteStore is by design. The DataStack's model is based on the newest schema, while the LocalStorage's model is based on the user's current version (which may be any version since the app's first release). That said, I should explain this better in the source documentation for `DataStack.init`'s `bundle` argument. > Alternatively searching Bundle.allFrameworks would solve this issue, but would add a potentially huge overhead. The overhead would be relatively fine (you are already doing a migration anyway). The issue with using `Bundle.allFrameworks` by default is more about security. You wouldn't want a model to be accidentally loaded from a compromised 3rd party library. I'll close this issue as it looks like things are behaving as they were intended to. I would update the docs and maybe provide more helpful error logs when models cannot be found.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/CoreStore-JohnEstropia#251