diff --git a/Realm.xcodeproj/project.pbxproj b/Realm.xcodeproj/project.pbxproj index 964fb2f372..b8be50df37 100644 --- a/Realm.xcodeproj/project.pbxproj +++ b/Realm.xcodeproj/project.pbxproj @@ -61,6 +61,7 @@ 02AFB4671A80343600E11938 /* ResultsTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 02AFB4621A80343600E11938 /* ResultsTests.m */; }; 02AFB4681A80343600E11938 /* ResultsTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 02AFB4621A80343600E11938 /* ResultsTests.m */; }; 02E334C31A5F41C7009F8810 /* DynamicTests.m in Sources */ = {isa = PBXBuildFile; fileRef = E81A1FBA1955FE0100FDED82 /* DynamicTests.m */; }; + 1AB605D31D495927007F53DE /* RealmCollection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1AB605D21D495927007F53DE /* RealmCollection.swift */; }; 2973CCF91C175AB400FEA0FA /* fileformat-pre-null.realm in Resources */ = {isa = PBXBuildFile; fileRef = 29B7FDF71C0DE76B0023224E /* fileformat-pre-null.realm */; }; 297FBEFB1C19F696009D1118 /* RLMTestCaseUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 297FBEFA1C19F696009D1118 /* RLMTestCaseUtils.swift */; }; 297FBEFF1C19F844009D1118 /* TestUtils.mm in Sources */ = {isa = PBXBuildFile; fileRef = 297FBEFE1C19F844009D1118 /* TestUtils.mm */; }; @@ -243,7 +244,6 @@ 5D660FF61BE98D670021E04F /* Optional.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5D660FE81BE98D670021E04F /* Optional.swift */; }; 5D660FF71BE98D670021E04F /* Property.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5D660FE91BE98D670021E04F /* Property.swift */; }; 5D660FF81BE98D670021E04F /* Realm.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5D660FEA1BE98D670021E04F /* Realm.swift */; }; - 5D660FF91BE98D670021E04F /* RealmCollectionType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5D660FEB1BE98D670021E04F /* RealmCollectionType.swift */; }; 5D660FFA1BE98D670021E04F /* RealmConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5D660FEC1BE98D670021E04F /* RealmConfiguration.swift */; }; 5D660FFB1BE98D670021E04F /* Results.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5D660FED1BE98D670021E04F /* Results.swift */; }; 5D660FFC1BE98D670021E04F /* Schema.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5D660FEE1BE98D670021E04F /* Schema.swift */; }; @@ -509,6 +509,7 @@ 02B8EF5B19E7048D0045A93D /* RLMCollection.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RLMCollection.h; sourceTree = ""; }; 02E334C21A5F3C45009F8810 /* module.modulemap */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.module-map"; path = module.modulemap; sourceTree = ""; }; 02E334C41A5F4923009F8810 /* RLMRealm_Private.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = RLMRealm_Private.hpp; sourceTree = ""; }; + 1AB605D21D495927007F53DE /* RealmCollection.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RealmCollection.swift; sourceTree = ""; }; 26F3CA681986CC86004623E1 /* SwiftPropertyTypeTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SwiftPropertyTypeTest.swift; sourceTree = ""; }; 297FBEFA1C19F696009D1118 /* RLMTestCaseUtils.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RLMTestCaseUtils.swift; sourceTree = ""; }; 297FBEFD1C19F844009D1118 /* TestUtils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TestUtils.h; path = Realm/Tests/TestUtils.h; sourceTree = SOURCE_ROOT; }; @@ -608,7 +609,6 @@ 5D660FE81BE98D670021E04F /* Optional.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Optional.swift; sourceTree = ""; }; 5D660FE91BE98D670021E04F /* Property.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Property.swift; sourceTree = ""; }; 5D660FEA1BE98D670021E04F /* Realm.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Realm.swift; sourceTree = ""; }; - 5D660FEB1BE98D670021E04F /* RealmCollectionType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RealmCollectionType.swift; sourceTree = ""; }; 5D660FEC1BE98D670021E04F /* RealmConfiguration.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RealmConfiguration.swift; sourceTree = ""; }; 5D660FED1BE98D670021E04F /* Results.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Results.swift; sourceTree = ""; }; 5D660FEE1BE98D670021E04F /* Schema.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Schema.swift; sourceTree = ""; }; @@ -891,7 +891,7 @@ 5D660FE81BE98D670021E04F /* Optional.swift */, 5D660FE91BE98D670021E04F /* Property.swift */, 5D660FEA1BE98D670021E04F /* Realm.swift */, - 5D660FEB1BE98D670021E04F /* RealmCollectionType.swift */, + 1AB605D21D495927007F53DE /* RealmCollection.swift */, 5D660FEC1BE98D670021E04F /* RealmConfiguration.swift */, 5D660FED1BE98D670021E04F /* Results.swift */, 5D660FEE1BE98D670021E04F /* Schema.swift */, @@ -1820,10 +1820,10 @@ 5D660FF31BE98D670021E04F /* Migration.swift in Sources */, 5D660FF41BE98D670021E04F /* Object.swift in Sources */, 5D660FF51BE98D670021E04F /* ObjectSchema.swift in Sources */, + 1AB605D31D495927007F53DE /* RealmCollection.swift in Sources */, 5D660FF61BE98D670021E04F /* Optional.swift in Sources */, 5D660FF71BE98D670021E04F /* Property.swift in Sources */, 5D660FF81BE98D670021E04F /* Realm.swift in Sources */, - 5D660FF91BE98D670021E04F /* RealmCollectionType.swift in Sources */, 5D660FFA1BE98D670021E04F /* RealmConfiguration.swift in Sources */, 5D660FFB1BE98D670021E04F /* Results.swift in Sources */, 5D660FFC1BE98D670021E04F /* Schema.swift in Sources */, diff --git a/Realm/RLMObject.h b/Realm/RLMObject.h index b0ce0da75a..407a258aac 100644 --- a/Realm/RLMObject.h +++ b/Realm/RLMObject.h @@ -96,7 +96,7 @@ NS_ASSUME_NONNULL_BEGIN #pragma mark - Creating & Initializing Objects /** - Initializes an unmanaged instance of a Realm object. + Creates an unmanaged instance of a Realm object. Call `addObject:` on an `RLMRealm` instance to add an unmanaged object into that Realm. @@ -106,7 +106,7 @@ NS_ASSUME_NONNULL_BEGIN /** - Initializes an unmanaged instance of a Realm object. + Creates an unmanaged instance of a Realm object. Pass in an `NSArray` or `NSDictionary` instance to set the values of the object's properties. @@ -413,7 +413,7 @@ NS_ASSUME_NONNULL_BEGIN @param object The object to compare the receiver to. - @return A Boolean indicating whether the object represents the same object as the receiver. + @return Whether the object represents the same object as the receiver. */ - (BOOL)isEqualToObject:(RLMObject *)object; diff --git a/Realm/RLMObjectSchema.h b/Realm/RLMObjectSchema.h index a159119783..808cdfab5f 100644 --- a/Realm/RLMObjectSchema.h +++ b/Realm/RLMObjectSchema.h @@ -63,8 +63,8 @@ NS_ASSUME_NONNULL_BEGIN - (nullable RLMProperty *)objectForKeyedSubscript:(NSString *)propertyName; /** - Returns a Boolean value that indicates whether two `RLMObjectSchema` instances are equal. -*/ + Returns whether two `RLMObjectSchema` instances are equal. + */ - (BOOL)isEqualToObjectSchema:(RLMObjectSchema *)objectSchema; @end diff --git a/Realm/RLMProperty.h b/Realm/RLMProperty.h index 0f21e6fdb6..f19c592b3e 100644 --- a/Realm/RLMProperty.h +++ b/Realm/RLMProperty.h @@ -90,7 +90,7 @@ NS_ASSUME_NONNULL_BEGIN #pragma mark - Methods /** - Returns a Boolean value that indicates whether a given property object is equal to the receiver. + Returns whether a given property object is equal to the receiver. */ - (BOOL)isEqualToProperty:(RLMProperty *)property; diff --git a/Realm/RLMSchema.h b/Realm/RLMSchema.h index 5f731447bc..2b1179289b 100644 --- a/Realm/RLMSchema.h +++ b/Realm/RLMSchema.h @@ -68,7 +68,7 @@ NS_ASSUME_NONNULL_BEGIN - (RLMObjectSchema *)objectForKeyedSubscript:(NSString *)className; /** - Returns a Boolean value that indicates whether two `RLMSchema` instances are equivalent. + Returns whether two `RLMSchema` instances are equivalent. */ - (BOOL)isEqualToSchema:(RLMSchema *)schema; diff --git a/RealmSwift/Error.swift b/RealmSwift/Error.swift index 27f210f83a..779dcac879 100644 --- a/RealmSwift/Error.swift +++ b/RealmSwift/Error.swift @@ -21,80 +21,82 @@ import Realm #if swift(>=3.0) /** -Enumeration that describes the error codes within the Realm error domain. +Struct that describes the error codes within the Realm error domain. The values can be used to catch a variety of _recoverable_ errors, especially those happening when initializing a Realm instance. - let realm: Realm? - do { - realm = Realm() - } catch RealmSwift.Error.incompatibleLockFile { - print("Realm Browser app may be attached to Realm on device?") - } - +```swift +let realm: Realm? +do { + realm = Realm() +} catch RealmSwift.Error.incompatibleLockFile { + print("Realm Browser app may be attached to Realm on device?") +} +``` */ public struct Error { - public enum Code : Int { - /// Error thrown by Realm if no other specific error is returned when a realm is opened. + public enum Code: Int { + /// - see: `Error.fail` case fail - /// Error thrown by Realm for any I/O related exception scenarios when a realm is opened. + /// - see: `Error.fileAccess` case fileAccess - /// Error thrown by Realm if the user does not have permission to open or create - /// the specified file in the specified access mode when the realm is opened. + /// - see: `Error.filePermissionDenied` case filePermissionDenied - /// Error thrown by Realm if the file already exists when a copy should be written. + /// - see: `Error.fileExists` case fileExists - /// Error thrown by Realm if no file was found when a realm was opened as - /// read-only or if the directory part of the specified path was not found - /// when a copy should be written. + /// - see: `Error.fileNotFound` case fileNotFound - /// Error thrown by Realm if the database file is currently open in another process which - /// cannot share with the current process due to an architecture mismatch. + /// - see: `Error.incompatibleLockFile` case incompatibleLockFile - /// Error thrown by Realm if a file format upgrade is required to open the file, - /// but upgrades were explicitly disabled. + /// - see: `Error.fileFormatUpgradeRequired` case fileFormatUpgradeRequired - /// Error thrown by Realm if there is insufficient available address space. + /// - see: `Error.addressSpaceExhausted` case addressSpaceExhausted - /// Error thrown by Realm if there is a schema version mismatch, so that a migration is required. + /// - see: `Error.schemaMismatch` case schemaMismatch } - /// - see: `Error.Code.fail` + /// Error thrown by Realm if no other specific error is returned when a realm is opened. public static let fail: Code = .fail - /// - see: `Error.Code.fileAccess` + /// Error thrown by Realm for any I/O related exception scenarios when a realm is opened. public static let fileAccess: Code = .fileAccess - /// - see: `Error.Code.filePermissionDenied` + /// Error thrown by Realm if the user does not have permission to open or create + /// the specified file in the specified access mode when the realm is opened. public static let filePermissionDenied: Code = .filePermissionDenied - /// - see: `Error.Code.fileExists` + /// Error thrown by Realm if the file already exists when a copy should be written. public static let fileExists: Code = .fileExists - /// - see: `Error.Code.fileNotFound` + /// Error thrown by Realm if no file was found when a realm was opened as + /// read-only or if the directory part of the specified path was not found + /// when a copy should be written. public static let fileNotFound: Code = .fileNotFound - /// - see: `Error.Code.incompatibleLockFile` + /// Error thrown by Realm if the database file is currently open in another process which + /// cannot share with the current process due to an architecture mismatch. public static let incompatibleLockFile: Code = .incompatibleLockFile - /// - see: `Error.Code.fileFormatUpgradeRequired` + /// Error thrown by Realm if a file format upgrade is required to open the file, + /// but upgrades were explicitly disabled. public static let fileFormatUpgradeRequired: Code = .fileFormatUpgradeRequired - /// - see: `Error.Code.addressSpaceExhausted` + /// Error thrown by Realm if there is insufficient available address space. public static let addressSpaceExhausted: Code = .addressSpaceExhausted - /// - see: `Error.Code.schemaMismatch` + /// Error thrown by Realm if there is a schema version mismatch, so that a migration is required. public static let schemaMismatch: Code = .schemaMismatch + /// :nodoc: public var code: Code { let rlmError = _nsError as! RLMError switch rlmError.code { @@ -120,7 +122,7 @@ public struct Error { } /// :nodoc: - public var _nsError: NSError + public var _nsError: NSError // swiftlint:disable:this variable_name /// :nodoc: public init(_nsError error: NSError) { @@ -130,17 +132,37 @@ public struct Error { /// :nodoc: // Provide bridging from errors with domain RLMErrorDomain to Error. -extension Error : _BridgedStoredNSError { +extension Error: _BridgedStoredNSError { /// :nodoc: - public static var _nsErrorDomain = RLMErrorDomain + public static var _nsErrorDomain = RLMErrorDomain // swiftlint:disable:this variable_name } /// :nodoc: -extension Error.Code : _ErrorCodeProtocol { +extension Error.Code: _ErrorCodeProtocol { /// :nodoc: public typealias _ErrorType = RLMError } +// MARK: Equatable + +extension Error: Equatable {} + +/// Returns a Boolean indicating whether the errors are identical. +public func == (lhs: Swift.Error, rhs: Swift.Error) -> Bool { // swiftlint:disable:this valid_docs + return lhs._code == rhs._code + && lhs._domain == rhs._domain +} + +// MARK: Pattern Matching + +/** + Pattern matching matching for `Realm.Error`, so that the instances can be used with Swift's + `do { ... } catch { ... }` syntax. +*/ +public func ~= (lhs: Error, rhs: Swift.Error) -> Bool { // swiftlint:disable:this valid_docs + return lhs == rhs +} + #else /** diff --git a/RealmSwift/LinkingObjects.swift b/RealmSwift/LinkingObjects.swift index 20dded55c7..0cf5bc66e3 100644 --- a/RealmSwift/LinkingObjects.swift +++ b/RealmSwift/LinkingObjects.swift @@ -60,53 +60,53 @@ public class LinkingObjectsBase: NSObject, NSFastEnumeration { } /** - LinkingObjects is an auto-updating container type that represents a collection of objects that - link to a given object. + `LinkingObjects` is an auto-updating container type. It represents zero or more objects that are linked to its owning + model object through a property relationship. - LinkingObjects can be queried with the same predicates as `List` and `Results`. + `LinkingObjects` can be queried with the same predicates as `List` and `Results`. - LinkingObjects always reflect the current state of the Realm on the current thread, - including during write transactions on the current thread. The one exception to - this is when using `for...in` enumeration, which will always enumerate over the - linking objects when the enumeration is begun, even if some of them are deleted or + `LinkingObjects` always reflects the current state of the Realm on the current thread, including during write + transactions on the current thread. The one exception to this is when using `for...in` enumeration, which will always + enumerate over the linking objects that were present when the enumeration is begun, even if some of them are deleted or modified to no longer link to the target object during the enumeration. - LinkingObjects can only be used as a property on `Object` models. The property must - be declared as `let` and cannot be `dynamic`. + `LinkingObjects` can only be used as a property on `Object` models. Properties of this type must be declared as `let` + and cannot be `dynamic`. */ public final class LinkingObjects: LinkingObjectsBase { - /// Element type contained in this collection. + /// The type of the objects represented by the linking objects. public typealias Element = T // MARK: Properties - /// Returns the Realm these linking objects are associated with. + /// The Realm which manages the linking objects, or `nil` if the linking objects are unmanaged. public var realm: Realm? { return rlmResults.isAttached ? Realm(rlmResults.realm) : nil } - /// Indicates if the linking objects can no longer be accessed. + /// Indicates if the linking objects are no longer valid. + /// + /// The linking objects become invalid if `invalidate()` is called on the containing `realm` instance. /// - /// Linking objects can no longer be accessed if `invalidate` is called on the containing `Realm`. + /// An invalidated linking objects can be accessed, but will always be empty. public var isInvalidated: Bool { return rlmResults.isInvalidated } - /// Returns the number of objects in these linking objects. + /// The number of linking objects. public var count: Int { return Int(rlmResults.count) } // MARK: Initializers /** - Creates a LinkingObjects. This initializer should only be called when - declaring a property on a Realm model. + Creates an instance of a `LinkingObjects`. This initializer should only be called when declaring a property on a + Realm model. - - parameter type: The originating type linking to this object type. - - parameter propertyName: The property name of the incoming relationship - this LinkingObjects should refer to. - */ + - parameter type: The type of the object owning the property the linking objects should refer to. + - parameter propertyName: The property name of the property the linking objects should refer to. + */ public init(fromType type: T.Type, property propertyName: String) { let className = (T.self as Object.Type).className() super.init(fromClassName: className, property: propertyName) } - /// Returns a human-readable description of the objects contained in these linking objects. + /// A human-readable description of the objects represented by the linking objects. public override var description: String { let type = "LinkingObjects<\(rlmResults.objectClassName)>" return gsub(pattern: "RLMResults <0x[a-z0-9]+>", template: type, string: rlmResults.description) ?? type @@ -115,37 +115,29 @@ public final class LinkingObjects: LinkingObjectsBase { // MARK: Index Retrieval /** - Returns the index of the given object, or `nil` if the object is not present. + Returns the index of an object in the linking objects, or `nil` if the object is not present. - parameter object: The object whose index is being queried. - - - returns: The index of the given object, or `nil` if the object is not present. */ public func index(of object: T) -> Int? { return notFoundToNil(index: rlmResults.index(of: object.unsafeCastToRLMObject())) } /** - Returns the index of the first object matching the given predicate, - or `nil` if no objects match. - - - parameter predicate: The predicate to filter the objects. + Returns the index of the first object matching the given predicate, or `nil` if no objects match. - - returns: The index of the first matching object, or `nil` if no objects match. + - parameter predicate: The predicate with which to filter the objects. */ - public func indexOfObject(for predicate: NSPredicate) -> Int? { + public func index(matching predicate: NSPredicate) -> Int? { return notFoundToNil(index: rlmResults.indexOfObject(with: predicate)) } /** - Returns the index of the first object matching the given predicate, - or `nil` if no objects match. - - - parameter predicateFormat: The predicate format string which can accept variable arguments. + Returns the index of the first object matching the given predicate, or `nil` if no objects match. - - returns: The index of the first matching object, or `nil` if no objects match. + - parameter predicateFormat: A predicate format string, optionally followed by a variable number of arguments. */ - public func indexOfObject(for predicateFormat: String, _ args: Any...) -> Int? { + public func index(matching predicateFormat: String, _ args: Any...) -> Int? { return notFoundToNil(index: rlmResults.indexOfObject(with: NSPredicate(format: predicateFormat, argumentArray: args))) } @@ -156,8 +148,6 @@ public final class LinkingObjects: LinkingObjectsBase { Returns the object at the given `index`. - parameter index: The index. - - - returns: The object at the given `index`. */ public subscript(index: Int) -> T { get { @@ -166,47 +156,40 @@ public final class LinkingObjects: LinkingObjectsBase { } } - /// Returns the first object in the collection, or `nil` if empty. + /// Returns the first object in the linking objects, or `nil` if the linking objects are empty. public var first: T? { return unsafeBitCast(rlmResults.firstObject(), to: Optional.self) } - /// Returns the last object in the collection, or `nil` if empty. + /// Returns the last object in the linking objects, or `nil` if the linking objects are empty. public var last: T? { return unsafeBitCast(rlmResults.lastObject(), to: Optional.self) } // MARK: KVC /** - Returns an Array containing the results of invoking `valueForKey(_:)` using key on each of the - collection's objects. + Returns an `Array` containing the results of invoking `valueForKey(_:)` with `key` on each of the linking objects. - - parameter key: The name of the property. - - - returns: Array containing the results of invoking `valueForKey(_:)` using key on each of the - collection's objects. + - parameter key: The name of the property whose values are desired. */ public override func value(forKey key: String) -> Any? { return value(forKeyPath: key) } /** - Returns an Array containing the results of invoking `valueForKeyPath(_:)` using keyPath on each of the - collection's objects. - - - parameter keyPath: The key path to the property. + Returns an `Array` containing the results of invoking `valueForKeyPath(_:)` with `keyPath` on each of the linking + objects. - - returns: Array containing the results of invoking `valueForKeyPath(_:)` using keyPath on each of the - collection's objects. + - parameter keyPath: The key path to the property whose values are desired. */ public override func value(forKeyPath keyPath: String) -> Any? { return rlmResults.value(forKeyPath: keyPath) } /** - Invokes `setValue(_:forKey:)` on each of the collection's objects using the specified value and key. + Invokes `setValue(_:forKey:)` on each of the linking objects using the specified `value` and `key`. - - warning: This method can only be called during a write transaction. + - warning: This method may only be called during a write transaction. - - parameter value: The object value. - - parameter key: The name of the property. + - parameter value: The value to set the property to. + - parameter key: The name of the property whose value should be set on each object. */ public override func setValue(_ value: Any?, forKey key: String) { return rlmResults.setValue(value, forKeyPath: key) @@ -215,104 +198,100 @@ public final class LinkingObjects: LinkingObjectsBase { // MARK: Filtering /** - Filters the collection to the objects that match the given predicate. - - - parameter predicateFormat: The predicate format string which can accept variable arguments. + Returns a `Results` containing all objects matching the given predicate in the linking objects. - - returns: Results containing objects that match the given predicate. + - parameter predicateFormat: A predicate format string, optionally followed by a variable number of arguments. */ - public func filter(using predicateFormat: String, _ args: Any...) -> Results { + public func filter(_ predicateFormat: String, _ args: Any...) -> Results { return Results(rlmResults.objects(with: NSPredicate(format: predicateFormat, argumentArray: args))) } /** - Filters the collection to the objects that match the given predicate. - - - parameter predicate: The predicate to filter the objects. + Returns a `Results` containing all objects matching the given predicate in the linking objects. - - returns: Results containing objects that match the given predicate. + - parameter predicate: The predicate with which to filter the objects. */ - public func filter(using predicate: NSPredicate) -> Results { + public func filter(_ predicate: NSPredicate) -> Results { return Results(rlmResults.objects(with: predicate)) } // MARK: Sorting /** - Returns `Results` with elements sorted by the given property name. + Returns a `Results` containing all the linking objects, but sorted. + + Objects are sorted based on the values of the given property. For example, to sort a collection of `Student`s from + youngest to oldest based on their `age` property, you might call + `students.sorted(byProperty: "age", ascending: true)`. - - parameter property: The property name to sort by. - - parameter ascending: The direction to sort by. + - warning: Collections may only be sorted by properties of boolean, `Date`, `NSDate`, single and double-precision + floating point, integer, and string types. - - returns: `Results` with elements sorted by the given property name. + - parameter property: The name of the property to sort by. + - parameter ascending: The direction to sort in. */ - public func sorted(onProperty property: String, ascending: Bool = true) -> Results { - return sorted(with: [SortDescriptor(property: property, ascending: ascending)]) + public func sorted(byProperty property: String, ascending: Bool = true) -> Results { + return sorted(by: [SortDescriptor(property: property, ascending: ascending)]) } /** - Returns `Results` with elements sorted by the given sort descriptors. + Returns a `Results` containing all the linking objects, but sorted. - - parameter sortDescriptors: `SortDescriptor`s to sort by. + - warning: Collections may only be sorted by properties of boolean, `Date`, `NSDate`, single and double-precision + floating point, integer, and string types. - - returns: `Results` with elements sorted by the given sort descriptors. + - see: `sorted(byProperty:ascending:)` + + - parameter sortDescriptors: A sequence of `SortDescriptor`s to sort by. */ - public func sorted(with sortDescriptors: S) -> Results where S.Iterator.Element == SortDescriptor { + public func sorted(by sortDescriptors: S) -> Results where S.Iterator.Element == SortDescriptor { return Results(rlmResults.sortedResults(using: sortDescriptors.map { $0.rlmSortDescriptorValue })) } // MARK: Aggregate Operations /** - Returns the minimum value of the given property. + Returns the minimum (lowest) value of the given property among all the linking objects, or `nil` if the linking + objects are empty. - - warning: Only names of properties of a type conforming to the `MinMaxType` protocol can be used. - - - parameter property: The name of a property conforming to `MinMaxType` to look for a minimum on. + - warning: Only a property whose type conforms to the `MinMaxType` protocol can be specified. - - returns: The minimum value for the property amongst objects in the collection, or `nil` if the collection - is empty. + - parameter property: The name of a property whose minimum value is desired. */ - public func minimumValue(ofProperty property: String) -> U? { + public func min(ofProperty property: String) -> U? { return rlmResults.min(ofProperty: property).map(dynamicBridgeCast) } /** - Returns the maximum value of the given property. - - - warning: Only names of properties of a type conforming to the `MinMaxType` protocol can be used. + Returns the maximum (highest) value of the given property among all the linking objects, or `nil` if the linking + objects are empty. - - parameter property: The name of a property conforming to `MinMaxType` to look for a maximum on. + - warning: Only a property whose type conforms to the `MinMaxType` protocol can be specified. - - returns: The maximum value for the property amongst objects in the collection, or `nil` if the collection - is empty. + - parameter property: The name of a property whose minimum value is desired. */ - public func maximumValue(ofProperty property: String) -> U? { + public func max(ofProperty property: String) -> U? { return rlmResults.max(ofProperty: property).map(dynamicBridgeCast) } /** - Returns the sum of the given property for objects in the collection. - - - warning: Only names of properties of a type conforming to the `AddableType` protocol can be used. + Returns the sum of the values of a given property over all the linking objects. - - parameter property: The name of a property conforming to `AddableType` to calculate sum on. + - warning: Only a property whose type conforms to the `AddableType` protocol can be specified. - - returns: The sum of the given property over all objects in the collection. + - parameter property: The name of a property whose values should be summed. */ public func sum(ofProperty property: String) -> U { return dynamicBridgeCast(fromObjectiveC: rlmResults.sum(ofProperty: property)) } /** - Returns the average of the given property for objects in the collection. + Returns the average value of a given property over all the linking objects, or `nil` if the linking objects are + empty. - - warning: Only names of properties of a type conforming to the `AddableType` protocol can be used. - - - parameter property: The name of a property conforming to `AddableType` to calculate average on. + - warning: Only the name of a property whose type conforms to the `AddableType` protocol can be specified. - - returns: The average of the given property over all objects in the collection, or `nil` if the collection - is empty. + - parameter property: The name of a property whose average value should be calculated. */ public func average(ofProperty property: String) -> U? { return rlmResults.average(ofProperty: property).map(dynamicBridgeCast) @@ -321,64 +300,61 @@ public final class LinkingObjects: LinkingObjectsBase { // MARK: Notifications /** - Register a block to be called each time the LinkingObjects changes. + Registers a block to be called each time the collection changes. - The block will be asynchronously called with the initial set of objects, and then - called again after each write transaction which changes either any of the - objects in the collection, or which objects are in the collection. + The block will be asynchronously called with the initial results, and then called again after each write + transaction which changes either any of the objects in the collection, or which objects are in the collection. - This version of this method reports which of the objects in the collection were - added, removed, or modified in each write transaction as indices within the - collection. See the RealmCollectionChange documentation for more information on - the change information supplied and an example of how to use it to update - a UITableView. + The `change` parameter that is passed to the block reports, in the form of indices within the collection, which of + the objects were added, removed, or modified during each write transaction. See the `RealmCollectionChange` + documentation for more information on the change information supplied and an example of how to use it to update a + `UITableView`. - At the time when the block is called, the LinkingObjects object will be fully - evaluated and up-to-date, and as long as you do not perform a write transaction - on the same thread or explicitly call realm.refresh(), accessing it will never + At the time when the block is called, the collection will be fully evaluated and up-to-date, and as long as you do + not perform a write transaction on the same thread or explicitly call `realm.refresh()`, accessing it will never perform blocking work. - Notifications are delivered via the standard run loop, and so can't be - delivered while the run loop is blocked by other activity. When - notifications can't be delivered instantly, multiple notifications may be - coalesced into a single notification. This can include the notification - with the initial set of objects. For example, the following code performs a write - transaction immediately after adding the notification block, so there is no - opportunity for the initial notification to be delivered first. As a - result, the initial notification will reflect the state of the Realm after - the write transaction. - - let dog = realm.objects(Dog).first! - let owners = dog.owners - print("owners.count: \(owners.count)") // => 0 - let token = owners.addNotificationBlock { (changes: RealmCollectionChange) in - switch changes { - case .Initial(let owners): - // Will print "owners.count: 1" - print("owners.count: \(owners.count)") - break - case .Update: - // Will not be hit in this example - break - case .Error: - break - } - } - try! realm.write { - realm.add(Person.self, value: ["name": "Mark", dogs: [dog]]) + Notifications are delivered via the standard run loop, and so can't be delivered while the run loop is blocked by + other activity. When notifications can't be delivered instantly, multiple notifications may be coalesced into a + single notification. This can include the notification with the initial collection. + + For example, the following code performs a write transaction immediately after adding the notification block, so + there is no opportunity for the initial notification to be delivered first. As a result, the initial notification + will reflect the state of the Realm after the write transaction. + + ```swift + let results = realm.objects(Dog.self) + print("dogs.count: \(dogs?.count)") // => 0 + let token = dogs.addNotificationBlock { changes in + switch changes { + case .initial(let dogs): + // Will print "dogs.count: 1" + print("dogs.count: \(dogs.count)") + break + case .update: + // Will not be hit in this example + break + case .error: + break } - // end of runloop execution context + } + try! realm.write { + let dog = Dog() + dog.name = "Rex" + person.dogs.append(dog) + } + // end of run loop execution context + ``` - You must retain the returned token for as long as you want updates to continue - to be sent to the block. To stop receiving updates, call stop() on the token. + You must retain the returned token for as long as you want updates to be sent to the block. To stop receiving + updates, call `stop()` on the token. - - warning: This method cannot be called during a write transaction, or when - the source realm is read-only. + - warning: This method cannot be called during a write transaction, or when the containing Realm is read-only. - - parameter block: The block to be called with the evaluated linking objects and change information. + - parameter block: The block to be called whenever a change occurs. - returns: A token which must be held for as long as you want updates to be delivered. */ - public func addNotificationBlock(block: @escaping (RealmCollectionChange) -> Void) -> NotificationToken { + public func addNotificationBlock(_ block: @escaping (RealmCollectionChange) -> Void) -> NotificationToken { return rlmResults.addNotificationBlock { results, change, error in block(RealmCollectionChange.fromObjc(value: self, change: change, error: error)) } @@ -388,7 +364,7 @@ public final class LinkingObjects: LinkingObjectsBase { extension LinkingObjects : RealmCollection { // MARK: Sequence Support - /// Returns a `GeneratorOf` that yields successive elements in the results. + /// Returns an iterator that yields successive elements in the linking objects. public func makeIterator() -> RLMIterator { return RLMIterator(collection: rlmResults) } @@ -413,7 +389,7 @@ extension LinkingObjects : RealmCollection { } /// :nodoc: - public func _addNotificationBlock(block: @escaping (RealmCollectionChange>) -> Void) -> + public func _addNotificationBlock(_ block: @escaping (RealmCollectionChange>) -> Void) -> NotificationToken { let anyCollection = AnyRealmCollection(self) return rlmResults.addNotificationBlock { _, change, error in @@ -425,39 +401,33 @@ extension LinkingObjects : RealmCollection { // MARK: Unavailable extension LinkingObjects { - @available(*, unavailable, renamed:"isInvalidated") - public var invalidated : Bool { fatalError() } + @available(*, unavailable, renamed: "isInvalidated") + public var invalidated: Bool { fatalError() } - @available(*, unavailable, renamed:"indexOfObject(for:)") + @available(*, unavailable, renamed: "index(matching:)") public func index(of predicate: NSPredicate) -> Int? { fatalError() } - @available(*, unavailable, renamed:"indexOfObject(for:_:)") + @available(*, unavailable, renamed: "index(matching:_:)") public func index(of predicateFormat: String, _ args: Any...) -> Int? { fatalError() } - @available(*, unavailable, renamed:"filter(using:)") - public func filter(_ predicate: NSPredicate) -> Results { fatalError() } - - @available(*, unavailable, renamed:"filter(using:_:)") - public func filter(_ predicateFormat: String, _ args: Any...) -> Results { fatalError() } - - @available(*, unavailable, renamed:"sorted(onProperty:ascending:)") + @available(*, unavailable, renamed: "sorted(byProperty:ascending:)") public func sorted(_ property: String, ascending: Bool = true) -> Results { fatalError() } - @available(*, unavailable, renamed:"sorted(with:)") + @available(*, unavailable, renamed: "sorted(by:)") public func sorted(_ sortDescriptors: S) -> Results where S.Iterator.Element == SortDescriptor { fatalError() } - @available(*, unavailable, renamed:"minimumValue(ofProperty:)") + @available(*, unavailable, renamed: "min(ofProperty:)") public func min(_ property: String) -> U? { fatalError() } - @available(*, unavailable, renamed:"maximumValue(ofProperty:)") + @available(*, unavailable, renamed: "max(ofProperty:)") public func max(_ property: String) -> U? { fatalError() } - @available(*, unavailable, renamed:"sum(ofProperty:)") + @available(*, unavailable, renamed: "sum(ofProperty:)") public func sum(_ property: String) -> U { fatalError() } - @available(*, unavailable, renamed:"average(ofProperty:)") + @available(*, unavailable, renamed: "average(ofProperty:)") public func average(_ property: String) -> U? { fatalError() } } @@ -502,8 +472,8 @@ public class LinkingObjectsBase: NSObject, NSFastEnumeration { } /** - `LinkingObjects` is an auto-updating container type. It represents a collection of objects that - link to its parent object. + `LinkingObjects` is an auto-updating container type. It represents zero or more objects that are linked to its owning + model object through a property relationship. `LinkingObjects` can be queried with the same predicates as `List` and `Results`. @@ -522,34 +492,34 @@ public final class LinkingObjects: LinkingObjectsBase { // MARK: Properties - /// The Realm which manages this linking objects collection, or `nil` if the collection is unmanaged. + /// The Realm which manages the linking objects, or `nil` if the linking objects are unmanaged. public var realm: Realm? { return rlmResults.attached ? Realm(rlmResults.realm) : nil } - /// Indicates if the linking objects collection is no longer valid. + /// Indicates if the linking objects are no longer valid. /// - /// The linking objects collection becomes invalid if `invalidate` is called on the containing `realm`. + /// The linking objects become invalid if `invalidate()` is called on the containing `realm` instance. /// /// An invalidated linking objects can be accessed, but will always be empty. public var invalidated: Bool { return rlmResults.invalidated } - /// The number of objects in the linking objects. + /// The number of linking objects. public var count: Int { return Int(rlmResults.count) } // MARK: Initializers /** - Creates an instance of a `LinkingObjects`. This initializer should only be called when - declaring a property on a Realm model. + Creates an instance of a `LinkingObjects`. This initializer should only be called when declaring a property on a + Realm model. - - parameter type: The type of the object owning the property this `LinkingObjects` should refer to. - - parameter propertyName: The property name of the property this `LinkingObjects` should refer to. + - parameter type: The type of the object owning the property the linking objects should refer to. + - parameter propertyName: The property name of the property the linking objects should refer to. */ public init(fromType type: T.Type, property propertyName: String) { let className = (T.self as Object.Type).className() super.init(fromClassName: className, property: propertyName) } - /// Returns a description of the objects contained within the linking objects. + /// Returns a description of the linking objects. public override var description: String { let type = "LinkingObjects<\(rlmResults.objectClassName)>" return gsub("RLMResults <0x[a-z0-9]+>", template: type, string: rlmResults.description) ?? type @@ -558,7 +528,7 @@ public final class LinkingObjects: LinkingObjectsBase { // MARK: Index Retrieval /** - Returns the index of an object in the linking objects collection, or `nil` if the object is not present. + Returns the index of an object in the linking objects, or `nil` if the object is not present. - parameter object: The object whose index is being queried. */ @@ -591,8 +561,6 @@ public final class LinkingObjects: LinkingObjectsBase { Returns the object at the given `index`. - parameter index: The index. - - - returns: The object at the given `index`. */ public subscript(index: Int) -> T { get { @@ -601,17 +569,16 @@ public final class LinkingObjects: LinkingObjectsBase { } } - /// Returns the first object in the linking objects collection, or `nil` if the collection is empty. + /// Returns the first object in the linking objects, or `nil` if the linking objects are empty. public var first: T? { return unsafeBitCast(rlmResults.firstObject(), Optional.self) } - /// Returns the last object in the linking objects collection, or `nil` if collection is empty. + /// Returns the last object in the linking objects, or `nil` if the linking objects are empty. public var last: T? { return unsafeBitCast(rlmResults.lastObject(), Optional.self) } // MARK: KVC /** - Returns an `Array` containing the results of invoking `valueForKey(_:)` with `key` on each of the linking objects - collection's objects. + Returns an `Array` containing the results of invoking `valueForKey(_:)` with `key` on each of the linking objects. - parameter key: The name of the property whose values are desired. */ @@ -621,7 +588,7 @@ public final class LinkingObjects: LinkingObjectsBase { /** Returns an `Array` containing the results of invoking `valueForKeyPath(_:)` with `keyPath` on each of the linking - objects collection's objects. + objects. - parameter keyPath: The key path to the property whose values are desired. */ @@ -630,8 +597,7 @@ public final class LinkingObjects: LinkingObjectsBase { } /** - Invokes `setValue(_:forKey:)` on each of the linking objects collection's objects using the specified `value` and - `key`. + Invokes `setValue(_:forKey:)` on each of the linking objects using the specified `value` and `key`. - warning: This method may only be called during a write transaction. @@ -645,7 +611,7 @@ public final class LinkingObjects: LinkingObjectsBase { // MARK: Filtering /** - Returns a `Results` containing all objects matching the given predicate in the linking objects collection. + Returns a `Results` containing all objects matching the given predicate in the linking objects. - parameter predicateFormat: A predicate format string, optionally followed by a variable number of arguments. */ @@ -654,7 +620,7 @@ public final class LinkingObjects: LinkingObjectsBase { } /** - Returns a `Results` containing all objects matching the given predicate in the linking objects collection. + Returns a `Results` containing all objects matching the given predicate in the linking objects. - parameter predicate: The predicate with which to filter the objects. */ @@ -665,7 +631,7 @@ public final class LinkingObjects: LinkingObjectsBase { // MARK: Sorting /** - Returns a `Results` containing the objects in the linking objects collection, but sorted. + Returns a `Results` containing all the linking objects, but sorted. Objects are sorted based on the values of the given property. For example, to sort a collection of `Student`s from youngest to oldest based on their `age` property, you might call `students.sorted("age", ascending: true)`. @@ -681,7 +647,7 @@ public final class LinkingObjects: LinkingObjectsBase { } /** - Returns a `Results` containing the objects in the linking objects collection, but sorted. + Returns a `Results` containing all the linking objects, but sorted. - warning: Collections may only be sorted by properties of boolean, `NSDate`, single and double-precision floating point, integer, and string types. @@ -697,55 +663,47 @@ public final class LinkingObjects: LinkingObjectsBase { // MARK: Aggregate Operations /** - Returns the minimum (lowest) value of the given property among all the objects represented by the linking objects - collection. + Returns the minimum (lowest) value of the given property among all the linking objects, or `nil` if the linking + objects are empty. - warning: Only a property whose type conforms to the `MinMaxType` protocol can be specified. - parameter property: The name of a property whose minimum value is desired. - - - returns: The minimum value of the property, or `nil` if the collection is empty. */ public func min(property: String) -> U? { return rlmResults.minOfProperty(property).map(dynamicBridgeCast) } /** - Returns the maximum (highest) value of the given property among all the objects represented by the linking objects - collection. + Returns the maximum (highest) value of the given property among all the linking objects, or `nil` if the linking + objects are empty. - warning: Only a property whose type conforms to the `MinMaxType` protocol can be specified. - parameter property: The name of a property whose minimum value is desired. - - - returns: The maximum value of the property, or `nil` if the collection is empty. */ public func max(property: String) -> U? { return rlmResults.maxOfProperty(property).map(dynamicBridgeCast) } /** - Returns the sum of the values of a given property over all the objects represented by the linking objects - collection. + Returns the sum of the values of a given property over all the linking objects. - warning: Only a property whose type conforms to the `AddableType` protocol can be specified. - parameter property: The name of a property whose values should be summed. - - - returns: The sum of the given property. */ public func sum(property: String) -> U { return dynamicBridgeCast(fromObjectiveC: rlmResults.sumOfProperty(property)) } /** - Returns the average value of a given property over all the objects represented by the linking objects collection. + Returns the average value of a given property over all the linking objects, or `nil` if the linking objects are + empty. - warning: Only the name of a property whose type conforms to the `AddableType` protocol can be specified. - parameter property: The name of a property whose average value should be calculated. - - - returns: The average value of the given property, or `nil` if the collection is empty. */ public func average(property: String) -> U? { return rlmResults.averageOfProperty(property).map(dynamicBridgeCast) @@ -774,11 +732,11 @@ public final class LinkingObjects: LinkingObjectsBase { delivered while the run loop is blocked by other activity. When notifications can't be delivered instantly, multiple notifications may be coalesced into a single notification. This can include the notification - with the initial set of objects. For example, the following code performs a write - transaction immediately after adding the notification block, so there is no - opportunity for the initial notification to be delivered first. As a - result, the initial notification will reflect the state of the Realm after - the write transaction. + with the initial set of objects. + + For example, the following code performs a write transaction immediately after adding the notification block, so + there is no opportunity for the initial notification to be delivered first. As a result, the initial notification + will reflect the state of the Realm after the write transaction. ```swift let dog = realm.objects(Dog.self).first! @@ -806,11 +764,10 @@ public final class LinkingObjects: LinkingObjectsBase { You must retain the returned token for as long as you want updates to be sent to the block. To stop receiving updates, call `stop()` on the token. - - warning: This method cannot be called during a write transaction, or when - the containing Realm is read-only. + - warning: This method cannot be called during a write transaction, or when the containing Realm is read-only. - parameter block: The block to be called whenever a change occurs. - - returns: A token which must be retained for as long as you want updates to be delivered. + - returns: A token which must be held for as long as you want updates to be delivered. */ @warn_unused_result(message="You must hold on to the NotificationToken returned from addNotificationBlock") public func addNotificationBlock(block: (RealmCollectionChange -> Void)) -> NotificationToken { diff --git a/RealmSwift/List.swift b/RealmSwift/List.swift index 59bc0a5931..8338422ef5 100644 --- a/RealmSwift/List.swift +++ b/RealmSwift/List.swift @@ -43,33 +43,35 @@ public class ListBase: RLMListBase { } /** -`List` is the container type in Realm used to define to-many relationships. + `List` is the container type in Realm used to define to-many relationships. -Lists hold a single `Object` subclass (`T`) which defines the "type" of the List. + Like Swift's `Array`, `List` is a generic type that is parameterized on the type of `Object` it stores. -Lists can be filtered and sorted with the same predicates as `Results`. + Unlike Swift's native collections, `List`s are reference types, and are only immutable if the Realm that manages them + is opened as read-only. -When added as a property on `Object` models, the property must be declared as `let` and cannot be `dynamic`. -*/ + Lists can be filtered and sorted with the same predicates as `Results`. + + Properties of `List` type defined on `Object` subclasses must be declared as `let` and cannot be `dynamic`. + */ public final class List: ListBase { - /// Element type contained in this collection. + /// The type of the elements contained within the collection. public typealias Element = T // MARK: Properties - /// The Realm the objects in this List belong to, or `nil` if the List's - /// owning object does not belong to a Realm (the List is standalone). + /// The Realm which manages the list, or `nil` if the list is unmanaged. public var realm: Realm? { return _rlmArray.realm.map { Realm($0) } } - /// Indicates if the List can no longer be accessed. + /// Indicates if the list can no longer be accessed. public var isInvalidated: Bool { return _rlmArray.isInvalidated } // MARK: Initializers - /// Creates a `List` that holds objects of type `T`. + /// Creates a `List` that holds Realm model objects of type `T`. public override init() { super.init(array: RLMArray(objectClassName: (T.self as Object.Type).className())) } @@ -81,53 +83,41 @@ public final class List: ListBase { // MARK: Index Retrieval /** - Returns the index of the given object, or `nil` if the object is not in the List. - - - parameter object: The object whose index is being queried. + Returns the index of an object in the list, or `nil` if the object is not present. - - returns: The index of the given object, or `nil` if the object is not in the List. - */ + - parameter object: An object to find. + */ public func index(of object: T) -> Int? { return notFoundToNil(index: _rlmArray.index(of: object.unsafeCastToRLMObject())) } /** - Returns the index of the first object matching the given predicate, - or `nil` no objects match. - - - parameter predicate: The `NSPredicate` used to filter the objects. + Returns the index of the first object in the list matching the predicate, or `nil` if no objects match. - - returns: The index of the first matching object, or `nil` if no objects match. + - parameter predicate: The predicate with which to filter the objects. */ - public func indexOfObject(for predicate: NSPredicate) -> Int? { + public func index(matching predicate: NSPredicate) -> Int? { return notFoundToNil(index: _rlmArray.indexOfObject(with: predicate)) } /** - Returns the index of the first object matching the given predicate, - or `nil` if no objects match. - - - parameter predicateFormat: The predicate format string, optionally - followed by a variable number of arguments. + Returns the index of the first object in the list matching the predicate, or `nil` if no objects match. - - returns: The index of the first matching object, or `nil` if no objects match. + - parameter predicateFormat: A predicate format string, optionally followed by a variable number of arguments. */ - public func indexOfObject(for predicateFormat: String, _ args: Any...) -> Int? { - return indexOfObject(for: NSPredicate(format: predicateFormat, argumentArray: args)) + public func index(matching predicateFormat: String, _ args: Any...) -> Int? { + return index(matching: NSPredicate(format: predicateFormat, argumentArray: args)) } // MARK: Object Retrieval /** - Returns the object at the given `index` on get. - Replaces the object at the given `index` on set. - - - warning: You can only set an object during a write transaction. + Returns the object at the given index (get), or replaces the object at the given index (set). - - parameter index: The index. + - warning: You can only set an object during a write transaction. - - returns: The object at the given `index`. - */ + - parameter index: The index of the object to retrieve or replace. + */ public subscript(position: Int) -> T { get { throwForNegativeIndex(position) @@ -139,45 +129,39 @@ public final class List: ListBase { } } - /// Returns the first object in the List, or `nil` if empty. + /// Returns the first object in the list, or `nil` if the list is empty. public var first: T? { return _rlmArray.firstObject() as! T? } - /// Returns the last object in the List, or `nil` if empty. + /// Returns the last object in the list, or `nil` if the list is empty. public var last: T? { return _rlmArray.lastObject() as! T? } // MARK: KVC /** - Returns an Array containing the results of invoking `valueForKey(_:)` using key on each of the collection's objects. - - - parameter key: The name of the property. - - - returns: Array containing the results of invoking `valueForKey(_:)` using key on each of the collection's objects. + Returns an `Array` containing the results of invoking `valueForKey(_:)` using `key` on each of the collection's + objects. */ public override func value(forKey key: String) -> Any? { return value(forKeyPath: key) } /** - Returns an Array containing the results of invoking `valueForKeyPath(_:)` using keyPath on each of the + Returns an `Array` containing the results of invoking `valueForKeyPath(_:)` using `keyPath` on each of the collection's objects. - - parameter keyPath: The key path to the property. - - - returns: Array containing the results of invoking `valueForKeyPath(_:)` using keyPath on each of the - collection's objects. + - parameter keyPath: The key path to the property whose values are desired. */ public override func value(forKeyPath keyPath: String) -> Any? { return _rlmArray.value(forKeyPath: keyPath) } /** - Invokes `setValue(_:forKey:)` on each of the collection's objects using the specified value and key. + Invokes `setValue(_:forKey:)` on each of the collection's objects using the specified `value` and `key`. - - warning: This method can only be called during a write transaction. + - warning: This method can only be called during a write transaction. - - parameter value: The object value. - - parameter key: The name of the property. + - parameter value: The object value. + - parameter key: The name of the property whose value should be set on each object. */ public override func setValue(_ value: Any?, forKey key: String) { return _rlmArray.setValue(value, forKeyPath: key) @@ -186,126 +170,122 @@ public final class List: ListBase { // MARK: Filtering /** - Returns `Results` containing elements that match the given predicate. - - - parameter predicateFormat: The predicate format string which can accept variable arguments. + Returns a `Results` containing all objects matching the given predicate in the list. - - returns: `Results` containing elements that match the given predicate. + - parameter predicateFormat: A predicate format string, optionally followed by a variable number of arguments. */ - public func filter(using predicateFormat: String, _ args: Any...) -> Results { + public func filter(_ predicateFormat: String, _ args: Any...) -> Results { return Results(_rlmArray.objects(with: NSPredicate(format: predicateFormat, argumentArray: args))) } /** - Returns `Results` containing elements that match the given predicate. - - - parameter predicate: The predicate to filter the objects. + Returns a `Results` containing all objects matching the given predicate in the list. - - returns: `Results` containing elements that match the given predicate. - */ - public func filter(using predicate: NSPredicate) -> Results { + - parameter predicate: The predicate with which to filter the objects. + */ + public func filter(_ predicate: NSPredicate) -> Results { return Results(_rlmArray.objects(with: predicate)) } // MARK: Sorting /** - Returns `Results` containing elements sorted by the given property. + Returns a `Results` containing the objects in the list, but sorted. - - parameter property: The property name to sort by. - - parameter ascending: The direction to sort by. + Objects are sorted based on the values of the given property. For example, to sort a list of `Student`s from + youngest to oldest based on their `age` property, you might call + `students.sorted(byProperty: "age", ascending: true)`. - - returns: `Results` containing elements sorted by the given property. - */ - public func sorted(onProperty property: String, ascending: Bool = true) -> Results { - return sorted(with: [SortDescriptor(property: property, ascending: ascending)]) + - warning: Lists may only be sorted by properties of boolean, `Date`, `NSDate`, single and double-precision + floating point, integer, and string types. + + - parameter property: The name of the property to sort by. + - parameter ascending: The direction to sort in. + */ + public func sorted(byProperty property: String, ascending: Bool = true) -> Results { + return sorted(by: [SortDescriptor(property: property, ascending: ascending)]) } /** - Returns `Results` with elements sorted by the given sort descriptors. + Returns a `Results` containing the objects in the list, but sorted. - - parameter sortDescriptors: `SortDescriptor`s to sort by. + - warning: Lists may only be sorted by properties of boolean, `Date`, `NSDate`, single and double-precision + floating point, integer, and string types. - - returns: `Results` with elements sorted by the given sort descriptors. + - see: `sorted(byProperty:ascending:)` */ - public func sorted(with sortDescriptors: S) -> Results where S.Iterator.Element == SortDescriptor { + public func sorted(by sortDescriptors: S) -> Results where S.Iterator.Element == SortDescriptor { return Results(_rlmArray.sortedResults(using: sortDescriptors.map { $0.rlmSortDescriptorValue })) } // MARK: Aggregate Operations /** - Returns the minimum value of the given property. - - - warning: Only names of properties of a type conforming to the `MinMaxType` protocol can be used. + Returns the minimum (lowest) value of the given property among all the objects in the list, or `nil` if the list is + empty. - - parameter property: The name of a property conforming to `MinMaxType` to look for a minimum on. + - warning: Only a property whose type conforms to the `MinMaxType` protocol can be specified. - - returns: The minimum value for the property amongst objects in the List, or `nil` if the List is empty. - */ - public func minimumValue(ofProperty property: String) -> U? { - return filter(using: NSPredicate(value: true)).minimumValue(ofProperty: property) + - parameter property: The name of a property whose minimum value is desired. + */ + public func min(ofProperty property: String) -> U? { + return filter(NSPredicate(value: true)).min(ofProperty: property) } /** - Returns the maximum value of the given property. + Returns the maximum (highest) value of the given property among all the objects in the list, or `nil` if the list + is empty. - - warning: Only names of properties of a type conforming to the `MinMaxType` protocol can be used. - - - parameter property: The name of a property conforming to `MinMaxType` to look for a maximum on. + - warning: Only a property whose type conforms to the `MinMaxType` protocol can be specified. - - returns: The maximum value for the property amongst objects in the List, or `nil` if the List is empty. - */ - public func maximumValue(ofProperty property: String) -> U? { - return filter(using: NSPredicate(value: true)).maximumValue(ofProperty: property) + - parameter property: The name of a property whose maximum value is desired. + */ + public func max(ofProperty property: String) -> U? { + return filter(NSPredicate(value: true)).max(ofProperty: property) } /** - Returns the sum of the given property for objects in the List. - - - warning: Only names of properties of a type conforming to the `AddableType` protocol can be used. + Returns the sum of the values of a given property over all the objects in the list. - - parameter property: The name of a property conforming to `AddableType` to calculate sum on. + - warning: Only a property whose type conforms to the `AddableType` protocol can be specified. - - returns: The sum of the given property over all objects in the List. - */ + - parameter property: The name of a property whose values should be summed. + */ public func sum(ofProperty property: String) -> U { - return filter(using: NSPredicate(value: true)).sum(ofProperty: property) + return filter(NSPredicate(value: true)).sum(ofProperty: property) } /** - Returns the average of the given property for objects in the List. + Returns the average value of a given property over all the objects in the list, or `nil` if the list is empty. - - warning: Only names of properties of a type conforming to the `AddableType` protocol can be used. - - - parameter property: The name of a property conforming to `AddableType` to calculate average on. + - warning: Only a property whose type conforms to the `AddableType` protocol can be specified. - - returns: The average of the given property over all objects in the List, or `nil` if the List is empty. - */ + - parameter property: The name of a property whose average value should be calculated. + */ public func average(ofProperty property: String) -> U? { - return filter(using: NSPredicate(value: true)).average(ofProperty: property) + return filter(NSPredicate(value: true)).average(ofProperty: property) } // MARK: Mutation /** - Appends the given object to the end of the List. If the object is from a - different Realm it is copied to the List's Realm. + Appends the given object to the end of the list. + + If the object is managed by a different Realm than the receiver, a copy is made and added to the Realm managing + the receiver. - - warning: This method can only be called during a write transaction. + - warning: This method may only be called during a write transaction. - - parameter object: An object. - */ + - parameter object: An object. + */ public func append(_ object: T) { _rlmArray.add(object.unsafeCastToRLMObject()) } /** - Appends the objects in the given sequence to the end of the List. - - - warning: This method can only be called during a write transaction. + Appends the objects in the given sequence to the end of the list. - - parameter objects: A sequence of objects. + - warning: This method may only be called during a write transaction. */ public func append(objectsIn objects: S) where S.Iterator.Element == T { for obj in objects { @@ -314,77 +294,77 @@ public final class List: ListBase { } /** - Inserts the given object at the given index. + Inserts an object at the given index. - - warning: This method can only be called during a write transaction. - - warning: Throws an exception when called with an index smaller than zero - or greater than or equal to the number of objects in the List. + - warning: This method may only be called during a write transaction. - - parameter object: An object. - - parameter index: The index at which to insert the object. - */ + - warning: This method will throw an exception if called with an invalid index. + + - parameter object: An object. + - parameter index: The index at which to insert the object. + */ public func insert(_ object: T, at index: Int) { throwForNegativeIndex(index) _rlmArray.insert(object.unsafeCastToRLMObject(), at: UInt(index)) } /** - Removes the object at the given index from the List. Does not remove the object from the Realm. + Removes an object at the given index. The object is not removed from the Realm that manages it. - - warning: This method can only be called during a write transaction. - - warning: Throws an exception when called with an index smaller than zero - or greater than or equal to the number of objects in the List. + - warning: This method may only be called during a write transaction. - - parameter index: The index at which to remove the object. - */ + - warning: This method will throw an exception if called with an invalid index. + + - parameter index: The index at which to remove the object. + */ public func remove(objectAtIndex index: Int) { throwForNegativeIndex(index) _rlmArray.removeObject(at: UInt(index)) } /** - Removes the last object in the List. Does not remove the object from the Realm. + Removes the last object in the list. The object is not removed from the Realm that manages it. - - warning: This method can only be called during a write transaction. - */ - public func removeLastObject() { + - warning: This method may only be called during a write transaction. + */ + public func removeLast() { _rlmArray.removeLastObject() } /** - Removes all objects from the List. Does not remove the objects from the Realm. + Removes all objects from the list. The objects are not removed from the Realm that manages them. - - warning: This method can only be called during a write transaction. - */ - public func removeAllObjects() { + - warning: This method may only be called during a write transaction. + */ + public func removeAll() { _rlmArray.removeAllObjects() } /** - Replaces an object at the given index with a new object. + Replaces an object at the given index with a new object. - - warning: This method can only be called during a write transaction. - - warning: Throws an exception when called with an index smaller than zero - or greater than or equal to the number of objects in the List. + - warning: This method may only be called during a write transaction. - - parameter index: The index of the object to be replaced. - - parameter object: An object to replace at the specified index. - */ + - warning: This method will throw an exception if called with an invalid index. + + - parameter index: The index of the object to be replaced. + - parameter object: An object. + */ public func replace(index: Int, object: T) { throwForNegativeIndex(index) _rlmArray.replaceObject(at: UInt(index), with: object.unsafeCastToRLMObject()) } /** - Moves the object at the given source index to the given destination index. + Moves the object at the given source index to the given destination index. - - warning: This method can only be called during a write transaction. - - warning: Throws an exception when called with an index smaller than zero or greater than - or equal to the number of objects in the List. + - warning: This method may only be called during a write transaction. - - parameter from: The index of the object to be moved. - - parameter to: index to which the object at `from` should be moved. - */ + - warning: This method will throw an exception if called with invalid indices. + + - parameter from: The index of the object to be moved. + - parameter to: index to which the object at `from` should be moved. + */ public func move(from: Int, to: Int) { // swiftlint:disable:this variable_name throwForNegativeIndex(from) throwForNegativeIndex(to) @@ -392,14 +372,15 @@ public final class List: ListBase { } /** - Exchanges the objects in the List at given indexes. + Exchanges the objects in the list at given indices. - - warning: Throws an exception when either index exceeds the bounds of the List. - - warning: This method can only be called during a write transaction. + - warning: This method may only be called during a write transaction. - - parameter index1: The index of the object with which to replace the object at index `index2`. - - parameter index2: The index of the object with which to replace the object at index `index1`. - */ + - warning: This method will throw an exception if called with invalid indices. + + - parameter index1: The index of the object which should replace the object at index `index2`. + - parameter index2: The index of the object which should replace the object at index `index1`. + */ public func swap(index1: Int, _ index2: Int) { throwForNegativeIndex(index1, parameterName: "index1") throwForNegativeIndex(index2, parameterName: "index2") @@ -409,66 +390,61 @@ public final class List: ListBase { // MARK: Notifications /** - Register a block to be called each time the List changes. - - The block will be asynchronously called with the initial list, and then - called again after each write transaction which changes the list or any of - the items in the list. - - This version of this method reports which of the objects in the List were - added, removed, or modified in each write transaction as indices within the - List. See the RealmCollectionChange documentation for more information on - the change information supplied and an example of how to use it to update - a UITableView. - - The block is called on the same thread as it was added on, and can only - be added on threads which are currently within a run loop. Unless you are - specifically creating and running a run loop on a background thread, this - will normally only be the main thread. - - Notifications can't be delivered as long as the run loop is blocked by - other activity. When notifications can't be delivered instantly, multiple - notifications may be coalesced into a single notification. This can include - the notification with the initial list. For example, the following code - performs a write transaction immediately after adding the notification block, - so there is no opportunity for the initial notification to be delivered first. - As a result, the initial notification will reflect the state of the Realm - after the write transaction, and will not include change information. - - let person = realm.objects(Person).first! - print("dogs.count: \(person.dogs.count)") // => 0 - let token = person.dogs.addNotificationBlock { (changes: RealmCollectionChange) in - switch changes { - case .Initial(let dogs): - // Will print "dogs.count: 1" - print("dogs.count: \(dogs.count)") - break - case .Update: - // Will not be hit in this example - break - case .Error: - break - } - } - try! realm.write { - let dog = Dog() - dog.name = "Rex" - person.dogs.append(dog) - } - // end of run loop execution context + Registers a block to be called each time the collection changes. - You must retain the returned token for as long as you want updates to continue - to be sent to the block. To stop receiving updates, call stop() on the token. + The block will be asynchronously called with the initial results, and then called again after each write + transaction which changes either any of the objects in the collection, or which objects are in the collection. - - warning: This method cannot be called during a write transaction, or when - the source realm is read-only. - - warning: This method can only be called on Lists which are stored on an - Object which has been added to or retrieved from a Realm. + The `change` parameter that is passed to the block reports, in the form of indices within the collection, which of + the objects were added, removed, or modified during each write transaction. See the `RealmCollectionChange` + documentation for more information on the change information supplied and an example of how to use it to update a + `UITableView`. - - parameter block: The block to be called each time the list changes. - - returns: A token which must be held for as long as you want notifications to be delivered. - */ - public func addNotificationBlock(block: @escaping (RealmCollectionChange) -> ()) -> NotificationToken { + At the time when the block is called, the collection will be fully evaluated and up-to-date, and as long as you do + not perform a write transaction on the same thread or explicitly call `realm.refresh()`, accessing it will never + perform blocking work. + + Notifications are delivered via the standard run loop, and so can't be delivered while the run loop is blocked by + other activity. When notifications can't be delivered instantly, multiple notifications may be coalesced into a + single notification. This can include the notification with the initial collection. + + For example, the following code performs a write transaction immediately after adding the notification block, so + there is no opportunity for the initial notification to be delivered first. As a result, the initial notification + will reflect the state of the Realm after the write transaction. + + ```swift + let results = realm.objects(Dog.self) + print("dogs.count: \(dogs?.count)") // => 0 + let token = dogs.addNotificationBlock { changes in + switch changes { + case .initial(let dogs): + // Will print "dogs.count: 1" + print("dogs.count: \(dogs.count)") + break + case .update: + // Will not be hit in this example + break + case .error: + break + } + } + try! realm.write { + let dog = Dog() + dog.name = "Rex" + person.dogs.append(dog) + } + // end of run loop execution context + ``` + + You must retain the returned token for as long as you want updates to be sent to the block. To stop receiving + updates, call `stop()` on the token. + + - warning: This method cannot be called during a write transaction, or when the containing Realm is read-only. + + - parameter block: The block to be called whenever a change occurs. + - returns: A token which must be held for as long as you want updates to be delivered. + */ + public func addNotificationBlock(_ block: @escaping (RealmCollectionChange) -> ()) -> NotificationToken { return _rlmArray.addNotificationBlock { list, change, error in block(RealmCollectionChange.fromObjc(value: self, change: change, error: error)) } @@ -486,12 +462,12 @@ extension List : RealmCollection, RangeReplaceableCollection { // MARK: RangeReplaceableCollection Support /** - Replace the given `subRange` of elements with `newElements`. + Replace the given `subRange` of elements with `newElements`. - parameter subRange: The range of elements to be replaced. - parameter newElements: The new elements to be inserted into the List. */ - public func replaceSubrange(_ subrange: Range, with newElements: C) + public func replaceSubrange(_ subrange: Range, with newElements: C) where C.Iterator.Element == T { for _ in subrange.lowerBound.. Int { return i - 1 } /// :nodoc: - public func _addNotificationBlock(block: @escaping (RealmCollectionChange>) -> Void) -> + public func _addNotificationBlock(_ block: @escaping (RealmCollectionChange>) -> Void) -> NotificationToken { let anyCollection = AnyRealmCollection(self) return _rlmArray.addNotificationBlock { _, change, error in @@ -526,51 +502,39 @@ extension List : RealmCollection, RangeReplaceableCollection { // MARK: Unavailable extension List { - @available(*, unavailable, renamed:"append(objectsIn:)") + @available(*, unavailable, renamed: "append(objectsIn:)") public func appendContentsOf(_ objects: S) where S.Iterator.Element == T { fatalError() } - @available(*, unavailable, renamed:"removeAllObjects()") - public func removeAll() { } - - @available(*, unavailable, renamed:"removeLastObject()") - public func removeLast() { } - @available(*, unavailable, renamed: "remove(objectAtIndex:)") - public func remove(at index: Int) { } + public func remove(at index: Int) { fatalError() } - @available(*, unavailable, renamed:"isInvalidated") - public var invalidated : Bool { fatalError() } + @available(*, unavailable, renamed: "isInvalidated") + public var invalidated: Bool { fatalError() } - @available(*, unavailable, renamed:"indexOfObject(for:)") + @available(*, unavailable, renamed: "index(matching:)") public func index(of predicate: NSPredicate) -> Int? { fatalError() } - @available(*, unavailable, renamed:"indexOfObject(for:_:)") + @available(*, unavailable, renamed: "index(matching:_:)") public func index(of predicateFormat: String, _ args: Any...) -> Int? { fatalError() } - @available(*, unavailable, renamed:"filter(using:)") - public func filter(_ predicate: NSPredicate) -> Results { fatalError() } - - @available(*, unavailable, renamed:"filter(using:_:)") - public func filter(_ predicateFormat: String, _ args: Any...) -> Results { fatalError() } - - @available(*, unavailable, renamed:"sorted(onProperty:ascending:)") + @available(*, unavailable, renamed: "sorted(byProperty:ascending:)") public func sorted(_ property: String, ascending: Bool = true) -> Results { fatalError() } - @available(*, unavailable, renamed:"sorted(with:)") + @available(*, unavailable, renamed: "sorted(by:)") public func sorted(_ sortDescriptors: S) -> Results where S.Iterator.Element == SortDescriptor { fatalError() } - @available(*, unavailable, renamed:"minimumValue(ofProperty:)") + @available(*, unavailable, renamed: "min(ofProperty:)") public func min(_ property: String) -> U? { fatalError() } - @available(*, unavailable, renamed:"maximumValue(ofProperty:)") + @available(*, unavailable, renamed: "max(ofProperty:)") public func max(_ property: String) -> U? { fatalError() } - @available(*, unavailable, renamed:"sum(ofProperty:)") + @available(*, unavailable, renamed: "sum(ofProperty:)") public func sum(_ property: String) -> U { fatalError() } - @available(*, unavailable, renamed:"average(ofProperty:)") + @available(*, unavailable, renamed: "average(ofProperty:)") public func average(_ property: String) -> U? { fatalError() } } @@ -671,8 +635,6 @@ public final class List: ListBase { - warning: You can only set an object during a write transaction. - parameter index: The index of the object to retrieve or replace. - - - returns: The object at the given index. */ public subscript(index: Int) -> T { get { @@ -730,7 +692,7 @@ public final class List: ListBase { /** Returns a `Results` containing all objects matching the given predicate in the list. - - parameter predicateFormat: A predicate format string; variable arguments are supported. + - parameter predicateFormat: A predicate format string, optionally followed by a variable number of arguments. */ public func filter(predicateFormat: String, _ args: AnyObject...) -> Results { return Results(_rlmArray.objectsWithPredicate(NSPredicate(format: predicateFormat, argumentArray: args))) @@ -780,26 +742,24 @@ public final class List: ListBase { // MARK: Aggregate Operations /** - Returns the minimum (lowest) value of the given property among all the objects in the list. + Returns the minimum (lowest) value of the given property among all the objects in the list, or `nil` if the list is + empty. - - warning: Only a property whose type conforms to the `MinMaxType` protocol can be specified. - - - parameter property: The name of a property whose minimum value is desired. + - warning: Only a property whose type conforms to the `MinMaxType` protocol can be specified. - - returns: The minimum value of the property, or `nil` if the list is empty. - */ + - parameter property: The name of a property whose minimum value is desired. + */ public func min(property: String) -> U? { return filter(NSPredicate(value: true)).min(property) } /** - Returns the maximum (highest) value of the given property among all the objects in the list. + Returns the maximum (highest) value of the given property among all the objects in the list, or `nil` if the list + is empty. - warning: Only a property whose type conforms to the `MinMaxType` protocol can be specified. - parameter property: The name of a property whose maximum value is desired. - - - returns: The maximum value of the property, or `nil` if the list is empty. */ public func max(property: String) -> U? { return filter(NSPredicate(value: true)).max(property) @@ -811,21 +771,17 @@ public final class List: ListBase { - warning: Only a property whose type conforms to the `AddableType` protocol can be specified. - parameter property: The name of a property whose values should be summed. - - - returns: The sum of the given property. */ public func sum(property: String) -> U { return filter(NSPredicate(value: true)).sum(property) } /** - Returns the average value of a given property over all the objects in the list. + Returns the average value of a given property over all the objects in the list, or `nil` if the list is empty. - warning: Only a property whose type conforms to the `AddableType` protocol can be specified. - parameter property: The name of a property whose average value should be calculated. - - - returns: The average value of the given property, or `nil` if the list is empty. */ public func average(property: String) -> U? { return filter(NSPredicate(value: true)).average(property) @@ -976,11 +932,11 @@ public final class List: ListBase { Notifications can't be delivered as long as the run loop is blocked by other activity. When notifications can't be delivered instantly, multiple notifications may be coalesced into a single notification. This can include - the notification with the initial list. For example, the following code - performs a write transaction immediately after adding the notification block, - so there is no opportunity for the initial notification to be delivered first. - As a result, the initial notification will reflect the state of the Realm - after the write transaction, and will not include change information. + the notification with the initial list. + + For example, the following code performs a write transaction immediately after adding the notification block, so + there is no opportunity for the initial notification to be delivered first. As a result, the initial notification + will reflect the state of the Realm after the write transaction, and will not include change information. ```swift let person = realm.objects(Person.self).first! @@ -1009,8 +965,7 @@ public final class List: ListBase { You must retain the returned token for as long as you want updates to be sent to the block. To stop receiving updates, call `stop()` on the token. - - warning: This method cannot be called during a write transaction, or when - the containing Realm is read-only. + - warning: This method cannot be called during a write transaction, or when the containing Realm is read-only. - warning: This method may only be called on a managed list. - parameter block: The block to be called each time the list changes. diff --git a/RealmSwift/Migration.swift b/RealmSwift/Migration.swift index da3bdf683b..924466ba75 100644 --- a/RealmSwift/Migration.swift +++ b/RealmSwift/Migration.swift @@ -23,37 +23,35 @@ import Realm.Private #if swift(>=3.0) /** -Migration block used to migrate a Realm. + The type of a migration block used to migrate a Realm. -- parameter migration: `Migration` object used to perform the migration. The - migration object allows you to enumerate and alter any - existing objects which require migration. -- parameter oldSchemaVersion: The schema version of the `Realm` being migrated. -*/ + - parameter migration: A `Migration` object used to perform the migration. The migration object allows you to + enumerate and alter any existing objects which require migration. + + - parameter oldSchemaVersion: The schema version of the Realm being migrated. + */ public typealias MigrationBlock = (_ migration: Migration, _ oldSchemaVersion: UInt64) -> Void -/// Object class used during migrations. +/// An object class used during migrations. public typealias MigrationObject = DynamicObject /** -Provides both the old and new versions of an object in this Realm. Object properties can only be -accessed using subscripting. + A block type which provides both the old and new versions of an object in the Realm. Object + properties can only be accessed using subscripting. -- parameter oldObject: Object in original `Realm` (read-only). -- parameter newObject: Object in migrated `Realm` (read-write). -*/ + - parameter oldObject: The object from the original Realm (read-only). + - parameter newObject: The object from the migrated Realm (read-write). + */ public typealias MigrationObjectEnumerateBlock = (_ oldObject: MigrationObject?, _ newObject: MigrationObject?) -> Void /** -Get the schema version for a Realm at a given local URL. - -- parameter fileURL: Local URL to a Realm file. -- parameter encryptionKey: Optional 64-byte encryption key for encrypted Realms. + Returns the schema version for a Realm at a given local URL. -- throws: An NSError that describes the problem. + - parameter fileURL: Local URL to a Realm file. + - parameter encryptionKey: 64-byte key used to encrypt the file, or `nil` if it is unencrypted. -- returns: The version of the Realm at `fileURL`. -*/ + - throws: An `NSError` that describes the problem. + */ public func schemaVersionAtURL(_ fileURL: URL, encryptionKey: Data? = nil) throws -> UInt64 { var error: NSError? let version = RLMRealm.__schemaVersion(at: fileURL, encryptionKey: encryptionKey, error: &error) @@ -67,13 +65,10 @@ extension Realm { /** Performs the given Realm configuration's migration block on a Realm at the given path. - This method is called automatically when opening a Realm for the first time and does - not need to be called explicitly. You can choose to call this method to control - exactly when and how migrations are performed. + This method is called automatically when opening a Realm for the first time and does not need to be called + explicitly. You can choose to call this method to control exactly when and how migrations are performed. - parameter configuration: The Realm configuration used to open and migrate the Realm. - - - throws: An `NSError` that describes an error that occurred while applying the migration, if any. */ public static func performMigration(for configuration: Realm.Configuration = Realm.Configuration.defaultConfiguration) throws { try RLMRealm.performMigration(for: configuration.rlmConfiguration) @@ -81,19 +76,20 @@ extension Realm { } /** -`Migration` is the object passed into a user-defined `MigrationBlock` when updating the version -of a `Realm` instance. + `Migration` instances encapsulate information intended to facilitate a schema migration. -This object provides access to the previous and current `Schema`s for this migration. -*/ + A `Migration` instance is passed into a user-defined `MigrationBlock` block when updating the version of a Realm. This + instance provides access to the old and new database schemas, the objects in the Realm, and provides functionality for + modifying the Realm during the migration. + */ public final class Migration { // MARK: Properties - /// The migration's old `Schema`, describing the `Realm` before applying a migration. + /// The old schema, describing the Realm before applying a migration. public var oldSchema: Schema { return Schema(rlmMigration.oldSchema) } - /// The migration's new `Schema`, describing the `Realm` after applying a migration. + /// The new schema, describing the Realm after applying a migration. public var newSchema: Schema { return Schema(rlmMigration.newSchema) } internal var rlmMigration: RLMMigration @@ -101,12 +97,12 @@ public final class Migration { // MARK: Altering Objects During a Migration /** - Enumerates objects of a given type in this Realm, providing both the old and new versions of - each object. Object properties can be accessed using subscripting. + Enumerates all the objects of a given type in this Realm, providing both the old and new versions of each object. + Properties on an object can be accessed using subscripting. - - parameter objectClassName: The name of the `Object` class to enumerate. - - parameter block: The block providing both the old and new versions of an object in this Realm. - */ + - parameter objectClassName: The name of the `Object` class to enumerate. + - parameter block: The block providing both the old and new versions of an object in this Realm. + */ public func enumerateObjects(ofType typeName: String, _ block: MigrationObjectEnumerateBlock) { rlmMigration.enumerateObjects(typeName) { oldObject, newObject in block(unsafeBitCast(oldObject, to: MigrationObject.self), @@ -115,56 +111,62 @@ public final class Migration { } /** - Create an `Object` of type `className` in the Realm being migrated. + Creates and returns an `Object` of type `className` in the Realm being migrated. + + The `value` argument is used to populate the object. It can be a key-value coding compliant object, an array or + dictionary returned from the methods in `NSJSONSerialization`, or an `Array` containing one element for each + managed property. An exception will be thrown if any required properties are not present and those properties were + not defined with default values. + + When passing in an `Array` as the `value` argument, all properties must be present, valid and in the same order as + the properties defined in the model. - - parameter className: The name of the `Object` class to create. - - parameter value: The object used to populate the new `Object`. This can be any key/value coding - compliant object, or a JSON object such as those returned from the methods in - `NSJSONSerialization`, or an `Array` with one object for each persisted - property. An exception will be thrown if any required properties are not - present and no default is set. + - parameter className: The name of the `Object` class to create. + - parameter value: The value used to populate the created object. - - returns: The created object. - */ + - returns: The newly created object. + */ @discardableResult - public func createObject(ofType typeName: String, populatedWith value: Any = [:]) -> MigrationObject { + public func create(_ typeName: String, value: Any = [:]) -> MigrationObject { return unsafeBitCast(rlmMigration.createObject(typeName, withValue: value), to: MigrationObject.self) } /** - Delete an object from a Realm during a migration. This can be called within - `enumerate(_:block:)`. + Deletes an object from a Realm during a migration. - - parameter object: Object to be deleted from the Realm being migrated. - */ + It is permitted to call this method from within the block passed to `enumerate(_:block:)`. + + - parameter object: An object to be deleted from the Realm being migrated. + */ public func delete(_ object: MigrationObject) { RLMDeleteObjectFromRealm(object, RLMObjectBaseRealm(object)!) } /** - Deletes the data for the class with the given name. - This deletes all objects of the given class, and if the Object subclass no longer exists in your program, - cleans up any remaining metadata for the class in the Realm file. + Deletes the data for the class with the given name. - - parameter objectClassName: The name of the Object class to delete. + All objects of the given class will be deleted. If the `Object` subclass no longer exists in your program, any + remaining metadata for the class will be removed from the Realm file. - - returns: `true` if there was any data to delete. - */ + - parameter objectClassName: The name of the `Object` class to delete. + + - returns: A Boolean value indicating whether there was any data to delete. + */ @discardableResult public func deleteData(forType typeName: String) -> Bool { return rlmMigration.deleteData(forClassName: typeName) } /** - Rename property of the given class from `oldName` to `newName`. - - - parameter className: Class for which the property is to be renamed. Must be present - in both the old and new Realm schemas. - - parameter oldName: Old name for the property to be renamed. Must not be present - in the new Realm. - - parameter newName: New name for the property to be renamed. Must not be present - in the old Realm. - */ + Renames a property of the given class from `oldName` to `newName`. + + - parameter className: The name of the class whose property should be renamed. This class must be present + in both the old and new Realm schemas. + - parameter oldName: The old name for the property to be renamed. There must not be a property with this name in + the class as defined by the new Realm schema. + - parameter newName: The new name for the property to be renamed. There must not be a property with this name in + the class as defined by the old Realm schema. + */ public func renameProperty(onType typeName: String, from oldName: String, to newName: String) { rlmMigration.renameProperty(forClass: typeName, oldName: oldName, newName: newName) } @@ -199,21 +201,16 @@ internal func accessorMigrationBlock(_ migrationBlock: @escaping MigrationBlock) // MARK: Unavailable extension Migration { - @available(*, unavailable, renamed:"enumerateObjects(ofType:_:)") - public func enumerate(_ objectClassName: String, _ block: MigrationObjectEnumerateBlock) { } - - @available(*, unavailable, renamed:"createObject(ofType:populatedWith:)") - public func create(_ className: String, value: Any = [:]) -> MigrationObject { - fatalError() - } + @available(*, unavailable, renamed: "enumerateObjects(ofType:_:)") + public func enumerate(_ objectClassName: String, _ block: MigrationObjectEnumerateBlock) { fatalError() } - @available(*, unavailable, renamed:"deleteData(forType:)") + @available(*, unavailable, renamed: "deleteData(forType:)") public func deleteData(_ objectClassName: String) -> Bool { fatalError() } @available(*, unavailable, renamed: "renameProperty(onType:from:to:)") - public func renamePropertyForClass(_ className: String, oldName: String, newName: String) { } + public func renamePropertyForClass(_ className: String, oldName: String, newName: String) { fatalError() } } #else @@ -221,7 +218,7 @@ extension Migration { /** The type of a migration block used to migrate a Realm. - - parameter migration: A `RLMMigration` object used to perform the migration. The + - parameter migration: A `Migration` object used to perform the migration. The migration object allows you to enumerate and alter any existing objects which require migration. @@ -322,7 +319,7 @@ public final class Migration { /** Enumerates all the objects of a given type in this Realm, providing both the old and new versions of - each object. Object properties can be accessed using subscripting. + each object. Properties on an object can be accessed using subscripting. - parameter objectClassName: The name of the `Object` class to enumerate. - parameter block: The block providing both the old and new versions of an object in this Realm. diff --git a/RealmSwift/Object.swift b/RealmSwift/Object.swift index 49ff486c3d..2d98102092 100644 --- a/RealmSwift/Object.swift +++ b/RealmSwift/Object.swift @@ -23,75 +23,82 @@ import Realm.Private #if swift(>=3.0) /** -In Realm you define your model classes by subclassing `Object` and adding properties to be persisted. -You then instantiate and use your custom subclasses instead of using the Object class directly. - -```swift -class Dog: Object { - dynamic var name: String = "" - dynamic var adopted: Bool = false - let siblings = List() -} -``` + `Object` is a class used to define Realm model objects. + + In Realm you define your model classes by subclassing `Object` and adding properties to be managed. + You then instantiate and use your custom subclasses instead of using the `Object` class directly. + + ```swift + class Dog: Object { + dynamic var name: String = "" + dynamic var adopted: Bool = false + let siblings = List() + } + ``` + + ### Supported property types -### Supported property types + - `String`, `NSString` + - `Int` + - `Int8`, `Int16`, `Int32`, `Int64` + - `Float` + - `Double` + - `Bool` + - `Date`, `NSDate` + - `Data`, `NSData` + - `RealmOptional` for optional numeric properties + - `Object` subclasses, to model many-to-one relationships + - `List`, to model many-to-many relationships -- `String`, `NSString` -- `Int` -- `Int8`, `Int16`, `Int32`, `Int64` -- `Float` -- `Double` -- `Bool` -- `Date`, `NSDate` -- `Data`, `NSData` -- `RealmOptional` for optional numeric properties -- `Object` subclasses for to-one relationships -- `List` for to-many relationships + `String`, `NSString`, `Date`, `NSDate`, `Data`, `NSData` and `Object` subclass properties can be declared as optional. + `Int`, `Int8`, `Int16`, Int32`, `Int64`, `Float`, `Double`, `Bool`, and `List` properties cannot. To store an optional + number, use `RealmOptional`, `RealmOptional`, `RealmOptional`, or `RealmOptional` instead, + which wraps an optional numeric value. -`String`, `NSString`, `Date`, `NSDate`, `Data`, `NSData` and `Object` subclass properties -can be optional. `Int`, `Int8`, Int16`, Int32`, `Int64`, `Float`, `Double`, `Bool` -and `List` properties cannot. To store an optional number, instead use -`RealmOptional`, `RealmOptional`, `RealmOptional`, or -`RealmOptional` instead, which wraps an optional value of the generic type. + All property types except for `List` and `RealmOptional` *must* be declared as `dynamic var`. `List` and + `RealmOptional` properties must be declared as non-dynamic `let` properties. Swift `lazy` properties are not allowed. -All property types except for `List` and `RealmOptional` *must* be declared as -`dynamic var`. `List` and `RealmOptional` properties must be declared as -non-dynamic `let` properties. + Note that none of the restrictions listed above apply to properties that are configured to be ignored by Realm. -### Querying + ### Querying -You can gets `Results` of an Object subclass via the `objects(_:)` instance -method on `Realm`. + You can retrieve all objects of a given type from a Realm by calling the `objects(_:)` instance method. -### Relationships + ### Relationships -See our [Cocoa guide](http://realm.io/docs/cocoa) for more details. -*/ + See our [Cocoa guide](http://realm.io/docs/cocoa) for more details. + */ @objc(RealmSwiftObject) open class Object: RLMObjectBase { // MARK: Initializers /** - Initialize a standalone (unpersisted) `Object`. - Call `add(_:)` on a `Realm` to add standalone objects to a realm. + Creates an unmanaged instance of a Realm object. - - see: Realm().add(_:) - */ + Call `add(_:)` on a `Realm` instance to add an unmanaged object into that Realm. + + - see: `Realm().add(_:)` + */ public override required init() { super.init() } /** - Initialize a standalone (unpersisted) `Object` with values from an `Array` or - `Dictionary`. - Call `add(_:)` on a `Realm` to add standalone objects to a realm. - - - parameter value: The value used to populate the object. This can be any key/value coding compliant - object, or a JSON object such as those returned from the methods in `NSJSONSerialization`, - or an `Array` with one object for each persisted property. An exception will be - thrown if any required properties are not present and no default is set. - */ + Creates an unmanaged instance of a Realm object. + + The `value` argument is used to populate the object. It can be a key-value coding compliant object, an array or + dictionary returned from the methods in `NSJSONSerialization`, or an `Array` containing one element for each + managed property. An exception will be thrown if any required properties are not present and those properties were + not defined with default values. + + When passing in an `Array` as the `value` argument, all properties must be present, valid and in the same order as + the properties defined in the model. + + Call `add(_:)` on a `Realm` instance to add an unmanaged object into that Realm. + + - parameter value: The value used to populate the object. + */ public init(value: Any) { type(of: self).sharedSchema() // ensure this class' objectSchema is loaded in the partialSharedSchema super.init(value: value, schema: RLMSchema.partialShared()) @@ -100,8 +107,7 @@ open class Object: RLMObjectBase { // MARK: Properties - /// The `Realm` this object belongs to, or `nil` if the object - /// does not belong to a realm (the object is standalone). + /// The Realm which manages the object, or `nil` if the object is unmanaged. public var realm: Realm? { if let rlmReam = RLMObjectBaseRealm(self) { return Realm(rlmReam) @@ -109,18 +115,18 @@ open class Object: RLMObjectBase { return nil } - /// The `ObjectSchema` which lists the persisted properties for this object. + /// The object schema which lists the managed properties for the object. public var objectSchema: ObjectSchema { return ObjectSchema(RLMObjectBaseObjectSchema(self)!) } - /// Indicates if an object can no longer be accessed. + /// Indicates if the object can no longer be accessed because it is now invalid. /// - /// An object can no longer be accessed if the object has been deleted from the containing - /// `realm` or if `invalidate` is called on the containing `realm`. + /// An object can no longer be accessed if the object has been deleted from the Realm that manages it, or if + /// `invalidate()` is called on that Realm. open override var isInvalidated: Bool { return super.isInvalidated } - /// Returns a human-readable description of this object. + /// A human-readable description of the object. open override var description: String { return super.description } #if os(OSX) @@ -143,31 +149,32 @@ open class Object: RLMObjectBase { // MARK: Object Customization /** - Override to designate a property as the primary key for an `Object` subclass. Only properties of - type String and Int can be designated as the primary key. Primary key - properties enforce uniqueness for each value whenever the property is set which incurs some overhead. - Indexes are created automatically for primary key properties. + Override this method to specify the name of a property to be used as the primary key. - - returns: Name of the property designated as the primary key, or `nil` if the model has no primary key. - */ + Only properties of types `String` and `Int` can be designated as the primary key. Primary key properties enforce + uniqueness for each value whenever the property is set, which incurs minor overhead. Indexes are created + automatically for primary key properties. + + - returns: The name of the property designated as the primary key, or `nil` if the model has no primary key. + */ open class func primaryKey() -> String? { return nil } /** - Override to return an array of property names to ignore. These properties will not be persisted - and are treated as transient. + Override this method to specify the names of properties to ignore. These properties will not be managed by + the Realm that manages the object. - - returns: `Array` of property names to ignore. - */ + - returns: An array of property names to ignore. + */ open class func ignoredProperties() -> [String] { return [] } /** - Return an array of property names for properties which should be indexed. - Only supported for string, integer, boolean and date properties. + Returns an array of property names for properties which should be indexed. - - returns: `Array` of property names to index. - */ - open class func indexedProperties() -> [String] { return [] } + Only string, integer, boolean, `Date`, and `NSDate` properties are supported. + - returns: An array of property names. + */ + open class func indexedProperties() -> [String] { return [] } // MARK: Key-Value Coding & Subscripting @@ -191,20 +198,18 @@ open class Object: RLMObjectBase { // MARK: Dynamic list /** - This method is useful only in specialized circumstances, for example, when building - components that integrate with Realm. If you are simply building an app on Realm, it is - recommended to use instance variables or cast the KVC returns. - - Returns a List of DynamicObjects for a property name + Returns a list of `DynamicObject`s for a given property name. - - warning: This method is useful only in specialized circumstances + - warning: This method is useful only in specialized circumstances, for example, when building + components that integrate with Realm. If you are simply building an app on Realm, it is + recommended to use instance variables or cast the values returned from key-value coding. - - parameter propertyName: The name of the property to get a List + - parameter propertyName: The name of the property. - - returns: A List of DynamicObjects + - returns: A list of `DynamicObject`s. - :nodoc: - */ + :nodoc: + */ public func dynamicList(_ propertyName: String) -> List { return unsafeBitCast(RLMDynamicGetByName(self, propertyName, true) as! RLMListBase, to: List.self) @@ -213,13 +218,13 @@ open class Object: RLMObjectBase { // MARK: Equatable /** - Returns whether both objects are equal. + Returns whether two Realm objects are equal. - Objects are considered equal when they are both from the same Realm and point to the same - underlying object in the database. + Objects are considered equal if and only if they are both managed by the same Realm and point to the same + underlying object in the database. - - parameter object: Object to compare for equality. - */ + - parameter object: The object to compare the receiver to. + */ open override func isEqual(_ object: Any?) -> Bool { return RLMObjectBaseAreEqual(self as RLMObjectBase?, object as? RLMObjectBase) } @@ -408,7 +413,9 @@ public class ObjectUtil: NSObject { optional numeric value. All property types except for `List` and `RealmOptional` *must* be declared as `dynamic var`. `List` and - `RealmOptional` properties must be declared as non-dynamic `let` properties. + `RealmOptional` properties must be declared as non-dynamic `let` properties. Swift `lazy` properties are not allowed. + + Note that none of the restrictions listed above apply to properties that are configured to be ignored by Realm. ### Querying @@ -420,11 +427,10 @@ public class ObjectUtil: NSObject { */ @objc(RealmSwiftObject) public class Object: RLMObjectBase { - // MARK: Initializers /** - Initializes an unmanaged instance of a Realm object. + Creates an unmanaged instance of a Realm object. Call `add(_:)` on a `Realm` instance to add an unmanaged object into that Realm. @@ -435,7 +441,7 @@ public class Object: RLMObjectBase { } /** - Initializes an unmanaged instance of a Realm object. + Creates an unmanaged instance of a Realm object. The `value` argument is used to populate the object. It can be a key-value coding compliant object, an array or dictionary returned from the methods in `NSJSONSerialization`, or an `Array` containing one element for each @@ -473,7 +479,7 @@ public class Object: RLMObjectBase { /// Indicates if the object can no longer be accessed because it is now invalid. /// /// An object can no longer be accessed if the object has been deleted from the Realm that manages it, or if - /// `invalidate` is called on that Realm. + /// `invalidate()` is called on that Realm. public override var invalidated: Bool { return super.invalidated } /// Returns a human-readable description of the object. diff --git a/RealmSwift/ObjectSchema.swift b/RealmSwift/ObjectSchema.swift index 1cbe1e32c1..463931ed2c 100644 --- a/RealmSwift/ObjectSchema.swift +++ b/RealmSwift/ObjectSchema.swift @@ -22,28 +22,31 @@ import Realm #if swift(>=3.0) /** -This class represents Realm model object schemas. + This class represents Realm model object schemas. -When using Realm, `ObjectSchema` objects allow performing migrations and -introspecting the database's schema. + When using Realm, `ObjectSchema` instances allow performing migrations and introspecting the database's schema. -`ObjectSchema`s map to tables in the core database. -*/ + Object schemas map to tables in the core database. + */ public final class ObjectSchema: CustomStringConvertible { // MARK: Properties internal let rlmObjectSchema: RLMObjectSchema - /// Array of persisted `Property` objects for an object. + /** + An array of `Property` instances representing the managed properties of a class described by the schema. + + - see: `Property` + */ public var properties: [Property] { return rlmObjectSchema.properties.map { Property($0) } } - /// The name of the class this schema describes. + /// The name of the class the schema describes. public var className: String { return rlmObjectSchema.className } - /// The property that serves as the primary key, if there is a primary key. + /// The property which serves as the primary key for the class the schema describes, if any. public var primaryKeyProperty: Property? { if let rlmProperty = rlmObjectSchema.primaryKeyProperty { return Property(rlmProperty) @@ -51,7 +54,7 @@ public final class ObjectSchema: CustomStringConvertible { return nil } - /// Returns a human-readable description of the properties contained in this object schema. + /// A human-readable description of the properties contained in the object schema. public var description: String { return rlmObjectSchema.description } // MARK: Initializers diff --git a/RealmSwift/Optional.swift b/RealmSwift/Optional.swift index f5f9865941..89f493512c 100644 --- a/RealmSwift/Optional.swift +++ b/RealmSwift/Optional.swift @@ -20,7 +20,7 @@ import Realm #if swift(>=3.0) -/// Types that can be represented in a `RealmOptional`. +/// A protocol describing types that can parameterize a `RealmOptional`. public protocol RealmOptionalType {} extension Int: RealmOptionalType {} extension Int8: RealmOptionalType {} @@ -32,14 +32,13 @@ extension Double: RealmOptionalType {} extension Bool: RealmOptionalType {} /** -A `RealmOptional` represents a optional value for types that can't be directly -declared as `dynamic` in Swift, such as `Int`s, `Float`, `Double`, and `Bool`. + A `RealmOptional` instance represents a optional value for types that can't be directly declared as `dynamic` in Swift, + such as `Int`, `Float`, `Double`, and `Bool`. -It encapsulates a value in its `value` property, which is the only way to mutate -a `RealmOptional` property on an `Object`. -*/ + To change the underlying value stored by a `RealmOptional` instance, mutate the instance's `value` property. + */ public final class RealmOptional: RLMOptionalBase { - /// The value this optional represents. + /// The value the optional represents. public var value: T? { get { return underlyingValue.map(dynamicBridgeCast) @@ -50,10 +49,10 @@ public final class RealmOptional: RLMOptionalBase { } /** - Creates a `RealmOptional` with the given default value (defaults to `nil`). + Creates a `RealmOptional` instance encapsulating the given default value. - - parameter value: The default value for this optional. - */ + - parameter value: The value to store in the optional, or `nil` if not specified. + */ public init(_ value: T? = nil) { super.init() self.value = value diff --git a/RealmSwift/Property.swift b/RealmSwift/Property.swift index cd69f659d3..5ff235b6eb 100644 --- a/RealmSwift/Property.swift +++ b/RealmSwift/Property.swift @@ -22,35 +22,36 @@ import Realm #if swift(>=3.0) /** -This class represents properties persisted to Realm in an `ObjectSchema`. + `Property` instances represent properties managed by a Realm in the context of an object schema. Such properties may be + persisted to a Realm file or computed from other data in the Realm. -When using Realm, `Property` objects allow performing migrations and -introspecting the database's schema. + When using Realm, property instances allow performing migrations and introspecting the database's schema. -These properties map to columns in the core database. -*/ + Property instances map to columns in the core database. + */ public final class Property: CustomStringConvertible { // MARK: Properties internal let rlmProperty: RLMProperty - /// Property name. + /// The name of the property. public var name: String { return rlmProperty.name } - /// Property type. + /// The type of the property. public var type: PropertyType { return rlmProperty.type } - /// Whether this property is indexed. + /// Indicates whether this property is indexed. public var isIndexed: Bool { return rlmProperty.indexed } - /// Whether this property is optional (can contain `nil` values). + /// Indicates whether this property is optional. (Note that certain numeric types must be wrapped in a + /// `RealmOptional` instance in order to be declared as optional.) public var isOptional: Bool { return rlmProperty.optional } - /// Object class name - specify object types for `Object` and `List` properties. + /// For `Object` and `List` properties, the name of the class of object stored in the property. public var objectClassName: String? { return rlmProperty.objectClassName } - /// Returns a human-readable description of this property. + /// A human-readable description of the property object. public var description: String { return rlmProperty.description } // MARK: Initializers @@ -72,22 +73,22 @@ public func == (lhs: Property, rhs: Property) -> Bool { // swiftlint:disable:thi // MARK: Unavailable extension Property { - @available(*, unavailable, renamed:"isIndexed") - public var indexed : Bool { fatalError() } + @available(*, unavailable, renamed: "isIndexed") + public var indexed: Bool { fatalError() } - @available(*, unavailable, renamed:"isOptional") - public var optional : Bool { fatalError() } + @available(*, unavailable, renamed: "isOptional") + public var optional: Bool { fatalError() } } #else /** `Property` instances represent properties managed by a Realm in the context of an object schema. Such properties may be - persisted to a Realm file or computed from other data from the Realm. + persisted to a Realm file or computed from other data in the Realm. - When using Realm, `Property` instances allow performing migrations and introspecting the database's schema. + When using Realm, property instances allow performing migrations and introspecting the database's schema. - These property instances map to columns in the core database. + Property instances map to columns in the core database. */ public final class Property: CustomStringConvertible { diff --git a/RealmSwift/Realm.swift b/RealmSwift/Realm.swift index efe6741803..e33717bd59 100644 --- a/RealmSwift/Realm.swift +++ b/RealmSwift/Realm.swift @@ -23,72 +23,72 @@ import Realm.Private #if swift(>=3.0) /** -A Realm instance (also referred to as "a realm") represents a Realm -database. - -Realms can either be stored on disk (see `init(path:)`) or in -memory (see `Configuration`). - -Realm instances are cached internally, and constructing equivalent Realm -objects (with the same path or identifier) produces limited overhead. - -If you specifically want to ensure a Realm object is -destroyed (for example, if you wish to open a realm, check some property, and -then possibly delete the realm file and re-open it), place the code which uses -the realm within an `autoreleasepool {}` and ensure you have no other -strong references to it. - -- warning: Realm instances are not thread safe and can not be shared across - threads or dispatch queues. You must construct a new instance on each thread you want - to interact with the realm on. For dispatch queues, this means that you must - call it in each block which is dispatched, as a queue is not guaranteed to run - on a consistent thread. -*/ + A `Realm` instance (also referred to as "a Realm") represents a Realm database. + + Realms can either be stored on disk (see `init(path:)`) or in memory (see `Configuration`). + + `Realm` instances are cached internally, and constructing equivalent `Realm` objects (for example, by using the same + path or identifier) produces limited overhead. + + If you specifically want to ensure a `Realm` instance is destroyed (for example, if you wish to open a Realm, check + some property, and then possibly delete the Realm file and re-open it), place the code which uses the Realm within an + `autoreleasepool {}` and ensure you have no other strong references to it. + + - warning: `Realm` instances are not thread safe and cannot be shared across threads or dispatch queues. You must + construct a new instance for each thread in which a Realm will be accessed. For dispatch queues, this means + that you must construct a new instance in each block which is dispatched, as a queue is not guaranteed to + run all of its blocks on the same thread. + */ public final class Realm { // MARK: Properties - /// The Schema used by this realm. + /// The `Schema` used by the Realm. public var schema: Schema { return Schema(rlmRealm.schema) } - /// Returns the `Configuration` that was used to create this `Realm` instance. + /// The `Configuration` value that was used to create the `Realm` instance. public var configuration: Configuration { return Configuration.fromRLMRealmConfiguration(rlmConfiguration: rlmRealm.configuration) } - /// Indicates if this Realm contains any objects. + /// Indicates if the Realm contains any objects. public var isEmpty: Bool { return rlmRealm.isEmpty } // MARK: Initializers /** - Obtains a Realm instance with the default Realm configuration, which can be - changed by setting `Realm.Configuration.defaultConfiguration`. + Obtains an instance of the default Realm. - - throws: An NSError if the Realm could not be initialized. - */ + The default Realm is persisted as *default.realm* under the *Documents* directory of your Application on iOS, and + in your application's *Application Support* directory on OS X. + + The default Realm is created using the default `Configuration`, which can be changed by setting the + `Realm.Configuration.defaultConfiguration` property to a new value. + + - throws: An `NSError` if the Realm could not be initialized. + */ public convenience init() throws { let rlmRealm = try RLMRealm(configuration: RLMRealmConfiguration.default()) self.init(rlmRealm) } /** - Obtains a Realm instance with the given configuration. + Obtains a `Realm` instance with the given configuration. - - parameter configuration: The configuration to use when creating the Realm instance. + - parameter configuration: A configuration value to use when creating the Realm. - - throws: An NSError if the Realm could not be initialized. - */ + - throws: An `NSError` if the Realm could not be initialized. + */ public convenience init(configuration: Configuration) throws { let rlmRealm = try RLMRealm(configuration: configuration.rlmConfiguration) self.init(rlmRealm) } /** - Obtains a Realm instance persisted at the specified file URL. + Obtains a `Realm` instance persisted at a specified file URL. - - parameter fileURL: Local URL to the realm file. + - parameter fileURL: The local URL of the file the Realm should be saved at. - - throws: An NSError if the Realm could not be initialized. - */ + - throws: An `NSError` if the Realm could not be initialized. + */ public convenience init(fileURL: URL) throws { var configuration = Configuration.defaultConfiguration configuration.fileURL = fileURL @@ -98,99 +98,95 @@ public final class Realm { // MARK: Transactions /** - Performs actions contained within the given block inside a write transaction. + Performs actions contained within the given block inside a write transaction. - Write transactions cannot be nested, and trying to execute a write transaction - on a `Realm` which is already in a write transaction will throw an exception. - Calls to `write` from `Realm` instances in other threads will block - until the current write transaction completes. + If the block throws an error, the transaction will be canceled, reverting any writes made in the block before the + error was thrown. - Before executing the write transaction, `write` updates the `Realm` to the - latest Realm version, as if `refresh()` was called, and generates notifications - if applicable. This has no effect if the `Realm` was already up to date. + Write transactions cannot be nested, and trying to execute a write transaction on a Realm which is already + participating in a write transaction will throw an error. Calls to `write` from `Realm` instances in other threads + will block until the current write transaction completes. - - parameter block: The block to be executed inside a write transaction. + Before executing the write transaction, `write` updates the `Realm` instance to the latest Realm version, as if + `refresh()` had been called, and generates notifications if applicable. This has no effect if the Realm was already + up to date. - - throws: An NSError if the transaction could not be written. - */ - public func write(block: () -> Void) throws { + - parameter block: The block containing actions to perform. + + - throws: An `NSError` if the transaction could not be completed successfully. + If `block` throws, the function throws the propagated `ErrorType` instead. + */ + public func write(_ block: () -> Void) throws { try rlmRealm.transaction(block) } /** - Begins a write transaction in a `Realm`. - - Only one write transaction can be open at a time. Write transactions cannot be - nested, and trying to begin a write transaction on a `Realm` which is - already in a write transaction will throw an exception. Calls to - `beginWrite` from `Realm` instances in other threads will block - until the current write transaction completes. - - Before beginning the write transaction, `beginWrite` updates the - `Realm` to the latest Realm version, as if `refresh()` was called, and - generates notifications if applicable. This has no effect if the `Realm` - was already up to date. - - It is rarely a good idea to have write transactions span multiple cycles of - the run loop, but if you do wish to do so you will need to ensure that the - `Realm` in the write transaction is kept alive until the write transaction - is committed. - */ + Begins a write transaction on the Realm. + + Only one write transaction can be open at a time. Write transactions cannot be nested, and trying to begin a write + transaction on a Realm which is already in a write transaction will throw an error. Calls to `beginWrite` from + `Realm` instances in other threads will block until the current write transaction completes. + + Before beginning the write transaction, `beginWrite` updates the `Realm` instance to the latest Realm version, as + if `refresh()` had been called, and generates notifications if applicable. This has no effect if the Realm was + already up to date. + + It is rarely a good idea to have write transactions span multiple cycles of the run loop, but if you do wish to do + so you will need to ensure that the Realm in the write transaction is kept alive until the write transaction is + committed. + */ public func beginWrite() { rlmRealm.beginWriteTransaction() } /** - Commits all writes operations in the current write transaction, and ends - the transaction. + Commits all write operations in the current write transaction, and ends the transaction. - Calling this when not in a write transaction will throw an exception. + - warning: This method may only be called during a write transaction. - - throws: An NSError if the transaction could not be written. - */ + - throws: An `NSError` if the transaction could not be written. + */ public func commitWrite() throws { try rlmRealm.commitWriteTransaction() } /** - Reverts all writes made in the current write transaction and end the transaction. + Reverts all writes made in the current write transaction and ends the transaction. + + This rolls back all objects in the Realm to the state they were in at the beginning of the write transaction, and + then ends the transaction. - This rolls back all objects in the Realm to the state they were in at the - beginning of the write transaction, and then ends the transaction. + This restores the data for deleted objects, but does not revive invalidated object instances. Any `Object`s which + were added to the Realm will be invalidated rather than becoming unmanaged. - This restores the data for deleted objects, but does not revive invalidated - object instances. Any `Object`s which were added to the Realm will be - invalidated rather than switching back to standalone objects. - Given the following code: + Given the following code: - ```swift - let oldObject = objects(ObjectType).first! - let newObject = ObjectType() + ```swift + let oldObject = objects(ObjectType).first! + let newObject = ObjectType() - realm.beginWrite() - realm.add(newObject) - realm.delete(oldObject) - realm.cancelWrite() - ``` + realm.beginWrite() + realm.add(newObject) + realm.delete(oldObject) + realm.cancelWrite() + ``` - Both `oldObject` and `newObject` will return `true` for `invalidated`, - but re-running the query which provided `oldObject` will once again return - the valid object. + Both `oldObject` and `newObject` will return `true` for `isInvalidated`, but re-running the query which provided + `oldObject` will once again return the valid object. - Calling this when not in a write transaction will throw an exception. - */ + - warning: This method may only be called during a write transaction. + */ public func cancelWrite() { rlmRealm.cancelWriteTransaction() } /** - Indicates if this Realm is currently in a write transaction. + Indicates whether the Realm is currently in a write transaction. - - warning: Wrapping mutating operations in a write transaction if this property returns `false` - may cause a large number of write transactions to be created, which could negatively - impact Realm's performance. Always prefer performing multiple mutations in a single - transaction when possible. - */ + - warning: Do not simply check this property and then start a write transaction whenever an object needs to be + created, updated, or removed. Doing so might cause a large number of write transactions to be created, + degrading performance. Instead, always prefer performing multiple updates during a single transaction. + */ public var isInWriteTransaction: Bool { return rlmRealm.inWriteTransaction } @@ -198,24 +194,22 @@ public final class Realm { // MARK: Adding and Creating objects /** - Adds or updates an object to be persisted it in this Realm. + Adds or updates an existing object into the Realm. - When 'update' is 'true', the object must have a primary key. If no objects exist in - the Realm instance with the same primary key value, the object is inserted. Otherwise, - the existing object is updated with any changed values. + Only pass `true` to `update` if the object has a primary key. If no objects exist in the Realm with the same + primary key value, the object is inserted. Otherwise, the existing object is updated with any changed values. - When added, all (child) relationships referenced by this object will also be - added to the Realm if they are not already in it. If the object or any related - objects already belong to a different Realm an exception will be thrown. Use one - of the `create` functions to insert a copy of a persisted object into a different - Realm. + When added, all child relationships referenced by this object will also be added to the Realm if they are not + already in it. If the object or any related objects are already being managed by a different Realm an error will be + thrown. Instead, use one of the `create` functions to insert a copy of a managed object into a different Realm. - The object to be added must be valid and cannot have been previously deleted - from a Realm (i.e. `invalidated` must be false). + The object to be added must be valid and cannot have been previously deleted from a Realm (i.e. `isInvalidated` + must be `false`). - - parameter object: Object to be added to this Realm. - - parameter update: If true will try to update existing objects with the same primary key. - */ + - parameter object: The object to be added to this Realm. + - parameter update: If `true`, the Realm will try to find an existing copy of the object (with the same primary + key), and update it. Otherwise, the object will be added. + */ public func add(_ object: Object, update: Bool = false) { if update && object.objectSchema.primaryKeyProperty == nil { throwRealmException("'\(object.objectSchema.className)' does not have a primary key and can not be updated") @@ -224,15 +218,15 @@ public final class Realm { } /** - Adds or updates objects in the given sequence to be persisted it in this Realm. + Adds or updates all the objects in a collection into the Realm. - - see: add(_:update:) + - see: `add(_:update:)` - - warning: This method can only be called during a write transaction. + - warning: This method may only be called during a write transaction. - - parameter objects: A sequence which contains objects to be added to this Realm. - - parameter update: If true will try to update existing objects with the same primary key. - */ + - parameter objects: A sequence which contains objects to be added to the Realm. + - parameter update: If `true`, objects that are already in the Realm will be updated instead of added anew. + */ public func add(_ objects: S, update: Bool = false) where S.Iterator.Element: Object { for obj in objects { add(obj, update: update) @@ -240,30 +234,31 @@ public final class Realm { } /** - Create an `Object` with the given value. + Creates or updates a Realm object with a given value, adding it to the Realm and returning it. - Creates or updates an instance of this object and adds it to the `Realm` populating - the object with the given value. + Only pass `true` to `update` if the object has a primary key. If no objects exist in + the Realm with the same primary key value, the object is inserted. Otherwise, + the existing object is updated with any changed values. - When 'update' is 'true', the object must have a primary key. If no objects exist in - the Realm instance with the same primary key value, the object is inserted. Otherwise, - the existing object is updated with any changed values. + The `value` argument can be a key-value coding compliant object, an array or dictionary returned from the methods + in `NSJSONSerialization`, or an `Array` containing one element for each managed property. An exception will be + thrown if any required properties are not present and those properties were not defined with default values. Do not + pass in a `LinkingObjects` instance, either by itself or as a member of a collection. - - warning: This method can only be called during a write transaction. + When passing in an `Array` as the `value` argument, all properties must be present, valid and in the same order as + the properties defined in the model. - - parameter type: The object type to create. - - parameter value: The value used to populate the object. This can be any key/value coding compliant - object, or a JSON dictionary such as those returned from the methods in `NSJSONSerialization`, - or an `Array` with one object for each persisted property. An exception will be - thrown if any required properties are not present and no default is set. - When passing in an `Array`, all properties must be present, - valid and in the same order as the properties defined in the model. - - parameter update: If true will try to update existing objects with the same primary key. + - warning: This method may only be called during a write transaction. - - returns: The created object. - */ + - parameter type: The type of the object to create. + - parameter value: The value used to populate the object. + - parameter update: If `true`, the Realm will try to find an existing copy of the object (with the same primary + key), and update it. Otherwise, the object will be added. + + - returns: The newly created object. + */ @discardableResult - public func createObject(ofType type: T.Type, populatedWith value: Any = [:], update: Bool = false) -> T { + public func create(_ type: T.Type, value: Any = [:], update: Bool = false) -> T { let typeName = (type as Object.Type).className() if update && schema[typeName]?.primaryKeyProperty == nil { throwRealmException("'\(typeName)' does not have a primary key and can not be updated") @@ -272,35 +267,37 @@ public final class Realm { } /** - This method is useful only in specialized circumstances, for example, when building - components that integrate with Realm. If you are simply building an app on Realm, it is - recommended to use the typed method `create(_:value:update:)`. + This method is useful only in specialized circumstances, for example, when building + components that integrate with Realm. If you are simply building an app on Realm, it is + recommended to use the typed method `create(_:value:update:)`. - Creates or updates an object with the given class name and adds it to the `Realm`, populating - the object with the given value. + Creates or updates an object with the given class name and adds it to the `Realm`, populating + the object with the given value. + + When 'update' is 'true', the object must have a primary key. If no objects exist in + the Realm instance with the same primary key value, the object is inserted. Otherwise, + the existing object is updated with any changed values. - When 'update' is 'true', the object must have a primary key. If no objects exist in - the Realm instance with the same primary key value, the object is inserted. Otherwise, - the existing object is updated with any changed values. + The `value` argument is used to populate the object. It can be a key-value coding compliant object, an array or + dictionary returned from the methods in `NSJSONSerialization`, or an `Array` containing one element for each + managed property. An exception will be thrown if any required properties are not present and those properties were + not defined with default values. - - warning: This method can only be called during a write transaction. + When passing in an `Array` as the `value` argument, all properties must be present, valid and in the same order as + the properties defined in the model. - - parameter className: The class name of the object to create. - - parameter value: The value used to populate the object. This can be any key/value coding compliant - object, or a JSON dictionary such as those returned from the methods in `NSJSONSerialization`, - or an `Array` with one object for each persisted property. An exception will be - thrown if any required properties are not present and no default is set. + - warning: This method can only be called during a write transaction. - When passing in an `Array`, all properties must be present, - valid and in the same order as the properties defined in the model. - - parameter update: If true will try to update existing objects with the same primary key. + - parameter className: The class name of the object to create. + - parameter value: The value used to populate the object. + - parameter update: If true will try to update existing objects with the same primary key. - - returns: The created object. + - returns: The created object. - :nodoc: - */ + :nodoc: + */ @discardableResult - public func createDynamicObject(ofType typeName: String, populatedWith value: Any = [:], update: Bool = false) -> DynamicObject { + public func dynamicCreate(_ typeName: String, value: Any = [:], update: Bool = false) -> DynamicObject { if update && schema[typeName]?.primaryKeyProperty == nil { throwRealmException("'\(typeName)' does not have a primary key and can not be updated") } @@ -310,24 +307,24 @@ public final class Realm { // MARK: Deleting objects /** - Deletes the given object from this Realm. + Deletes an object from the Realm. Once the object is deleted it is considered invalidated. - - warning: This method can only be called during a write transaction. + - warning: This method may only be called during a write transaction. - - parameter object: The object to be deleted. - */ + - parameter object: The object to be deleted. + */ public func delete(_ object: Object) { RLMDeleteObjectFromRealm(object, rlmRealm) } /** - Deletes the given objects from this Realm. + Deletes zero or more objects from the Realm. - - warning: This method can only be called during a write transaction. + - warning: This method may only be called during a write transaction. - - parameter objects: The objects to be deleted. This can be a `List`, `Results`, - or any other enumerable SequenceType which generates Object. - */ + - parameter objects: The objects to be deleted. This can be a `List`, `Results`, or any other + Swift `Sequence` whose elements are `Object`s. + */ public func delete(_ objects: S) where S.Iterator.Element: Object { for obj in objects { delete(obj) @@ -335,86 +332,81 @@ public final class Realm { } /** - Deletes the given objects from this Realm. + Deletes zero or more objects from the Realm. - - warning: This method can only be called during a write transaction. + - warning: This method may only be called during a write transaction. - - parameter objects: The objects to be deleted. Must be `List`. + - parameter objects: A list of objects to delete. - :nodoc: - */ + :nodoc: + */ public func delete(_ objects: List) { rlmRealm.deleteObjects(objects._rlmArray) } /** - Deletes the given objects from this Realm. + Deletes zero or more objects from the Realm. - - warning: This method can only be called during a write transaction. + - warning: This method may only be called during a write transaction. - - parameter objects: The objects to be deleted. Must be `Results`. + - parameter objects: A `Results` containing the objects to be deleted. - :nodoc: - */ + :nodoc: + */ public func delete(_ objects: Results) { rlmRealm.deleteObjects(objects.rlmResults) } /** - Deletes all objects from this Realm. + Deletes all objects from the Realm. - - warning: This method can only be called during a write transaction. - */ - public func deleteAllObjects() { + - warning: This method may only be called during a write transaction. + */ + public func deleteAll() { RLMDeleteAllObjectsFromRealm(rlmRealm) } // MARK: Object Retrieval /** - Returns all objects of the given type in the Realm. + Returns all objects of the given type stored in the Realm. - - parameter type: The type of the objects to be returned. + - parameter type: The type of the objects to be returned. - - returns: All objects of the given type in Realm. - */ - public func allObjects(ofType type: T.Type) -> Results { + - returns: A `Results` containing the objects. + */ + public func objects(_ type: T.Type) -> Results { return Results(RLMGetObjects(rlmRealm, (type as Object.Type).className(), nil)) } /** - This method is useful only in specialized circumstances, for example, when building - components that integrate with Realm. If you are simply building an app on Realm, it is - recommended to use the typed method `objects(type:)`. - - Returns all objects for a given class name in the Realm. - - - warning: This method is useful only in specialized circumstances. + This method is useful only in specialized circumstances, for example, when building + components that integrate with Realm. If you are simply building an app on Realm, it is + recommended to use the typed method `objects(type:)`. - - parameter className: The class name of the objects to be returned. + Returns all objects for a given class name in the Realm. - - returns: All objects for the given class name as dynamic objects + - parameter typeName: The class name of the objects to be returned. + - returns: All objects for the given class name as dynamic objects - :nodoc: - */ - public func allDynamicObjects(ofType typeName: String) -> Results { + :nodoc: + */ + public func dynamicObjects(_ typeName: String) -> Results { return Results(RLMGetObjects(rlmRealm, typeName, nil)) } /** - Get an object with the given primary key. - - Returns `nil` if no object exists with the given primary key. + Retrieves the single instance of a given object type with the given primary key from the Realm. - This method requires that `primaryKey()` be overridden on the given subclass. + This method requires that `primaryKey()` be overridden on the given object class. - - see: Object.primaryKey() + - see: `Object.primaryKey()` - - parameter type: The type of the objects to be returned. - - parameter key: The primary key of the desired object. + - parameter type: The type of the object to be returned. + - parameter key: The primary key of the desired object. - - returns: An object of type `type` or `nil` if an object with the given primary key does not exist. - */ + - returns: An object of type `type`, or `nil` if no instance with the given primary key exists. + */ public func object(ofType type: T.Type, forPrimaryKey key: K) -> T? { return unsafeBitCast(RLMGetObject(rlmRealm, (type as Object.Type).className(), dynamicBridgeCast(fromSwift: key)) as! RLMObjectBase?, @@ -422,27 +414,27 @@ public final class Realm { } /** - This method is useful only in specialized circumstances, for example, when building - components that integrate with Realm. If you are simply building an app on Realm, it is - recommended to use the typed method `objectForPrimaryKey(_:key:)`. + This method is useful only in specialized circumstances, for example, when building + components that integrate with Realm. If you are simply building an app on Realm, it is + recommended to use the typed method `objectForPrimaryKey(_:key:)`. - Get a dynamic object with the given class name and primary key. + Get a dynamic object with the given class name and primary key. - Returns `nil` if no object exists with the given class name and primary key. + Returns `nil` if no object exists with the given class name and primary key. - This method requires that `primaryKey()` be overridden on the given subclass. + This method requires that `primaryKey()` be overridden on the given subclass. - - see: Object.primaryKey() + - see: Object.primaryKey() - - warning: This method is useful only in specialized circumstances. + - warning: This method is useful only in specialized circumstances. - - parameter className: The class name of the object to be returned. - - parameter key: The primary key of the desired object. + - parameter className: The class name of the object to be returned. + - parameter key: The primary key of the desired object. - - returns: An object of type `DynamicObject` or `nil` if an object with the given primary key does not exist. + - returns: An object of type `DynamicObject` or `nil` if an object with the given primary key does not exist. - :nodoc: - */ + :nodoc: + */ public func dynamicObject(ofType typeName: String, forPrimaryKey key: Any) -> DynamicObject? { return unsafeBitCast(RLMGetObject(rlmRealm, typeName, key) as! RLMObjectBase?, to: Optional.self) } @@ -450,38 +442,33 @@ public final class Realm { // MARK: Notifications /** - Add a notification handler for changes in this Realm. - - Notification handlers are called after each write transaction is committed, - independent from the thread or process. + Adds a notification handler for changes made to this Realm, and returns a notification token. - The block is called on the same thread as it was added on, and can only - be added on threads which are currently within a run loop. Unless you are - specifically creating and running a run loop on a background thread, this - normally will only be the main thread. + Notification handlers are called after each write transaction is committed, independent of the thread or process. - Notifications can't be delivered as long as the runloop is blocked by - other activity. When notifications can't be delivered instantly, multiple - notifications may be coalesced. + Handler blocks are called on the same thread that they were added on, and may only be added on threads which are + currently within a run loop. Unless you are specifically creating and running a run loop on a background thread, + this will normally only be the main thread. - You must retain the returned token for as long as you want updates to continue - to be sent to the block. To stop receiving updates, call stop() on the token. + Notifications can't be delivered as long as the run loop is blocked by other activity. When notifications can't be + delivered instantly, multiple notifications may be coalesced. - - parameter block: A block which is called to process Realm notifications. - It receives the following parameters: + You must retain the returned token for as long as you want updates to be sent to the block. To stop receiving + updates, call `stop()` on the token. - - `Notification`: The incoming notification. - - `Realm`: The realm for which this notification occurred. + - parameter block: A block which is called to process Realm notifications. It receives the following parameters: + `notification`: the incoming notification; `realm`: the Realm for which the notification + occurred. - - returns: A token which must be held for as long as you want notifications to be delivered. - */ - public func addNotificationBlock(block: @escaping NotificationBlock) -> NotificationToken { + - returns: A token which must be held for as long as you wish to continue receiving change notifications. + */ + public func addNotificationBlock(_ block: @escaping NotificationBlock) -> NotificationToken { return rlmRealm.addNotificationBlock { rlmNotification, _ in switch rlmNotification { case RLMNotification.DidChange: - block(.DidChange, self) + block(.didChange, self) case RLMNotification.RefreshRequired: - block(.RefreshRequired, self) + block(.refreshRequired, self) default: fatalError("Unhandled notification type: \(rlmNotification)") } @@ -491,35 +478,29 @@ public final class Realm { // MARK: Autorefresh and Refresh /** - Whether this Realm automatically updates when changes happen in other threads. + Set this property to `true` to automatically update this Realm when changes happen in other threads. - If set to `true` (the default), changes made on other threads will be reflected - in this Realm on the next cycle of the run loop after the changes are - committed. If set to `false`, you must manually call `refresh()` on the Realm to - update it to get the latest version. + If set to `true` (the default), changes made on other threads will be reflected in this Realm on the next cycle of + the run loop after the changes are committed. If set to `false`, you must manually call `refresh()` on the Realm + to update it to get the latest data. - Note that by default, background threads do not have an active run loop and you - will need to manually call `refresh()` in order to update to the latest version, - even if `autorefresh` is set to `true`. + Note that by default, background threads do not have an active run loop and you will need to manually call + `refresh()` in order to update to the latest version, even if `autorefresh` is set to `true`. - Even with this enabled, you can still call `refresh()` at any time to update the - Realm before the automatic refresh would occur. + Even with this property enabled, you can still call `refresh()` at any time to update the Realm before the + automatic refresh would occur. - Notifications are sent when a write transaction is committed whether or not - this is enabled. + Notifications are sent when a write transaction is committed whether or not automatic refreshing is enabled. - Disabling this on a `Realm` without any strong references to it will not - have any effect, and it will switch back to YES the next time the `Realm` - object is created. This is normally irrelevant as it means that there is - nothing to refresh (as persisted `Object`s, `List`s, and `Results` have strong - references to the containing `Realm`), but it means that setting - `Realm().autorefresh = false` in - `application(_:didFinishLaunchingWithOptions:)` and only later storing Realm - objects will not work. + Disabling `autorefresh` on a `Realm` without any strong references to it will not have any effect, and + `autorefresh` will revert back to `true` the next time the Realm is created. This is normally irrelevant as it + means that there is nothing to refresh (as managed `Object`s, `List`s, and `Results` have strong references to the + `Realm` that manages them), but it means that setting `autorefresh = false` in + `application(_:didFinishLaunchingWithOptions:)` and only later storing Realm objects will not work. - Defaults to true. - */ - public var shouldAutorefresh: Bool { + Defaults to `true`. + */ + public var autorefresh: Bool { get { return rlmRealm.autorefresh } @@ -529,12 +510,11 @@ public final class Realm { } /** - Update a `Realm` and outstanding objects to point to the most recent - data for this `Realm`. + Updates the Realm and outstanding objects managed by the Realm to point to the most recent data. - - returns: Whether the realm had any updates. - Note that this may return true even if no data has actually changed. - */ + - returns: Whether there were any updates for the Realm. Note that `true` may be returned even if no data actually + changed. + */ @discardableResult public func refresh() -> Bool { return rlmRealm.refresh() @@ -543,25 +523,24 @@ public final class Realm { // MARK: Invalidation /** - Invalidate all `Object`s and `Results` read from this Realm. - - A Realm holds a read lock on the version of the data accessed by it, so - that changes made to the Realm on different threads do not modify or delete the - data seen by this Realm. Calling this method releases the read lock, - allowing the space used on disk to be reused by later write transactions rather - than growing the file. This method should be called before performing long - blocking operations on a background thread on which you previously read data - from the Realm which you no longer need. - - All `Object`, `Results` and `List` instances obtained from this - `Realm` on the current thread are invalidated, and can not longer be used. - The `Realm` itself remains valid, and a new read transaction is implicitly - begun the next time data is read from the Realm. - - Calling this method multiple times in a row without reading any data from the - Realm, or before ever reading any data from the Realm is a no-op. This method - cannot be called on a read-only Realm. - */ + Invalidates all `Object`s, `Results`, `LinkingObjects`, and `List`s managed by the Realm. + + A Realm holds a read lock on the version of the data accessed by it, so + that changes made to the Realm on different threads do not modify or delete the + data seen by this Realm. Calling this method releases the read lock, + allowing the space used on disk to be reused by later write transactions rather + than growing the file. This method should be called before performing long + blocking operations on a background thread on which you previously read data + from the Realm which you no longer need. + + All `Object`, `Results` and `List` instances obtained from this `Realm` instance on the current thread are + invalidated. `Object`s and `Array`s cannot be used. `Results` will become empty. The Realm itself remains valid, + and a new read transaction is implicitly begun the next time data is read from the Realm. + + Calling this method multiple times in a row without reading any data from the + Realm, or before ever reading any data from the Realm, is a no-op. This method + may not be called on a read-only Realm. + */ public func invalidate() { rlmRealm.invalidate() } @@ -569,20 +548,20 @@ public final class Realm { // MARK: Writing a Copy /** - Write an encrypted and compacted copy of the Realm to the given local URL. + Writes a compacted and optionally encrypted copy of the Realm to the given local URL. - The destination file cannot already exist. + The destination file cannot already exist. - Note that if this is called from within a write transaction it writes the - *current* data, and not data when the last write transaction was committed. + Note that if this method is called from within a write transaction, the *current* data is written, not the data + from the point when the previous write transaction was committed. - - parameter fileURL: Local URL to save the Realm to. - - parameter encryptionKey: Optional 64-byte encryption key to encrypt the new file with. + - parameter fileURL: Local URL to save the Realm to. + - parameter encryptionKey: Optional 64-byte encryption key to encrypt the new file with. - - throws: An NSError if the copy could not be written. - */ - public func writeCopy(toFileURL url: URL, encryptionKey: Data? = nil) throws { - try rlmRealm.writeCopy(to: url, encryptionKey: encryptionKey) + - throws: An `NSError` if the copy could not be written. + */ + public func writeCopy(toFile fileURL: URL, encryptionKey: Data? = nil) throws { + try rlmRealm.writeCopy(to: fileURL, encryptionKey: encryptionKey) } // MARK: Internal @@ -598,81 +577,58 @@ public final class Realm { extension Realm: Equatable { } -/// Returns whether the two realms are equal. +/// Returns whether two `Realm` isntances are equal. public func == (lhs: Realm, rhs: Realm) -> Bool { // swiftlint:disable:this valid_docs return lhs.rlmRealm == rhs.rlmRealm } // MARK: Notifications -/// A notification due to changes to a realm. -public enum Notification: String { - /** - Posted when the data in a realm has changed. - - DidChange is posted after a realm has been refreshed to reflect a write transaction, i.e. when - an autorefresh occurs, `refresh()` is called, after an implicit refresh from - `write(_:)`/`beginWrite()`, and after a local write transaction is committed. - */ - case DidChange = "RLMRealmDidChangeNotification" - - /** - Posted when a write transaction has been committed to a Realm on a different thread for the same - file. This is not posted if `autorefresh` is enabled or if the Realm is refreshed before the - notification has a chance to run. - - Realms with autorefresh disabled should normally have a handler for this notification which - calls `refresh()` after doing some work. - While not refreshing is allowed, it may lead to large Realm files as Realm has to keep an extra - copy of the data for the un-refreshed Realm. - */ - case RefreshRequired = "RLMRealmRefreshRequiredNotification" +extension Realm { + /// A notification indicating that changes were made to a Realm. + public enum Notification: String { + /** + This notification is posted when the data in a Realm has changed. + + `didChange` is posted after a Realm has been refreshed to reflect a write transaction, This can happen when an + autorefresh occurs, `refresh()` is called, after an implicit refresh from `write(_:)`/`beginWrite()`, or after + a local write transaction is committed. + */ + case didChange = "RLMRealmDidChangeNotification" + + /** + This notification is posted when a write transaction has been committed to a Realm on a different thread for + the same file. + + It is not posted if `autorefresh` is enabled, or if the Realm is refreshed before the notification has a chance + to run. + + Realms with autorefresh disabled should normally install a handler for this notification which calls + `refresh()` after doing some work. Refreshing the Realm is optional, but not refreshing the Realm may lead to + large Realm files. This is because an extra copy of the data must be kept for the stale Realm. + */ + case refreshRequired = "RLMRealmRefreshRequiredNotification" + } } -/// Closure to run when the data in a Realm was modified. -public typealias NotificationBlock = (_ notification: Notification, _ realm: Realm) -> Void +/// The type of a block to run for notification purposes when the data in a Realm is modified. +public typealias NotificationBlock = (_ notification: Realm.Notification, _ realm: Realm) -> Void // MARK: Unavailable extension Realm { - @available(*, unavailable, renamed:"isInWriteTransaction") - public var inWriteTransaction : Bool { fatalError() } - - @available(*, unavailable, renamed:"createObject(ofType:populatedWith:update:)") - public func create(_ type: T.Type, value: AnyObject = [:] as NSDictionary, update: Bool = false) -> T { fatalError() } + @available(*, unavailable, renamed: "isInWriteTransaction") + public var inWriteTransaction: Bool { fatalError() } - @available(*, unavailable, renamed:"createDynamicObject(ofType:populatedWith:update:)") - public func dynamicCreate(_ className: String, value: AnyObject = [:] as NSDictionary, update: Bool = false) -> DynamicObject { - fatalError() - } - - @available(*, unavailable, renamed:"delete(_:)") - public func delete(objects: List) { } - - @available(*, unavailable, renamed:"delete(_:)") - public func delete(objects: Results) { } - - @available(*, unavailable, renamed:"deleteAllObjects()") - public func deleteAll() { } - - @available(*, unavailable, renamed:"allObjects(ofType:)") - public func objects(_ type: T.Type) -> Results { fatalError() } - - @available(*, unavailable, renamed:"allDynamicObjects(ofType:)") - public func dynamicObjects(_ className: String) -> Results { fatalError() } - - @available(*, unavailable, renamed:"object(ofType:forPrimaryKey:)") + @available(*, unavailable, renamed: "object(ofType:forPrimaryKey:)") public func objectForPrimaryKey(_ type: T.Type, key: AnyObject) -> T? { fatalError() } - @available(*, unavailable, renamed:"dynamicObject(ofType:forPrimaryKey:)") + @available(*, unavailable, renamed: "dynamicObject(ofType:forPrimaryKey:)") public func dynamicObjectForPrimaryKey(_ className: String, key: AnyObject) -> DynamicObject? { fatalError() } - @available(*, unavailable, renamed:"shouldAutorefresh") - public var autorefresh : Bool { get { fatalError() } set { fatalError() } } - - @available(*, unavailable, renamed:"writeCopy(toFileURL:encryptionKey:)") + @available(*, unavailable, renamed: "writeCopy(toFile:encryptionKey:)") public func writeCopyToURL(_ fileURL: NSURL, encryptionKey: Data? = nil) throws { fatalError() } } @@ -987,7 +943,7 @@ public final class Realm { } /** - Deletes one or more objects from the Realm. + Deletes zero or more objects from the Realm. - warning: This method may only be called during a write transaction. @@ -1001,7 +957,7 @@ public final class Realm { } /** - Deletes one or more objects from the Realm. + Deletes zero or more objects from the Realm. - warning: This method may only be called during a write transaction. @@ -1014,7 +970,7 @@ public final class Realm { } /** - Deletes one or more objects from the Realm. + Deletes zero or more objects from the Realm. - warning: This method may only be called during a write transaction. @@ -1130,7 +1086,7 @@ public final class Realm { `notification`: the incoming notification; `realm`: the Realm for which the notification occurred. - - returns: A token which must be retained for as long as you wish to continue receiving change notifications. + - returns: A token which must be held for as long as you wish to continue receiving change notifications. */ @warn_unused_result(message="You must hold on to the NotificationToken returned from addNotificationBlock") public func addNotificationBlock(block: NotificationBlock) -> NotificationToken { @@ -1283,7 +1239,7 @@ public enum Notification: String { Realms with autorefresh disabled should normally install a handler for this notification which calls `refresh()` after doing some work. Refreshing the Realm is optional, but not refreshing the Realm may lead to large Realm - files. This is because Realm must keep an extra copy of the data for the stale Realm. + files. This is because an extra copy of the data must be kept for the stale Realm. */ case RefreshRequired = "RLMRealmRefreshRequiredNotification" } diff --git a/RealmSwift/RealmCollectionType.swift b/RealmSwift/RealmCollection.swift similarity index 52% rename from RealmSwift/RealmCollectionType.swift rename to RealmSwift/RealmCollection.swift index 6ff4b83ab0..f6893fa9df 100644 --- a/RealmSwift/RealmCollectionType.swift +++ b/RealmSwift/RealmCollection.swift @@ -22,11 +22,11 @@ import Realm #if swift(>=3.0) /** -Encapsulates iteration state and interface for iteration over a `RealmCollection`. -*/ + An iterator for a `RealmCollection` instance. + */ public final class RLMIterator: IteratorProtocol { private var i: UInt = 0 - private let generatorBase : NSFastEnumerationIterator + private let generatorBase: NSFastEnumerationIterator init(collection: RLMCollection) { generatorBase = NSFastEnumerationIterator(collection) @@ -43,324 +43,312 @@ public final class RLMIterator: IteratorProtocol { } /** - RealmCollectionChange is passed to the notification blocks for Realm - collections, and reports the current state of the collection and what changes - were made to the collection since the last time the notification was called. - - The arrays of indices in the .Update case follow UITableView's batching - conventions, and can be passed as-is to a table view's batch update functions - after converting to index paths in the appropriate section. For example, for a - simple one-section table view, you can do the following: - - self.notificationToken = results.addNotificationBlock { changes - switch changes { - case .Initial: - // Results are now populated and can be accessed without blocking the UI - self.tableView.reloadData() - break - case .Update(_, let deletions, let insertions, let modifications): - // Query results have changed, so apply them to the TableView - self.tableView.beginUpdates() - self.tableView.insertRowsAtIndexPaths(insertions.map { NSIndexPath(forRow: $0, inSection: 0) }, - withRowAnimation: .Automatic) - self.tableView.deleteRowsAtIndexPaths(deletions.map { NSIndexPath(forRow: $0, inSection: 0) }, - withRowAnimation: .Automatic) - self.tableView.reloadRowsAtIndexPaths(modifications.map { NSIndexPath(forRow: $0, inSection: 0) }, - withRowAnimation: .Automatic) - self.tableView.endUpdates() - break - case .Error(let err): - // An error occurred while opening the Realm file on the background worker thread - fatalError("\(err)") - break - } - } + A `RealmCollectionChange` value encapsulates information about changes to collections + that are reported by Realm notifications. + + The change information is available in two formats: a simple array of row + indices in the collection for each type of change, and an array of index paths + in a requested section suitable for passing directly to `UITableView`'s batch + update methods. + + The arrays of indices in the `.Update` case follow `UITableView`'s batching + conventions, and can be passed as-is to a table view's batch update functions after being converted to index paths. + For example, for a simple one-section table view, you can do the following: + + ```swift + self.notificationToken = results.addNotificationBlock { changes in + switch changes { + case .initial: + // Results are now populated and can be accessed without blocking the UI + self.tableView.reloadData() + break + case .update(_, let deletions, let insertions, let modifications): + // Query results have changed, so apply them to the TableView + self.tableView.beginUpdates() + self.tableView.insertRowsAtIndexPaths(insertions.map { NSIndexPath(forRow: $0, inSection: 0) }, + withRowAnimation: .Automatic) + self.tableView.deleteRowsAtIndexPaths(deletions.map { NSIndexPath(forRow: $0, inSection: 0) }, + withRowAnimation: .Automatic) + self.tableView.reloadRowsAtIndexPaths(modifications.map { NSIndexPath(forRow: $0, inSection: 0) }, + withRowAnimation: .Automatic) + self.tableView.endUpdates() + break + case .error(let err): + // An error occurred while opening the Realm file on the background worker thread + fatalError("\(err)") + break + } + } + ``` */ public enum RealmCollectionChange { - /// The initial run of the query has completed (if applicable), and the - /// collection can now be used without performing any blocking work. - case Initial(T) + /** + `.initial` indicates that the initial run of the query has completed (if applicable), and the collection can now be + used without performing any blocking work. + */ + case initial(T) - /// A write transaction has been committed which either changed which objects - /// are in the collection and/or modified one or more of the objects in the - /// collection. - /// - /// All three of the change arrays are always sorted in ascending order. - /// - /// - parameter deletions: The indices in the previous version of the collection - /// which were removed from this one. - /// - parameter insertions: The indices in the new collection which were added in - /// this version. - /// - parameter modifications: The indices of the objects in the new collection which - /// were modified in this version. - case Update(T, deletions: [Int], insertions: [Int], modifications: [Int]) + /** + `.update` indicates that a write transaction has been committed which either changed which objects + are in the collection, and/or modified one or more of the objects in the collection. - /// If an error occurs, notification blocks are called one time with a - /// .Error result and an NSError with details. Currently the only thing - /// that can fail is opening the Realm on a background worker thread to - /// calculate the change set. - case Error(Swift.Error) + All three of the change arrays are always sorted in ascending order. + + - parameter deletions: The indices in the previous version of the collection which were removed from this one. + - parameter insertions: The indices in the new collection which were added in this version. + - parameter modifications: The indices of the objects in the new collection which were modified in this version. + */ + case update(T, deletions: [Int], insertions: [Int], modifications: [Int]) + + /** + If an error occurs, notification blocks are called one time with a `.error` result and an `NSError` containing + details about the error. This can only currently happen if the Realm is opened on a background worker thread to + calculate the change set. + */ + case error(Swift.Error) static func fromObjc(value: T, change: RLMCollectionChange?, error: Swift.Error?) -> RealmCollectionChange { if let error = error { - return .Error(error) + return .error(error) } if let change = change { - return .Update(value, + return .update(value, deletions: change.deletions as [Int], insertions: change.insertions as [Int], modifications: change.modifications as [Int]) } - return .Initial(value) + return .initial(value) } } /** -A homogenous collection of `Object`s which can be retrieved, filtered, sorted, -and operated upon. + A homogenous collection of `Object`s which can be retrieved, filtered, sorted, and operated upon. */ public protocol RealmCollection: RandomAccessCollection, LazyCollectionProtocol, CustomStringConvertible { - /// Element type contained in this collection. + /// The type of the objects contained in the collection. associatedtype Element: Object // MARK: Properties - /// The Realm the objects in this collection belong to, or `nil` if the - /// collection's owning object does not belong to a realm (the collection is - /// standalone). + /// The Realm which manages the collection, or `nil` for unmanaged collections. var realm: Realm? { get } - /// Indicates if the collection can no longer be accessed. - /// - /// The collection can no longer be accessed if `invalidate` is called on the containing `Realm`. + /** + Indicates if the collection can no longer be accessed. + + The collection can no longer be accessed if `invalidate()` is called on the `Realm` that manages the collection. + */ var isInvalidated: Bool { get } - /// Returns the number of objects in this collection. + /// The number of objects in the collection. var count: Int { get } - /// Returns a human-readable description of the objects contained in this collection. + /// A human-readable description of the objects contained in the collection. var description: String { get } // MARK: Index Retrieval /** - Returns the index of the given object, or `nil` if the object is not in the collection. - - - parameter object: The object whose index is being queried. + Returns the index of an object in the collection, or `nil` if the object is not present. - - returns: The index of the given object, or `nil` if the object is not in the collection. - */ + - parameter object: An object. + */ func index(of object: Element) -> Int? /** - Returns the index of the first object matching the given predicate, - or `nil` no objects match. - - - parameter predicate: The `NSPredicate` used to filter the objects. + Returns the index of the first object matching the predicate, or `nil` if no objects match. - - returns: The index of the first matching object, or `nil` if no objects match. - */ - func indexOfObject(for predicate: NSPredicate) -> Int? + - parameter predicate: The predicate to use to filter the objects. + */ + func index(matching predicate: NSPredicate) -> Int? /** - Returns the index of the first object matching the given predicate, - or `nil` if no objects match. - - - parameter predicateFormat: The predicate format string, optionally followed by a variable number - of arguments. + Returns the index of the first object matching the predicate, or `nil` if no objects match. - - returns: The index of the first matching object, or `nil` if no objects match. - */ - func indexOfObject(for predicateFormat: String, _ args: Any...) -> Int? + - parameter predicateFormat: A predicate format string, optionally followed by a variable number of arguments. + */ + func index(matching predicateFormat: String, _ args: Any...) -> Int? // MARK: Filtering /** - Returns `Results` containing collection elements that match the given predicate. - - - parameter predicateFormat: The predicate format string which can accept variable arguments. + Returns a `Results` containing all objects matching the given predicate in the collection. - - returns: `Results` containing collection elements that match the given predicate. - */ - func filter(using predicateFormat: String, _ args: Any...) -> Results + - parameter predicateFormat: A predicate format string, optionally followed by a variable number of arguments. + */ + func filter(_ predicateFormat: String, _ args: Any...) -> Results /** - Returns `Results` containing collection elements that match the given predicate. - - - parameter predicate: The predicate to filter the objects. + Returns a `Results` containing all objects matching the given predicate in the collection. - - returns: `Results` containing collection elements that match the given predicate. - */ - func filter(using predicate: NSPredicate) -> Results + - parameter predicate: The predicate to use to filter the objects. + */ + func filter(_ predicate: NSPredicate) -> Results // MARK: Sorting /** - Returns `Results` containing collection elements sorted by the given property. + Returns a `Results` containing the objects in the collection, but sorted. - - parameter property: The property name to sort by. - - parameter ascending: The direction to sort by. + Objects are sorted based on the values of the given property. For example, to sort a collection of `Student`s from + youngest to oldest based on their `age` property, you might call + `students.sorted(byProperty: "age", ascending: true)`. - - returns: `Results` containing collection elements sorted by the given property. - */ - func sorted(onProperty property: String, ascending: Bool) -> Results + - warning: Collections may only be sorted by properties of boolean, `Date`, `NSDate`, single and double-precision + floating point, integer, and string types. + + - parameter property: The name of the property to sort by. + - parameter ascending: The direction to sort in. + */ + func sorted(byProperty property: String, ascending: Bool) -> Results /** - Returns `Results` with elements sorted by the given sort descriptors. + Returns a `Results` containing the objects in the collection, but sorted. - - parameter sortDescriptors: `SortDescriptor`s to sort by. + - warning: Collections may only be sorted by properties of boolean, `Date`, `NSDate`, single and double-precision + floating point, integer, and string types. - - returns: `Results` with elements sorted by the given sort descriptors. - */ - func sorted(with sortDescriptors: S) -> Results where S.Iterator.Element == SortDescriptor + - see: `sorted(byProperty:ascending:)` + - parameter sortDescriptors: A sequence of `SortDescriptor`s to sort by. + */ + func sorted(by sortDescriptors: S) -> Results where S.Iterator.Element == SortDescriptor // MARK: Aggregate Operations /** - Returns the minimum value of the given property. + Returns the minimum (lowest) value of the given property among all the objects in the collection, or `nil` if the + collection is empty. - - warning: Only names of properties of a type conforming to the `MinMaxType` protocol can be used. - - - parameter property: The name of a property conforming to `MinMaxType` to look for a minimum on. + - warning: Only a property whose type conforms to the `MinMaxType` protocol can be specified. - - returns: The minimum value for the property amongst objects in the collection, or `nil` if the - collection is empty. - */ - func minimumValue(ofProperty property: String) -> U? + - parameter property: The name of a property whose minimum value is desired. + */ + func min(ofProperty property: String) -> U? /** - Returns the maximum value of the given property. - - - warning: Only names of properties of a type conforming to the `MinMaxType` protocol can be used. + Returns the maximum (highest) value of the given property among all the objects in the collection, or `nil` if the + collection is empty. - - parameter property: The name of a property conforming to `MinMaxType` to look for a maximum on. + - warning: Only a property whose type conforms to the `MinMaxType` protocol can be specified. - - returns: The maximum value for the property amongst objects in the collection, or `nil` if the - collection is empty. - */ - func maximumValue(ofProperty property: String) -> U? + - parameter property: The name of a property whose minimum value is desired. + */ + func max(ofProperty property: String) -> U? /** - Returns the sum of the given property for objects in the collection. + Returns the sum of the given property for objects in the collection, or `nil` if the collection is empty. - warning: Only names of properties of a type conforming to the `AddableType` protocol can be used. - parameter property: The name of a property conforming to `AddableType` to calculate sum on. - - - returns: The sum of the given property over all objects in the collection. */ func sum(ofProperty property: String) -> U /** - Returns the average of the given property for objects in the collection. - - - warning: Only names of properties of a type conforming to the `AddableType` protocol can be used. + Returns the sum of the values of a given property over all the objects in the collection. - - parameter property: The name of a property conforming to `AddableType` to calculate average on. + - warning: Only a property whose type conforms to the `AddableType` protocol can be specified. - - returns: The average of the given property over all objects in the collection, or `nil` if the - collection is empty. - */ + - parameter property: The name of a property whose values should be summed. + */ func average(ofProperty property: String) -> U? // MARK: Key-Value Coding /** - Returns an Array containing the results of invoking `valueForKey(_:)` using key on each of the collection's objects. - - - parameter key: The name of the property. + Returns an `Array` containing the results of invoking `valueForKey(_:)` with `key` on each of the collection's + objects. - - returns: Array containing the results of invoking `valueForKey(_:)` using key on each of the collection's objects. - */ + - parameter key: The name of the property whose values are desired. + */ func value(forKey key: String) -> Any? /** - Returns an Array containing the results of invoking `valueForKeyPath(_:)` using keyPath on each of the + Returns an `Array` containing the results of invoking `valueForKeyPath(_:)` with `keyPath` on each of the collection's objects. - - parameter keyPath: The key path to the property. - - - returns: Array containing the results of invoking `valueForKeyPath(_:)` using keyPath on each of the - collection's objects. + - parameter keyPath: The key path to the property whose values are desired. */ func value(forKeyPath keyPath: String) -> Any? /** - Invokes `setValue(_:forKey:)` on each of the collection's objects using the specified value and key. + Invokes `setValue(_:forKey:)` on each of the collection's objects using the specified `value` and `key`. - - warning: This method can only be called during a write transaction. + - warning: This method may only be called during a write transaction. - - parameter value: The object value. - - parameter key: The name of the property. - */ + - parameter value: The object value. + - parameter key: The name of the property whose value should be set on each object. + */ func setValue(_ value: Any?, forKey key: String) // MARK: Notifications /** - Register a block to be called each time the collection changes. + Registers a block to be called each time the collection changes. - The block will be asynchronously called with the initial results, and then - called again after each write transaction which changes either any of the - objects in the collection, or which objects are in the collection. + The block will be asynchronously called with the initial results, and then called again after each write + transaction which changes either any of the objects in the collection, or which objects are in the collection. - At the time when the block is called, the collection object will be fully - evaluated and up-to-date, and as long as you do not perform a write - transaction on the same thread or explicitly call realm.refresh(), - accessing it will never perform blocking work. + The `change` parameter that is passed to the block reports, in the form of indices within the collection, which of + the objects were added, removed, or modified during each write transaction. See the `RealmCollectionChange` + documentation for more information on the change information supplied and an example of how to use it to update a + `UITableView`. - Notifications are delivered via the standard run loop, and so can't be - delivered while the run loop is blocked by other activity. When - notifications can't be delivered instantly, multiple notifications may be - coalesced into a single notification. This can include the notification - with the initial collection. For example, the following code performs a write - transaction immediately after adding the notification block, so there is no - opportunity for the initial notification to be delivered first. As a - result, the initial notification will reflect the state of the Realm after - the write transaction. + At the time when the block is called, the collection will be fully evaluated and up-to-date, and as long as you do + not perform a write transaction on the same thread or explicitly call `realm.refresh()`, accessing it will never + perform blocking work. - let results = realm.objects(Dog) - print("dogs.count: \(dogs?.count)") // => 0 - let token = dogs.addNotificationBlock { (changes: RealmCollectionChange) in - switch changes { - case .Initial(let dogs): - // Will print "dogs.count: 1" - print("dogs.count: \(dogs.count)") - break - case .Update: - // Will not be hit in this example - break - case .Error: - break - } - } - try! realm.write { - let dog = Dog() - dog.name = "Rex" - person.dogs.append(dog) + Notifications are delivered via the standard run loop, and so can't be delivered while the run loop is blocked by + other activity. When notifications can't be delivered instantly, multiple notifications may be coalesced into a + single notification. This can include the notification with the initial collection. + + For example, the following code performs a write transaction immediately after adding the notification block, so + there is no opportunity for the initial notification to be delivered first. As a result, the initial notification + will reflect the state of the Realm after the write transaction. + + ```swift + let results = realm.objects(Dog.self) + print("dogs.count: \(dogs?.count)") // => 0 + let token = dogs.addNotificationBlock { changes in + switch changes { + case .initial(let dogs): + // Will print "dogs.count: 1" + print("dogs.count: \(dogs.count)") + break + case .update: + // Will not be hit in this example + break + case .error: + break } - // end of run loop execution context + } + try! realm.write { + let dog = Dog() + dog.name = "Rex" + person.dogs.append(dog) + } + // end of run loop execution context + ``` - You must retain the returned token for as long as you want updates to continue - to be sent to the block. To stop receiving updates, call stop() on the token. + You must retain the returned token for as long as you want updates to be sent to the block. To stop receiving + updates, call `stop()` on the token. - - warning: This method cannot be called during a write transaction, or when - the source realm is read-only. + - warning: This method cannot be called during a write transaction, or when the containing Realm is read-only. - - parameter block: The block to be called with the evaluated collection and change information. + - parameter block: The block to be called whenever a change occurs. - returns: A token which must be held for as long as you want updates to be delivered. */ - func addNotificationBlock(block: @escaping (RealmCollectionChange) -> Void) -> NotificationToken + func addNotificationBlock(_ block: @escaping (RealmCollectionChange) -> Void) -> NotificationToken /// :nodoc: - func _addNotificationBlock(block: @escaping (RealmCollectionChange>) -> Void) -> NotificationToken + func _addNotificationBlock(_ block: @escaping (RealmCollectionChange>) -> Void) -> NotificationToken } private class _AnyRealmCollectionBase { @@ -371,16 +359,16 @@ private class _AnyRealmCollectionBase { var count: Int { fatalError() } var description: String { fatalError() } func index(of object: Element) -> Int? { fatalError() } - func indexOfObject(for predicate: NSPredicate) -> Int? { fatalError() } - func indexOfObject(for predicateFormat: String, _ args: Any...) -> Int? { fatalError() } - func filter(using predicateFormat: String, _ args: Any...) -> Results { fatalError() } - func filter(using predicate: NSPredicate) -> Results { fatalError() } - func sorted(onProperty property: String, ascending: Bool) -> Results { fatalError() } - func sorted(with sortDescriptors: S) -> Results where S.Iterator.Element == SortDescriptor { + func index(matching predicate: NSPredicate) -> Int? { fatalError() } + func index(matching predicateFormat: String, _ args: Any...) -> Int? { fatalError() } + func filter(_ predicateFormat: String, _ args: Any...) -> Results { fatalError() } + func filter(_ predicate: NSPredicate) -> Results { fatalError() } + func sorted(byProperty property: String, ascending: Bool) -> Results { fatalError() } + func sorted(by sortDescriptors: S) -> Results where S.Iterator.Element == SortDescriptor { fatalError() } - func minimumValue(ofProperty property: String) -> U? { fatalError() } - func maximumValue(ofProperty property: String) -> U? { fatalError() } + func min(ofProperty property: String) -> U? { fatalError() } + func max(ofProperty property: String) -> U? { fatalError() } func sum(ofProperty property: String) -> U { fatalError() } func average(ofProperty property: String) -> U? { fatalError() } subscript(position: Int) -> Element { fatalError() } @@ -390,7 +378,7 @@ private class _AnyRealmCollectionBase { func value(forKey key: String) -> Any? { fatalError() } func value(forKeyPath keyPath: String) -> Any? { fatalError() } func setValue(_ value: Any?, forKey key: String) { fatalError() } - func _addNotificationBlock(block: @escaping (RealmCollectionChange) -> Void) + func _addNotificationBlock(_ block: @escaping (RealmCollectionChange) -> Void) -> NotificationToken { fatalError() } } @@ -402,160 +390,56 @@ private final class _AnyRealmCollection: _AnyRealmCollection // MARK: Properties - /// The Realm the objects in this collection belong to, or `nil` if the - /// collection's owning object does not belong to a realm (the collection is - /// standalone). override var realm: Realm? { return base.realm } - - /// Indicates if the collection can no longer be accessed. - /// - /// The collection can no longer be accessed if `invalidate` is called on the containing `Realm`. override var isInvalidated: Bool { return base.isInvalidated } - - /// Returns the number of objects in this collection. override var count: Int { return base.count } - - /// Returns a human-readable description of the objects contained in this collection. override var description: String { return base.description } // MARK: Index Retrieval - /** - Returns the index of the given object, or `nil` if the object is not in the collection. - - - parameter object: The object whose index is being queried. - - - returns: The index of the given object, or `nil` if the object is not in the collection. - */ override func index(of object: C.Element) -> Int? { return base.index(of: object) } - /** - Returns the index of the first object matching the given predicate, - or `nil` no objects match. - - - parameter predicate: The `NSPredicate` used to filter the objects. - - - returns: The index of the first matching object, or `nil` if no objects match. - */ - override func indexOfObject(for predicate: NSPredicate) -> Int? { return base.indexOfObject(for: predicate) } - - /** - Returns the index of the first object matching the given predicate, - or `nil` if no objects match. - - - parameter predicateFormat: The predicate format string, optionally followed by a variable number - of arguments. + override func index(matching predicate: NSPredicate) -> Int? { return base.index(matching: predicate) } - - returns: The index of the first matching object, or `nil` if no objects match. - */ - override func indexOfObject(for predicateFormat: String, _ args: Any...) -> Int? { - return base.indexOfObject(for: NSPredicate(format: predicateFormat, argumentArray: args)) + override func index(matching predicateFormat: String, _ args: Any...) -> Int? { + return base.index(matching: NSPredicate(format: predicateFormat, argumentArray: args)) } // MARK: Filtering - /** - Returns `Results` containing collection elements that match the given predicate. - - - parameter predicateFormat: The predicate format string which can accept variable arguments. - - - returns: `Results` containing collection elements that match the given predicate. - */ - override func filter(using predicateFormat: String, _ args: Any...) -> Results { - return base.filter(using: NSPredicate(format: predicateFormat, argumentArray: args)) + override func filter(_ predicateFormat: String, _ args: Any...) -> Results { + return base.filter(NSPredicate(format: predicateFormat, argumentArray: args)) } - /** - Returns `Results` containing collection elements that match the given predicate. - - - parameter predicate: The predicate to filter the objects. - - - returns: `Results` containing collection elements that match the given predicate. - */ - override func filter(using predicate: NSPredicate) -> Results { return base.filter(using: predicate) } - + override func filter(_ predicate: NSPredicate) -> Results { return base.filter(predicate) } // MARK: Sorting - /** - Returns `Results` containing collection elements sorted by the given property. - - - parameter property: The property name to sort by. - - parameter ascending: The direction to sort by. - - - returns: `Results` containing collection elements sorted by the given property. - */ - override func sorted(onProperty property: String, ascending: Bool) -> Results { - return base.sorted(onProperty: property, ascending: ascending) + override func sorted(byProperty property: String, ascending: Bool) -> Results { + return base.sorted(byProperty: property, ascending: ascending) } - /** - Returns `Results` with elements sorted by the given sort descriptors. - - - parameter sortDescriptors: `SortDescriptor`s to sort by. - - - returns: `Results` with elements sorted by the given sort descriptors. - */ override func sorted - (with sortDescriptors: S) -> Results where S.Iterator.Element == SortDescriptor { - return base.sorted(with: sortDescriptors) + (by sortDescriptors: S) -> Results where S.Iterator.Element == SortDescriptor { + return base.sorted(by: sortDescriptors) } // MARK: Aggregate Operations - /** - Returns the minimum value of the given property. - - - warning: Only names of properties of a type conforming to the `MinMaxType` protocol can be used. - - - parameter property: The name of a property conforming to `MinMaxType` to look for a minimum on. - - - returns: The minimum value for the property amongst objects in the collection, or `nil` if the - collection is empty. - */ - override func minimumValue(ofProperty property: String) -> U? { - return base.minimumValue(ofProperty: property) + override func min(ofProperty property: String) -> U? { + return base.min(ofProperty: property) } - /** - Returns the maximum value of the given property. - - - warning: Only names of properties of a type conforming to the `MinMaxType` protocol can be used. - - - parameter property: The name of a property conforming to `MinMaxType` to look for a maximum on. - - - returns: The maximum value for the property amongst objects in the collection, or `nil` if the - collection is empty. - */ - override func maximumValue(ofProperty property: String) -> U? { - return base.maximumValue(ofProperty: property) + override func max(ofProperty property: String) -> U? { + return base.max(ofProperty: property) } - /** - Returns the sum of the given property for objects in the collection. - - - warning: Only names of properties of a type conforming to the `AddableType` protocol can be used. - - - parameter property: The name of a property conforming to `AddableType` to calculate sum on. - - - returns: The sum of the given property over all objects in the collection. - */ override func sum(ofProperty property: String) -> U { return base.sum(ofProperty: property) } - /** - Returns the average of the given property for objects in the collection. - - - warning: Only names of properties of a type conforming to the `AddableType` protocol can be used. - - - parameter property: The name of a property conforming to `AddableType` to calculate average on. - - - returns: The average of the given property over all objects in the collection, or `nil` if the - collection is empty. - */ override func average(ofProperty property: String) -> U? { return base.average(ofProperty: property) } @@ -563,19 +447,11 @@ private final class _AnyRealmCollection: _AnyRealmCollection // MARK: Sequence Support - /** - Returns the object at the given `index`. - - - parameter index: The index. - - - returns: The object at the given `index`. - */ override subscript(position: Int) -> C.Element { // FIXME: it should be possible to avoid this force-casting return unsafeBitCast(base[position as! C.Index], to: C.Element.self) } - /// Returns a `RLMIterator` that yields successive elements in the collection. override func makeIterator() -> RLMIterator { // FIXME: it should be possible to avoid this force-casting return base.makeIterator() as! RLMIterator @@ -584,16 +460,11 @@ private final class _AnyRealmCollection: _AnyRealmCollection // MARK: Collection Support - /// The position of the first element in a non-empty collection. - /// Identical to endIndex in an empty collection. override var startIndex: Int { // FIXME: it should be possible to avoid this force-casting return base.startIndex as! Int } - /// The collection's "past the end" position. - /// endIndex is not a valid argument to subscript, and is always reachable from startIndex by - /// zero or more applications of successor(). override var endIndex: Int { // FIXME: it should be possible to avoid this force-casting return base.endIndex as! Int @@ -602,229 +473,191 @@ private final class _AnyRealmCollection: _AnyRealmCollection // MARK: Key-Value Coding - /** - Returns an Array containing the results of invoking `valueForKey(_:)` using key on each of the collection's objects. - - - parameter key: The name of the property. - - - returns: Array containing the results of invoking `valueForKey(_:)` using key on each of the collection's objects. - */ override func value(forKey key: String) -> Any? { return base.value(forKey: key) } - /** - Returns an Array containing the results of invoking `valueForKeyPath(_:)` using keyPath on each of the - collection's objects. - - - parameter keyPath: The key path to the property. - - - returns: Array containing the results of invoking `valueForKeyPath(_:)` using keyPath on each of the - collection's objects. - */ override func value(forKeyPath keyPath: String) -> Any? { return base.value(forKeyPath: keyPath) } - /** - Invokes `setValue(_:forKey:)` on each of the collection's objects using the specified value and key. - - - warning: This method can only be called during a write transaction. - - - parameter value: The object value. - - parameter key: The name of the property. - */ override func setValue(_ value: Any?, forKey key: String) { base.setValue(value, forKey: key) } // MARK: Notifications /// :nodoc: - override func _addNotificationBlock(block: @escaping (RealmCollectionChange) -> Void) - -> NotificationToken { return base._addNotificationBlock(block: block) } + override func _addNotificationBlock(_ block: @escaping (RealmCollectionChange) -> Void) + -> NotificationToken { return base._addNotificationBlock(block) } } /** -A type-erased `RealmCollection`. + A type-erased `RealmCollection`. -Forwards operations to an arbitrary underlying collection having the same -Element type, hiding the specifics of the underlying `RealmCollection`. -*/ + Instances of `RealmCollection` forward operations to an opaque underlying collection having the same `Element` type. + */ public final class AnyRealmCollection: RealmCollection { public func index(after i: Int) -> Int { return i + 1 } public func index(before i: Int) -> Int { return i - 1 } - /// Element type contained in this collection. + /// The type of the objects contained in the collection. public typealias Element = T private let base: _AnyRealmCollectionBase - /// Creates an AnyRealmCollection wrapping `base`. + /// Creates an `AnyRealmCollection` wrapping `base`. public init(_ base: C) where C.Element == T { self.base = _AnyRealmCollection(base: base) } // MARK: Properties - /// The Realm the objects in this collection belong to, or `nil` if the - /// collection's owning object does not belong to a realm (the collection is - /// standalone). + /// The Realm which manages the collection, or `nil` if the collection is unmanaged. public var realm: Realm? { return base.realm } - /// Indicates if the collection can no longer be accessed. - /// - /// The collection can no longer be accessed if `invalidate` is called on the containing `Realm`. + /** + Indicates if the collection can no longer be accessed. + + The collection can no longer be accessed if `invalidate()` is called on the containing `realm`. + */ public var isInvalidated: Bool { return base.isInvalidated } - /// Returns the number of objects in this collection. + /// The number of objects in the collection. public var count: Int { return base.count } - /// Returns a human-readable description of the objects contained in this collection. + /// A human-readable description of the objects contained in the collection. public var description: String { return base.description } // MARK: Index Retrieval /** - Returns the index of the given object, or `nil` if the object is not in the collection. - - - parameter object: The object whose index is being queried. + Returns the index of the given object, or `nil` if the object is not in the collection. - - returns: The index of the given object, or `nil` if the object is not in the collection. - */ + - parameter object: An object. + */ public func index(of object: Element) -> Int? { return base.index(of: object) } /** - Returns the index of the first object matching the given predicate, - or `nil` no objects match. - - - parameter predicate: The `NSPredicate` used to filter the objects. + Returns the index of the first object matching the given predicate, or `nil` if no objects match. - - returns: The index of the first matching object, or `nil` if no objects match. - */ - public func indexOfObject(for predicate: NSPredicate) -> Int? { return base.indexOfObject(for: predicate) } + - parameter predicate: The predicate with which to filter the objects. + */ + public func index(matching predicate: NSPredicate) -> Int? { return base.index(matching: predicate) } /** - Returns the index of the first object matching the given predicate, - or `nil` if no objects match. - - - parameter predicateFormat: The predicate format string, optionally followed by a variable number - of arguments. + Returns the index of the first object matching the given predicate, or `nil` if no objects match. - - returns: The index of the first matching object, or `nil` if no objects match. - */ - public func indexOfObject(for predicateFormat: String, _ args: Any...) -> Int? { - return base.indexOfObject(for: NSPredicate(format: predicateFormat, argumentArray: args)) + - parameter predicateFormat: A predicate format string, optionally followed by a variable number of arguments. + */ + public func index(matching predicateFormat: String, _ args: Any...) -> Int? { + return base.index(matching: NSPredicate(format: predicateFormat, argumentArray: args)) } // MARK: Filtering /** - Returns `Results` containing collection elements that match the given predicate. - - - parameter predicateFormat: The predicate format string which can accept variable arguments. + Returns a `Results` containing all objects matching the given predicate in the collection. - - returns: `Results` containing collection elements that match the given predicate. - */ - public func filter(using predicateFormat: String, _ args: Any...) -> Results { - return base.filter(using: NSPredicate(format: predicateFormat, argumentArray: args)) + - parameter predicateFormat: A predicate format string, optionally followed by a variable number of arguments. + */ + public func filter(_ predicateFormat: String, _ args: Any...) -> Results { + return base.filter(NSPredicate(format: predicateFormat, argumentArray: args)) } /** - Returns `Results` containing collection elements that match the given predicate. + Returns a `Results` containing all objects matching the given predicate in the collection. - - parameter predicate: The predicate to filter the objects. + - parameter predicate: The predicate with which to filter the objects. - - returns: `Results` containing collection elements that match the given predicate. - */ - public func filter(using predicate: NSPredicate) -> Results { return base.filter(using: predicate) } + - returns: A `Results` containing objects that match the given predicate. + */ + public func filter(_ predicate: NSPredicate) -> Results { return base.filter(predicate) } // MARK: Sorting /** - Returns `Results` containing collection elements sorted by the given property. + Returns a `Results` containing the objects in the collection, but sorted. + + Objects are sorted based on the values of the given property. For example, to sort a collection of `Student`s from + youngest to oldest based on their `age` property, you might call + `students.sorted(byProperty: "age", ascending: true)`. - - parameter property: The property name to sort by. - - parameter ascending: The direction to sort by. + - warning: Collections may only be sorted by properties of boolean, `Date`, `NSDate`, single and double-precision + floating point, integer, and string types. - - returns: `Results` containing collection elements sorted by the given property. - */ - public func sorted(onProperty property: String, ascending: Bool) -> Results { - return base.sorted(onProperty: property, ascending: ascending) + - parameter property: The name of the property to sort by. + - parameter ascending: The direction to sort in. + */ + public func sorted(byProperty property: String, ascending: Bool) -> Results { + return base.sorted(byProperty: property, ascending: ascending) } /** - Returns `Results` with elements sorted by the given sort descriptors. + Returns a `Results` containing the objects in the collection, but sorted. - - parameter sortDescriptors: `SortDescriptor`s to sort by. + - warning: Collections may only be sorted by properties of boolean, `Date`, `NSDate`, single and double-precision + floating point, integer, and string types. - - returns: `Results` with elements sorted by the given sort descriptors. - */ - public func sorted(with sortDescriptors: S) -> Results + - see: `sorted(byProperty:ascending:)` + + - parameter sortDescriptors: A sequence of `SortDescriptor`s to sort by. + */ + public func sorted(by sortDescriptors: S) -> Results where S.Iterator.Element == SortDescriptor { - return base.sorted(with: sortDescriptors) + return base.sorted(by: sortDescriptors) } // MARK: Aggregate Operations /** - Returns the minimum value of the given property. + Returns the minimum (lowest) value of the given property among all the objects in the collection, or `nil` if the + collection is empty. - - warning: Only names of properties of a type conforming to the `MinMaxType` protocol can be used. - - - parameter property: The name of a property conforming to `MinMaxType` to look for a minimum on. + - warning: Only a property whose type conforms to the `MinMaxType` protocol can be specified. - - returns: The minimum value for the property amongst objects in the collection, or `nil` if the - collection is empty. - */ - public func minimumValue(ofProperty property: String) -> U? { - return base.minimumValue(ofProperty: property) + - parameter property: The name of a property whose minimum value is desired. + */ + public func min(ofProperty property: String) -> U? { + return base.min(ofProperty: property) } /** - Returns the maximum value of the given property. - - - warning: Only names of properties of a type conforming to the `MinMaxType` protocol can be used. + Returns the maximum (highest) value of the given property among all the objects in the collection, or `nil` if the + collection is empty. - - parameter property: The name of a property conforming to `MinMaxType` to look for a maximum on. + - warning: Only a property whose type conforms to the `MinMaxType` protocol can be specified. - - returns: The maximum value for the property amongst objects in the collection, or `nil` if the - collection is empty. - */ - public func maximumValue(ofProperty property: String) -> U? { - return base.maximumValue(ofProperty: property) + - parameter property: The name of a property whose minimum value is desired. + */ + public func max(ofProperty property: String) -> U? { + return base.max(ofProperty: property) } /** - Returns the sum of the given property for objects in the collection. - - - warning: Only names of properties of a type conforming to the `AddableType` protocol can be used. + Returns the sum of the values of a given property over all the objects in the collection. - - parameter property: The name of a property conforming to `AddableType` to calculate sum on. + - warning: Only a property whose type conforms to the `AddableType` protocol can be specified. - - returns: The sum of the given property over all objects in the collection. - */ + - parameter property: The name of a property whose values should be summed. + */ public func sum(ofProperty property: String) -> U { return base.sum(ofProperty: property) } /** - Returns the average of the given property for objects in the collection. - - - warning: Only names of properties of a type conforming to the `AddableType` protocol can be used. + Returns the average value of a given property over all the objects in the collection, or `nil` if the collection is + empty. - - parameter property: The name of a property conforming to `AddableType` to calculate average on. + - warning: Only the name of a property whose type conforms to the `AddableType` protocol can be specified. - - returns: The average of the given property over all objects in the collection, or `nil` if the - collection is empty. - */ + - parameter property: The name of a property whose average value should be calculated. + */ public func average(ofProperty property: String) -> U? { return base.average(ofProperty: property) } // MARK: Sequence Support /** - Returns the object at the given `index`. - - - parameter index: The index. + Returns the object at the given `index`. - - returns: The object at the given `index`. - */ + - parameter index: The index. + */ public subscript(position: Int) -> T { return base[position] } /// Returns a `RLMIterator` that yields successive elements in the collection. @@ -846,135 +679,127 @@ public final class AnyRealmCollection: RealmCollection { // MARK: Key-Value Coding /** - Returns an Array containing the results of invoking `valueForKey(_:)` using key on each of the collection's objects. - - - parameter key: The name of the property. + Returns an `Array` containing the results of invoking `valueForKey(_:)` with `key` on each of the collection's + objects. - - returns: Array containing the results of invoking `valueForKey(_:)` using key on each of the collection's objects. - */ + - parameter key: The name of the property whose values are desired. + */ public func value(forKey key: String) -> Any? { return base.value(forKey: key) } /** - Returns an Array containing the results of invoking `valueForKeyPath(_:)` using keyPath on each of the + Returns an `Array` containing the results of invoking `valueForKeyPath(_:)` with `keyPath` on each of the collection's objects. - - parameter keyPath: The key path to the property. - - - returns: Array containing the results of invoking `valueForKeyPath(_:)` using keyPath on each of the - collection's objects. + - parameter keyPath: The key path to the property whose values are desired. */ public func value(forKeyPath keyPath: String) -> Any? { return base.value(forKeyPath: keyPath) } /** - Invokes `setValue(_:forKey:)` on each of the collection's objects using the specified value and key. + Invokes `setValue(_:forKey:)` on each of the collection's objects using the specified `value` and `key`. - - warning: This method can only be called during a write transaction. + - warning: This method may only be called during a write transaction. - - parameter value: The object value. - - parameter key: The name of the property. - */ + - parameter value: The value to set the property to. + - parameter key: The name of the property whose value should be set on each object. + */ public func setValue(_ value: Any?, forKey key: String) { base.setValue(value, forKey: key) } // MARK: Notifications /** - Register a block to be called each time the collection changes. + Registers a block to be called each time the collection changes. - The block will be asynchronously called with the initial results, and then - called again after each write transaction which changes either any of the - objects in the collection, or which objects are in the collection. + The block will be asynchronously called with the initial results, and then called again after each write + transaction which changes either any of the objects in the collection, or which objects are in the collection. - At the time when the block is called, the collection object will be fully - evaluated and up-to-date, and as long as you do not perform a write - transaction on the same thread or explicitly call realm.refresh(), - accessing it will never perform blocking work. + The `change` parameter that is passed to the block reports, in the form of indices within the collection, which of + the objects were added, removed, or modified during each write transaction. See the `RealmCollectionChange` + documentation for more information on the change information supplied and an example of how to use it to update a + `UITableView`. - Notifications are delivered via the standard run loop, and so can't be - delivered while the run loop is blocked by other activity. When - notifications can't be delivered instantly, multiple notifications may be - coalesced into a single notification. This can include the notification - with the initial collection. For example, the following code performs a write - transaction immediately after adding the notification block, so there is no - opportunity for the initial notification to be delivered first. As a - result, the initial notification will reflect the state of the Realm after - the write transaction. + At the time when the block is called, the collection will be fully evaluated and up-to-date, and as long as you do + not perform a write transaction on the same thread or explicitly call `realm.refresh()`, accessing it will never + perform blocking work. - let results = realm.objects(Dog) - print("dogs.count: \(dogs?.count)") // => 0 - let token = dogs.addNotificationBlock { (changes: RealmCollectionChange) in - switch changes { - case .Initial(let dogs): - // Will print "dogs.count: 1" - print("dogs.count: \(dogs.count)") - break - case .Update: - // Will not be hit in this example - break - case .Error: - break - } - } - try! realm.write { - let dog = Dog() - dog.name = "Rex" - person.dogs.append(dog) + Notifications are delivered via the standard run loop, and so can't be delivered while the run loop is blocked by + other activity. When notifications can't be delivered instantly, multiple notifications may be coalesced into a + single notification. This can include the notification with the initial collection. + + For example, the following code performs a write transaction immediately after adding the notification block, so + there is no opportunity for the initial notification to be delivered first. As a result, the initial notification + will reflect the state of the Realm after the write transaction. + + ```swift + let results = realm.objects(Dog.self) + print("dogs.count: \(dogs?.count)") // => 0 + let token = dogs.addNotificationBlock { changes in + switch changes { + case .initial(let dogs): + // Will print "dogs.count: 1" + print("dogs.count: \(dogs.count)") + break + case .update: + // Will not be hit in this example + break + case .error: + break } - // end of run loop execution context + } + try! realm.write { + let dog = Dog() + dog.name = "Rex" + person.dogs.append(dog) + } + // end of run loop execution context + ``` - You must retain the returned token for as long as you want updates to continue - to be sent to the block. To stop receiving updates, call stop() on the token. + You must retain the returned token for as long as you want updates to be sent to the block. To stop receiving + updates, call `stop()` on the token. - - warning: This method cannot be called during a write transaction, or when - the source realm is read-only. + - warning: This method cannot be called during a write transaction, or when the containing Realm is read-only. - - parameter block: The block to be called with the evaluated collection and change information. + - parameter block: The block to be called whenever a change occurs. - returns: A token which must be held for as long as you want updates to be delivered. */ - public func addNotificationBlock(block: @escaping (RealmCollectionChange) -> ()) - -> NotificationToken { return base._addNotificationBlock(block: block) } + public func addNotificationBlock(_ block: @escaping (RealmCollectionChange) -> ()) + -> NotificationToken { return base._addNotificationBlock(block) } /// :nodoc: - public func _addNotificationBlock(block: @escaping (RealmCollectionChange) -> ()) - -> NotificationToken { return base._addNotificationBlock(block: block) } + public func _addNotificationBlock(_ block: @escaping (RealmCollectionChange) -> ()) + -> NotificationToken { return base._addNotificationBlock(block) } } // MARK: Unavailable extension AnyRealmCollection { - @available(*, unavailable, renamed:"isInvalidated") - public var invalidated : Bool { fatalError() } + @available(*, unavailable, renamed: "isInvalidated") + public var invalidated: Bool { fatalError() } - @available(*, unavailable, renamed:"indexOfObject(for:)") + @available(*, unavailable, renamed: "index(matching:)") public func index(of predicate: NSPredicate) -> Int? { fatalError() } - @available(*, unavailable, renamed:"indexOfObject(for:_:)") + @available(*, unavailable, renamed: "index(matching:_:)") public func index(of predicateFormat: String, _ args: AnyObject...) -> Int? { fatalError() } - @available(*, unavailable, renamed:"filter(using:)") - public func filter(_ predicate: NSPredicate) -> Results { fatalError() } - - @available(*, unavailable, renamed:"filter(using:_:)") - public func filter(_ predicateFormat: String, _ args: AnyObject...) -> Results { fatalError() } - - @available(*, unavailable, renamed:"sorted(onProperty:ascending:)") + @available(*, unavailable, renamed: "sorted(byProperty:ascending:)") public func sorted(_ property: String, ascending: Bool = true) -> Results { fatalError() } - @available(*, unavailable, renamed:"sorted(with:)") + @available(*, unavailable, renamed: "sorted(by:)") public func sorted(_ sortDescriptors: S) -> Results where S.Iterator.Element == SortDescriptor { fatalError() } - @available(*, unavailable, renamed:"minimumValue(ofProperty:)") + @available(*, unavailable, renamed: "min(ofProperty:)") public func min(_ property: String) -> U? { fatalError() } - @available(*, unavailable, renamed:"maximumValue(ofProperty:)") + @available(*, unavailable, renamed: "max(ofProperty:)") public func max(_ property: String) -> U? { fatalError() } - @available(*, unavailable, renamed:"sum(ofProperty:)") + @available(*, unavailable, renamed: "sum(ofProperty:)") public func sum(_ property: String) -> U { fatalError() } - @available(*, unavailable, renamed:"average(ofProperty:)") + @available(*, unavailable, renamed: "average(ofProperty:)") public func average(_ property: String) -> U? { fatalError() } } @@ -1093,7 +918,7 @@ public protocol RealmCollectionType: CollectionType, CustomStringConvertible { /// Indicates if the collection can no longer be accessed. /// - /// The collection can no longer be accessed if `invalidate` is called on the `Realm` that manages the collection. + /// The collection can no longer be accessed if `invalidate()` is called on the `Realm` that manages the collection. var invalidated: Bool { get } /// The number of objects in the collection. @@ -1133,8 +958,6 @@ public protocol RealmCollectionType: CollectionType, CustomStringConvertible { Returns all objects matching the given predicate in the collection. - parameter predicateFormat: A predicate format string, optionally followed by a variable number of arguments. - - - returns: A `Results` containing objects that match the given predicate. */ func filter(predicateFormat: String, _ args: AnyObject...) -> Results @@ -1142,8 +965,6 @@ public protocol RealmCollectionType: CollectionType, CustomStringConvertible { Returns all objects matching the given predicate in the collection. - parameter predicate: The predicate to use to filter the objects. - - - returns: A `Results` containing objects that match the given predicate. */ func filter(predicate: NSPredicate) -> Results @@ -1154,23 +975,24 @@ public protocol RealmCollectionType: CollectionType, CustomStringConvertible { Returns a `Results` containing the objects in the collection, but sorted. Objects are sorted based on the values of the given property. For example, to sort a collection of `Student`s from - youngest to oldest based on their `age` property, you might call `students.sorted("age", ascending: true)`. + youngest to oldest based on their `age` property, you might call + `students.sorted(byProperty: "age", ascending: true)`. - - warning: Collections may only be sorted by properties of boolean, `NSDate`, single and double-precision floating - point, integer, and string types. + - warning: Collections may only be sorted by properties of boolean, `Date`, `NSDate`, single and double-precision + floating point, integer, and string types. - parameter property: The name of the property to sort by. - parameter ascending: The direction to sort in. */ - func sorted(property: String, ascending: Bool) -> Results + func sorted(byProperty: String, ascending: Bool) -> Results /** Returns a `Results` containing the objects in the collection, but sorted. - - warning: Collections may only be sorted by properties of boolean, `NSDate`, single and double-precision floating - point, integer, and string types. + - warning: Collections may only be sorted by properties of boolean, `Date`, `NSDate`, single and double-precision + floating point, integer, and string types. - - see: `sorted(_:ascending:)` + - see: `sorted(byProperty:ascending:)` - parameter sortDescriptors: A sequence of `SortDescriptor`s to sort by. */ @@ -1180,24 +1002,22 @@ public protocol RealmCollectionType: CollectionType, CustomStringConvertible { // MARK: Aggregate Operations /** - Returns the minimum (lowest) value of the given property among all the objects represented by the collection. + Returns the minimum (lowest) value of the given property among all the objects in the collection, or `nil` if the + collection is empty. - warning: Only a property whose type conforms to the `MinMaxType` protocol can be specified. - parameter property: The name of a property whose minimum value is desired. - - - returns: The minimum value of the property, or `nil` if the collection is empty. */ func min(property: String) -> U? /** - Returns the maximum (highest) value of the given property among all the objects represented by the collection. + Returns the maximum (highest) value of the given property among all the objects in the collection, or `nil` if the + collection is empty. - warning: Only a property whose type conforms to the `MinMaxType` protocol can be specified. - parameter property: The name of a property whose minimum value is desired. - - - returns: The maximum value of the property, or `nil` if the collection is empty. */ func max(property: String) -> U? @@ -1207,19 +1027,16 @@ public protocol RealmCollectionType: CollectionType, CustomStringConvertible { - warning: Only a property whose type conforms to the `AddableType` protocol can be specified. - parameter property: The name of a property whose values should be summed. - - - returns: The sum of the given property. */ func sum(property: String) -> U /** - Returns the average value of a given property over all the objects represented by the collection. + Returns the average value of a given property over all the objects in the collection, or `nil` if the collection is + empty. - warning: Only the name of a property whose type conforms to the `AddableType` protocol can be specified. - parameter property: The name of a property whose average value should be calculated. - - - returns: The average value of the given property, or `nil` if the collection is empty. */ func average(property: String) -> U? @@ -1312,7 +1129,7 @@ public protocol RealmCollectionType: CollectionType, CustomStringConvertible { the containing Realm is read-only. - parameter block: The block to be called whenever a change occurs. - - returns: A token which must be retained for as long as you want updates to be delivered. + - returns: A token which must be held for as long as you want updates to be delivered. */ func addNotificationBlock(block: (RealmCollectionChange) -> Void) -> NotificationToken @@ -1357,175 +1174,60 @@ private final class _AnyRealmCollection: _AnyRealmCollec self.base = base } - // TODO (az): copyedit private docstrings - // MARK: Properties - - /// The Realm the objects in this collection belong to, or `nil` if the - /// collection's owning object does not belong to a realm (the collection is - /// unmanaged). override var realm: Realm? { return base.realm } - - /// Indicates if the collection can no longer be accessed. - /// - /// The collection can no longer be accessed if `invalidate` is called on the containing `Realm`. override var invalidated: Bool { return base.invalidated } - - /// Returns the number of objects in this collection. override var count: Int { return base.count } - - /// Returns a human-readable description of the objects contained in this collection. override var description: String { return base.description } // MARK: Index Retrieval - /** - Returns the index of the given object, or `nil` if the object is not in the collection. - - - parameter object: The object whose index is being queried. - */ override func indexOf(object: C.Element) -> Int? { return base.indexOf(object) } - /** - Returns the index of the first object matching the given predicate, or `nil` no objects match. - - - parameter predicate: The `NSPredicate` used to filter the objects. - */ override func indexOf(predicate: NSPredicate) -> Int? { return base.indexOf(predicate) } - /** - Returns the index of the first object matching the given predicate, or `nil` if no objects match. - - - parameter predicateFormat: A predicate format string, optionally followed by a variable number - of arguments. - */ override func indexOf(predicateFormat: String, _ args: AnyObject...) -> Int? { return base.indexOf(NSPredicate(format: predicateFormat, argumentArray: args)) } // MARK: Filtering - /** - Returns a `Results` containing collection elements that match the given predicate. - - - parameter predicateFormat: A predicate format string, optionally followed by a variable number - of arguments. - - - returns: `Results` containing collection elements that match the given predicate. - */ override func filter(predicateFormat: String, _ args: AnyObject...) -> Results { return base.filter(NSPredicate(format: predicateFormat, argumentArray: args)) } - /** - Returns a `Results` containing collection elements that match the given predicate. - - - parameter predicate: The predicate to use to filter the objects. - - - returns: `Results` containing collection elements that match the given predicate. - */ override func filter(predicate: NSPredicate) -> Results { return base.filter(predicate) } // MARK: Sorting - /** - Returns a `Results` containing the objects in the collection, but sorted. - - Objects are sorted based on the values of the given property. For example, to sort a collection of `Student`s from - youngest to oldest based on their `age` property, you might call `students.sorted("age", ascending: true)`. - - - warning: Collections may only be sorted by properties of boolean, `NSDate`, single and double-precision floating - point, integer, and string types. - - - parameter property: The name of the property to sort by. - - parameter ascending: The direction to sort in. - */ override func sorted(property: String, ascending: Bool) -> Results { return base.sorted(property, ascending: ascending) } - /** - Returns a `Results` containing the objects in the collection, but sorted. - - - warning: Collections may only be sorted by properties of boolean, `NSDate`, single and double-precision floating - point, integer, and string types. - - - see: `sorted(_:ascending:)` - - - parameter sortDescriptors: A sequence of `SortDescriptor`s to sort by. - */ override func sorted (sortDescriptors: S) -> Results { return base.sorted(sortDescriptors) } - // MARK: Aggregate Operations - /** - Returns the minimum value of the given property. - - - warning: Only names of properties of a type conforming to the `MinMaxType` protocol can be used. - - - parameter property: The name of a property conforming to `MinMaxType` to look for a minimum on. - - - returns: The minimum value of the property amongst objects in the collection, or `nil` if the - collection is empty. - */ override func min(property: String) -> U? { return base.min(property) } - /** - Returns the maximum value of the given property. - - - warning: Only names of properties of a type conforming to the `MinMaxType` protocol can be used. - - - parameter property: The name of a property conforming to `MinMaxType` to look for a maximum on. - - - returns: The maximum value of the property amongst objects in the collection, or `nil` if the - collection is empty. - */ override func max(property: String) -> U? { return base.max(property) } - /** - Returns the sum of the given property for objects in the collection. - - - warning: Only names of properties of a type conforming to the `AddableType` protocol can be used. - - - parameter property: The name of a property conforming to `AddableType` to calculate sum on. - - - returns: The sum of the given property over all objects in the collection. - */ override func sum(property: String) -> U { return base.sum(property) } - /** - Returns the average of the given property for objects in the collection. - - - warning: Only names of properties of a type conforming to the `AddableType` protocol can be used. - - - parameter property: The name of a property conforming to `AddableType` to calculate average on. - - - returns: The average of the given property over all objects in the collection, or `nil` if the - collection is empty. - */ override func average(property: String) -> U? { return base.average(property) } // MARK: Sequence Support - /** - Returns the object at the given `index`. - - - parameter index: The index. - - - returns: The object at the given `index`. - */ override subscript(index: Int) -> C.Element { // FIXME: it should be possible to avoid this force-casting return unsafeBitCast(base[index as! C.Index], C.Element.self) } - /// Returns an `RLMGenerator` that yields successive elements in the collection. override func generate() -> RLMGenerator { // FIXME: it should be possible to avoid this force-casting return base.generate() as! RLMGenerator @@ -1534,16 +1236,11 @@ private final class _AnyRealmCollection: _AnyRealmCollec // MARK: Collection Support - /// The position of the first element in a non-empty collection. - /// Identical to endIndex in an empty collection. override var startIndex: Int { // FIXME: it should be possible to avoid this force-casting return base.startIndex as! Int } - /// The collection's "past the end" position. - /// endIndex is not a valid argument to subscript, and is always reachable from startIndex by - /// zero or more applications of successor(). override var endIndex: Int { // FIXME: it should be possible to avoid this force-casting return base.endIndex as! Int @@ -1552,34 +1249,10 @@ private final class _AnyRealmCollection: _AnyRealmCollec // MARK: Key-Value Coding - /** - Returns an Array containing the results of invoking `valueForKey(_:)` using key on each of the collection's objects. - - - parameter key: The name of the property. - - - returns: Array containing the results of invoking `valueForKey(_:)` using key on each of the collection's objects. - */ override func valueForKey(key: String) -> AnyObject? { return base.valueForKey(key) } - /** - Returns an Array containing the results of invoking `valueForKeyPath(_:)` using keyPath on each of the - collection's objects. - - - parameter keyPath: The key path to the property. - - - returns: Array containing the results of invoking `valueForKeyPath(_:)` using keyPath on each of the - collection's objects. - */ override func valueForKeyPath(keyPath: String) -> AnyObject? { return base.valueForKeyPath(keyPath) } - /** - Invokes `setValue(_:forKey:)` on each of the collection's objects using the specified value and key. - - - warning: This method can only be called during a write transaction. - - - parameter value: The object value. - - parameter key: The name of the property. - */ override func setValue(value: AnyObject?, forKey key: String) { base.setValue(value, forKey: key) } // MARK: Notifications @@ -1613,7 +1286,7 @@ public final class AnyRealmCollection: RealmCollectionType { /// Indicates if the collection can no longer be accessed. /// - /// The collection can no longer be accessed if `invalidate` is called on the containing `realm`. + /// The collection can no longer be accessed if `invalidate()` is called on the containing `realm`. public var invalidated: Bool { return base.invalidated } /// The number of objects in the collection. @@ -1663,8 +1336,6 @@ public final class AnyRealmCollection: RealmCollectionType { Returns a `Results` containing all objects matching the given predicate in the collection. - parameter predicate: The predicate with which to filter the objects. - - - returns: A `Results` containing objects that match the given predicate. */ public func filter(predicate: NSPredicate) -> Results { return base.filter(predicate) } @@ -1706,46 +1377,41 @@ public final class AnyRealmCollection: RealmCollectionType { // MARK: Aggregate Operations /** - Returns the minimum (lowest) value of the given property among all the objects represented by the collection. + Returns the minimum (lowest) value of the given property among all the objects in the collection, or `nil` if the + collection is empty. - warning: Only a property whose type conforms to the `MinMaxType` protocol can be specified. - parameter property: The name of a property whose minimum value is desired. - - - returns: The minimum value of the property, or `nil` if the collection is empty. */ public func min(property: String) -> U? { return base.min(property) } /** - Returns the maximum (highest) value of the given property among all the objects represented by the collection. + Returns the maximum (highest) value of the given property among all the objects in the collection, or `nil` if the + collection is empty. - warning: Only a property whose type conforms to the `MinMaxType` protocol can be specified. - parameter property: The name of a property whose minimum value is desired. - - - returns: The maximum value of the property, or `nil` if the collection is empty. */ public func max(property: String) -> U? { return base.max(property) } /** - Returns the sum of the values of a given property over all the objects represented by the collection. + Returns the sum of the values of a given property over all the objects in the collection. - warning: Only a property whose type conforms to the `AddableType` protocol can be specified. - parameter property: The name of a property whose values should be summed. - - - returns: The sum of the given property. */ public func sum(property: String) -> U { return base.sum(property) } /** - Returns the average value of a given property over all the objects represented by the collection. + Returns the average value of a given property over all the objects in the collection, or `nil` if the collection is + empty. - warning: Only the name of a property whose type conforms to the `AddableType` protocol can be specified. - parameter property: The name of a property whose average value should be calculated. - - - returns: The average value of the given property, or `nil` if the collection is empty. */ public func average(property: String) -> U? { return base.average(property) } @@ -1755,9 +1421,7 @@ public final class AnyRealmCollection: RealmCollectionType { /** Returns the object at the given `index`. - - parameter index: The index. - - - returns: The object at the given `index`. + - parameter index: An index to retrieve or set an object from. */ public subscript(index: Int) -> T { return base[index] } @@ -1784,8 +1448,6 @@ public final class AnyRealmCollection: RealmCollectionType { objects. - parameter key: The name of the property whose values are desired. - - - returns: An `Array` containing the results. */ public func valueForKey(key: String) -> AnyObject? { return base.valueForKey(key) } @@ -1794,8 +1456,6 @@ public final class AnyRealmCollection: RealmCollectionType { collection's objects. - parameter keyPath: The key path to the property whose values are desired. - - - returns: An `Array` containing the results. */ public func valueForKeyPath(keyPath: String) -> AnyObject? { return base.valueForKeyPath(keyPath) } @@ -1832,7 +1492,9 @@ public final class AnyRealmCollection: RealmCollectionType { delivered while the run loop is blocked by other activity. When notifications can't be delivered instantly, multiple notifications may be coalesced into a single notification. This can include the notification - with the initial collection. For example, the following code performs a write + with the initial collection. + + For example, the following code performs a write transaction immediately after adding the notification block, so there is no opportunity for the initial notification to be delivered first. As a result, the initial notification will reflect the state of the Realm after @@ -1865,11 +1527,10 @@ public final class AnyRealmCollection: RealmCollectionType { You must retain the returned token for as long as you want updates to be sent to the block. To stop receiving updates, call `stop()` on the token. - - warning: This method cannot be called during a write transaction, or when - the containing Realm is read-only. + - warning: This method cannot be called during a write transaction, or when the containing Realm is read-only. - parameter block: The block to be called whenever a change occurs. - - returns: A token which must be retained for as long as you want updates to be delivered. + - returns: A token which must be held for as long as you want updates to be delivered. */ public func addNotificationBlock(block: (RealmCollectionChange) -> ()) -> NotificationToken { return base._addNotificationBlock(block) } diff --git a/RealmSwift/RealmConfiguration.swift b/RealmSwift/RealmConfiguration.swift index 38914ff643..ac125849c6 100644 --- a/RealmSwift/RealmConfiguration.swift +++ b/RealmSwift/RealmConfiguration.swift @@ -24,22 +24,23 @@ import Realm.Private extension Realm { /** - A `Realm.Configuration` is used to describe the different options used to - create a `Realm` instance. - - `Realm.Configuration` instances are just plain Swift structs, and unlike - `Realm` and `Object`s can be freely shared between threads. Creating - configuration objects for class subsets (by setting the `objectTypes` - property) can be expensive, and so you will normally want to cache and reuse - a single configuration object for each distinct configuration that you are - using rather than creating a new one each time you open a `Realm`. - */ + A `Configuration` instance describes the different options used to create an instance of a Realm. + + `Configuration` instances are just plain Swift structs. Unlike `Realm`s and `Object`s, they can be freely shared + between threads as long as you do not mutate them. + + Creating configuration values for class subsets (by setting the `objectClasses` property) can be expensive. Because + of this, you will normally want to cache and reuse a single configuration value for each distinct configuration + rather than creating a new value each time you open a Realm. + */ public struct Configuration { // MARK: Default Configuration - /// Returns the default Realm.Configuration used to create Realms when no other - /// configuration is explicitly specified (i.e. `Realm()`). + /** + The default `Configuration` used to create Realms when no configuration is explicitly specified (i.e. + `Realm()`) + */ public static var defaultConfiguration: Configuration { get { return fromRLMRealmConfiguration(rlmConfiguration: RLMRealmConfiguration.default()) @@ -52,17 +53,17 @@ extension Realm { // MARK: Initialization /** - Initializes a `Realm.Configuration`, suitable for creating new `Realm` instances. - - - parameter fileURL: The local URL to the realm file. - - parameter inMemoryIdentifier: A string used to identify a particular in-memory Realm. - - parameter encryptionKey: 64-byte key to use to encrypt the data. - - parameter readOnly: Whether the Realm is read-only (must be true for read-only files). - - parameter schemaVersion: The current schema version. - - parameter migrationBlock: The block which migrates the Realm to the current version. - - parameter deleteRealmIfMigrationNeeded: If `true`, recreate the Realm file with the provided - schema if a migration is required. - - parameter objectTypes: The subset of `Object` subclasses persisted in the Realm. + Creates a `Configuration` which can be used to create new `Realm` instances. + + - parameter fileURL: The local URL to the Realm file. + - parameter inMemoryIdentifier: A string used to identify a particular in-memory Realm. + - parameter encryptionKey: An optional 64-byte key to use to encrypt the data. + - parameter readOnly: Whether the Realm is read-only (must be true for read-only files). + - parameter schemaVersion: The current schema version. + - parameter migrationBlock: The block which migrates the Realm to the current version. + - parameter deleteRealmIfMigrationNeeded: If `true`, recreate the Realm file with the provided + schema if a migration is required. + - parameter objectTypes: The subset of `Object` subclasses persisted in the Realm. */ public init(fileURL: URL? = URL(fileURLWithPath: RLMRealmPathForFile("default.realm"), isDirectory: false), inMemoryIdentifier: String? = nil, @@ -86,8 +87,7 @@ extension Realm { // MARK: Configuration Properties - /// The local URL to the realm file. - /// Mutually exclusive with `inMemoryIdentifier`. + /// The local URL of the Realm file. Mutually exclusive with `inMemoryIdentifier`. public var fileURL: URL? { set { _inMemoryIdentifier = nil @@ -100,8 +100,7 @@ extension Realm { private var _path: String? - /// A string used to identify a particular in-memory Realm. - /// Mutually exclusive with `path`. + /// A string used to identify a particular in-memory Realm. Mutually exclusive with `fileURL`. public var inMemoryIdentifier: String? { set { _path = nil @@ -114,10 +113,18 @@ extension Realm { private var _inMemoryIdentifier: String? = nil - /// 64-byte key to use to encrypt the data. + /// A 64-byte key to use to encrypt the data, or `nil` if encryption is not enabled. public var encryptionKey: Data? = nil - /// Whether the Realm is read-only (must be true for read-only files). + /** + Whether to open the Realm in read-only mode. + + This is required to be able to open Realm files which are not writeable or are in a directory which is not + writeable. This should only be used on files which will not be modified by anyone while they are open, and not + just to get a read-only view of a file which may be written to by another thread or process. Opening in + read-only mode requires disabling Realm's reader/writer coordination, so committing a write transaction from + another process will result in crashes. + */ public var readOnly: Bool = false /// The current schema version. @@ -127,16 +134,16 @@ extension Realm { public var migrationBlock: MigrationBlock? = nil /** - Recreate the Realm file with the provided schema if a migration is required. - This is the case when the stored schema differs from the provided schema or - the stored schema version differs from the version on this configuration. - This deletes the file if a migration would otherwise be required or run. + Whether to recreate the Realm file with the provided schema if a migration is required. This is the case when + the stored schema differs from the provided schema or the stored schema version differs from the version on + this configuration. Setting this property to `true` deletes the file if a migration would otherwise be required + or executed. - - note: This doesn't disable file format migrations. - */ + - note: Setting this property to `true` doesn't disable file format migrations. + */ public var deleteRealmIfMigrationNeeded: Bool = false - /// The classes persisted in the Realm. + /// The classes managed by the Realm. public var objectTypes: [Object.Type]? { set { self.customSchema = newValue.map { RLMSchema(objectClasses: $0) } @@ -149,7 +156,7 @@ extension Realm { /// A custom schema to use for the Realm. private var customSchema: RLMSchema? = nil - /// Allows to disable automatic format upgrades when accessing the Realm. + /// If `true`, disables automatic format upgrades when accessing the Realm. internal var disableFormatUpgrade: Bool = false // MARK: Private Methods @@ -196,7 +203,7 @@ extension Realm { // MARK: CustomStringConvertible extension Realm.Configuration: CustomStringConvertible { - /// Returns a human-readable description of the configuration. + /// A human-readable description of the configuration value. public var description: String { return gsub(pattern: "\\ARLMRealmConfiguration", template: "Realm.Configuration", @@ -238,18 +245,18 @@ extension Realm { // MARK: Initialization /** - Initializes a `Realm.Configuration`, suitable for creating new `Realm` instances. - - - parameter fileURL: The local URL to the Realm file. - - parameter inMemoryIdentifier: A string used to identify a particular in-memory Realm. - - parameter encryptionKey: An optional 64-byte key to use to encrypt the data. - - parameter readOnly: Whether the Realm is read-only (must be true for read-only files). - - parameter schemaVersion: The current schema version. - - parameter migrationBlock: The block which migrates the Realm to the current version. - - parameter deleteRealmIfMigrationNeeded: If `true`, recreate the Realm file with the provided - schema if a migration is required. - - parameter objectTypes: The subset of `Object` subclasses managed by the Realm. - */ + Creates a `Configuration` which can be used to create new `Realm` instances. + + - parameter fileURL: The local URL to the Realm file. + - parameter inMemoryIdentifier: A string used to identify a particular in-memory Realm. + - parameter encryptionKey: An optional 64-byte key to use to encrypt the data. + - parameter readOnly: Whether the Realm is read-only (must be true for read-only files). + - parameter schemaVersion: The current schema version. + - parameter migrationBlock: The block which migrates the Realm to the current version. + - parameter deleteRealmIfMigrationNeeded: If `true`, recreate the Realm file with the provided + schema if a migration is required. + - parameter objectTypes: The subset of `Object` subclasses managed by the Realm. + */ public init(fileURL: NSURL? = NSURL(fileURLWithPath: RLMRealmPathForFile("default.realm"), isDirectory: false), inMemoryIdentifier: String? = nil, encryptionKey: NSData? = nil, diff --git a/RealmSwift/Results.swift b/RealmSwift/Results.swift index 0547c043e8..b286d5729e 100644 --- a/RealmSwift/Results.swift +++ b/RealmSwift/Results.swift @@ -22,7 +22,11 @@ import Realm #if swift(>=3.0) // MARK: MinMaxType -/// Types which can be used for min()/max(). +/** + Types of properties which can be used with the minimum and maximum value APIs. + + - see: `min(ofProperty:)`, `max(ofProperty:)` + */ public protocol MinMaxType {} extension NSNumber: MinMaxType {} extension Double: MinMaxType {} @@ -37,7 +41,11 @@ extension NSDate: MinMaxType {} // MARK: AddableType -/// Types which can be used for average()/sum(). +/** + Types of properties which can be used with the sum and average value APIs. + + - see: `sum(ofProperty:)`, `average(ofProperty:)` + */ public protocol AddableType {} extension NSNumber: AddableType {} extension Double: AddableType {} @@ -49,34 +57,30 @@ extension Int32: AddableType {} extension Int64: AddableType {} /** -Results is an auto-updating container type in Realm returned from object queries. + `Results` is an auto-updating container type in Realm returned from object queries. -Results can be queried with the same predicates as `List` and you can chain -queries to further filter query results. + `Results` can be queried with the same predicates as `List`, and you can chain queries to further filter query + results. -Results always reflect the current state of the Realm on the current thread, -including during write transactions on the current thread. The one exception to -this is when using `for...in` enumeration, which will always enumerate over the - objects which matched the query when the enumeration is begun, even if -some of them are deleted or modified to be excluded by the filter during the -enumeration. + `Results` always reflect the current state of the Realm on the current thread, including during write transactions on + the current thread. The one exception to this is when using `for...in` enumeration, which will always enumerate over + the objects which matched the query when the enumeration is begun, even if some of them are deleted or modified to be + excluded by the filter during the enumeration. -Results are initially lazily evaluated, and only run queries when the result -of the query is requested. This means that chaining several temporary -Results to sort and filter your data does not perform any extra work -processing the intermediate state. + `Results` are lazily evaluated the first time they are accessed; they only run queries when the result of the query is + requested. This means that chaining several temporary `Results` to sort and filter your data does not perform any + unnecessary work processing the intermediate state. -Once the results have been evaluated or a notification block has been added, -the results are eagerly kept up-to-date, with the work done to keep them -up-to-date done on a background thread whenever possible. + Once the results have been evaluated or a notification block has been added, the results are eagerly kept up-to-date, + with the work done to keep them up-to-date done on a background thread whenever possible. -Results cannot be created directly. -*/ + Results instances cannot be directly instantiated. + */ public final class Results: NSObject, NSFastEnumeration { internal let rlmResults: RLMResults - /// Returns a human-readable description of the objects contained in these results. + /// A human-readable description of the objects represented by the results. public override var description: String { let type = "Results<\(rlmResults.objectClassName)>" return gsub(pattern: "RLMResults <0x[a-z0-9]+>", template: type, string: rlmResults.description) ?? type @@ -91,23 +95,23 @@ public final class Results: NSObject, NSFastEnumeration { return Int(rlmResults.countByEnumerating(with: state, objects: buffer, count: UInt(len))) } - /// Element type contained in this collection. + /// The type of the objects described by the results. public typealias Element = T // MARK: Properties - /// Returns the Realm these results are associated with. - /// Despite returning an `Optional` in order to conform to - /// `RealmCollection`, it will always return `.Some()` since a `Results` - /// cannot exist independently from a `Realm`. + /// The Realm which manages this results. Note that this property will never return `nil`. public var realm: Realm? { return Realm(rlmResults.realm) } - /// Indicates if the results can no longer be accessed. - /// - /// Results can no longer be accessed if `invalidate` is called on the containing `Realm`. + /** + Indicates if the results are no longer valid. + + The results becomes invalid if `invalidate()` is called on the containing `realm`. An invalidated results can be + accessed, but will always be empty. + */ public var isInvalidated: Bool { return rlmResults.isInvalidated } - /// Returns the number of objects in these results. + /// The number of objects in the results. public var count: Int { return Int(rlmResults.count) } // MARK: Initializers @@ -119,37 +123,27 @@ public final class Results: NSObject, NSFastEnumeration { // MARK: Index Retrieval /** - Returns the index of the given object, or `nil` if the object is not in the results. - - - parameter object: The object whose index is being queried. - - - returns: The index of the given object, or `nil` if the object is not in the results. - */ + Returns the index of the given object in the results, or `nil` if the object is not present. + */ public func index(of object: T) -> Int? { return notFoundToNil(index: rlmResults.index(of: object.unsafeCastToRLMObject())) } /** - Returns the index of the first object matching the given predicate, - or `nil` if no objects match. - - - parameter predicate: The predicate to filter the objects. + Returns the index of the first object matching the predicate, or `nil` if no objects match. - - returns: The index of the first matching object, or `nil` if no objects match. - */ - public func indexOfObject(for predicate: NSPredicate) -> Int? { + - parameter predicate: The predicate with which to filter the objects. + */ + public func index(matching predicate: NSPredicate) -> Int? { return notFoundToNil(index: rlmResults.indexOfObject(with: predicate)) } /** - Returns the index of the first object matching the given predicate, - or `nil` if no objects match. - - - parameter predicateFormat: The predicate format string which can accept variable arguments. + Returns the index of the first object matching the predicate, or `nil` if no objects match. - - returns: The index of the first matching object, or `nil` if no objects match. - */ - public func indexOfObject(for predicateFormat: String, _ args: Any...) -> Int? { + - parameter predicateFormat: A predicate format string, optionally followed by a variable number of arguments. + */ + public func index(matching predicateFormat: String, _ args: Any...) -> Int? { return notFoundToNil(index: rlmResults.indexOfObject(with: NSPredicate(format: predicateFormat, argumentArray: args))) } @@ -157,57 +151,50 @@ public final class Results: NSObject, NSFastEnumeration { // MARK: Object Retrieval /** - Returns the object at the given `index`. - - - parameter index: The index. + Returns the object at the given `index`. - - returns: The object at the given `index`. - */ + - parameter index: The index. + */ public subscript(position: Int) -> T { throwForNegativeIndex(position) return unsafeBitCast(rlmResults.object(at: UInt(position)), to: T.self) } - /// Returns the first object in the results, or `nil` if empty. + /// Returns the first object in the results, or `nil` if the results are empty. public var first: T? { return unsafeBitCast(rlmResults.firstObject(), to: Optional.self) } - /// Returns the last object in the results, or `nil` if empty. + /// Returns the last object in the results, or `nil` if the results are empty. public var last: T? { return unsafeBitCast(rlmResults.lastObject(), to: Optional.self) } // MARK: KVC /** - Returns an Array containing the results of invoking `valueForKey(_:)` using key on each of the collection's objects. - - - parameter key: The name of the property. + Returns an `Array` containing the results of invoking `valueForKey(_:)` with `key` on each of the results. - - returns: Array containing the results of invoking `valueForKey(_:)` using key on each of the collection's objects. - */ + - parameter key: The name of the property whose values are desired. + */ public override func value(forKey key: String) -> Any? { return value(forKeyPath: key) } /** - Returns an Array containing the results of invoking `valueForKeyPath(_:)` using keyPath on each of the - collection's objects. + Returns an `Array` containing the results of invoking `valueForKeyPath(_:)` with `keyPath` on each of the results. - - parameter keyPath: The key path to the property. - - - returns: Array containing the results of invoking `valueForKeyPath(_:)` using keyPath on each of the - collection's objects. + - parameter keyPath: The key path to the property whose values are desired. */ public override func value(forKeyPath keyPath: String) -> Any? { return rlmResults.value(forKeyPath: keyPath) } /** - Invokes `setValue(_:forKey:)` on each of the collection's objects using the specified value and key. + Invokes `setValue(_:forKey:)` on each of the objects represented by the results using the specified `value` and + `key`. - - warning: This method can only be called during a write transaction. + - warning: This method may only be called during a write transaction. - - parameter value: The object value. - - parameter key: The name of the property. - */ + - parameter value: The object value. + - parameter key: The name of the property whose value should be set on each object. + */ public override func setValue(_ value: Any?, forKey key: String) { return rlmResults.setValue(value, forKeyPath: key) } @@ -215,102 +202,98 @@ public final class Results: NSObject, NSFastEnumeration { // MARK: Filtering /** - Filters the results to the objects that match the given predicate. - - - parameter predicateFormat: The predicate format string which can accept variable arguments. + Returns a `Results` containing all objects matching the given predicate in the collection. - - returns: Results containing objects that match the given predicate. - */ - public func filter(using predicateFormat: String, _ args: Any...) -> Results { + - parameter predicateFormat: A predicate format string, optionally followed by a variable number of arguments. + */ + public func filter(_ predicateFormat: String, _ args: Any...) -> Results { return Results(rlmResults.objects(with: NSPredicate(format: predicateFormat, argumentArray: args))) } /** - Filters the results to the objects that match the given predicate. - - - parameter predicate: The predicate to filter the objects. + Returns a `Results` containing all objects matching the given predicate in the collection. - - returns: Results containing objects that match the given predicate. - */ - public func filter(using predicate: NSPredicate) -> Results { + - parameter predicate: The predicate with which to filter the objects. + */ + public func filter(_ predicate: NSPredicate) -> Results { return Results(rlmResults.objects(with: predicate)) } // MARK: Sorting /** - Returns `Results` with elements sorted by the given property name. + Returns a `Results` containing the objects represented by the results, but sorted. + + Objects are sorted based on the values of the given property. For example, to sort a collection of `Student`s from + youngest to oldest based on their `age` property, you might call + `students.sorted(byProperty: "age", ascending: true)`. - - parameter property: The property name to sort by. - - parameter ascending: The direction to sort by. + - warning: Collections may only be sorted by properties of boolean, `Date`, `NSDate`, single and double-precision + floating point, integer, and string types. - - returns: `Results` with elements sorted by the given property name. - */ - public func sorted(onProperty property: String, ascending: Bool = true) -> Results { - return sorted(with: [SortDescriptor(property: property, ascending: ascending)]) + - parameter property: The name of the property to sort by. + - parameter ascending: The direction to sort in. + */ + public func sorted(byProperty property: String, ascending: Bool = true) -> Results { + return sorted(by: [SortDescriptor(property: property, ascending: ascending)]) } /** - Returns `Results` with elements sorted by the given sort descriptors. + Returns a `Results` containing the objects represented by the results, but sorted. + + - warning: Collections may only be sorted by properties of boolean, `Date`, `NSDate`, single and double-precision + floating point, integer, and string types. - - parameter sortDescriptors: `SortDescriptor`s to sort by. + - see: `sorted(byProperty:ascending:)` - - returns: `Results` with elements sorted by the given sort descriptors. - */ - public func sorted(with sortDescriptors: S) -> Results where S.Iterator.Element == SortDescriptor { + - parameter sortDescriptors: A sequence of `SortDescriptor`s to sort by. + */ + public func sorted(by sortDescriptors: S) -> Results where S.Iterator.Element == SortDescriptor { return Results(rlmResults.sortedResults(using: sortDescriptors.map { $0.rlmSortDescriptorValue })) } // MARK: Aggregate Operations /** - Returns the minimum value of the given property. - - - warning: Only names of properties of a type conforming to the `MinMaxType` protocol can be used. + Returns the minimum (lowest) value of the given property among all the results, or `nil` if the results are empty. - - parameter property: The name of a property conforming to `MinMaxType` to look for a minimum on. + - warning: Only a property whose type conforms to the `MinMaxType` protocol can be specified. - - returns: The minimum value for the property amongst objects in the Results, or `nil` if the Results is empty. - */ - public func minimumValue(ofProperty property: String) -> U? { + - parameter property: The name of a property whose minimum value is desired. + */ + public func min(ofProperty property: String) -> U? { return rlmResults.min(ofProperty: property).map(dynamicBridgeCast) } /** - Returns the maximum value of the given property. + Returns the maximum (highest) value of the given property among all the results, or `nil` if the results are empty. - - warning: Only names of properties of a type conforming to the `MinMaxType` protocol can be used. - - - parameter property: The name of a property conforming to `MinMaxType` to look for a maximum on. + - warning: Only a property whose type conforms to the `MinMaxType` protocol can be specified. - - returns: The maximum value for the property amongst objects in the Results, or `nil` if the Results is empty. - */ - public func maximumValue(ofProperty property: String) -> U? { + - parameter property: The name of a property whose minimum value is desired. + */ + public func max(ofProperty property: String) -> U? { return rlmResults.max(ofProperty: property).map(dynamicBridgeCast) } /** - Returns the sum of the given property for objects in the Results. - - - warning: Only names of properties of a type conforming to the `AddableType` protocol can be used. + Returns the sum of the values of a given property over all the results. - - parameter property: The name of a property conforming to `AddableType` to calculate sum on. + - warning: Only a property whose type conforms to the `AddableType` protocol can be specified. - - returns: The sum of the given property over all objects in the Results. - */ + - parameter property: The name of a property whose values should be summed. + */ public func sum(ofProperty property: String) -> U { return dynamicBridgeCast(fromObjectiveC: rlmResults.sum(ofProperty: property)) } /** - Returns the average of the given property for objects in the Results. - - - warning: Only names of properties of a type conforming to the `AddableType` protocol can be used. + Returns the average value of a given property over all the results, or `nil` if the results are empty. - - parameter property: The name of a property conforming to `AddableType` to calculate average on. + - warning: Only the name of a property whose type conforms to the `AddableType` protocol can be specified. - - returns: The average of the given property over all objects in the Results, or `nil` if the Results is empty. - */ + - parameter property: The name of a property whose average value should be calculated. + */ public func average(ofProperty property: String) -> U? { return rlmResults.average(ofProperty: property).map(dynamicBridgeCast) } @@ -318,65 +301,61 @@ public final class Results: NSObject, NSFastEnumeration { // MARK: Notifications /** - Register a block to be called each time the Results changes. + Registers a block to be called each time the collection changes. - The block will be asynchronously called with the initial results, and then - called again after each write transaction which changes either any of the - objects in the results, or which objects are in the results. + The block will be asynchronously called with the initial results, and then called again after each write + transaction which changes either any of the objects in the collection, or which objects are in the collection. - This version of this method reports which of the objects in the results were - added, removed, or modified in each write transaction as indices within the - results. See the RealmCollectionChange documentation for more information on - the change information supplied and an example of how to use it to update - a UITableView. + The `change` parameter that is passed to the block reports, in the form of indices within the collection, which of + the objects were added, removed, or modified during each write transaction. See the `RealmCollectionChange` + documentation for more information on the change information supplied and an example of how to use it to update a + `UITableView`. - At the time when the block is called, the Results object will be fully - evaluated and up-to-date, and as long as you do not perform a write transaction - on the same thread or explicitly call realm.refresh(), accessing it will never + At the time when the block is called, the collection will be fully evaluated and up-to-date, and as long as you do + not perform a write transaction on the same thread or explicitly call `realm.refresh()`, accessing it will never perform blocking work. - Notifications are delivered via the standard run loop, and so can't be - delivered while the run loop is blocked by other activity. When - notifications can't be delivered instantly, multiple notifications may be - coalesced into a single notification. This can include the notification - with the initial results. For example, the following code performs a write - transaction immediately after adding the notification block, so there is no - opportunity for the initial notification to be delivered first. As a - result, the initial notification will reflect the state of the Realm after - the write transaction. - - let dogs = realm.objects(Dog) - print("dogs.count: \(dogs?.count)") // => 0 - let token = dogs.addNotificationBlock { (changes: RealmCollectionChange) in - switch changes { - case .Initial(let dogs): - // Will print "dogs.count: 1" - print("dogs.count: \(dogs.count)") - break - case .Update: - // Will not be hit in this example - break - case .Error: - break - } - } - try! realm.write { - let dog = Dog() - dog.name = "Rex" - person.dogs.append(dog) + Notifications are delivered via the standard run loop, and so can't be delivered while the run loop is blocked by + other activity. When notifications can't be delivered instantly, multiple notifications may be coalesced into a + single notification. This can include the notification with the initial collection. + + For example, the following code performs a write transaction immediately after adding the notification block, so + there is no opportunity for the initial notification to be delivered first. As a result, the initial notification + will reflect the state of the Realm after the write transaction. + + ```swift + let results = realm.objects(Dog.self) + print("dogs.count: \(dogs?.count)") // => 0 + let token = dogs.addNotificationBlock { changes in + switch changes { + case .initial(let dogs): + // Will print "dogs.count: 1" + print("dogs.count: \(dogs.count)") + break + case .update: + // Will not be hit in this example + break + case .error: + break } - // end of run loop execution context + } + try! realm.write { + let dog = Dog() + dog.name = "Rex" + person.dogs.append(dog) + } + // end of run loop execution context + ``` - You must retain the returned token for as long as you want updates to continue - to be sent to the block. To stop receiving updates, call stop() on the token. + You must retain the returned token for as long as you want updates to be sent to the block. To stop receiving + updates, call `stop()` on the token. - - warning: This method cannot be called during a write transaction, or when - the source realm is read-only. + - warning: This method cannot be called during a write transaction, or when the containing Realm is read-only. - - parameter block: The block to be called with the evaluated results and change information. - - returns: A token which must be held for as long as you want query results to be delivered. + - parameter block: The block to be called whenever a change occurs. + - returns: A token which must be held for as long as you want updates to be delivered. */ - public func addNotificationBlock(block: @escaping (RealmCollectionChange) -> Void) -> NotificationToken { + public func addNotificationBlock(_ block: @escaping (RealmCollectionChange) -> Void) -> NotificationToken { return rlmResults.addNotificationBlock { results, change, error in block(RealmCollectionChange.fromObjc(value: self, change: change, error: error)) } @@ -406,7 +385,7 @@ extension Results: RealmCollection { public func index(before i: Int) -> Int { return i - 1 } /// :nodoc: - public func _addNotificationBlock(block: @escaping (RealmCollectionChange>) -> Void) -> + public func _addNotificationBlock(_ block: @escaping (RealmCollectionChange>) -> Void) -> NotificationToken { let anyCollection = AnyRealmCollection(self) return rlmResults.addNotificationBlock { _, change, error in @@ -418,39 +397,33 @@ extension Results: RealmCollection { // MARK: Unavailable extension Results { - @available(*, unavailable, renamed:"isInvalidated") - public var invalidated : Bool { fatalError() } + @available(*, unavailable, renamed: "isInvalidated") + public var invalidated: Bool { fatalError() } - @available(*, unavailable, renamed:"indexOfObject(for:)") + @available(*, unavailable, renamed: "index(matching:)") public func index(of predicate: NSPredicate) -> Int? { fatalError() } - @available(*, unavailable, renamed:"indexOfObject(for:_:)") + @available(*, unavailable, renamed: "index(matching:_:)") public func index(of predicateFormat: String, _ args: AnyObject...) -> Int? { fatalError() } - @available(*, unavailable, renamed:"filter(using:)") - public func filter(_ predicate: NSPredicate) -> Results { fatalError() } - - @available(*, unavailable, renamed:"filter(using:_:)") - public func filter(_ predicateFormat: String, _ args: AnyObject...) -> Results { fatalError() } - - @available(*, unavailable, renamed:"sorted(onProperty:ascending:)") + @available(*, unavailable, renamed: "sorted(byProperty:ascending:)") public func sorted(_ property: String, ascending: Bool = true) -> Results { fatalError() } - @available(*, unavailable, renamed:"sorted(with:)") + @available(*, unavailable, renamed: "sorted(by:)") public func sorted(_ sortDescriptors: S) -> Results where S.Iterator.Element == SortDescriptor { fatalError() } - @available(*, unavailable, renamed:"minimumValue(ofProperty:)") + @available(*, unavailable, renamed: "min(ofProperty:)") public func min(_ property: String) -> U? { fatalError() } - @available(*, unavailable, renamed:"maximumValue(ofProperty:)") + @available(*, unavailable, renamed: "max(ofProperty:)") public func max(_ property: String) -> U? { fatalError() } - @available(*, unavailable, renamed:"sum(ofProperty:)") + @available(*, unavailable, renamed: "sum(ofProperty:)") public func sum(_ property: String) -> U { fatalError() } - @available(*, unavailable, renamed:"average(ofProperty:)") + @available(*, unavailable, renamed: "average(ofProperty:)") public func average(_ property: String) -> U? { fatalError() } } @@ -461,7 +434,7 @@ extension Results { /** Types of properties which can be used with the minimum and maximum value APIs. - - see: `min(_:)`, `max(_:)` + - see: `min(ofProperty:)`, `max(ofProperty:)` */ public protocol MinMaxType {} extension NSNumber: MinMaxType {} @@ -479,7 +452,7 @@ extension NSDate: MinMaxType {} /** Types of properties which can be used with the sum and average value APIs. - - see: `sum(_:)`, `average(_:)` + - see: `sum(ofProperty:)`, `average(ofProperty:)` */ public protocol AddableType {} extension NSNumber: AddableType {} @@ -535,7 +508,7 @@ public class ResultsBase: NSObject, NSFastEnumeration { `Results` are lazily evaluated the first time they are accessed; they only run queries when the result of the query is requested. This means that chaining several temporary `Results` to sort and filter your data does not - perform any extra work processing the intermediate state. + perform any unnecessary work processing the intermediate state. Once the results have been evaluated or a notification block has been added, the results are eagerly kept up-to-date, with the work done to keep them @@ -556,7 +529,7 @@ public final class Results: ResultsBase { /** Indicates if the results collection is no longer valid. - The results collection becomes invalid if `invalidate` is called on the containing `realm`. + The results collection becomes invalid if `invalidate()` is called on the containing `realm`. An invalidated results collection can be accessed, but will always be empty. */ public var invalidated: Bool { return rlmResults.invalidated } @@ -573,7 +546,7 @@ public final class Results: ResultsBase { // MARK: Index Retrieval /** - Returns the index of an object in the results collection, or `nil` if the object is not present. + Returns the index of an object in the results, or `nil` if the object is not present. - parameter object: An object. */ @@ -593,7 +566,7 @@ public final class Results: ResultsBase { /** Returns the index of the first object matching the predicate, or `nil` if no objects match. - - parameter predicateFormat: A predicate format string, optionally followed by a variable number of arguments.` + - parameter predicateFormat: A predicate format string, optionally followed by a variable number of arguments. */ public func indexOf(predicateFormat: String, _ args: AnyObject...) -> Int? { return notFoundToNil(rlmResults.indexOfObjectWithPredicate(NSPredicate(format: predicateFormat, @@ -606,8 +579,6 @@ public final class Results: ResultsBase { Returns the object at the given `index`. - parameter index: An index. - - - returns: The object at the given `index`. */ public subscript(index: Int) -> T { get { @@ -616,17 +587,16 @@ public final class Results: ResultsBase { } } - /// Returns the first object in the results collection, or `nil` if the collection is empty. + /// Returns the first object in the results, or `nil` if the results are empty. public var first: T? { return unsafeBitCast(rlmResults.firstObject(), Optional.self) } - /// Returns the last object in the results collection, or `nil` if the collection is empty. + /// Returns the last object in the results, or `nil` if the results are empty. public var last: T? { return unsafeBitCast(rlmResults.lastObject(), Optional.self) } // MARK: KVC /** - Returns an `Array` containing the results of invoking `valueForKey(_:)` with `key` on each of the results - collection's objects. + Returns an `Array` containing the results of invoking `valueForKey(_:)` with `key` on each of the results. - parameter key: The name of the property whose values are desired. */ @@ -635,8 +605,7 @@ public final class Results: ResultsBase { } /** - Returns an `Array` containing the results of invoking `valueForKeyPath(_:)` with `keyPath` on each of the results - collection's objects. + Returns an `Array` containing the results of invoking `valueForKeyPath(_:)` with `keyPath` on each of the results. - parameter keyPath: The key path to the property whose values are desired. */ @@ -645,7 +614,8 @@ public final class Results: ResultsBase { } /** - Invokes `setValue(_:forKey:)` on each of the results collection's objects using the specified `value` and `key`. + Invokes `setValue(_:forKey:)` on each of the objects represented by the results using the specified `value` and + `key`. - warning: This method may only be called during a write transaction. @@ -659,7 +629,7 @@ public final class Results: ResultsBase { // MARK: Filtering /** - Returns a `Results` containing all objects matching the given predicate in the results collection. + Returns a `Results` containing all objects matching the given predicate in the results. - parameter predicateFormat: A predicate format string, optionally followed by a variable number of arguments. */ @@ -668,7 +638,7 @@ public final class Results: ResultsBase { } /** - Returns a `Results` containing all objects matching the given predicate in the results collection. + Returns a `Results` containing all objects matching the given predicate in the results. - parameter predicate: The predicate with which to filter the objects. */ @@ -679,7 +649,7 @@ public final class Results: ResultsBase { // MARK: Sorting /** - Returns a `Results` containing the objects in the results collection, but sorted. + Returns a `Results` containing the objects represented by the results, but sorted. Objects are sorted based on the values of the given property. For example, to sort a collection of `Student`s from youngest to oldest based on their `age` property, you might call `students.sorted("age", ascending: true)`. @@ -695,12 +665,12 @@ public final class Results: ResultsBase { } /** - Returns a `Results` containing the objects in the results collection, but sorted. + Returns a `Results` containing the objects represented by the results, but sorted. - warning: Collections may only be sorted by properties of boolean, `NSDate`, single and double-precision floating point, integer, and string types. - - see: `sorted(_:ascending:)` + - see: `sorted(byProperty:ascending:)` - parameter sortDescriptors: A sequence of `SortDescriptor`s to sort by. */ @@ -711,52 +681,44 @@ public final class Results: ResultsBase { // MARK: Aggregate Operations /** - Returns the minimum (lowest) value of the given property among all the objects represented by the collection. + Returns the minimum (lowest) value of the given property among all the results, or `nil` if the results are empty. - warning: Only a property whose type conforms to the `MinMaxType` protocol can be specified. - parameter property: The name of a property whose minimum value is desired. - - - returns: The minimum value of the property, or `nil` if the collection is empty. */ public func min(property: String) -> U? { return rlmResults.minOfProperty(property).map(dynamicBridgeCast) } /** - Returns the maximum (highest) value of the given property among all the objects represented by the collection. + Returns the maximum (highest) value of the given property among all the results, or `nil` if the results are empty. - warning: Only a property whose type conforms to the `MinMaxType` protocol can be specified. - parameter property: The name of a property whose minimum value is desired. - - - returns: The maximum value of the property, or `nil` if the collection is empty. */ public func max(property: String) -> U? { return rlmResults.maxOfProperty(property).map(dynamicBridgeCast) } /** - Returns the sum of the values of a given property over all the objects represented by the collection. + Returns the sum of the values of a given property over all the results. - warning: Only a property whose type conforms to the `AddableType` protocol can be specified. - parameter property: The name of a property whose values should be summed. - - - returns: The sum of the given property. */ public func sum(property: String) -> U { return dynamicBridgeCast(fromObjectiveC: rlmResults.sumOfProperty(property)) } /** - Returns the average value of a given property over all the objects represented by the collection. + Returns the average value of a given property over all the results, or `nil` if the results are empty. - warning: Only the name of a property whose type conforms to the `AddableType` protocol can be specified. - parameter property: The name of a property whose average value should be calculated. - - - returns: The average value of the given property, or `nil` if the collection is empty. */ public func average(property: String) -> U? { return rlmResults.averageOfProperty(property).map(dynamicBridgeCast) @@ -765,62 +727,59 @@ public final class Results: ResultsBase { // MARK: Notifications /** - Registers a block to be called each time the results collection changes. - - The block will be asynchronously called with the initial results, and then - called again after each write transaction which changes either any of the - objects in the collection, or which objects are in the collection. - - The `change` parameter that is passed to the block reports, in the form of indices within the - collection, which of the objects were added, removed, or modified during each write transaction. See the - `RealmCollectionChange` documentation for more information on the change information supplied and an example of how - to use it to update a `UITableView`. - - At the time when the block is called, the collection will be fully - evaluated and up-to-date, and as long as you do not perform a write - transaction on the same thread or explicitly call `realm.refresh()`, - accessing it will never perform blocking work. - - Notifications are delivered via the standard run loop, and so can't be - delivered while the run loop is blocked by other activity. When - notifications can't be delivered instantly, multiple notifications may be - coalesced into a single notification. This can include the notification - with the initial collection. For example, the following code performs a write - transaction immediately after adding the notification block, so there is no - opportunity for the initial notification to be delivered first. As a - result, the initial notification will reflect the state of the Realm after - the write transaction. - - let dogs = realm.objects(Dog.self) - print("dogs.count: \(dogs?.count)") // => 0 - let token = dogs.addNotificationBlock { (changes: RealmCollectionChange) in - switch changes { - case .Initial(let dogs): - // Will print "dogs.count: 1" - print("dogs.count: \(dogs.count)") - break - case .Update: - // Will not be hit in this example - break - case .Error: - break - } - } - try! realm.write { - let dog = Dog() - dog.name = "Rex" - person.dogs.append(dog) + Registers a block to be called each time the collection changes. + + The block will be asynchronously called with the initial results, and then called again after each write + transaction which changes either any of the objects in the collection, or which objects are in the collection. + + The `change` parameter that is passed to the block reports, in the form of indices within the collection, which of + the objects were added, removed, or modified during each write transaction. See the `RealmCollectionChange` + documentation for more information on the change information supplied and an example of how to use it to update a + `UITableView`. + + At the time when the block is called, the collection will be fully evaluated and up-to-date, and as long as you do + not perform a write transaction on the same thread or explicitly call `realm.refresh()`, accessing it will never + perform blocking work. + + Notifications are delivered via the standard run loop, and so can't be delivered while the run loop is blocked by + other activity. When notifications can't be delivered instantly, multiple notifications may be coalesced into a + single notification. This can include the notification with the initial collection. + + For example, the following code performs a write transaction immediately after adding the notification block, so + there is no opportunity for the initial notification to be delivered first. As a result, the initial notification + will reflect the state of the Realm after the write transaction. + + ```swift + let results = realm.objects(Dog.self) + print("dogs.count: \(dogs?.count)") // => 0 + let token = dogs.addNotificationBlock { changes in + switch changes { + case .Initial(let dogs): + // Will print "dogs.count: 1" + print("dogs.count: \(dogs.count)") + break + case .Update: + // Will not be hit in this example + break + case .Error: + break } - // end of run loop execution context + } + try! realm.write { + let dog = Dog() + dog.name = "Rex" + person.dogs.append(dog) + } + // end of run loop execution context + ``` - You must retain the returned token for as long as you want updates to continue - to be sent to the block. To stop receiving updates, call `stop()` on the token. + You must retain the returned token for as long as you want updates to be sent to the block. To stop receiving + updates, call `stop()` on the token. - - warning: This method cannot be called during a write transaction, or when - the containing Realm is read-only. + - warning: This method cannot be called during a write transaction, or when the containing Realm is read-only. - parameter block: The block to be called whenever a change occurs. - - returns: A token which must be retained for as long as you want updates to be delivered. + - returns: A token which must be held for as long as you want updates to be delivered. */ @warn_unused_result(message="You must hold on to the NotificationToken returned from addNotificationBlock") public func addNotificationBlock(block: (RealmCollectionChange -> Void)) -> NotificationToken { diff --git a/RealmSwift/Schema.swift b/RealmSwift/Schema.swift index fb217377ec..a0d9f818ce 100644 --- a/RealmSwift/Schema.swift +++ b/RealmSwift/Schema.swift @@ -22,26 +22,28 @@ import Realm #if swift(>=3.0) /** -This class represents the collection of model object schemas persisted to Realm. + `Schema` instances represent collections of model object schemas managed by a Realm. -When using Realm, `Schema` objects allow performing migrations and -introspecting the database's schema. + When using Realm, `Schema` instances allow performing migrations and introspecting the database's schema. -`Schema`s map to collections of tables in the core database. -*/ + Schemas map to collections of tables in the core database. + */ public final class Schema: CustomStringConvertible { // MARK: Properties internal let rlmSchema: RLMSchema - /// `ObjectSchema`s for all object types in this Realm. Meant - /// to be used during migrations for dynamic introspection. + /** + An array of `ObjectSchema`s for all object types in the Realm. + + This property is intended to be used during migrations for dynamic introspection. + */ public var objectSchema: [ObjectSchema] { return rlmSchema.objectSchema.map(ObjectSchema.init) } - /// Returns a human-readable description of the object schemas contained in this schema. + /// A human-readable description of the object schemas contained within. public var description: String { return rlmSchema.description } // MARK: Initializers @@ -52,7 +54,7 @@ public final class Schema: CustomStringConvertible { // MARK: ObjectSchema Retrieval - /// Returns the object schema with the given class name, if it exists. + /// Looks up and returns an `ObjectSchema` for the given class name in the Realm, if it exists. public subscript(className: String) -> ObjectSchema? { if let rlmObjectSchema = rlmSchema.schema(forClassName: className) { return ObjectSchema(rlmObjectSchema) @@ -119,7 +121,7 @@ public final class Schema: CustomStringConvertible { extension Schema: Equatable {} -/// Returns a Boolean value that indicates whether two `Schema` instances are equivalent. +/// Returns whether the two schemas are equal. public func == (lhs: Schema, rhs: Schema) -> Bool { // swiftlint:disable:this valid_docs return lhs.rlmSchema.isEqualToSchema(rhs.rlmSchema) } diff --git a/RealmSwift/SortDescriptor.swift b/RealmSwift/SortDescriptor.swift index d58dcb7191..af3e1acaa6 100644 --- a/RealmSwift/SortDescriptor.swift +++ b/RealmSwift/SortDescriptor.swift @@ -22,22 +22,20 @@ import Realm #if swift(>=3.0) /** -A `SortDescriptor` stores a property name and a sort order for use with -`sorted(sortDescriptors:)`. It is similar to `NSSortDescriptor`, but supports -only the subset of functionality which can be efficiently run by Realm's query -engine. -*/ + A `SortDescriptor` stores a property name and a sort order for use with `sorted(sortDescriptors:)`. It is similar to + `NSSortDescriptor`, but supports only the subset of functionality which can be efficiently run by Realm's query engine. + */ public struct SortDescriptor { // MARK: Properties - /// The name of the property which this sort descriptor orders results by. + /// The name of the property which the sort descriptor orders results by. public let property: String /// Whether this descriptor sorts in ascending or descending order. public let ascending: Bool - /// Converts the receiver to an `RLMSortDescriptor` + /// Converts the receiver to an `RLMSortDescriptor`. internal var rlmSortDescriptorValue: RLMSortDescriptor { return RLMSortDescriptor(property: property, ascending: ascending) } @@ -45,11 +43,11 @@ public struct SortDescriptor { // MARK: Initializers /** - Creates a `SortDescriptor` with the given property and ascending values. + Creates a sort descriptor with the given property and sort order values. - - parameter property: The name of the property which this sort descriptor orders results by. - - parameter ascending: Whether this descriptor sorts in ascending or descending order. - */ + - parameter property: The name of the property which the sort descriptor orders results by. + - parameter ascending: Whether the descriptor sorts in ascending or descending order. + */ public init(property: String, ascending: Bool = true) { self.property = property self.ascending = ascending @@ -57,7 +55,7 @@ public struct SortDescriptor { // MARK: Functions - /// Returns a copy of the `SortDescriptor` with the sort order reversed. + /// Returns a copy of the sort descriptor with the sort order reversed. public func reversed() -> SortDescriptor { return SortDescriptor(property: property, ascending: !ascending) } @@ -66,7 +64,7 @@ public struct SortDescriptor { // MARK: CustomStringConvertible extension SortDescriptor: CustomStringConvertible { - /// Returns a human-readable description of the sort descriptor. + /// A human-readable description of the sort descriptor. public var description: String { let direction = ascending ? "ascending" : "descending" return "SortDescriptor (property: \(property), direction: \(direction))" @@ -88,35 +86,32 @@ public func == (lhs: SortDescriptor, rhs: SortDescriptor) -> Bool { extension SortDescriptor: ExpressibleByStringLiteral { - /// `StringLiteralType`. Required for `StringLiteralConvertible` conformance. public typealias UnicodeScalarLiteralType = StringLiteralType - - /// `StringLiteralType`. Required for `StringLiteralConvertible` conformance. public typealias ExtendedGraphemeClusterLiteralType = StringLiteralType /** - Creates a `SortDescriptor` from a `UnicodeScalarLiteralType`. + Creates a `SortDescriptor` out of a Unicode scalar literal. - - parameter unicodeScalarLiteral: Property name literal. + - parameter unicodeScalarLiteral: Property name literal. */ public init(unicodeScalarLiteral value: UnicodeScalarLiteralType) { self.init(property: value) } /** - Creates a `SortDescriptor` from an `ExtendedGraphemeClusterLiteralType`. + Creates a `SortDescriptor` out of a character literal. - - parameter extendedGraphemeClusterLiteral: Property name literal. - */ + - parameter extendedGraphemeClusterLiteral: Property name literal. + */ public init(extendedGraphemeClusterLiteral value: ExtendedGraphemeClusterLiteralType) { self.init(property: value) } /** - Creates a `SortDescriptor` from a `StringLiteralType`. + Creates a `SortDescriptor` out of a string literal. - - parameter stringLiteral: Property name literal. - */ + - parameter stringLiteral: Property name literal. + */ public init(stringLiteral value: StringLiteralType) { self.init(property: value) } @@ -148,7 +143,7 @@ public struct SortDescriptor { // MARK: Initializers /** - Initializes a sort descriptor with the given property and sort order values. + Creates a sort descriptor with the given property and sort order values. - parameter property: The name of the property which the sort descriptor orders results by. - parameter ascending: Whether the descriptor sorts in ascending or descending order. diff --git a/RealmSwift/Tests/KVOTests.swift b/RealmSwift/Tests/KVOTests.swift index ec67afe7b6..05662b917f 100644 --- a/RealmSwift/Tests/KVOTests.swift +++ b/RealmSwift/Tests/KVOTests.swift @@ -151,7 +151,7 @@ class KVOTests: TestCase { obj.arrayCol.append(obj) } observeListChange(obj, "arrayCol", .removal, NSIndexSet(index: 0)) { - obj.arrayCol.removeAllObjects() + obj.arrayCol.removeAll() } observeChange(obj, "optIntCol", nil, 10) { obj.optIntCol.value = 10 } @@ -195,7 +195,7 @@ class KVOTests: TestCase { obj.arrayCol.append(obj) } observeListChange(obj, "arrayCol", .removal, NSIndexSet(index: 0)) { - obj.arrayCol.removeAllObjects() + obj.arrayCol.removeAll() } observeChange(obj, "optIntCol", nil, 10) { obj.optIntCol.value = 10 } @@ -250,7 +250,7 @@ class KVOTests: TestCase { obj.arrayCol.append(obj) } observeListChange(obs, "arrayCol", .removal, NSIndexSet(index: 0)) { - obj.arrayCol.removeAllObjects() + obj.arrayCol.removeAll() } observeChange(obs, "optIntCol", nil, 10) { obj.optIntCol.value = 10 } diff --git a/RealmSwift/Tests/ListTests.swift b/RealmSwift/Tests/ListTests.swift index aa76b49a99..0649691faf 100644 --- a/RealmSwift/Tests/ListTests.swift +++ b/RealmSwift/Tests/ListTests.swift @@ -133,7 +133,7 @@ class ListTests: TestCase { guard let array = array, let str1 = str1, let str2 = str2 else { fatalError("Test precondition failure") } - array.append(objectsIn: realmWithTestPath().allObjects(ofType: SwiftStringObject.self)) + array.append(objectsIn: realmWithTestPath().objects(SwiftStringObject.self)) XCTAssertEqual(Int(2), array.count) XCTAssertEqual(str1, array[0]) XCTAssertEqual(str2, array[1]) @@ -181,14 +181,14 @@ class ListTests: TestCase { array.append(objectsIn: [str1, str2]) - array.removeLastObject() + array.removeLast() XCTAssertEqual(Int(1), array.count) XCTAssertEqual(str1, array[0]) - array.removeLastObject() + array.removeLast() XCTAssertEqual(Int(0), array.count) - array.removeLastObject() // should be a no-op + array.removeLast() // should be a no-op XCTAssertEqual(Int(0), array.count) } @@ -199,10 +199,10 @@ class ListTests: TestCase { array.append(objectsIn: [str1, str2]) - array.removeAllObjects() + array.removeAll() XCTAssertEqual(Int(0), array.count) - array.removeAllObjects() // should be a no-op + array.removeAll() // should be a no-op XCTAssertEqual(Int(0), array.count) } @@ -314,7 +314,7 @@ class ListTests: TestCase { if let realm = array.realm { array.append(objectsIn: [str1, str2]) - let otherArray = realm.allObjects(ofType: SwiftArrayPropertyObject.self).first!.array + let otherArray = realm.objects(SwiftArrayPropertyObject.self).first!.array XCTAssertEqual(Int(2), otherArray.count) } } @@ -329,7 +329,7 @@ class ListTests: TestCase { let obj = SwiftStringObject() obj.stringCol = "a" array.append(obj) - array.append(realmWithTestPath().createObject(ofType: SwiftStringObject.self, populatedWith: ["b"])) + array.append(realmWithTestPath().create(SwiftStringObject.self, value: ["b"])) array.append(obj) XCTAssertEqual(array.count, 3) @@ -401,7 +401,7 @@ class ListNewlyCreatedTests: ListTests { override func createArray() -> SwiftArrayPropertyObject { let realm = realmWithTestPath() realm.beginWrite() - let array = realm.createObject(ofType: SwiftArrayPropertyObject.self, populatedWith: ["name", [], []]) + let array = realm.create(SwiftArrayPropertyObject.self, value: ["name", [], []]) try! realm.commitWrite() XCTAssertNotNil(array.realm) @@ -411,7 +411,7 @@ class ListNewlyCreatedTests: ListTests { override func createArrayWithLinks() -> SwiftListOfSwiftObject { let realm = try! Realm() realm.beginWrite() - let array = realm.createObject(ofType: SwiftListOfSwiftObject.self) + let array = realm.create(SwiftListOfSwiftObject.self) try! realm.commitWrite() XCTAssertNotNil(array.realm) @@ -423,9 +423,9 @@ class ListRetrievedTests: ListTests { override func createArray() -> SwiftArrayPropertyObject { let realm = realmWithTestPath() realm.beginWrite() - realm.createObject(ofType: SwiftArrayPropertyObject.self, populatedWith: ["name", [], []]) + realm.create(SwiftArrayPropertyObject.self, value: ["name", [], []]) try! realm.commitWrite() - let array = realm.allObjects(ofType: SwiftArrayPropertyObject.self).first! + let array = realm.objects(SwiftArrayPropertyObject.self).first! XCTAssertNotNil(array.realm) return array @@ -434,9 +434,9 @@ class ListRetrievedTests: ListTests { override func createArrayWithLinks() -> SwiftListOfSwiftObject { let realm = try! Realm() realm.beginWrite() - realm.createObject(ofType: SwiftListOfSwiftObject.self) + realm.create(SwiftListOfSwiftObject.self) try! realm.commitWrite() - let array = realm.allObjects(ofType: SwiftListOfSwiftObject.self).first! + let array = realm.objects(SwiftListOfSwiftObject.self).first! XCTAssertNotNil(array.realm) return array diff --git a/RealmSwift/Tests/MigrationTests.swift b/RealmSwift/Tests/MigrationTests.swift index e57a818cbf..255ac89946 100644 --- a/RealmSwift/Tests/MigrationTests.swift +++ b/RealmSwift/Tests/MigrationTests.swift @@ -170,7 +170,7 @@ class MigrationTests: TestCase { autoreleasepool { // add object try! Realm().write { - try! Realm().createObject(ofType: SwiftStringObject.self, populatedWith: ["string"]) + try! Realm().create(SwiftStringObject.self, value: ["string"]) return } } @@ -191,7 +191,7 @@ class MigrationTests: TestCase { autoreleasepool { try! Realm().write { - try! Realm().createObject(ofType: SwiftArrayPropertyObject.self, populatedWith: ["string", [["array"]], [[2]]]) + try! Realm().create(SwiftArrayPropertyObject.self, value: ["string", [["array"]], [[2]]]) } } @@ -261,14 +261,14 @@ class MigrationTests: TestCase { } migrateAndTestDefaultRealm() { migration, oldSchemaVersion in - migration.createObject(ofType: "SwiftStringObject", populatedWith: ["string"]) - migration.createObject(ofType: "SwiftStringObject", populatedWith: ["stringCol": "string"]) - migration.createObject(ofType: "SwiftStringObject") + migration.create("SwiftStringObject", value: ["string"]) + migration.create("SwiftStringObject", value: ["stringCol": "string"]) + migration.create("SwiftStringObject") - self.assertThrows(migration.createObject(ofType: "NoSuchObject", populatedWith: [])) + self.assertThrows(migration.create("NoSuchObject", value: [])) } - let objects = try! Realm().allObjects(ofType: SwiftStringObject.self) + let objects = try! Realm().objects(SwiftStringObject.self) XCTAssertEqual(objects.count, 3) XCTAssertEqual(objects[0].stringCol, "string") @@ -279,8 +279,8 @@ class MigrationTests: TestCase { func testDelete() { autoreleasepool { try! Realm().write { - try! Realm().createObject(ofType: SwiftStringObject.self, populatedWith: ["string1"]) - try! Realm().createObject(ofType: SwiftStringObject.self, populatedWith: ["string2"]) + try! Realm().create(SwiftStringObject.self, value: ["string1"]) + try! Realm().create(SwiftStringObject.self, value: ["string2"]) return } } @@ -295,7 +295,7 @@ class MigrationTests: TestCase { }) } - XCTAssertEqual(try! Realm().allObjects(ofType: SwiftStringObject.self).count, 1) + XCTAssertEqual(try! Realm().objects(SwiftStringObject.self).count, 1) } func testDeleteData() { @@ -315,7 +315,7 @@ class MigrationTests: TestCase { XCTAssertTrue(migration.deleteData(forType: "DeletedClass")) XCTAssertFalse(migration.deleteData(forType: "NoSuchClass")) - migration.createObject(ofType: SwiftStringObject.className(), populatedWith: ["migration"]) + migration.create(SwiftStringObject.className(), value: ["migration"]) XCTAssertTrue(migration.deleteData(forType: SwiftStringObject.className())) } @@ -406,7 +406,7 @@ class MigrationTests: TestCase { list[0]["boolCol"] = true list.append(newObj!["objectCol"] as! MigrationObject) - let trueObj = migration.createObject(ofType: SwiftBoolObject.className(), populatedWith: [true]) + let trueObj = migration.create(SwiftBoolObject.className(), value: [true]) list.append(trueObj) // verify list property @@ -431,7 +431,7 @@ class MigrationTests: TestCase { try! Realm().refresh() // check edited values - let object = try! Realm().allObjects(ofType: SwiftObject.self).first! + let object = try! Realm().objects(SwiftObject.self).first! XCTAssertEqual(object.boolCol, false) XCTAssertEqual(object.intCol, 1) XCTAssertEqual(object.floatCol, 1.0 as Float) @@ -444,7 +444,7 @@ class MigrationTests: TestCase { XCTAssertEqual(object.arrayCol[1].boolCol, true) // make sure we added new bool objects as object property and in the list - XCTAssertEqual(try! Realm().allObjects(ofType: SwiftBoolObject.self).count, 4) + XCTAssertEqual(try! Realm().objects(SwiftBoolObject.self).count, 4) } func testFailOnSchemaMismatch() { diff --git a/RealmSwift/Tests/ObjectAccessorTests.swift b/RealmSwift/Tests/ObjectAccessorTests.swift index 12f947dc13..97aaacac35 100644 --- a/RealmSwift/Tests/ObjectAccessorTests.swift +++ b/RealmSwift/Tests/ObjectAccessorTests.swift @@ -79,8 +79,8 @@ class ObjectAccessorTests: TestCase { func testPersistedAccessors() { let realm = try! Realm() realm.beginWrite() - let object = realm.createObject(ofType: SwiftObject.self) - let optionalObject = realm.createObject(ofType: SwiftOptionalObject.self) + let object = realm.create(SwiftObject.self) + let optionalObject = realm.create(SwiftOptionalObject.self) setAndTestAllProperties(object) setAndTestAllOptionalProperties(optionalObject) try! realm.commitWrite() @@ -139,7 +139,7 @@ class ObjectAccessorTests: TestCase { testObject() } - let obj = realm.allObjects(ofType: SwiftAllIntSizesObject.self).first! + let obj = realm.objects(SwiftAllIntSizesObject.self).first! XCTAssertEqual(obj.int8, v8) XCTAssertEqual(obj.int16, v16) XCTAssertEqual(obj.int32, v32) @@ -155,12 +155,12 @@ class ObjectAccessorTests: TestCase { let realm = realmWithTestPath() realm.beginWrite() - realm.createObject(ofType: SwiftLongObject.self, populatedWith: [NSNumber(value: longNumber)]) - realm.createObject(ofType: SwiftLongObject.self, populatedWith: [NSNumber(value: intNumber)]) - realm.createObject(ofType: SwiftLongObject.self, populatedWith: [NSNumber(value: negativeLongNumber)]) + realm.create(SwiftLongObject.self, value: [NSNumber(value: longNumber)]) + realm.create(SwiftLongObject.self, value: [NSNumber(value: intNumber)]) + realm.create(SwiftLongObject.self, value: [NSNumber(value: negativeLongNumber)]) try! realm.commitWrite() - let objects = realm.allObjects(ofType: SwiftLongObject.self) + let objects = realm.objects(SwiftLongObject.self) XCTAssertEqual(objects.count, Int(3), "3 rows expected") XCTAssertEqual(objects[0].longCol, longNumber, "2 ^ 34 expected") XCTAssertEqual(objects[1].longCol, intNumber, "2 ^ 31 - 1 expected") @@ -196,7 +196,7 @@ class ObjectAccessorTests: TestCase { realm.add(object2) } - let objects = realm.allObjects(ofType: SwiftObject.self) + let objects = realm.objects(SwiftObject.self) let firstObject = objects.first XCTAssertEqual(2, firstObject!.arrayCol.count) @@ -216,8 +216,8 @@ class ObjectAccessorTests: TestCase { func testSettingOptionalPropertyOnDeletedObjectsThrows() { let realm = try! Realm() try! realm.write { - let obj = realm.createObject(ofType: SwiftOptionalObject.self) - let copy = realm.allObjects(ofType: SwiftOptionalObject.self).first! + let obj = realm.create(SwiftOptionalObject.self) + let copy = realm.objects(SwiftOptionalObject.self).first! realm.delete(obj) self.assertThrows(copy.optIntCol.value = 1) diff --git a/RealmSwift/Tests/ObjectCreationTests.swift b/RealmSwift/Tests/ObjectCreationTests.swift index 9dbaa1fe0e..7812d45e60 100644 --- a/RealmSwift/Tests/ObjectCreationTests.swift +++ b/RealmSwift/Tests/ObjectCreationTests.swift @@ -157,14 +157,14 @@ class ObjectCreationTests: TestCase { func testCreateWithDefaults() { let realm = try! Realm() - assertThrows(realm.createObject(ofType: SwiftObject.self), "Must be in write transaction") + assertThrows(realm.create(SwiftObject.self), "Must be in write transaction") var object: SwiftObject! - let objects = realm.allObjects(ofType: SwiftObject.self) + let objects = realm.objects(SwiftObject.self) XCTAssertEqual(0, objects.count) try! realm.write { // test create with all defaults - object = realm.createObject(ofType: SwiftObject.self) + object = realm.create(SwiftObject.self) return } verifySwiftObjectWithDictionaryLiteral(object, dictionary: SwiftObject.defaultValues(), boolObjectValue: false, @@ -179,7 +179,7 @@ class ObjectCreationTests: TestCase { func testCreateWithOptionalWithoutDefaults() { let realm = try! Realm() try! realm.write { - let object = realm.createObject(ofType: SwiftOptionalObject.self) + let object = realm.create(SwiftOptionalObject.self) for prop in object.objectSchema.properties { XCTAssertNil(object[prop.name]) } @@ -189,7 +189,7 @@ class ObjectCreationTests: TestCase { func testCreateWithOptionalDefaults() { let realm = try! Realm() try! realm.write { - let object = realm.createObject(ofType: SwiftOptionalDefaultValuesObject.self) + let object = realm.create(SwiftOptionalDefaultValuesObject.self) self.verifySwiftOptionalObjectWithDictionaryLiteral(object, dictionary: SwiftOptionalDefaultValuesObject.defaultValues(), boolObjectValue: true) } @@ -198,7 +198,7 @@ class ObjectCreationTests: TestCase { func testCreateWithOptionalIgnoredProperties() { let realm = try! Realm() try! realm.write { - let object = realm.createObject(ofType: SwiftOptionalIgnoredPropertiesObject.self) + let object = realm.create(SwiftOptionalIgnoredPropertiesObject.self) let properties = object.objectSchema.properties XCTAssertEqual(properties.count, 1) XCTAssertEqual(properties[0].name, "id") @@ -227,7 +227,7 @@ class ObjectCreationTests: TestCase { var values = baselineValues values[props[propNum].name] = validValue try! Realm().beginWrite() - let object = try! Realm().createObject(ofType: SwiftObject.self, populatedWith: values) + let object = try! Realm().create(SwiftObject.self, value: values) verifySwiftObjectWithDictionaryLiteral(object, dictionary: values, boolObjectValue: true, boolObjectListValues: [true, false]) try! Realm().commitWrite() @@ -243,7 +243,7 @@ class ObjectCreationTests: TestCase { var values = baselineValues values[props[propNum].name] = invalidValue try! Realm().beginWrite() - assertThrows(try! Realm().createObject(ofType: SwiftObject.self, populatedWith: values), "Invalid property value") + assertThrows(try! Realm().create(SwiftObject.self, value: values), "Invalid property value") try! Realm().cancelWrite() } } @@ -253,7 +253,7 @@ class ObjectCreationTests: TestCase { // test with dictionary with mix of default and one specified value let realm = try! Realm() realm.beginWrite() - let objectWithInt = realm.createObject(ofType: SwiftObject.self, populatedWith: ["intCol": 200]) + let objectWithInt = realm.create(SwiftObject.self, value: ["intCol": 200]) try! realm.commitWrite() let valueDict = defaultSwiftObjectValuesWithReplacements(["intCol": 200]) @@ -274,7 +274,7 @@ class ObjectCreationTests: TestCase { var values = baselineValues values[propNum] = validValue try! Realm().beginWrite() - let object = try! Realm().createObject(ofType: SwiftObject.self, populatedWith: values) + let object = try! Realm().create(SwiftObject.self, value: values) verifySwiftObjectWithArrayLiteral(object, array: values, boolObjectValue: true, boolObjectListValues: [true, false]) try! Realm().commitWrite() @@ -291,7 +291,7 @@ class ObjectCreationTests: TestCase { values[propNum] = invalidValue try! Realm().beginWrite() - assertThrows(try! Realm().createObject(ofType: SwiftObject.self, populatedWith: values), + assertThrows(try! Realm().create(SwiftObject.self, value: values), "Invalid property value '\(invalidValue)' for property number \(propNum)") try! Realm().cancelWrite() } @@ -301,25 +301,25 @@ class ObjectCreationTests: TestCase { func testCreateWithKVCObject() { // test with kvc object try! Realm().beginWrite() - let objectWithInt = try! Realm().createObject(ofType: SwiftObject.self, populatedWith: ["intCol": 200]) - let objectWithKVCObject = try! Realm().createObject(ofType: SwiftObject.self, populatedWith: objectWithInt) + let objectWithInt = try! Realm().create(SwiftObject.self, value: ["intCol": 200]) + let objectWithKVCObject = try! Realm().create(SwiftObject.self, value: objectWithInt) let valueDict = defaultSwiftObjectValuesWithReplacements(["intCol": 200]) try! Realm().commitWrite() verifySwiftObjectWithDictionaryLiteral(objectWithKVCObject, dictionary: valueDict, boolObjectValue: false, boolObjectListValues: []) - XCTAssertEqual(try! Realm().allObjects(ofType: SwiftObject.self).count, 2, "Object should have been copied") + XCTAssertEqual(try! Realm().objects(SwiftObject.self).count, 2, "Object should have been copied") } func testCreateWithNestedObjects() { let standalone = SwiftPrimaryStringObject(value: ["p0", 11]) try! Realm().beginWrite() - let objectWithNestedObjects = try! Realm().createObject(ofType: SwiftLinkToPrimaryStringObject.self, populatedWith: ["p1", ["p1", 11], + let objectWithNestedObjects = try! Realm().create(SwiftLinkToPrimaryStringObject.self, value: ["p1", ["p1", 11], [standalone]]) try! Realm().commitWrite() - let stringObjects = try! Realm().allObjects(ofType: SwiftPrimaryStringObject.self) + let stringObjects = try! Realm().objects(SwiftPrimaryStringObject.self) XCTAssertEqual(stringObjects.count, 2) let persistedObject = stringObjects.first! @@ -330,7 +330,7 @@ class ObjectCreationTests: TestCase { let standalone1 = SwiftPrimaryStringObject(value: ["p3", 11]) try! Realm().beginWrite() - assertThrows(try! Realm().createObject(ofType: SwiftLinkToPrimaryStringObject.self, populatedWith: ["p3", ["p3", 11], [standalone1]]), + assertThrows(try! Realm().create(SwiftLinkToPrimaryStringObject.self, value: ["p3", ["p3", 11], [standalone1]]), "Should throw with duplicate primary key") try! Realm().commitWrite() } @@ -338,11 +338,11 @@ class ObjectCreationTests: TestCase { func testUpdateWithNestedObjects() { let standalone = SwiftPrimaryStringObject(value: ["primary", 11]) try! Realm().beginWrite() - let object = try! Realm().createObject(ofType: SwiftLinkToPrimaryStringObject.self, populatedWith: ["otherPrimary", ["primary", 12], + let object = try! Realm().create(SwiftLinkToPrimaryStringObject.self, value: ["otherPrimary", ["primary", 12], [["primary", 12]]], update: true) try! Realm().commitWrite() - let stringObjects = try! Realm().allObjects(ofType: SwiftPrimaryStringObject.self) + let stringObjects = try! Realm().objects(SwiftPrimaryStringObject.self) XCTAssertEqual(stringObjects.count, 1) let persistedObject = object.object! @@ -366,11 +366,11 @@ class ObjectCreationTests: TestCase { ] realmWithTestPath().beginWrite() - let otherRealmObject = realmWithTestPath().createObject(ofType: SwiftObject.self, populatedWith: values) + let otherRealmObject = realmWithTestPath().create(SwiftObject.self, value: values) try! realmWithTestPath().commitWrite() try! Realm().beginWrite() - let object = try! Realm().createObject(ofType: SwiftObject.self, populatedWith: otherRealmObject) + let object = try! Realm().create(SwiftObject.self, value: otherRealmObject) try! Realm().commitWrite() XCTAssertNotEqual(otherRealmObject, object) @@ -397,12 +397,12 @@ class ObjectCreationTests: TestCase { var realmAObject: SwiftListOfSwiftObject! try! realmA.write { let array = [SwiftObject(value: values), SwiftObject(value: values)] - realmAObject = realmA.createObject(ofType: SwiftListOfSwiftObject.self, populatedWith: ["array": array]) + realmAObject = realmA.create(SwiftListOfSwiftObject.self, value: ["array": array]) } var realmBObject: SwiftListOfSwiftObject! try! realmB.write { - realmBObject = realmB.createObject(ofType: SwiftListOfSwiftObject.self, populatedWith: realmAObject) + realmBObject = realmB.create(SwiftListOfSwiftObject.self, value: realmAObject) } XCTAssertNotEqual(realmAObject, realmBObject) @@ -415,18 +415,18 @@ class ObjectCreationTests: TestCase { func testUpdateWithObjectsFromAnotherRealm() { realmWithTestPath().beginWrite() - let otherRealmObject = realmWithTestPath().createObject(ofType: SwiftLinkToPrimaryStringObject.self, - populatedWith: ["primary", NSNull(), [["2", 2], ["4", 4]]]) + let otherRealmObject = realmWithTestPath().create(SwiftLinkToPrimaryStringObject.self, + value: ["primary", NSNull(), [["2", 2], ["4", 4]]]) try! realmWithTestPath().commitWrite() try! Realm().beginWrite() - try! Realm().createObject(ofType: SwiftLinkToPrimaryStringObject.self, populatedWith: ["primary", ["10", 10], [["11", 11]]]) - let object = try! Realm().createObject(ofType: SwiftLinkToPrimaryStringObject.self, populatedWith: otherRealmObject, update: true) + try! Realm().create(SwiftLinkToPrimaryStringObject.self, value: ["primary", ["10", 10], [["11", 11]]]) + let object = try! Realm().create(SwiftLinkToPrimaryStringObject.self, value: otherRealmObject, update: true) try! Realm().commitWrite() XCTAssertNotEqual(otherRealmObject, object) // the object from the other realm should be copied into this realm - XCTAssertEqual(try! Realm().allObjects(ofType: SwiftLinkToPrimaryStringObject.self).count, 1) - XCTAssertEqual(try! Realm().allObjects(ofType: SwiftPrimaryStringObject.self).count, 4) + XCTAssertEqual(try! Realm().objects(SwiftLinkToPrimaryStringObject.self).count, 1) + XCTAssertEqual(try! Realm().objects(SwiftPrimaryStringObject.self).count, 4) } func testCreateWithNSNullLinks() { @@ -443,7 +443,7 @@ class ObjectCreationTests: TestCase { ] realmWithTestPath().beginWrite() - let object = realmWithTestPath().createObject(ofType: SwiftObject.self, populatedWith: values) + let object = realmWithTestPath().create(SwiftObject.self, value: values) try! realmWithTestPath().commitWrite() XCTAssert(object.objectCol == nil) // XCTAssertNil caused a NULL deref inside _swift_getClass @@ -456,7 +456,7 @@ class ObjectCreationTests: TestCase { // MARK: Add tests func testAddWithExisingNestedObjects() { try! Realm().beginWrite() - let existingObject = try! Realm().createObject(ofType: SwiftBoolObject.self) + let existingObject = try! Realm().create(SwiftBoolObject.self) try! Realm().commitWrite() try! Realm().beginWrite() @@ -471,7 +471,7 @@ class ObjectCreationTests: TestCase { func testAddAndUpdateWithExisingNestedObjects() { try! Realm().beginWrite() - let existingObject = try! Realm().createObject(ofType: SwiftPrimaryStringObject.self, populatedWith: ["primary", 1]) + let existingObject = try! Realm().create(SwiftPrimaryStringObject.self, value: ["primary", 1]) try! Realm().commitWrite() try! Realm().beginWrite() @@ -550,7 +550,7 @@ class ObjectCreationTests: TestCase { // swiftlint:disable:next cyclomatic_complexity private func validValuesForSwiftObjectType(_ type: PropertyType) -> [Any] { try! Realm().beginWrite() - let persistedObject = try! Realm().createObject(ofType: SwiftBoolObject.self, populatedWith: [true]) + let persistedObject = try! Realm().create(SwiftBoolObject.self, value: [true]) try! Realm().commitWrite() switch type { case .bool: return [true, NSNumber(value: 0 as Int), NSNumber(value: 1 as Int)] @@ -576,7 +576,7 @@ class ObjectCreationTests: TestCase { // swiftlint:disable:next cyclomatic_complexity private func invalidValuesForSwiftObjectType(_ type: PropertyType) -> [Any] { try! Realm().beginWrite() - let persistedObject = try! Realm().createObject(ofType: SwiftIntObject.self) + let persistedObject = try! Realm().create(SwiftIntObject.self) try! Realm().commitWrite() switch type { case .bool: return ["invalid", NSNumber(value: 2 as Int), NSNumber(value: 1.1 as Float), NSNumber(value: 11.1 as Double)] diff --git a/RealmSwift/Tests/ObjectTests.swift b/RealmSwift/Tests/ObjectTests.swift index 8fb6281f42..68720b5245 100644 --- a/RealmSwift/Tests/ObjectTests.swift +++ b/RealmSwift/Tests/ObjectTests.swift @@ -35,7 +35,7 @@ class ObjectTests: TestCase { let realm = try! Realm() var persisted: SwiftStringObject! try! realm.write { - persisted = realm.createObject(ofType: SwiftStringObject.self, populatedWith: [:]) + persisted = realm.create(SwiftStringObject.self, value: [:]) XCTAssertNotNil(persisted.realm) XCTAssertEqual(realm, persisted.realm!) } @@ -90,7 +90,7 @@ class ObjectTests: TestCase { } try! realm.write { - realm.deleteAllObjects() + realm.deleteAll() XCTAssertTrue(object.isInvalidated) } XCTAssertTrue(object.isInvalidated) @@ -213,7 +213,7 @@ class ObjectTests: TestCase { test(SwiftObject()) try! Realm().write { - let persistedObject = try! Realm().createObject(ofType: SwiftObject.self, populatedWith: [:]) + let persistedObject = try! Realm().create(SwiftObject.self, value: [:]) test(persistedObject) } } @@ -253,7 +253,7 @@ class ObjectTests: TestCase { XCTAssertEqual((getter(object, "arrayCol") as! List).count, 1) XCTAssertEqual((getter(object, "arrayCol") as! List).first!, boolObject) - list.removeAllObjects() + list.removeAll() setter(object, list, "arrayCol") XCTAssertEqual((getter(object, "arrayCol") as! List).count, 0) @@ -296,7 +296,7 @@ class ObjectTests: TestCase { XCTAssertEqual((getter(object, "arrayCol") as! List).first!, boolObject) let list = getter(object, "arrayCol") as! List - list.removeAllObjects() + list.removeAll() setter(object, list, "arrayCol") XCTAssertEqual((getter(object, "arrayCol") as! List).count, 0) @@ -310,7 +310,7 @@ class ObjectTests: TestCase { autoreleasepool { let realm = self.realmWithTestPath() try! realm.write { - _ = realm.createObject(ofType: SwiftObject.self) + _ = realm.create(SwiftObject.self) } } autoreleasepool { @@ -338,13 +338,13 @@ class ObjectTests: TestCase { } withMigrationObject { migrationObject, migration in - let boolObject = migration.createObject(ofType: "SwiftBoolObject", populatedWith: [true]) + let boolObject = migration.create("SwiftBoolObject", value: [true]) self.dynamicSetAndTestAllTypes(setter, getter: getter, object: migrationObject, boolObject: boolObject) } setAndTestAllTypes(setter, getter: getter, object: SwiftObject()) try! Realm().write { - let persistedObject = try! Realm().createObject(ofType: SwiftObject.self, populatedWith: [:]) + let persistedObject = try! Realm().create(SwiftObject.self, value: [:]) self.setAndTestAllTypes(setter, getter: getter, object: persistedObject) } } @@ -359,13 +359,13 @@ class ObjectTests: TestCase { } withMigrationObject { migrationObject, migration in - let boolObject = migration.createObject(ofType: "SwiftBoolObject", populatedWith: [true]) + let boolObject = migration.create("SwiftBoolObject", value: [true]) self.dynamicSetAndTestAllTypes(setter, getter: getter, object: migrationObject, boolObject: boolObject) } setAndTestAllTypes(setter, getter: getter, object: SwiftObject()) try! Realm().write { - let persistedObject = try! Realm().createObject(ofType: SwiftObject.self, populatedWith: [:]) + let persistedObject = try! Realm().create(SwiftObject.self, value: [:]) self.setAndTestAllTypes(setter, getter: getter, object: persistedObject) } } diff --git a/RealmSwift/Tests/PerformanceTests.swift b/RealmSwift/Tests/PerformanceTests.swift index 1f150c96ce..d384bc12fe 100644 --- a/RealmSwift/Tests/PerformanceTests.swift +++ b/RealmSwift/Tests/PerformanceTests.swift @@ -25,8 +25,8 @@ private func createStringObjects(_ factor: Int) -> Realm { let realm = inMemoryRealm(factor.description) try! realm.write { for _ in 0..<(1000 * factor) { - realm.createObject(ofType: SwiftStringObject.self, populatedWith: ["a"]) - realm.createObject(ofType: SwiftStringObject.self, populatedWith: ["b"]) + realm.create(SwiftStringObject.self, value: ["a"]) + realm.create(SwiftStringObject.self, value: ["b"]) } } return realm @@ -99,7 +99,7 @@ class SwiftPerformanceTests: TestCase { fatalError("Unexpected error: \(error)") } - try! realm.writeCopy(toFileURL: testRealmURL()) + try! realm.writeCopy(toFile: testRealmURL()) return realmWithTestPath() } @@ -125,7 +125,7 @@ class SwiftPerformanceTests: TestCase { self.startMeasuring() for _ in 0..<50 { try! realm.write { - _ = realm.createObject(ofType: SwiftStringObject.self, populatedWith: ["a"]) + _ = realm.create(SwiftStringObject.self, value: ["a"]) } } self.stopMeasuring() @@ -139,7 +139,7 @@ class SwiftPerformanceTests: TestCase { self.startMeasuring() try! realm.write { for _ in 0..<5000 { - realm.createObject(ofType: SwiftStringObject.self, populatedWith: ["a"]) + realm.create(SwiftStringObject.self, value: ["a"]) } } self.stopMeasuring() @@ -151,7 +151,7 @@ class SwiftPerformanceTests: TestCase { let realm = copyRealmToTestPath(largeRealm) measure { for _ in 0..<50 { - let results = realm.allObjects(ofType: SwiftStringObject.self).filter(using: "stringCol = 'a'") + let results = realm.objects(SwiftStringObject.self).filter("stringCol = 'a'") _ = results.count } } @@ -161,7 +161,7 @@ class SwiftPerformanceTests: TestCase { let realm = copyRealmToTestPath(mediumRealm) measure { for _ in 0..<50 { - let results = realm.allObjects(ofType: SwiftStringObject.self).filter(using: "stringCol = 'a'") + let results = realm.objects(SwiftStringObject.self).filter("stringCol = 'a'") _ = results.first _ = results.count } @@ -171,7 +171,7 @@ class SwiftPerformanceTests: TestCase { func testEnumerateAndAccessQuery() { let realm = copyRealmToTestPath(largeRealm) measure { - for stringObject in realm.allObjects(ofType: SwiftStringObject.self).filter(using: "stringCol = 'a'") { + for stringObject in realm.objects(SwiftStringObject.self).filter("stringCol = 'a'") { _ = stringObject.stringCol } } @@ -180,7 +180,7 @@ class SwiftPerformanceTests: TestCase { func testEnumerateAndAccessAll() { let realm = copyRealmToTestPath(largeRealm) measure { - for stringObject in realm.allObjects(ofType: SwiftStringObject.self) { + for stringObject in realm.objects(SwiftStringObject.self) { _ = stringObject.stringCol } } @@ -189,7 +189,7 @@ class SwiftPerformanceTests: TestCase { func testEnumerateAndAccessAllSlow() { let realm = copyRealmToTestPath(largeRealm) measure { - let results = realm.allObjects(ofType: SwiftStringObject.self) + let results = realm.objects(SwiftStringObject.self) for i in 0.. Results { - return realmWithTestPath().allObjects(ofType: CTTStringObjectWithLink.self) + return realmWithTestPath().objects(CTTStringObjectWithLink.self) } override func getAggregateableCollection() -> AnyRealmCollection { _ = makeAggregateableObjects() - return AnyRealmCollection(realmWithTestPath().allObjects(ofType: CTTAggregateObject.self)) + return AnyRealmCollection(realmWithTestPath().objects(CTTAggregateObject.self)) } } class ResultsFromTableViewTests: ResultsTests { override func collectionBaseInWriteTransaction() -> Results { - return realmWithTestPath().allObjects(ofType: CTTStringObjectWithLink.self).filter(using: "stringCol != ''") + return realmWithTestPath().objects(CTTStringObjectWithLink.self).filter("stringCol != ''") } override func getAggregateableCollection() -> AnyRealmCollection { _ = makeAggregateableObjects() - return AnyRealmCollection(realmWithTestPath().allObjects(ofType: CTTAggregateObject.self).filter(using: "trueCol == true")) + return AnyRealmCollection(realmWithTestPath().objects(CTTAggregateObject.self).filter("trueCol == true")) } } @@ -678,8 +678,8 @@ class ResultsFromLinkViewTests: ResultsTests { guard let str1 = str1, let str2 = str2 else { fatalError("Test precondition failed") } - let array = realmWithTestPath().createObject(ofType: CTTStringList.self, populatedWith: [[str1, str2]]) - return array.array.filter(using: NSPredicate(value: true)) + let array = realmWithTestPath().create(CTTStringList.self, value: [[str1, str2]]) + return array.array.filter(NSPredicate(value: true)) } override func getAggregateableCollection() -> AnyRealmCollection { @@ -689,14 +689,14 @@ class ResultsFromLinkViewTests: ResultsTests { realmWithTestPath().add(list!) list!.list.append(objectsIn: makeAggregateableObjectsInWriteTransaction()) } - return AnyRealmCollection(list!.list.filter(using: NSPredicate(value: true))) + return AnyRealmCollection(list!.list.filter(NSPredicate(value: true))) } override func addObjectToResults() { let realm = realmWithTestPath() try! realm.write { - let array = realm.allObjects(ofType: CTTStringList.self).last! - array.array.append(realm.createObject(ofType: CTTStringObjectWithLink.self, populatedWith: ["a"])) + let array = realm.objects(CTTStringList.self).last! + array.array.append(realm.create(CTTStringObjectWithLink.self, value: ["a"])) } } } @@ -750,13 +750,13 @@ class ListRealmCollectionTypeTests: RealmCollectionTypeTests { let theExpectation = expectation(description: "") let token = collection.addNotificationBlock { (changes: RealmCollectionChange) in switch changes { - case .Initial(let list): + case .initial(let list): XCTAssertEqual(list.count, 2) break - case .Update: + case .update: XCTFail("Shouldn't happen") break - case .Error: + case .error: XCTFail("Shouldn't happen") break } @@ -804,8 +804,8 @@ class ListStandaloneRealmCollectionTypeTests: ListRealmCollectionTypeTests { override func testSortWithDescriptor() { let collection = getAggregateableCollection() - assertThrows(collection.sorted(with: [SortDescriptor(property: "intCol", ascending: true)])) - assertThrows(collection.sorted(with: [SortDescriptor(property: "doubleCol", ascending: false), + assertThrows(collection.sorted(by: [SortDescriptor(property: "intCol", ascending: true)])) + assertThrows(collection.sorted(by: [SortDescriptor(property: "doubleCol", ascending: false), SortDescriptor(property: "intCol", ascending: false)])) } @@ -833,16 +833,16 @@ class ListStandaloneRealmCollectionTypeTests: ListRealmCollectionTypeTests { guard let collection = collection else { fatalError("Test precondition failed") } - assertThrows(collection.sorted(onProperty: "stringCol", ascending: true)) - assertThrows(collection.sorted(onProperty: "noSuchCol", ascending: true)) + assertThrows(collection.sorted(byProperty: "stringCol", ascending: true)) + assertThrows(collection.sorted(byProperty: "noSuchCol", ascending: true)) } override func testFilterFormat() { guard let collection = collection else { fatalError("Test precondition failed") } - assertThrows(collection.filter(using: "stringCol = '1'")) - assertThrows(collection.filter(using: "noSuchCol = '1'")) + assertThrows(collection.filter("stringCol = '1'")) + assertThrows(collection.filter("noSuchCol = '1'")) } override func testFilterPredicate() { @@ -852,59 +852,59 @@ class ListStandaloneRealmCollectionTypeTests: ListRealmCollectionTypeTests { let pred1 = NSPredicate(format: "stringCol = '1'") let pred2 = NSPredicate(format: "noSuchCol = '2'") - assertThrows(collection.filter(using: pred1)) - assertThrows(collection.filter(using: pred2)) + assertThrows(collection.filter(pred1)) + assertThrows(collection.filter(pred2)) } override func testArrayAggregateWithSwiftObjectDoesntThrow() { guard let collection = collection else { fatalError("Test precondition failed") } - assertThrows(collection.filter(using: "ANY stringListCol == %@", CTTStringObjectWithLink())) + assertThrows(collection.filter("ANY stringListCol == %@", CTTStringObjectWithLink())) } override func testMin() { guard let collection = collection else { fatalError("Test precondition failed") } - assertThrows(collection.minimumValue(ofProperty: "intCol") as NSNumber!) - assertThrows(collection.minimumValue(ofProperty: "intCol") as Int!) - assertThrows(collection.minimumValue(ofProperty: "int8Col") as NSNumber!) - assertThrows(collection.minimumValue(ofProperty: "int8Col") as Int8!) - assertThrows(collection.minimumValue(ofProperty: "int16Col") as NSNumber!) - assertThrows(collection.minimumValue(ofProperty: "int16Col") as Int16!) - assertThrows(collection.minimumValue(ofProperty: "int32Col") as NSNumber!) - assertThrows(collection.minimumValue(ofProperty: "int32Col") as Int32!) - assertThrows(collection.minimumValue(ofProperty: "int64Col") as NSNumber!) - assertThrows(collection.minimumValue(ofProperty: "int64Col") as Int64!) - assertThrows(collection.minimumValue(ofProperty: "floatCol") as NSNumber!) - assertThrows(collection.minimumValue(ofProperty: "floatCol") as Float!) - assertThrows(collection.minimumValue(ofProperty: "doubleCol") as NSNumber!) - assertThrows(collection.minimumValue(ofProperty: "doubleCol") as Double!) - assertThrows(collection.minimumValue(ofProperty: "dateCol") as NSDate!) - assertThrows(collection.minimumValue(ofProperty: "dateCol") as Date!) + assertThrows(collection.min(ofProperty: "intCol") as NSNumber!) + assertThrows(collection.min(ofProperty: "intCol") as Int!) + assertThrows(collection.min(ofProperty: "int8Col") as NSNumber!) + assertThrows(collection.min(ofProperty: "int8Col") as Int8!) + assertThrows(collection.min(ofProperty: "int16Col") as NSNumber!) + assertThrows(collection.min(ofProperty: "int16Col") as Int16!) + assertThrows(collection.min(ofProperty: "int32Col") as NSNumber!) + assertThrows(collection.min(ofProperty: "int32Col") as Int32!) + assertThrows(collection.min(ofProperty: "int64Col") as NSNumber!) + assertThrows(collection.min(ofProperty: "int64Col") as Int64!) + assertThrows(collection.min(ofProperty: "floatCol") as NSNumber!) + assertThrows(collection.min(ofProperty: "floatCol") as Float!) + assertThrows(collection.min(ofProperty: "doubleCol") as NSNumber!) + assertThrows(collection.min(ofProperty: "doubleCol") as Double!) + assertThrows(collection.min(ofProperty: "dateCol") as NSDate!) + assertThrows(collection.min(ofProperty: "dateCol") as Date!) } override func testMax() { guard let collection = collection else { fatalError("Test precondition failed") } - assertThrows(collection.maximumValue(ofProperty: "intCol") as NSNumber!) - assertThrows(collection.maximumValue(ofProperty: "intCol") as Int!) - assertThrows(collection.maximumValue(ofProperty: "int8Col") as NSNumber!) - assertThrows(collection.maximumValue(ofProperty: "int8Col") as Int8!) - assertThrows(collection.maximumValue(ofProperty: "int16Col") as NSNumber!) - assertThrows(collection.maximumValue(ofProperty: "int16Col") as Int16!) - assertThrows(collection.maximumValue(ofProperty: "int32Col") as NSNumber!) - assertThrows(collection.maximumValue(ofProperty: "int32Col") as Int32!) - assertThrows(collection.maximumValue(ofProperty: "int64Col") as NSNumber!) - assertThrows(collection.maximumValue(ofProperty: "int64Col") as Int64!) - assertThrows(collection.maximumValue(ofProperty: "floatCol") as NSNumber!) - assertThrows(collection.maximumValue(ofProperty: "floatCol") as Float!) - assertThrows(collection.maximumValue(ofProperty: "doubleCol") as NSNumber!) - assertThrows(collection.maximumValue(ofProperty: "doubleCol") as Double!) - assertThrows(collection.maximumValue(ofProperty: "dateCol") as NSDate!) - assertThrows(collection.maximumValue(ofProperty: "dateCol") as Date!) + assertThrows(collection.max(ofProperty: "intCol") as NSNumber!) + assertThrows(collection.max(ofProperty: "intCol") as Int!) + assertThrows(collection.max(ofProperty: "int8Col") as NSNumber!) + assertThrows(collection.max(ofProperty: "int8Col") as Int8!) + assertThrows(collection.max(ofProperty: "int16Col") as NSNumber!) + assertThrows(collection.max(ofProperty: "int16Col") as Int16!) + assertThrows(collection.max(ofProperty: "int32Col") as NSNumber!) + assertThrows(collection.max(ofProperty: "int32Col") as Int32!) + assertThrows(collection.max(ofProperty: "int64Col") as NSNumber!) + assertThrows(collection.max(ofProperty: "int64Col") as Int64!) + assertThrows(collection.max(ofProperty: "floatCol") as NSNumber!) + assertThrows(collection.max(ofProperty: "floatCol") as Float!) + assertThrows(collection.max(ofProperty: "doubleCol") as NSNumber!) + assertThrows(collection.max(ofProperty: "doubleCol") as Double!) + assertThrows(collection.max(ofProperty: "dateCol") as NSDate!) + assertThrows(collection.max(ofProperty: "dateCol") as Date!) } override func testSum() { @@ -985,15 +985,15 @@ class ListNewlyCreatedRealmCollectionTypeTests: ListRealmCollectionTypeTests { guard let str1 = str1, let str2 = str2 else { fatalError("Test precondition failure - a property was unexpectedly nil") } - let array = realmWithTestPath().createObject(ofType: CTTStringList.self, populatedWith: [[str1, str2]]) + let array = realmWithTestPath().create(CTTStringList.self, value: [[str1, str2]]) return array.array } override func getAggregateableCollection() -> AnyRealmCollection { var list: CTTAggregateObjectList? try! realmWithTestPath().write { - list = realmWithTestPath().createObject(ofType: CTTAggregateObjectList.self, - populatedWith: [makeAggregateableObjectsInWriteTransaction()]) + list = realmWithTestPath().create(CTTAggregateObjectList.self, + value: [makeAggregateableObjectsInWriteTransaction()]) } return AnyRealmCollection(list!.list) } @@ -1004,17 +1004,17 @@ class ListRetrievedRealmCollectionTypeTests: ListRealmCollectionTypeTests { guard let str1 = str1, let str2 = str2 else { fatalError("Test precondition failure - a property was unexpectedly nil") } - _ = realmWithTestPath().createObject(ofType: CTTStringList.self, populatedWith: [[str1, str2]]) - let array = realmWithTestPath().allObjects(ofType: CTTStringList.self).first! + _ = realmWithTestPath().create(CTTStringList.self, value: [[str1, str2]]) + let array = realmWithTestPath().objects(CTTStringList.self).first! return array.array } override func getAggregateableCollection() -> AnyRealmCollection { var list: CTTAggregateObjectList? try! realmWithTestPath().write { - _ = realmWithTestPath().createObject(ofType: CTTAggregateObjectList.self, - populatedWith: [makeAggregateableObjectsInWriteTransaction()]) - list = realmWithTestPath().allObjects(ofType: CTTAggregateObjectList.self).first + _ = realmWithTestPath().create(CTTAggregateObjectList.self, + value: [makeAggregateableObjectsInWriteTransaction()]) + list = realmWithTestPath().objects(CTTAggregateObjectList.self).first } return AnyRealmCollection(list!.list) } @@ -1022,8 +1022,8 @@ class ListRetrievedRealmCollectionTypeTests: ListRealmCollectionTypeTests { class LinkingObjectsCollectionTypeTests: RealmCollectionTypeTests { func collectionBaseInWriteTransaction() -> LinkingObjects { - let target = realmWithTestPath().createObject(ofType: CTTLinkTarget.self, populatedWith: [0]) - for object in realmWithTestPath().allObjects(ofType: CTTStringObjectWithLink.self) { + let target = realmWithTestPath().create(CTTLinkTarget.self, value: [0]) + for object in realmWithTestPath().objects(CTTStringObjectWithLink.self) { object.linkCol = target } return target.stringObjects @@ -1045,7 +1045,7 @@ class LinkingObjectsCollectionTypeTests: RealmCollectionTypeTests { var target: CTTLinkTarget? try! realmWithTestPath().write { let objects = makeAggregateableObjectsInWriteTransaction() - target = realmWithTestPath().createObject(ofType: CTTLinkTarget.self, populatedWith: [0]) + target = realmWithTestPath().create(CTTLinkTarget.self, value: [0]) for object in objects { object.linkCol = target } diff --git a/RealmSwift/Tests/RealmTests.swift b/RealmSwift/Tests/RealmTests.swift index 9ad986157c..2df996c642 100644 --- a/RealmSwift/Tests/RealmTests.swift +++ b/RealmSwift/Tests/RealmTests.swift @@ -37,13 +37,13 @@ class RealmTests: TestCase { XCTAssertEqual(try! Realm().configuration.readOnly, false) try! Realm().write { - try! Realm().createObject(ofType: SwiftIntObject.self, populatedWith: [100]) + try! Realm().create(SwiftIntObject.self, value: [100]) } } let config = Realm.Configuration(fileURL: defaultRealmURL(), readOnly: true) let readOnlyRealm = try! Realm(configuration: config) XCTAssertEqual(true, readOnlyRealm.configuration.readOnly) - XCTAssertEqual(1, readOnlyRealm.allObjects(ofType: SwiftIntObject.self).count) + XCTAssertEqual(1, readOnlyRealm.objects(SwiftIntObject.self).count) assertThrows(try! Realm(), "Realm has different readOnly settings") } @@ -58,7 +58,7 @@ class RealmTests: TestCase { autoreleasepool { let realm = try! Realm(fileURL: testRealmURL()) try! realm.write { - realm.createObject(ofType: SwiftStringObject.self, populatedWith: ["a"]) + realm.create(SwiftStringObject.self, value: ["a"]) } } @@ -73,7 +73,7 @@ class RealmTests: TestCase { assertSucceeds { let realm = try Realm(configuration: Realm.Configuration(fileURL: testRealmURL(), readOnly: true)) - XCTAssertEqual(1, realm.allObjects(ofType: SwiftStringObject.self).count) + XCTAssertEqual(1, realm.objects(SwiftStringObject.self).count) } try! fileManager.setAttributes([ FileAttributeKey.immutable: false ], ofItemAtPath: testRealmURL().path) @@ -129,14 +129,14 @@ class RealmTests: TestCase { XCTAssert(realm.isEmpty, "Realm should be empty on creation.") realm.beginWrite() - realm.createObject(ofType: SwiftStringObject.self, populatedWith: ["a"]) + realm.create(SwiftStringObject.self, value: ["a"]) XCTAssertFalse(realm.isEmpty, "Realm should not be empty within a write transaction after adding an object.") realm.cancelWrite() XCTAssertTrue(realm.isEmpty, "Realm should be empty after canceling a write transaction that added an object.") realm.beginWrite() - realm.createObject(ofType: SwiftStringObject.self, populatedWith: ["a"]) + realm.create(SwiftStringObject.self, value: ["a"]) try! realm.commitWrite() XCTAssertFalse(realm.isEmpty, "Realm should not be empty after committing a write transaction that added an object.") @@ -166,23 +166,23 @@ class RealmTests: TestCase { autoreleasepool { let realm = inMemoryRealm("identifier") try! realm.write { - realm.createObject(ofType: SwiftIntObject.self, populatedWith: [1]) + realm.create(SwiftIntObject.self, value: [1]) return } } let realm = inMemoryRealm("identifier") - XCTAssertEqual(realm.allObjects(ofType: SwiftIntObject.self).count, 0) + XCTAssertEqual(realm.objects(SwiftIntObject.self).count, 0) try! realm.write { - realm.createObject(ofType: SwiftIntObject.self, populatedWith: [1]) - XCTAssertEqual(realm.allObjects(ofType: SwiftIntObject.self).count, 1) + realm.create(SwiftIntObject.self, value: [1]) + XCTAssertEqual(realm.objects(SwiftIntObject.self).count, 1) - inMemoryRealm("identifier").createObject(ofType: SwiftIntObject.self, populatedWith: [1]) - XCTAssertEqual(realm.allObjects(ofType: SwiftIntObject.self).count, 2) + inMemoryRealm("identifier").create(SwiftIntObject.self, value: [1]) + XCTAssertEqual(realm.objects(SwiftIntObject.self).count, 2) } let realm2 = inMemoryRealm("identifier2") - XCTAssertEqual(realm2.allObjects(ofType: SwiftIntObject.self).count, 0) + XCTAssertEqual(realm2.objects(SwiftIntObject.self).count, 0) } func testInitCustomClassList() { @@ -197,25 +197,25 @@ class RealmTests: TestCase { try! Realm().write { self.assertThrows(try! Realm().beginWrite()) self.assertThrows(try! Realm().write { }) - try! Realm().createObject(ofType: SwiftStringObject.self, populatedWith: ["1"]) - XCTAssertEqual(try! Realm().allObjects(ofType: SwiftStringObject.self).count, 1) + try! Realm().create(SwiftStringObject.self, value: ["1"]) + XCTAssertEqual(try! Realm().objects(SwiftStringObject.self).count, 1) } - XCTAssertEqual(try! Realm().allObjects(ofType: SwiftStringObject.self).count, 1) + XCTAssertEqual(try! Realm().objects(SwiftStringObject.self).count, 1) } func testDynamicWrite() { try! Realm().write { self.assertThrows(try! Realm().beginWrite()) self.assertThrows(try! Realm().write { }) - try! Realm().createDynamicObject(ofType: "SwiftStringObject", populatedWith: ["1"]) - XCTAssertEqual(try! Realm().allObjects(ofType: SwiftStringObject.self).count, 1) + try! Realm().dynamicCreate("SwiftStringObject", value: ["1"]) + XCTAssertEqual(try! Realm().objects(SwiftStringObject.self).count, 1) } - XCTAssertEqual(try! Realm().allObjects(ofType: SwiftStringObject.self).count, 1) + XCTAssertEqual(try! Realm().objects(SwiftStringObject.self).count, 1) } func testDynamicWriteSubscripting() { try! Realm().beginWrite() - let object = try! Realm().createDynamicObject(ofType: "SwiftStringObject", populatedWith: ["1"]) + let object = try! Realm().dynamicCreate("SwiftStringObject", value: ["1"]) try! Realm().commitWrite() XCTAssertNotNil(object, "Dynamic Object Creation Failed") @@ -229,33 +229,33 @@ class RealmTests: TestCase { assertThrows(try! Realm().beginWrite()) try! Realm().cancelWrite() try! Realm().beginWrite() - try! Realm().createObject(ofType: SwiftStringObject.self, populatedWith: ["1"]) - XCTAssertEqual(try! Realm().allObjects(ofType: SwiftStringObject.self).count, 1) + try! Realm().create(SwiftStringObject.self, value: ["1"]) + XCTAssertEqual(try! Realm().objects(SwiftStringObject.self).count, 1) } func testCommitWrite() { try! Realm().beginWrite() - try! Realm().createObject(ofType: SwiftStringObject.self, populatedWith: ["1"]) + try! Realm().create(SwiftStringObject.self, value: ["1"]) try! Realm().commitWrite() - XCTAssertEqual(try! Realm().allObjects(ofType: SwiftStringObject.self).count, 1) + XCTAssertEqual(try! Realm().objects(SwiftStringObject.self).count, 1) try! Realm().beginWrite() } func testCancelWrite() { assertThrows(try! Realm().cancelWrite()) try! Realm().beginWrite() - try! Realm().createObject(ofType: SwiftStringObject.self, populatedWith: ["1"]) + try! Realm().create(SwiftStringObject.self, value: ["1"]) try! Realm().cancelWrite() - XCTAssertEqual(try! Realm().allObjects(ofType: SwiftStringObject.self).count, 0) + XCTAssertEqual(try! Realm().objects(SwiftStringObject.self).count, 0) try! Realm().write { self.assertThrows(self.realmWithTestPath().cancelWrite()) - let object = try! Realm().createObject(ofType: SwiftStringObject.self) + let object = try! Realm().create(SwiftStringObject.self) try! Realm().cancelWrite() XCTAssertTrue(object.isInvalidated) - XCTAssertEqual(try! Realm().allObjects(ofType: SwiftStringObject.self).count, 0) + XCTAssertEqual(try! Realm().objects(SwiftStringObject.self).count, 0) } - XCTAssertEqual(try! Realm().allObjects(ofType: SwiftStringObject.self).count, 0) + XCTAssertEqual(try! Realm().objects(SwiftStringObject.self).count, 0) } func testInWriteTransaction() { @@ -278,16 +278,16 @@ class RealmTests: TestCase { func testAddSingleObject() { let realm = try! Realm() assertThrows(_ = realm.add(SwiftObject())) - XCTAssertEqual(0, realm.allObjects(ofType: SwiftObject.self).count) + XCTAssertEqual(0, realm.objects(SwiftObject.self).count) var defaultRealmObject: SwiftObject! try! realm.write { defaultRealmObject = SwiftObject() realm.add(defaultRealmObject) - XCTAssertEqual(1, realm.allObjects(ofType: SwiftObject.self).count) + XCTAssertEqual(1, realm.objects(SwiftObject.self).count) realm.add(defaultRealmObject) - XCTAssertEqual(1, realm.allObjects(ofType: SwiftObject.self).count) + XCTAssertEqual(1, realm.objects(SwiftObject.self).count) } - XCTAssertEqual(1, realm.allObjects(ofType: SwiftObject.self).count) + XCTAssertEqual(1, realm.objects(SwiftObject.self).count) let testRealm = realmWithTestPath() try! testRealm.write { @@ -297,16 +297,16 @@ class RealmTests: TestCase { func testAddWithUpdateSingleObject() { let realm = try! Realm() - XCTAssertEqual(0, realm.allObjects(ofType: SwiftPrimaryStringObject.self).count) + XCTAssertEqual(0, realm.objects(SwiftPrimaryStringObject.self).count) var defaultRealmObject: SwiftPrimaryStringObject! try! realm.write { defaultRealmObject = SwiftPrimaryStringObject() realm.add(defaultRealmObject, update: true) - XCTAssertEqual(1, realm.allObjects(ofType: SwiftPrimaryStringObject.self).count) + XCTAssertEqual(1, realm.objects(SwiftPrimaryStringObject.self).count) realm.add(SwiftPrimaryStringObject(), update: true) - XCTAssertEqual(1, realm.allObjects(ofType: SwiftPrimaryStringObject.self).count) + XCTAssertEqual(1, realm.objects(SwiftPrimaryStringObject.self).count) } - XCTAssertEqual(1, realm.allObjects(ofType: SwiftPrimaryStringObject.self).count) + XCTAssertEqual(1, realm.objects(SwiftPrimaryStringObject.self).count) let testRealm = realmWithTestPath() try! testRealm.write { @@ -317,33 +317,33 @@ class RealmTests: TestCase { func testAddMultipleObjects() { let realm = try! Realm() assertThrows(_ = realm.add([SwiftObject(), SwiftObject()])) - XCTAssertEqual(0, realm.allObjects(ofType: SwiftObject.self).count) + XCTAssertEqual(0, realm.objects(SwiftObject.self).count) try! realm.write { let objs = [SwiftObject(), SwiftObject()] realm.add(objs) - XCTAssertEqual(2, realm.allObjects(ofType: SwiftObject.self).count) + XCTAssertEqual(2, realm.objects(SwiftObject.self).count) } - XCTAssertEqual(2, realm.allObjects(ofType: SwiftObject.self).count) + XCTAssertEqual(2, realm.objects(SwiftObject.self).count) let testRealm = realmWithTestPath() try! testRealm.write { - self.assertThrows(_ = testRealm.add(realm.allObjects(ofType: SwiftObject.self))) + self.assertThrows(_ = testRealm.add(realm.objects(SwiftObject.self))) } } func testAddWithUpdateMultipleObjects() { let realm = try! Realm() - XCTAssertEqual(0, realm.allObjects(ofType: SwiftPrimaryStringObject.self).count) + XCTAssertEqual(0, realm.objects(SwiftPrimaryStringObject.self).count) try! realm.write { let objs = [SwiftPrimaryStringObject(), SwiftPrimaryStringObject()] realm.add(objs, update: true) - XCTAssertEqual(1, realm.allObjects(ofType: SwiftPrimaryStringObject.self).count) + XCTAssertEqual(1, realm.objects(SwiftPrimaryStringObject.self).count) } - XCTAssertEqual(1, realm.allObjects(ofType: SwiftPrimaryStringObject.self).count) + XCTAssertEqual(1, realm.objects(SwiftPrimaryStringObject.self).count) let testRealm = realmWithTestPath() try! testRealm.write { - self.assertThrows(_ = testRealm.add(realm.allObjects(ofType: SwiftPrimaryStringObject.self), update: true)) + self.assertThrows(_ = testRealm.add(realm.objects(SwiftPrimaryStringObject.self), update: true)) } } @@ -351,20 +351,20 @@ class RealmTests: TestCase { func testDeleteSingleObject() { let realm = try! Realm() - XCTAssertEqual(0, realm.allObjects(ofType: SwiftObject.self).count) + XCTAssertEqual(0, realm.objects(SwiftObject.self).count) assertThrows(_ = realm.delete(SwiftObject())) var defaultRealmObject: SwiftObject! try! realm.write { defaultRealmObject = SwiftObject() self.assertThrows(_ = realm.delete(defaultRealmObject)) - XCTAssertEqual(0, realm.allObjects(ofType: SwiftObject.self).count) + XCTAssertEqual(0, realm.objects(SwiftObject.self).count) realm.add(defaultRealmObject) - XCTAssertEqual(1, realm.allObjects(ofType: SwiftObject.self).count) + XCTAssertEqual(1, realm.objects(SwiftObject.self).count) realm.delete(defaultRealmObject) - XCTAssertEqual(0, realm.allObjects(ofType: SwiftObject.self).count) + XCTAssertEqual(0, realm.objects(SwiftObject.self).count) } assertThrows(_ = realm.delete(defaultRealmObject)) - XCTAssertEqual(0, realm.allObjects(ofType: SwiftObject.self).count) + XCTAssertEqual(0, realm.objects(SwiftObject.self).count) let testRealm = realmWithTestPath() assertThrows(_ = testRealm.delete(defaultRealmObject)) @@ -375,16 +375,16 @@ class RealmTests: TestCase { func testDeleteSequenceOfObjects() { let realm = try! Realm() - XCTAssertEqual(0, realm.allObjects(ofType: SwiftObject.self).count) + XCTAssertEqual(0, realm.objects(SwiftObject.self).count) var objs: [SwiftObject]! try! realm.write { objs = [SwiftObject(), SwiftObject()] realm.add(objs) - XCTAssertEqual(2, realm.allObjects(ofType: SwiftObject.self).count) + XCTAssertEqual(2, realm.objects(SwiftObject.self).count) realm.delete(objs) - XCTAssertEqual(0, realm.allObjects(ofType: SwiftObject.self).count) + XCTAssertEqual(0, realm.objects(SwiftObject.self).count) } - XCTAssertEqual(0, realm.allObjects(ofType: SwiftObject.self).count) + XCTAssertEqual(0, realm.objects(SwiftObject.self).count) let testRealm = realmWithTestPath() assertThrows(_ = testRealm.delete(objs)) @@ -395,74 +395,74 @@ class RealmTests: TestCase { func testDeleteListOfObjects() { let realm = try! Realm() - XCTAssertEqual(0, realm.allObjects(ofType: SwiftCompanyObject.self).count) + XCTAssertEqual(0, realm.objects(SwiftCompanyObject.self).count) try! realm.write { let obj = SwiftCompanyObject() obj.employees.append(SwiftEmployeeObject()) realm.add(obj) - XCTAssertEqual(1, realm.allObjects(ofType: SwiftEmployeeObject.self).count) + XCTAssertEqual(1, realm.objects(SwiftEmployeeObject.self).count) realm.delete(obj.employees) XCTAssertEqual(0, obj.employees.count) - XCTAssertEqual(0, realm.allObjects(ofType: SwiftEmployeeObject.self).count) + XCTAssertEqual(0, realm.objects(SwiftEmployeeObject.self).count) } - XCTAssertEqual(0, realm.allObjects(ofType: SwiftEmployeeObject.self).count) + XCTAssertEqual(0, realm.objects(SwiftEmployeeObject.self).count) } func testDeleteResults() { let realm = try! Realm(fileURL: testRealmURL()) - XCTAssertEqual(0, realm.allObjects(ofType: SwiftCompanyObject.self).count) + XCTAssertEqual(0, realm.objects(SwiftCompanyObject.self).count) try! realm.write { realm.add(SwiftIntObject(value: [1])) realm.add(SwiftIntObject(value: [1])) realm.add(SwiftIntObject(value: [2])) - XCTAssertEqual(3, realm.allObjects(ofType: SwiftIntObject.self).count) - realm.delete(realm.allObjects(ofType: SwiftIntObject.self).filter(using: "intCol = 1")) - XCTAssertEqual(1, realm.allObjects(ofType: SwiftIntObject.self).count) + XCTAssertEqual(3, realm.objects(SwiftIntObject.self).count) + realm.delete(realm.objects(SwiftIntObject.self).filter("intCol = 1")) + XCTAssertEqual(1, realm.objects(SwiftIntObject.self).count) } - XCTAssertEqual(1, realm.allObjects(ofType: SwiftIntObject.self).count) + XCTAssertEqual(1, realm.objects(SwiftIntObject.self).count) } func testDeleteAll() { let realm = try! Realm() try! realm.write { realm.add(SwiftObject()) - XCTAssertEqual(1, realm.allObjects(ofType: SwiftObject.self).count) - realm.deleteAllObjects() - XCTAssertEqual(0, realm.allObjects(ofType: SwiftObject.self).count) + XCTAssertEqual(1, realm.objects(SwiftObject.self).count) + realm.deleteAll() + XCTAssertEqual(0, realm.objects(SwiftObject.self).count) } - XCTAssertEqual(0, realm.allObjects(ofType: SwiftObject.self).count) + XCTAssertEqual(0, realm.objects(SwiftObject.self).count) } func testObjects() { try! Realm().write { - try! Realm().createObject(ofType: SwiftIntObject.self, populatedWith: [100]) - try! Realm().createObject(ofType: SwiftIntObject.self, populatedWith: [200]) - try! Realm().createObject(ofType: SwiftIntObject.self, populatedWith: [300]) + try! Realm().create(SwiftIntObject.self, value: [100]) + try! Realm().create(SwiftIntObject.self, value: [200]) + try! Realm().create(SwiftIntObject.self, value: [300]) } - XCTAssertEqual(0, try! Realm().allObjects(ofType: SwiftStringObject.self).count) - XCTAssertEqual(3, try! Realm().allObjects(ofType: SwiftIntObject.self).count) - assertThrows(try! Realm().allObjects(ofType: Object.self)) + XCTAssertEqual(0, try! Realm().objects(SwiftStringObject.self).count) + XCTAssertEqual(3, try! Realm().objects(SwiftIntObject.self).count) + assertThrows(try! Realm().objects(Object.self)) } func testDynamicObjects() { try! Realm().write { - try! Realm().createObject(ofType: SwiftIntObject.self, populatedWith: [100]) - try! Realm().createObject(ofType: SwiftIntObject.self, populatedWith: [200]) - try! Realm().createObject(ofType: SwiftIntObject.self, populatedWith: [300]) + try! Realm().create(SwiftIntObject.self, value: [100]) + try! Realm().create(SwiftIntObject.self, value: [200]) + try! Realm().create(SwiftIntObject.self, value: [300]) } - XCTAssertEqual(0, try! Realm().allDynamicObjects(ofType: "SwiftStringObject").count) - XCTAssertEqual(3, try! Realm().allDynamicObjects(ofType: "SwiftIntObject").count) - assertThrows(try! Realm().allDynamicObjects(ofType: "Object")) + XCTAssertEqual(0, try! Realm().dynamicObjects("SwiftStringObject").count) + XCTAssertEqual(3, try! Realm().dynamicObjects("SwiftIntObject").count) + assertThrows(try! Realm().dynamicObjects("Object")) } func testDynamicObjectProperties() { try! Realm().write { - try! Realm().createObject(ofType: SwiftObject.self) + try! Realm().create(SwiftObject.self) } - let object = try! Realm().allDynamicObjects(ofType: "SwiftObject")[0] + let object = try! Realm().dynamicObjects("SwiftObject")[0] let dictionary = SwiftObject.defaultValues() XCTAssertEqual(object["boolCol"] as? NSNumber, dictionary["boolCol"] as! NSNumber?) @@ -477,10 +477,10 @@ class RealmTests: TestCase { func testDynamicObjectOptionalProperties() { try! Realm().write { - try! Realm().createObject(ofType: SwiftOptionalDefaultValuesObject.self) + try! Realm().create(SwiftOptionalDefaultValuesObject.self) } - let object = try! Realm().allDynamicObjects(ofType: "SwiftOptionalDefaultValuesObject")[0] + let object = try! Realm().dynamicObjects("SwiftOptionalDefaultValuesObject")[0] let dictionary = SwiftOptionalDefaultValuesObject.defaultValues() XCTAssertEqual(object["optIntCol"] as? NSNumber, dictionary["optIntCol"] as! NSNumber?) @@ -503,8 +503,8 @@ class RealmTests: TestCase { let realm = try! Realm() try! realm.write { - realm.createObject(ofType: type, populatedWith: ["a", 1]) - realm.createObject(ofType: type, populatedWith: ["b", 2]) + realm.create(type, value: ["a", 1]) + realm.create(type, value: ["b", 2]) } let object = realm.object(ofType: type, forPrimaryKey: 1 as O.PrimaryKey) @@ -527,8 +527,8 @@ class RealmTests: TestCase { Wrapped: ExpressibleByIntegerLiteral { let realm = try! Realm() try! realm.write { - realm.createObject(ofType: type, populatedWith: ["a", NSNull()]) - realm.createObject(ofType: type, populatedWith: ["b", 2]) + realm.create(type, value: ["a", NSNull()]) + realm.create(type, value: ["b", 2]) } let object1a = realm.object(ofType: type, forPrimaryKey: NSNull()) @@ -554,8 +554,8 @@ class RealmTests: TestCase { func testStringPrimaryKey() { let realm = try! Realm() try! realm.write { - realm.createObject(ofType: SwiftPrimaryStringObject.self, populatedWith: ["a", 1]) - realm.createObject(ofType: SwiftPrimaryStringObject.self, populatedWith: ["b", 2]) + realm.create(SwiftPrimaryStringObject.self, value: ["a", 1]) + realm.create(SwiftPrimaryStringObject.self, value: ["b", 2]) } // When this is directly inside the XCTAssertNotNil, it doesn't work @@ -570,11 +570,11 @@ class RealmTests: TestCase { func testOptionalStringPrimaryKey() { let realm = try! Realm() try! realm.write { - realm.createObject(ofType: SwiftPrimaryStringObject.self, populatedWith: ["a", 1]) - realm.createObject(ofType: SwiftPrimaryStringObject.self, populatedWith: ["b", 2]) + realm.create(SwiftPrimaryStringObject.self, value: ["a", 1]) + realm.create(SwiftPrimaryStringObject.self, value: ["b", 2]) - realm.createObject(ofType: SwiftPrimaryOptionalStringObject.self, populatedWith: [NSNull(), 1]) - realm.createObject(ofType: SwiftPrimaryOptionalStringObject.self, populatedWith: ["b", 2]) + realm.create(SwiftPrimaryOptionalStringObject.self, value: [NSNull(), 1]) + realm.create(SwiftPrimaryOptionalStringObject.self, value: ["b", 2]) } let object1 = realm.object(ofType: SwiftPrimaryOptionalStringObject.self, forPrimaryKey: NSNull()) @@ -590,8 +590,8 @@ class RealmTests: TestCase { func testDynamicObjectForPrimaryKey() { let realm = try! Realm() try! realm.write { - realm.createObject(ofType: SwiftPrimaryStringObject.self, populatedWith: ["a", 1]) - realm.createObject(ofType: SwiftPrimaryStringObject.self, populatedWith: ["b", 2]) + realm.create(SwiftPrimaryStringObject.self, value: ["a", 1]) + realm.create(SwiftPrimaryStringObject.self, value: ["b", 2]) } XCTAssertNotNil(realm.dynamicObject(ofType: "SwiftPrimaryStringObject", forPrimaryKey: "a")) @@ -601,7 +601,7 @@ class RealmTests: TestCase { func testDynamicObjectForPrimaryKeySubscripting() { let realm = try! Realm() try! realm.write { - realm.createObject(ofType: SwiftPrimaryStringObject.self, populatedWith: ["a", 1]) + realm.create(SwiftPrimaryStringObject.self, value: ["a", 1]) } let object = realm.dynamicObject(ofType: "SwiftPrimaryStringObject", forPrimaryKey: "a") @@ -638,11 +638,11 @@ class RealmTests: TestCase { func testAutorefresh() { let realm = try! Realm() - XCTAssertTrue(realm.shouldAutorefresh, "Autorefresh should default to true") - realm.shouldAutorefresh = false - XCTAssertFalse(realm.shouldAutorefresh) - realm.shouldAutorefresh = true - XCTAssertTrue(realm.shouldAutorefresh) + XCTAssertTrue(realm.autorefresh, "Autorefresh should default to true") + realm.autorefresh = false + XCTAssertFalse(realm.autorefresh) + realm.autorefresh = true + XCTAssertTrue(realm.autorefresh) // test that autoreresh is applied // we have two notifications, one for opening the realm, and a second when performing our transaction @@ -655,22 +655,21 @@ class RealmTests: TestCase { dispatchSyncNewThread { let realm = try! Realm() try! realm.write { - realm.createObject(ofType: SwiftStringObject.self, populatedWith: ["string"]) + realm.create(SwiftStringObject.self, value: ["string"]) } } waitForExpectations(timeout: 1, handler: nil) token.stop() // get object - let results = realm.allObjects(ofType: SwiftStringObject.self - ) + let results = realm.objects(SwiftStringObject.self) XCTAssertEqual(results.count, Int(1), "There should be 1 object of type StringObject") XCTAssertEqual(results[0].stringCol, "string", "Value of first column should be 'string'") } func testRefresh() { let realm = try! Realm() - realm.shouldAutorefresh = false + realm.autorefresh = false // test that autoreresh is not applied // we have two notifications, one for opening the realm, and a second when performing our transaction @@ -680,12 +679,12 @@ class RealmTests: TestCase { notificationFired.fulfill() } - let results = realm.allObjects(ofType: SwiftStringObject.self) + let results = realm.objects(SwiftStringObject.self) XCTAssertEqual(results.count, Int(0), "There should be 1 object of type StringObject") dispatchSyncNewThread { try! Realm().write { - try! Realm().createObject(ofType: SwiftStringObject.self, populatedWith: ["string"]) + try! Realm().create(SwiftStringObject.self, value: ["string"]) return } } @@ -715,7 +714,7 @@ class RealmTests: TestCase { realm.add(SwiftObject()) return } - XCTAssertEqual(realm.allObjects(ofType: SwiftObject.self).count, 2) + XCTAssertEqual(realm.objects(SwiftObject.self).count, 2) XCTAssertEqual(object.isInvalidated, true) } @@ -726,13 +725,13 @@ class RealmTests: TestCase { } let fileURL = defaultRealmURL().deletingLastPathComponent().appendingPathComponent("copy.realm") do { - try realm.writeCopy(toFileURL: fileURL) + try realm.writeCopy(toFile: fileURL) } catch { XCTFail("writeCopyToURL failed") } autoreleasepool { let copy = try! Realm(fileURL: fileURL) - XCTAssertEqual(1, copy.allObjects(ofType: SwiftObject.self).count) + XCTAssertEqual(1, copy.objects(SwiftObject.self).count) } try! FileManager.default.removeItem(at: fileURL) } diff --git a/RealmSwift/Tests/SortDescriptorTests.swift b/RealmSwift/Tests/SortDescriptorTests.swift index f1b445780e..b9df6939bf 100644 --- a/RealmSwift/Tests/SortDescriptorTests.swift +++ b/RealmSwift/Tests/SortDescriptorTests.swift @@ -41,7 +41,7 @@ class SortDescriptorTests: TestCase { } func testStringLiteralConvertible() { - let literalSortDescriptor : RealmSwift.SortDescriptor = "property" + let literalSortDescriptor: RealmSwift.SortDescriptor = "property" XCTAssertEqual(sortDescriptor, literalSortDescriptor, "SortDescriptor should conform to StringLiteralConvertible") } diff --git a/RealmSwift/Tests/SwiftLinkTests.swift b/RealmSwift/Tests/SwiftLinkTests.swift index a4c3cf9e79..ad37219b1f 100644 --- a/RealmSwift/Tests/SwiftLinkTests.swift +++ b/RealmSwift/Tests/SwiftLinkTests.swift @@ -33,8 +33,8 @@ class SwiftLinkTests: TestCase { try! realm.write { realm.add(owner) } - let owners = realm.allObjects(ofType: SwiftOwnerObject.self) - let dogs = realm.allObjects(ofType: SwiftDogObject.self) + let owners = realm.objects(SwiftOwnerObject.self) + let dogs = realm.objects(SwiftDogObject.self) XCTAssertEqual(owners.count, Int(1), "Expecting 1 owner") XCTAssertEqual(dogs.count, Int(1), "Expecting 1 dog") XCTAssertEqual(owners[0].name, "Tim", "Tim is named Tim") @@ -53,16 +53,16 @@ class SwiftLinkTests: TestCase { try! realm.write { realm.add(owner) } - XCTAssertEqual(realm.allObjects(ofType: SwiftOwnerObject.self).count, Int(1), "Expecting 1 owner") - XCTAssertEqual(realm.allObjects(ofType: SwiftDogObject.self).count, Int(1), "Expecting 1 dog") + XCTAssertEqual(realm.objects(SwiftOwnerObject.self).count, Int(1), "Expecting 1 owner") + XCTAssertEqual(realm.objects(SwiftDogObject.self).count, Int(1), "Expecting 1 dog") realm.beginWrite() - let fiel = realm.createObject(ofType: SwiftOwnerObject.self, populatedWith: ["Fiel", NSNull()]) + let fiel = realm.create(SwiftOwnerObject.self, value: ["Fiel", NSNull()]) fiel.dog = owner.dog try! realm.commitWrite() - XCTAssertEqual(realm.allObjects(ofType: SwiftOwnerObject.self).count, Int(2), "Expecting 2 owners") - XCTAssertEqual(realm.allObjects(ofType: SwiftDogObject.self).count, Int(1), "Expecting 1 dog") + XCTAssertEqual(realm.objects(SwiftOwnerObject.self).count, Int(2), "Expecting 2 owners") + XCTAssertEqual(realm.objects(SwiftDogObject.self).count, Int(1), "Expecting 1 dog") } func testLinkRemoval() { @@ -75,18 +75,18 @@ class SwiftLinkTests: TestCase { try! realm.write { realm.add(owner) } - XCTAssertEqual(realm.allObjects(ofType: SwiftOwnerObject.self).count, Int(1), "Expecting 1 owner") - XCTAssertEqual(realm.allObjects(ofType: SwiftDogObject.self).count, Int(1), "Expecting 1 dog") + XCTAssertEqual(realm.objects(SwiftOwnerObject.self).count, Int(1), "Expecting 1 owner") + XCTAssertEqual(realm.objects(SwiftDogObject.self).count, Int(1), "Expecting 1 dog") try! realm.write { realm.delete(owner.dog!) } XCTAssertNil(owner.dog, "Dog should be nullified when deleted") // refresh owner and check - let owner2 = realm.allObjects(ofType: SwiftOwnerObject.self).first! + let owner2 = realm.objects(SwiftOwnerObject.self).first! XCTAssertNotNil(owner2, "Should have 1 owner") XCTAssertNil(owner2.dog, "Dog should be nullified when deleted") - XCTAssertEqual(realm.allObjects(ofType: SwiftDogObject.self).count, Int(0), "Expecting 0 dogs") + XCTAssertEqual(realm.objects(SwiftDogObject.self).count, Int(0), "Expecting 0 dogs") } func testLinkingObjects() { diff --git a/RealmSwift/Tests/SwiftUnicodeTests.swift b/RealmSwift/Tests/SwiftUnicodeTests.swift index f7fdd99bd7..c8246f0380 100644 --- a/RealmSwift/Tests/SwiftUnicodeTests.swift +++ b/RealmSwift/Tests/SwiftUnicodeTests.swift @@ -28,32 +28,32 @@ class SwiftUnicodeTests: TestCase { let realm = realmWithTestPath() try! realm.write { - realm.createObject(ofType: SwiftStringObject.self, populatedWith: [utf8TestString]) + realm.create(SwiftStringObject.self, value: [utf8TestString]) return } - let obj1 = realm.allObjects(ofType: SwiftStringObject.self).first! + let obj1 = realm.objects(SwiftStringObject.self).first! XCTAssertEqual(obj1.stringCol, utf8TestString) - let obj2 = realm.allObjects(ofType: SwiftStringObject.self).filter(using: "stringCol == %@", utf8TestString).first! + let obj2 = realm.objects(SwiftStringObject.self).filter("stringCol == %@", utf8TestString).first! XCTAssertEqual(obj1, obj2) XCTAssertEqual(obj2.stringCol, utf8TestString) - XCTAssertEqual(Int(0), realm.allObjects(ofType: SwiftStringObject.self).filter(using: "stringCol != %@", utf8TestString).count) + XCTAssertEqual(Int(0), realm.objects(SwiftStringObject.self).filter("stringCol != %@", utf8TestString).count) } func testUTF8PropertyWithUTF8StringContents() { let realm = realmWithTestPath() try! realm.write { - realm.createObject(ofType: SwiftUTF8Object.self, populatedWith: [utf8TestString]) + realm.create(SwiftUTF8Object.self, value: [utf8TestString]) return } - let obj1 = realm.allObjects(ofType: SwiftUTF8Object.self).first! + let obj1 = realm.objects(SwiftUTF8Object.self).first! XCTAssertEqual(obj1.柱колоéнǢкƱаم👍, utf8TestString, "Storing and retrieving a string with UTF8 content should work") - let obj2 = realm.allObjects(ofType: SwiftUTF8Object.self).filter(using: "%K == %@", "柱колоéнǢкƱаم👍", utf8TestString).first! + let obj2 = realm.objects(SwiftUTF8Object.self).filter("%K == %@", "柱колоéнǢкƱаم👍", utf8TestString).first! XCTAssertEqual(obj1, obj2, "Querying a realm searching for a string with UTF8 content should work") } } diff --git a/build.sh b/build.sh index 9fca3391f8..92d57c658f 100755 --- a/build.sh +++ b/build.sh @@ -923,7 +923,7 @@ EOM echo "Known Xcode error detected. Running job again." failed=0 sh build.sh verify-$target | tee build/build.log | xcpretty -r junit -o build/reports/junit.xml || failed=1 - elif [ "$failed" = "1" ] && tail ~/Library/Logs/CoreSimulator/CoreSimulator.log | grep "Operation not supported"; then + elif [ "$failed" = "1" ] && tail ~/Library/Logs/CoreSimulator/CoreSimulator.log | grep -E "Operation not supported|Failed to lookup com.apple.coreservices.lsuseractivity.simulatorsupport"; then echo "Known Xcode error detected. Running job again." failed=0 sh build.sh verify-$target | tee build/build.log | xcpretty -r junit -o build/reports/junit.xml || failed=1 diff --git a/examples/ios/swift-3.0/Backlink/AppDelegate.swift b/examples/ios/swift-3.0/Backlink/AppDelegate.swift index c3bc08a61f..3463a3a527 100644 --- a/examples/ios/swift-3.0/Backlink/AppDelegate.swift +++ b/examples/ios/swift-3.0/Backlink/AppDelegate.swift @@ -48,12 +48,12 @@ class AppDelegate: UIResponder, UIApplicationDelegate { let realm = try! Realm() try! realm.write { - realm.createObject(ofType: Person.self, populatedWith: ["John", [["Fido", 1]]]) - realm.createObject(ofType: Person.self, populatedWith: ["Mary", [["Rex", 2]]]) + realm.create(Person.self, value: ["John", [["Fido", 1]]]) + realm.create(Person.self, value: ["Mary", [["Rex", 2]]]) } // Log all dogs and their owners using the "owners" inverse relationship - let allDogs = realm.allObjects(ofType: Dog.self) + let allDogs = realm.objects(Dog.self) for dog in allDogs { let ownerNames = dog.owners.map { $0.name } print("\(dog.name) has \(ownerNames.count) owners (\(ownerNames))") diff --git a/examples/ios/swift-3.0/Encryption/ViewController.swift b/examples/ios/swift-3.0/Encryption/ViewController.swift index 9d961bc4a9..a21311a338 100644 --- a/examples/ios/swift-3.0/Encryption/ViewController.swift +++ b/examples/ios/swift-3.0/Encryption/ViewController.swift @@ -75,7 +75,7 @@ class ViewController: UIViewController { autoreleasepool { let configuration = Realm.Configuration(encryptionKey: getKey() as Data) let realm = try! Realm(configuration: configuration) - if let stringProp = realm.allObjects(ofType: EncryptionObject.self).first?.stringProp { + if let stringProp = realm.objects(EncryptionObject.self).first?.stringProp { log(text: "Saved object: \(stringProp)") } } diff --git a/examples/ios/swift-3.0/GettingStarted.playground/Contents.swift b/examples/ios/swift-3.0/GettingStarted.playground/Contents.swift index 9441031df2..6266da8083 100644 --- a/examples/ios/swift-3.0/GettingStarted.playground/Contents.swift +++ b/examples/ios/swift-3.0/GettingStarted.playground/Contents.swift @@ -63,7 +63,7 @@ try! realm.write { let favorites = ["Jennifer"] -let favoritePeopleWithSpousesAndCars = realm.allObjects(ofType: Person.self) +let favoritePeopleWithSpousesAndCars = realm.objects(Person.self) .filter(using: "cars.@count > 1 && spouse != nil && name IN %@", favorites) .sorted(onProperty: "age") @@ -91,5 +91,5 @@ try! realm.write { realm.deleteAllObjects() } -realm.allObjects(ofType: Person.self).count +realm.objects(Person.self).count //: Thanks! To learn more about Realm go to https://realm.io diff --git a/examples/ios/swift-3.0/GroupedTableView/TableViewController.swift b/examples/ios/swift-3.0/GroupedTableView/TableViewController.swift index 5ffd39041b..097212a01b 100644 --- a/examples/ios/swift-3.0/GroupedTableView/TableViewController.swift +++ b/examples/ios/swift-3.0/GroupedTableView/TableViewController.swift @@ -54,8 +54,8 @@ class TableViewController: UITableViewController { self.tableView.reloadData() } for section in sectionTitles { - let unsortedObjects = realm.allObjects(ofType: DemoObject.self).filter(using: "sectionTitle == '\(section)'") - let sortedObjects = unsortedObjects.sorted(onProperty: "date", ascending: true) + let unsortedObjects = realm.objects(DemoObject.self).filter("sectionTitle == '\(section)'") + let sortedObjects = unsortedObjects.sorted(byProperty: "date", ascending: true) objectsBySection.append(sortedObjects) } tableView.reloadData() @@ -113,7 +113,7 @@ class TableViewController: UITableViewController { realm.beginWrite() for _ in 0..<5 { // Add row via dictionary. Order is ignored. - realm.createObject(ofType: DemoObject.self, populatedWith: ["title": randomTitle(), "date": NSDate(), "sectionTitle": randomSectionTitle()]) + realm.create(DemoObject.self, value: ["title": randomTitle(), "date": NSDate(), "sectionTitle": randomSectionTitle()]) } try! realm.commitWrite() } @@ -121,7 +121,7 @@ class TableViewController: UITableViewController { func add() { try! realm.write { - realm.createObject(ofType: DemoObject.self, populatedWith: [randomTitle(), NSDate(), randomSectionTitle()]) + realm.create(DemoObject.self, value: [randomTitle(), NSDate(), randomSectionTitle()]) } } } diff --git a/examples/ios/swift-3.0/Migration/AppDelegate.swift b/examples/ios/swift-3.0/Migration/AppDelegate.swift index ac803917e3..af4e79f92f 100644 --- a/examples/ios/swift-3.0/Migration/AppDelegate.swift +++ b/examples/ios/swift-3.0/Migration/AppDelegate.swift @@ -90,7 +90,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate { migration.enumerateObjects(ofType: Person.className()) { oldObject, newObject in // give JP a dog if newObject?["fullName"] as? String == "JP McDonald" { - let jpsDog = migration.createObject(ofType: Pet.className(), populatedWith: ["Jimbo", "dog"]) + let jpsDog = migration.create(Pet.className(), value: ["Jimbo", "dog"]) let dogs = newObject?["pets"] as? List dogs?.append(jpsDog) } @@ -103,7 +103,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate { // print out all migrated objects in the default realm // migration is performed implicitly on Realm access - print("Migrated objects in the default Realm: \(try! Realm().allObjects(ofType: Person.self))") + print("Migrated objects in the default Realm: \(try! Realm().objects(Person.self))") // // Migrate a realms at a custom paths @@ -127,9 +127,9 @@ class AppDelegate: UIResponder, UIApplicationDelegate { // print out all migrated objects in the migrated realms let realmv1 = try! Realm(configuration: realmv1Configuration) - print("Migrated objects in the Realm migrated from v1: \(realmv1.allObjects(ofType: Person.self))") + print("Migrated objects in the Realm migrated from v1: \(realmv1.objects(Person.self))") let realmv2 = try! Realm(configuration: realmv2Configuration) - print("Migrated objects in the Realm migrated from v2: \(realmv2.allObjects(ofType: Person.self))") + print("Migrated objects in the Realm migrated from v2: \(realmv2.objects(Person.self))") } return true diff --git a/examples/ios/swift-3.0/Simple/AppDelegate.swift b/examples/ios/swift-3.0/Simple/AppDelegate.swift index 504cbc96a2..e22ad894e5 100644 --- a/examples/ios/swift-3.0/Simple/AppDelegate.swift +++ b/examples/ios/swift-3.0/Simple/AppDelegate.swift @@ -60,10 +60,10 @@ class AppDelegate: UIResponder, UIApplicationDelegate { try! realm.commitWrite() // Query - let results = realm.allObjects(ofType: Dog.self).filter(using: NSPredicate(format:"name contains 'x'")) + let results = realm.objects(Dog.self).filter(NSPredicate(format: "name contains 'x'")) // Queries are chainable! - let results2 = results.filter(using: "age > 8") + let results2 = results.filter("age > 8") print("Number of dogs: \(results.count)") print("Dogs older than eight: \(results2.count)") @@ -79,7 +79,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate { // Multi-threading DispatchQueue.global().async { let otherRealm = try! Realm() - let otherResults = otherRealm.allObjects(ofType: Dog.self).filter(using: NSPredicate(format:"name contains 'Rex'")) + let otherResults = otherRealm.objects(Dog.self).filter(NSPredicate(format: "name contains 'Rex'")) print("Number of dogs \(otherResults.count)") } diff --git a/examples/ios/swift-3.0/TableView/TableViewController.swift b/examples/ios/swift-3.0/TableView/TableViewController.swift index 589dd9ab50..9dcdca35d0 100644 --- a/examples/ios/swift-3.0/TableView/TableViewController.swift +++ b/examples/ios/swift-3.0/TableView/TableViewController.swift @@ -37,7 +37,7 @@ class Cell: UITableViewCell { class TableViewController: UITableViewController { let realm = try! Realm() - let results = try! Realm().allObjects(ofType: DemoObject.self).sorted(onProperty: "date") + let results = try! Realm().objects(DemoObject.self).sorted(byProperty: "date") var notificationToken: NotificationToken? override func viewDidLoad() { @@ -48,11 +48,11 @@ class TableViewController: UITableViewController { // Set results notification block self.notificationToken = results.addNotificationBlock { (changes: RealmCollectionChange) in switch changes { - case .Initial: + case .initial: // Results are now populated and can be accessed without blocking the UI self.tableView.reloadData() break - case .Update(_, let deletions, let insertions, let modifications): + case .update(_, let deletions, let insertions, let modifications): // Query results have changed, so apply them to the TableView self.tableView.beginUpdates() self.tableView.insertRows(at: insertions.map { IndexPath(row: $0, section: 0) }, with: .automatic) @@ -60,7 +60,7 @@ class TableViewController: UITableViewController { self.tableView.reloadRows(at: modifications.map { IndexPath(row: $0, section: 0) }, with: .automatic) self.tableView.endUpdates() break - case .Error(let err): + case .error(let err): // An error occurred while opening the Realm file on the background worker thread fatalError("\(err)") break @@ -114,7 +114,7 @@ class TableViewController: UITableViewController { realm.beginWrite() for _ in 0..<5 { // Add row via dictionary. Order is ignored. - realm.createObject(ofType: DemoObject.self, populatedWith: ["title": TableViewController.randomString(), "date": TableViewController.randomDate()]) + realm.create(DemoObject.self, value: ["title": TableViewController.randomString(), "date": TableViewController.randomDate()]) } try! realm.commitWrite() } @@ -122,7 +122,7 @@ class TableViewController: UITableViewController { func add() { realm.beginWrite() - realm.createObject(ofType: DemoObject.self, populatedWith: [TableViewController.randomString(), TableViewController.randomDate()]) + realm.create(DemoObject.self, value: [TableViewController.randomString(), TableViewController.randomDate()]) try! realm.commitWrite() } diff --git a/examples/tvos/swift-3.0/DownloadCache/RepositoriesViewController.swift b/examples/tvos/swift-3.0/DownloadCache/RepositoriesViewController.swift index c012aac73f..aef18725b3 100644 --- a/examples/tvos/swift-3.0/DownloadCache/RepositoriesViewController.swift +++ b/examples/tvos/swift-3.0/DownloadCache/RepositoriesViewController.swift @@ -97,11 +97,11 @@ class RepositoriesViewController: UICollectionViewController, UITextFieldDelegat func reloadData() { let realm = try! Realm() - results = realm.allObjects(ofType: Repository.self) + results = realm.objects(Repository.self) if let text = searchField.text, !text.isEmpty { - results = results?.filter(using: "name contains[c] %@", text) + results = results?.filter("name contains[c] %@", text) } - results = results?.sorted(onProperty: "name", ascending: sortOrderControl!.selectedSegmentIndex == 0) + results = results?.sorted(byProperty: "name", ascending: sortOrderControl!.selectedSegmentIndex == 0) collectionView?.reloadData() } diff --git a/examples/tvos/swift-3.0/PreloadedData/PlacesViewController.swift b/examples/tvos/swift-3.0/PreloadedData/PlacesViewController.swift index c9a3118476..7245402926 100644 --- a/examples/tvos/swift-3.0/PreloadedData/PlacesViewController.swift +++ b/examples/tvos/swift-3.0/PreloadedData/PlacesViewController.swift @@ -53,11 +53,11 @@ class PlacesViewController: UITableViewController, UITextFieldDelegate { func reloadData() { let realm = try! Realm() - results = realm.allObjects(ofType: Place.self) + results = realm.objects(Place.self) if let text = searchField.text, !text.isEmpty { - results = results?.filter(using: "postalCode beginswith %@", text) + results = results?.filter("postalCode beginswith %@", text) } - results = results?.sorted(onProperty: "postalCode") + results = results?.sorted(byProperty: "postalCode") tableView?.reloadData() } diff --git a/scripts/reset-simulators.sh b/scripts/reset-simulators.sh index b87a1d6de4..5d7b7c3b57 100755 --- a/scripts/reset-simulators.sh +++ b/scripts/reset-simulators.sh @@ -13,15 +13,21 @@ while pgrep -q Simulator; do pkill -9 Simulator 2>/dev/null || true done +# Run until we get a result since switching simulator versions often causes CoreSimulatorService to throw an exception. +devices="" +until [ "$devices" != "" ]; do + devices="$(xcrun simctl list devices -j || true)" +done + # Shut down booted simulators -xcrun simctl list devices -j | jq -c -r '.devices | flatten | map(select(.availability == "(available)")) | map(select(.state == "Booted")) | map(.udid) | .[]' | while read udid; do +echo "$devices" | ruby -rjson -e 'puts JSON.parse($stdin.read)["devices"].flat_map { |d| d[1] }.select { |d| d["state"] == "Booted" && d["availability"] == "(available)" }.map { |d| d["udid"] }' | while read udid; do echo "shutting down simulator with ID: $udid" xcrun simctl shutdown $udid done # Erase all available simulators echo "erasing simulators" -xcrun simctl list devices -j | jq -c -r '.devices | flatten | map(select(.availability == "(available)")) | map(.udid) | .[]' | while read udid; do +echo "$devices" | ruby -rjson -e 'puts JSON.parse($stdin.read)["devices"].flat_map { |d| d[1] }.select { |d| d["availability"] == "(available)" }.map { |d| d["udid"] }' | while read udid; do xcrun simctl erase $udid & done wait @@ -32,10 +38,10 @@ fi # Wait until the boot completes echo "waiting for simulator to boot..." -while xcrun simctl list devices -j | jq -c -r '.devices | flatten | map(select(.availability == "(available)")) | map(select(.state == "Booted")) | length' | grep 0 >/dev/null; do +until xcrun simctl list devices -j | ruby -rjson -e 'exit JSON.parse($stdin.read)["devices"].flat_map { |d| d[1] }.any? { |d| d["availability"] == "(available)" && d["state"] == "Booted" }'; do sleep 1 done # Wait until the simulator is fully booted by waiting for it to launch SpringBoard -xcrun simctl launch booted com.apple.springboard || true +xcrun simctl launch booted com.apple.springboard >/dev/null 2>&1 || true echo "simulator booted"