mirror of
https://github.com/JohnEstropia/CoreStore.git
synced 2026-01-18 15:07:00 +01:00
Added a "userInfo" property to relevant types to allow external code to store custom data
This commit is contained in:
@@ -434,6 +434,10 @@
|
||||
B5A991ED1E9DC2CE0091A2E3 /* VersionLock.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5A991EB1E9DC2CE0091A2E3 /* VersionLock.swift */; };
|
||||
B5A991EE1E9DC2CE0091A2E3 /* VersionLock.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5A991EB1E9DC2CE0091A2E3 /* VersionLock.swift */; };
|
||||
B5A991EF1E9DC2CE0091A2E3 /* VersionLock.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5A991EB1E9DC2CE0091A2E3 /* VersionLock.swift */; };
|
||||
B5A9921F1EA898710091A2E3 /* UserInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5A9921E1EA898710091A2E3 /* UserInfo.swift */; };
|
||||
B5A992201EA898720091A2E3 /* UserInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5A9921E1EA898710091A2E3 /* UserInfo.swift */; };
|
||||
B5A992211EA898720091A2E3 /* UserInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5A9921E1EA898710091A2E3 /* UserInfo.swift */; };
|
||||
B5A992221EA898720091A2E3 /* UserInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5A9921E1EA898710091A2E3 /* UserInfo.swift */; };
|
||||
B5AEFAB51C9962AE00AD137F /* CoreStoreBridge.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5AEFAB41C9962AE00AD137F /* CoreStoreBridge.swift */; };
|
||||
B5AEFAB61C9962AE00AD137F /* CoreStoreBridge.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5AEFAB41C9962AE00AD137F /* CoreStoreBridge.swift */; };
|
||||
B5AEFAB71C9962AE00AD137F /* CoreStoreBridge.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5AEFAB41C9962AE00AD137F /* CoreStoreBridge.swift */; };
|
||||
@@ -757,6 +761,7 @@
|
||||
B5A261201B64BFDB006EB6D3 /* MigrationType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MigrationType.swift; sourceTree = "<group>"; };
|
||||
B5A5F2651CAEC50F004AB9AF /* CSSelect.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CSSelect.swift; sourceTree = "<group>"; };
|
||||
B5A991EB1E9DC2CE0091A2E3 /* VersionLock.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = VersionLock.swift; sourceTree = "<group>"; };
|
||||
B5A9921E1EA898710091A2E3 /* UserInfo.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UserInfo.swift; sourceTree = "<group>"; };
|
||||
B5AD60CD1C90141E00F2B2E8 /* Package.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Package.swift; sourceTree = SOURCE_ROOT; };
|
||||
B5AEFAB41C9962AE00AD137F /* CoreStoreBridge.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CoreStoreBridge.swift; sourceTree = "<group>"; };
|
||||
B5BDC91A1C202269008147CD /* Cartfile */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = Cartfile; path = ../Cartfile; sourceTree = "<group>"; };
|
||||
@@ -1323,6 +1328,7 @@
|
||||
B512607E1E97A18000402229 /* CoreStoreObject+Convenience.swift */,
|
||||
B5FAD6A81B50A4B300714891 /* Progress+Convenience.swift */,
|
||||
B5202CF91C04688100DED140 /* NSFetchedResultsController+Convenience.swift */,
|
||||
B5A9921E1EA898710091A2E3 /* UserInfo.swift */,
|
||||
);
|
||||
path = Convenience;
|
||||
sourceTree = "<group>";
|
||||
@@ -1692,6 +1698,7 @@
|
||||
B52FD3AA1E3B3EF10001D919 /* NSManagedObject+Logging.swift in Sources */,
|
||||
B52F74411E9B8724005F3DAC /* LegacyXcodeDataModel.swift in Sources */,
|
||||
B51FE5AB1CD4D00300E54258 /* CoreStore+CustomDebugStringConvertible.swift in Sources */,
|
||||
B5A9921F1EA898710091A2E3 /* UserInfo.swift in Sources */,
|
||||
B54A6A551BA15F2A007870FD /* FetchedResultsControllerDelegate.swift in Sources */,
|
||||
B5D339E21E948C3600C880DE /* Value.swift in Sources */,
|
||||
B5A261211B64BFDB006EB6D3 /* MigrationType.swift in Sources */,
|
||||
@@ -1864,6 +1871,7 @@
|
||||
B52FD3AB1E3B3EF10001D919 /* NSManagedObject+Logging.swift in Sources */,
|
||||
B52F74421E9B8724005F3DAC /* LegacyXcodeDataModel.swift in Sources */,
|
||||
B51FE5AD1CD4D00300E54258 /* CoreStore+CustomDebugStringConvertible.swift in Sources */,
|
||||
B5A992201EA898720091A2E3 /* UserInfo.swift in Sources */,
|
||||
B5FE4DAD1C85D44E00FA6A91 /* SQLiteStore.swift in Sources */,
|
||||
B5D339E31E948C3600C880DE /* Value.swift in Sources */,
|
||||
82BA18C51C4BBD5300A0916E /* ListObserver.swift in Sources */,
|
||||
@@ -2036,6 +2044,7 @@
|
||||
B52FD3AD1E3B3EF10001D919 /* NSManagedObject+Logging.swift in Sources */,
|
||||
B52F74441E9B8724005F3DAC /* LegacyXcodeDataModel.swift in Sources */,
|
||||
B5ECDC2D1CA81CC700C7F112 /* CSDataStack+Transaction.swift in Sources */,
|
||||
B5A992221EA898720091A2E3 /* UserInfo.swift in Sources */,
|
||||
B5D7A5BA1CA3BF8F005C752B /* CSInto.swift in Sources */,
|
||||
B5D339E51E948C3600C880DE /* Value.swift in Sources */,
|
||||
B5A5F26A1CAEC50F004AB9AF /* CSSelect.swift in Sources */,
|
||||
@@ -2208,6 +2217,7 @@
|
||||
B52FD3AC1E3B3EF10001D919 /* NSManagedObject+Logging.swift in Sources */,
|
||||
B52F74431E9B8724005F3DAC /* LegacyXcodeDataModel.swift in Sources */,
|
||||
B51FE5AE1CD4D00300E54258 /* CoreStore+CustomDebugStringConvertible.swift in Sources */,
|
||||
B5A992211EA898720091A2E3 /* UserInfo.swift in Sources */,
|
||||
B563218C1BD65216006C9394 /* DataStack+Transaction.swift in Sources */,
|
||||
B5D339E41E948C3600C880DE /* Value.swift in Sources */,
|
||||
B53FBA0E1CAB5E6500F0D40A /* CSCoreStore+Migrating.swift in Sources */,
|
||||
|
||||
115
Sources/Convenience/UserInfo.swift
Normal file
115
Sources/Convenience/UserInfo.swift
Normal file
@@ -0,0 +1,115 @@
|
||||
//
|
||||
// UserInfo.swift
|
||||
// CoreStore
|
||||
//
|
||||
// Copyright © 2017 John Rommel Estropia
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
|
||||
// MARK: UserInfo
|
||||
|
||||
/**
|
||||
The `UserInfo` class is provided by several CoreStore types such as `DataStack`, `ListMonitor`, `ObjectMonitor` and transactions to allow external libraries or user apps to store their own custom data.
|
||||
```
|
||||
enum Static {
|
||||
static var myDataKey: Void?
|
||||
}
|
||||
CoreStore.defaultStack.userInfo[&Static.myDataKey] = myObject
|
||||
```
|
||||
- Important: Do not use this class to store thread-sensitive data.
|
||||
*/
|
||||
public final class UserInfo {
|
||||
|
||||
/**
|
||||
Allows external libraries to store custom data. App code should rarely have a need for this.
|
||||
```
|
||||
enum Static {
|
||||
static var myDataKey: Void?
|
||||
}
|
||||
CoreStore.defaultStack.userInfo[&Static.myDataKey] = myObject
|
||||
```
|
||||
- Important: Do not use this method to store thread-sensitive data.
|
||||
- parameter key: the key for custom data. Make sure this is a static pointer that will never be changed.
|
||||
*/
|
||||
public subscript(key: UnsafeRawPointer) -> Any? {
|
||||
|
||||
get {
|
||||
|
||||
self.lock.lock()
|
||||
defer {
|
||||
|
||||
self.lock.unlock()
|
||||
}
|
||||
return self.data[key]
|
||||
}
|
||||
set {
|
||||
|
||||
self.lock.lock()
|
||||
defer {
|
||||
|
||||
self.lock.unlock()
|
||||
}
|
||||
self.data[key] = newValue
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Allows external libraries to store custom data in the `DataStack`. App code should rarely have a need for this.
|
||||
```
|
||||
enum Static {
|
||||
static var myDataKey: Void?
|
||||
}
|
||||
CoreStore.defaultStack.userInfo[&Static.myDataKey, lazyInit: { MyObject() }] = myObject
|
||||
```
|
||||
- Important: Do not use this method to store thread-sensitive data.
|
||||
- parameter key: the key for custom data. Make sure this is a static pointer that will never be changed.
|
||||
- parameter lazyInit: a closure to use to lazily-initialize the data
|
||||
- returns: A custom data identified by `key`
|
||||
*/
|
||||
public subscript(key: UnsafeRawPointer, lazyInit closure: () -> Any) -> Any {
|
||||
|
||||
self.lock.lock()
|
||||
defer {
|
||||
|
||||
self.lock.unlock()
|
||||
}
|
||||
if let value = self.data[key] {
|
||||
|
||||
return value
|
||||
}
|
||||
let value = closure()
|
||||
self.data[key] = value
|
||||
return value
|
||||
}
|
||||
|
||||
|
||||
// MARK: Internal
|
||||
|
||||
internal init() {}
|
||||
|
||||
|
||||
// MARK: Private
|
||||
|
||||
private var data: [UnsafeRawPointer: Any] = [:]
|
||||
private let lock = NSRecursiveLock()
|
||||
}
|
||||
@@ -578,6 +578,21 @@ public final class ListMonitor<D: DynamicObject>: Hashable {
|
||||
}
|
||||
|
||||
|
||||
// MARK: Public (3rd Party Utilities)
|
||||
|
||||
/**
|
||||
Allow external libraries to store custom data in the `ListMonitor`. App code should rarely have a need for this.
|
||||
```
|
||||
enum Static {
|
||||
static var myDataKey: Void?
|
||||
}
|
||||
monitor.userInfo[&Static.myDataKey] = myObject
|
||||
```
|
||||
- Important: Do not use this method to store thread-sensitive data.
|
||||
*/
|
||||
private let userInfo = UserInfo()
|
||||
|
||||
|
||||
// MARK: Equatable
|
||||
|
||||
public static func == (lhs: ListMonitor<ObjectType>, rhs: ListMonitor<ObjectType>) -> Bool {
|
||||
|
||||
@@ -110,6 +110,21 @@ public final class ObjectMonitor<D: DynamicObject>: Equatable {
|
||||
}
|
||||
|
||||
|
||||
// MARK: Public (3rd Party Utilities)
|
||||
|
||||
/**
|
||||
Allow external libraries to store custom data in the `ObjectMonitor`. App code should rarely have a need for this.
|
||||
```
|
||||
enum Static {
|
||||
static var myDataKey: Void?
|
||||
}
|
||||
monitor.userInfo[&Static.myDataKey] = myObject
|
||||
```
|
||||
- Important: Do not use this method to store thread-sensitive data.
|
||||
*/
|
||||
private let userInfo = UserInfo()
|
||||
|
||||
|
||||
// MARK: Equatable
|
||||
|
||||
public static func == (lhs: ObjectMonitor<ObjectType>, rhs: ObjectMonitor<ObjectType>) -> Bool {
|
||||
|
||||
@@ -450,61 +450,11 @@ public final class DataStack: Equatable {
|
||||
enum Static {
|
||||
static var myDataKey: Void?
|
||||
}
|
||||
CoreStore.defaultStack[userInfoKey: &Static.myDataKey] = myObject
|
||||
CoreStore.defaultStack.userInfo[&Static.myDataKey] = myObject
|
||||
```
|
||||
- Important: Do not use this method to store thread-sensitive data.
|
||||
- parameter userInfoKey: the key for custom data. Make sure this is a static pointer that will never be changed.
|
||||
*/
|
||||
public subscript(userInfoKey key: UnsafeRawPointer) -> Any? {
|
||||
|
||||
get {
|
||||
|
||||
self.userInfoLock.lock()
|
||||
defer {
|
||||
|
||||
self.userInfoLock.unlock()
|
||||
}
|
||||
return self.userInfo[key]
|
||||
}
|
||||
set {
|
||||
|
||||
self.userInfoLock.lock()
|
||||
defer {
|
||||
|
||||
self.userInfoLock.unlock()
|
||||
}
|
||||
self.userInfo[key] = newValue
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Allow external libraries to store custom data in the `DataStack`. App code should rarely have a need for this.
|
||||
```
|
||||
enum Static {
|
||||
static var myDataKey: Void?
|
||||
}
|
||||
CoreStore.defaultStack[userInfoKey: &Static.myDataKey, lazyInit: { MyObject() }] = myObject
|
||||
```
|
||||
- Important: Do not use this method to store thread-sensitive data.
|
||||
- parameter userInfoKey: the key for custom data. Make sure this is a static pointer that will never be changed.
|
||||
- parameter lazyInit: a closure to use to lazily-initialize the data
|
||||
- returns: A custom data identified by `userInfoKey`
|
||||
*/
|
||||
public subscript(userInfoKey key: UnsafeRawPointer, lazyInit closure: () -> Any) -> Any {
|
||||
|
||||
self.userInfoLock.lock()
|
||||
defer {
|
||||
|
||||
self.userInfoLock.unlock()
|
||||
}
|
||||
if let value = self.userInfo[key] {
|
||||
|
||||
return value
|
||||
}
|
||||
let value = closure()
|
||||
self.userInfo[key] = value
|
||||
return value
|
||||
}
|
||||
private let userInfo = UserInfo()
|
||||
|
||||
|
||||
// MARK: Equatable
|
||||
@@ -636,8 +586,6 @@ public final class DataStack: Equatable {
|
||||
|
||||
private var persistentStoresByFinalConfiguration = [String: NSPersistentStore]()
|
||||
private var finalConfigurationsByEntityIdentifier = [EntityIdentifier: Set<String>]()
|
||||
private var userInfo: [UnsafeRawPointer: Any] = [:]
|
||||
private let userInfoLock = NSRecursiveLock()
|
||||
|
||||
deinit {
|
||||
|
||||
|
||||
@@ -444,64 +444,13 @@ public /*abstract*/ class BaseDataTransaction {
|
||||
Allow external libraries to store custom data in the transaction. App code should rarely have a need for this.
|
||||
```
|
||||
enum Static {
|
||||
static var myDataKey: Void?
|
||||
static var myDataKey: Void?
|
||||
}
|
||||
transaction[userInfoKey: &Static.myDataKey] = myObject
|
||||
transaction.userInfo[&Static.myDataKey] = myObject
|
||||
```
|
||||
- Important: Do not use this method to store thread-sensitive data.
|
||||
- parameter userInfoKey: the key for custom data. Make sure this is a static pointer that will never be changed.
|
||||
- returns: A custom data identified by `userInfoKey`
|
||||
*/
|
||||
public subscript(userInfoKey key: UnsafeRawPointer) -> Any? {
|
||||
|
||||
get {
|
||||
|
||||
self.userInfoLock.lock()
|
||||
defer {
|
||||
|
||||
self.userInfoLock.unlock()
|
||||
}
|
||||
return self.userInfo[key]
|
||||
}
|
||||
set {
|
||||
|
||||
self.userInfoLock.lock()
|
||||
defer {
|
||||
|
||||
self.userInfoLock.unlock()
|
||||
}
|
||||
self.userInfo[key] = newValue
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Allow external libraries to store custom data in the transaction. App code should rarely have a need for this.
|
||||
```
|
||||
enum Static {
|
||||
static var myDataKey: Void?
|
||||
}
|
||||
CoreStore.defaultStack[userInfoKey: &Static.myDataKey, lazyInit: { MyObject() }] = myObject
|
||||
```
|
||||
- Important: Do not use this method to store thread-sensitive data.
|
||||
- parameter userInfoKey: the key for custom data. Make sure this is a static pointer that will never be changed.
|
||||
- parameter lazyInit: a closure to use to lazily-initialize the data
|
||||
- returns: A custom data identified by `userInfoKey`
|
||||
*/
|
||||
public subscript(userInfoKey key: UnsafeRawPointer, lazyInit closure: () -> Any) -> Any {
|
||||
|
||||
self.userInfoLock.lock()
|
||||
defer {
|
||||
|
||||
self.userInfoLock.unlock()
|
||||
}
|
||||
if let value = self.userInfo[key] {
|
||||
|
||||
return value
|
||||
}
|
||||
let value = closure()
|
||||
self.userInfo[key] = value
|
||||
return value
|
||||
}
|
||||
private let userInfo = UserInfo()
|
||||
|
||||
|
||||
// MARK: Internal
|
||||
@@ -542,10 +491,4 @@ public /*abstract*/ class BaseDataTransaction {
|
||||
|
||||
return self.bypassesQueueing || self.transactionQueue.cs_isCurrentExecutionContext()
|
||||
}
|
||||
|
||||
|
||||
// MARK: Private
|
||||
|
||||
private var userInfo: [UnsafeRawPointer: Any] = [:]
|
||||
private let userInfoLock = NSRecursiveLock()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user