RLMSupport.swift 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. ////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright 2014 Realm Inc.
  4. //
  5. // Licensed under the Apache License, Version 2.0 (the "License");
  6. // you may not use this file except in compliance with the License.
  7. // You may obtain a copy of the License at
  8. //
  9. // http://www.apache.org/licenses/LICENSE-2.0
  10. //
  11. // Unless required by applicable law or agreed to in writing, software
  12. // distributed under the License is distributed on an "AS IS" BASIS,
  13. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. // See the License for the specific language governing permissions and
  15. // limitations under the License.
  16. //
  17. ////////////////////////////////////////////////////////////////////////////
  18. import Realm
  19. extension RLMRealm {
  20. /**
  21. Returns the schema version for a Realm at a given local URL.
  22. - see: `+ [RLMRealm schemaVersionAtURL:encryptionKey:error:]`
  23. */
  24. @nonobjc public class func schemaVersion(at url: URL, usingEncryptionKey key: Data? = nil) throws -> UInt64 {
  25. var error: NSError?
  26. let version = __schemaVersion(at: url, encryptionKey: key, error: &error)
  27. guard version != RLMNotVersioned else { throw error! }
  28. return version
  29. }
  30. /**
  31. Returns the same object as the one referenced when the `RLMThreadSafeReference` was first created,
  32. but resolved for the current Realm for this thread. Returns `nil` if this object was deleted after
  33. the reference was created.
  34. - see `- [RLMRealm resolveThreadSafeReference:]`
  35. */
  36. @nonobjc public func resolve<Confined>(reference: RLMThreadSafeReference<Confined>) -> Confined? {
  37. return __resolve(reference as! RLMThreadSafeReference<RLMThreadConfined>) as! Confined?
  38. }
  39. }
  40. extension RLMObject {
  41. /**
  42. Returns all objects of this object type matching the given predicate from the default Realm.
  43. - see `+ [RLMObject objectsWithPredicate:]`
  44. */
  45. public class func objects(where predicateFormat: String, _ args: CVarArg...) -> RLMResults<RLMObject> {
  46. return objects(with: NSPredicate(format: predicateFormat, arguments: getVaList(args))) as! RLMResults<RLMObject>
  47. }
  48. /**
  49. Returns all objects of this object type matching the given predicate from the specified Realm.
  50. - see `+ [RLMObject objectsInRealm:withPredicate:]`
  51. */
  52. public class func objects(in realm: RLMRealm,
  53. where predicateFormat: String,
  54. _ args: CVarArg...) -> RLMResults<RLMObject> {
  55. return objects(in: realm, with: NSPredicate(format: predicateFormat, arguments: getVaList(args))) as! RLMResults<RLMObject>
  56. }
  57. }
  58. /// A protocol defining iterator support for RLMArray, RLMSet & RLMResults.
  59. public protocol _RLMCollectionIterator {
  60. /**
  61. Returns a `RLMCollectionIterator` that yields successive elements in the collection.
  62. This enables support for sequence-style enumeration of `RLMObject` subclasses in Swift.
  63. */
  64. func makeIterator() -> RLMCollectionIterator
  65. }
  66. extension _RLMCollectionIterator where Self: RLMCollection {
  67. /// :nodoc:
  68. public func makeIterator() -> RLMCollectionIterator {
  69. return RLMCollectionIterator(self)
  70. }
  71. }
  72. /// :nodoc:
  73. public typealias RLMDictionarySingleEntry = (key: String, value: RLMObject)
  74. /// A protocol defining iterator support for RLMDictionary
  75. public protocol _RLMDictionaryIterator {
  76. /// :nodoc:
  77. func makeIterator() -> RLMDictionaryIterator
  78. }
  79. extension _RLMDictionaryIterator where Self: RLMCollection {
  80. /// :nodoc:
  81. public func makeIterator() -> RLMDictionaryIterator {
  82. return RLMDictionaryIterator(self)
  83. }
  84. }
  85. // Sequence conformance for RLMArray, RLMDictionary, RLMSet and RLMResults is provided by RLMCollection's
  86. // `makeIterator()` implementation.
  87. extension RLMArray: Sequence, _RLMCollectionIterator { }
  88. extension RLMDictionary: Sequence, _RLMDictionaryIterator {}
  89. extension RLMSet: Sequence, _RLMCollectionIterator {}
  90. extension RLMResults: Sequence, _RLMCollectionIterator {}
  91. /**
  92. This struct enables sequence-style enumeration for RLMObjects in Swift via `RLMCollection.makeIterator`
  93. */
  94. public struct RLMCollectionIterator: IteratorProtocol {
  95. private var iteratorBase: NSFastEnumerationIterator
  96. internal init(_ collection: RLMCollection) {
  97. iteratorBase = NSFastEnumerationIterator(collection)
  98. }
  99. public mutating func next() -> RLMObject? {
  100. return iteratorBase.next() as! RLMObject?
  101. }
  102. }
  103. /**
  104. This struct enables sequence-style enumeration for RLMDictionary in Swift via `RLMDictionary.makeIterator`
  105. */
  106. public struct RLMDictionaryIterator: IteratorProtocol {
  107. private var iteratorBase: NSFastEnumerationIterator
  108. private let dictionary: RLMDictionary<AnyObject, AnyObject>
  109. internal init(_ collection: RLMCollection) {
  110. dictionary = collection as! RLMDictionary<AnyObject, AnyObject>
  111. iteratorBase = NSFastEnumerationIterator(collection)
  112. }
  113. public mutating func next() -> RLMDictionarySingleEntry? {
  114. let key = iteratorBase.next()
  115. if let key = key {
  116. return (key: key as Any, value: dictionary[key as AnyObject]) as? RLMDictionarySingleEntry
  117. }
  118. if key != nil {
  119. fatalError("unsupported key type")
  120. }
  121. return nil
  122. }
  123. }
  124. // Swift query convenience functions
  125. extension RLMCollection {
  126. /**
  127. Returns the index of the first object in the collection matching the predicate.
  128. */
  129. public func indexOfObject(where predicateFormat: String, _ args: CVarArg...) -> UInt {
  130. guard let index = indexOfObject?(with: NSPredicate(format: predicateFormat, arguments: getVaList(args))) else {
  131. fatalError("This RLMCollection does not support indexOfObject(where:)")
  132. }
  133. return index
  134. }
  135. /**
  136. Returns all objects matching the given predicate in the collection.
  137. */
  138. public func objects(where predicateFormat: String, _ args: CVarArg...) -> RLMResults<NSObject> {
  139. return objects(with: NSPredicate(format: predicateFormat, arguments: getVaList(args))) as! RLMResults<NSObject>
  140. }
  141. }
  142. extension RLMCollection {
  143. /// Allows for subscript support with RLMDictionary.
  144. public subscript(_ key: String) -> AnyObject? {
  145. get {
  146. (self as! RLMDictionary<NSString, AnyObject>).object(forKey: key as NSString)
  147. }
  148. set {
  149. (self as! RLMDictionary<NSString, AnyObject>).setObject(newValue, forKey: key as NSString)
  150. }
  151. }
  152. }