Search code examples
core-datansorderedset

Insert an object at a specific position in NSOrderedSet in CoreData?


Setting up a "To Many" relationship in CoreData and ticking the "Ordered" box defines your attribute as a NSOrderedSet.

Is there an efficient way to insert an object at a specific position or to move an object up and down?

Or do I need to create a NSMutabledOrderedSet with the data from the NSOrderedSet, insert or move my objects and then convert it back to NSOrderedSet?

Or should I use a standard NSSet and manage a 'position' attribute myself?


Solution

  • CoreData 'Create NSManagedObject Subclasses...' will generate a lot of methods for you to use to manipulate your ordered set. Or you can do the same with Codegen.

    Objective C

    @interface MyObject (CoreDataGeneratedAccessors)
    
    - (void)insertObject:(NSManagedObject *)value inItemsAtIndex:(NSUInteger)idx;
    - (void)removeObjectFromItemsAtIndex:(NSUInteger)idx;
    - (void)insertItems:(NSArray<NSManagedObject *> *)value atIndexes:(NSIndexSet *)indexes;
    - (void)removeItemsAtIndexes:(NSIndexSet *)indexes;
    - (void)replaceObjectInItemsAtIndex:(NSUInteger)idx withObject:(NSManagedObject *)value;
    - (void)replaceItemsAtIndexes:(NSIndexSet *)indexes withItems:(NSArray<NSManagedObject *> *)values;
    - (void)addItemsObject:(NSManagedObject *)value;
    - (void)removeItemsObject:(NSManagedObject *)value;
    - (void)addItems:(NSOrderedSet<NSManagedObject *> *)values;
    - (void)removeItems:(NSOrderedSet<NSManagedObject *> *)values;
    
    @end
    

    Swift

    // MARK: Generated accessors for items
    extension MyObject {
    
        @objc(insertObject:inItemsAtIndex:)
        @NSManaged public func insertIntoItems(_ value: NSManagedObject, at idx: Int)
    
        @objc(removeObjectFromItemsAtIndex:)
        @NSManaged public func removeFromItems(at idx: Int)
    
        @objc(insertItems:atIndexes:)
        @NSManaged public func insertIntoItems(_ values: [NSManagedObject], at indexes: NSIndexSet)
    
        @objc(removeItemsAtIndexes:)
        @NSManaged public func removeFromItems(at indexes: NSIndexSet)
    
        @objc(replaceObjectInItemsAtIndex:withObject:)
        @NSManaged public func replaceItems(at idx: Int, with value: NSManagedObject)
    
        @objc(replaceItemsAtIndexes:withItems:)
        @NSManaged public func replaceItems(at indexes: NSIndexSet, with values: [NSManagedObject])
    
        @objc(addItemsObject:)
        @NSManaged public func addToItems(_ value: NSManagedObject)
    
        @objc(removeItemsObject:)
        @NSManaged public func removeFromItems(_ value: NSManagedObject)
    
        @objc(addItems:)
        @NSManaged public func addToItems(_ values: NSOrderedSet)
    
        @objc(removeItems:)
        @NSManaged public func removeFromItems(_ values: NSOrderedSet)
    
    }
    

    Otherwise yes just make a mutable copy, manipulate as necessary, then set it back into the NSManagedObject. btw, you don't need to convert it back to a non-mutable set either