25.1 C
New York
Saturday, March 29, 2025

ios – SwiftData Many-To-Many Relationship: Failed to satisfy hyperlink PendingRelationshipLink


I bought two fashions right here:

@Mannequin
    last class PresetParams: Identifiable {
        @Attribute(.distinctive) var id: UUID = UUID()
        
        var positionX: Float = 0.0
        var positionY: Float = 0.0
        var positionZ: Float = 0.0
        
        var quantity: Float = 1.0
        
        @Relationship(deleteRule: .nullify, inverse: Preset.presetAudioParams)
        var preset = [Preset]()
        
        init(place: SIMD3, quantity: Float) {
            self.positionX = place.x
            self.positionY = place.y
            self.positionZ = place.z
            self.quantity = quantity
            self.preset = []
        }
        
        var place: SIMD3 {
            get {
                return SIMD3(x: positionX, y: positionY, z: positionZ)
            }
            set {
                positionX = newValue.x
                positionY = newValue.y
                positionZ = newValue.z
            }
        }
    }
    
    @Mannequin
    last class Preset: Identifiable {
        @Attribute(.distinctive) var id: UUID = UUID()
        var presetName: String
        var presetDesc: String?
        
        var presetAudioParams = [PresetParams]()  // Many-To-Many Relationship.
        
        init(presetName: String, presetDesc: String? = nil) {
            self.presetName = presetName
            self.presetDesc = presetDesc
            self.presetAudioParams = []
        }
    }

To be trustworthy, I do not absolutely perceive how the @Relationship factor works correctly in a Many-To-Many relationship state of affairs. Some tutorials recommend that it is required on the “One” facet of an One-To-Many Relationship, whereas the “Many” facet does not want it.

After which there’s an ObservableObject known as “ModelActors” to handle all ModelActors, ModelContainer, and so forth.

class ModelActors: ObservableObject {
    static let shared: ModelActors = ModelActors()
    
    let sharedModelContainer: ModelContainer
    
    personal init() {
        var schema = Schema([
            // ...
            Preset.self,
            PresetParams.self,
            // ...
        ])
        
        do {
            sharedModelContainer = attempt ModelContainer(for: schema, migrationPlan: MigrationPlan.self)
        } catch {
            fatalError("Couldn't create ModelContainer: (error.localizedDescription)")
        }
    }
    
}

And there’s a migrationPlan:

// MARK: V102
// typealias ...

// MARK: V101
typealias Preset = AppSchemaV101.Preset
typealias PresetParams = AppSchemaV101.PresetParams

// MARK: V100
// typealias ...

enum MigrationPlan: SchemaMigrationPlan {
    static var schemas: [VersionedSchema.Type] {
        [
            AppSchemaV100.self,
            AppSchemaV101.self,
            AppSchemaV102.self,
        ]
    }

    static var phases: [MigrationStage] {
        [AppMigrateV100toV101, AppMigrateV101toV102]
    }
    
    static let AppMigrateV100toV101 = MigrationStage.light-weight(fromVersion: AppSchemaV100.self, toVersion: AppSchemaV101.self)
    
    static let AppMigrateV101toV102 = MigrationStage.light-weight(fromVersion: AppSchemaV101.self, toVersion: AppSchemaV102.self)

}

// MARK: Right here is the AppSchemaV101

enum AppSchemaV101: VersionedSchema {
    static var versionIdentifier: Schema.Model = Schema.Model(1, 0, 1)
    
    static var fashions: [any PersistentModel.Type] {
        return [  // ...
                Preset.self,
                PresetParams.self
        ]
    }
}

So I anticipated the SwiftData subsystem to work appropriately with model management. A excellent news is that on `iOS 18.1 `it does work. But it surely fails on iOS 18.3.x with a deadly Error:

"SwiftData/SchemaCoreData.swift:581: Deadly error: Failed to satisfy hyperlink PendingRelationshipLink(relationshipDescription: (), identify preset, isOptional 0, isTransient 0, entity PresetParams, renamingIdentifier preset, validation predicates (), warnings (), versionHashModifier (null)userInfo {}, vacation spot entity Preset, inverseRelationship (null), minCount 0, maxCount 0, isOrdered 0, deleteRule 1, destinationEntityName: "Preset", inverseRelationshipName: Elective("presetAudioParams")), could not discover inverse relationship 'Preset.presetAudioParams' in mannequin"

I examined it on iOS 17.5 and located one other subject: Accessing or mutating the "PresetAudioParams" property causes the SwiftData Macro Codes to crash, affecting each Getter and Setter. It fails with an error "EXC_BREAKPOINT (code=1, subcode=0x1cc1698ec)"

Tweaking the @Relationship marker and ModelContainer settings did not repair the issue.

Related Articles

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Latest Articles