diff --git a/RealmSwift/List.swift b/RealmSwift/List.swift index 8ee5ec5193..66ba7b2339 100644 --- a/RealmSwift/List.swift +++ b/RealmSwift/List.swift @@ -154,6 +154,33 @@ public final class List: RLMSwiftCollectionBase, rlmArray.removeObject(at: UInt(index)) } + /** + Removes an object in the list if present, otherwise throws an error. The object is not removed from the Realm that manages it. + + - warning: This method may only be called during a write transaction. + + - parameter object: The object to remove. + */ + public func remove(_ object: Element) { + guard let index = self.index(of: object) else { + throwRealmException("Object does not exist in List") // ???: Is this too harsh? Should method just return a bool or something? + } + self.remove(at: index) + } + + /** + Removes a sequence of objects in the list if present, otherwise throws an error. The objects are not removed from the Realm that manages it. + + - warning: This method may only be called during a write transaction. + + - parameter objects: The objects to remove. + */ + public func remove(objectsIn objects: S) where S.Iterator.Element == Element { + for obj in objects { + remove(obj) + } + } + /** Removes all objects from the list. The objects are not removed from the Realm that manages them. diff --git a/RealmSwift/Tests/AnyRealmValueTests.swift b/RealmSwift/Tests/AnyRealmValueTests.swift index c493d77c41..d6c15dd6bb 100644 --- a/RealmSwift/Tests/AnyRealmValueTests.swift +++ b/RealmSwift/Tests/AnyRealmValueTests.swift @@ -387,6 +387,27 @@ class AnyRealmValueListTests: AnyRealmValu assertThrows(array[1]) } + func testRemoveWithObject() { + assertThrows(array.remove(values[0])) + + array.append(objectsIn: values) + assertEqual(values[0], array[0]) + assertEqual(values[1], array[1]) + assertEqual(values[2], array[2]) + assertThrows(array[3]) + + array.remove(values[0]) + assertThrows(array.remove(values[0])) + assertEqual(values[1], array[0]) + assertEqual(values[2], array[1]) + assertThrows(array[2]) + + array.remove(array[1]) + assertThrows(array.remove(values[2])) // values[2] was already removed in line 406 + assertEqual(values[1], array[0]) + assertThrows(array[1]) + } + func testRemoveLast() { assertThrows(array.removeLast()) diff --git a/RealmSwift/Tests/ListTests.swift b/RealmSwift/Tests/ListTests.swift index d15786caae..9ac9e1357a 100644 --- a/RealmSwift/Tests/ListTests.swift +++ b/RealmSwift/Tests/ListTests.swift @@ -244,6 +244,46 @@ class ListTests: TestCase { assertThrows(array.remove(atOffsets: [1])) } + func testRemoveObject() { + guard let array = array, let str1 = str1, let str2 = str2 else { + fatalError("Test precondition failure") + } + + array.append(objectsIn: [str1, str2, str1]) + array.remove(str2) + + XCTAssertEqual(array.count, 2) + assertEqual(array[0], str1) + assertEqual(array[1], str1) + assertThrows(array.remove(str2)) + } + + func testRemoveWhenDuplicates() { + guard let array = array, let str1 = str1, let str2 = str2 else { + fatalError("Test precondition failure") + } + + array.append(objectsIn: [str1, str2, str1]) + array.remove(str1) + + XCTAssertEqual(array.count, 2) + assertEqual(array[0], str2) // Expect the str1 that was at index 0 to be removed + assertEqual(array[1], str1) + } + + func testRemoveSequence() { + guard let array = array, let str1 = str1, let str2 = str2 else { + fatalError("Test precondition failure") + } + + array.append(objectsIn: [str1, str2, str1]) + array.remove(objectsIn: [str2, str1]) + + XCTAssertEqual(array.count, 1) + assertEqual(array[0], str1) + assertThrows(array.remove(str2)) + } + func testRemoveLast() { guard let array = array, let str1 = str1, let str2 = str2 else { fatalError("Test precondition failure") diff --git a/RealmSwift/Tests/SwiftUITests.swift b/RealmSwift/Tests/SwiftUITests.swift index 021054410b..f853f69f1a 100644 --- a/RealmSwift/Tests/SwiftUITests.swift +++ b/RealmSwift/Tests/SwiftUITests.swift @@ -150,7 +150,6 @@ class SwiftUITests: TestCase { state.projectedValue.remove(at: 0) XCTAssertEqual(state.wrappedValue.count, 0) } - func testManagedListAppendRemoveObservedObject() throws { let object = SwiftUIObject() var state = StateRealmObject(wrappedValue: object.list)