XMPPCoreDataStorage.h
6.55 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
#import <Foundation/Foundation.h>
#import <CoreData/CoreData.h>
/**
* This class provides an optional base class that may be used to implement
* a CoreDataStorage class for an xmpp extension (or perhaps any core data storage class).
*
* It operates on its own dispatch queue which allows it to easily provide storage for multiple extension instance.
* More importantly, it smartly buffers its save operations to maximize performance!
*
* It does this using two techniques:
*
* First, it monitors the number of pending requests.
* When a operation is requested of the class, it increments an atomic variable, and schedules the request.
* After the request has been processed, it decrements the atomic variable.
* At this point it knows if there are other pending requests,
* and it uses the information to decide if it should save now,
* or postpone the save operation until the pending requests have been executed.
*
* Second, it monitors the number of unsaved changes.
* Since NSManagedObjectContext retains any changed objects until they are saved to disk
* it is an important memory management concern to keep the number of changed objects within a healthy range.
* This class uses a configurable saveThreshold to save at appropriate times.
*
* This class also offers several useful features such as
* preventing multiple instances from using the same database file (conflict)
* and caching of xmppStream.myJID to improve performance.
*
* For more information on how to extend this class,
* please see the XMPPCoreDataStorageProtected.h header file.
*
* The framework comes with several classes that extend this base class such as:
* - XMPPRosterCoreDataStorage (Extensions/Roster)
* - XMPPCapabilitiesCoreDataStorage (Extensions/XEP-0115)
* - XMPPvCardCoreDataStorage (Extensions/XEP-0054)
*
* Feel free to skim over these as reference implementations.
**/
@interface XMPPCoreDataStorage : NSObject {
@private
NSMutableDictionary *myJidCache;
int32_t pendingRequests;
NSManagedObjectModel *managedObjectModel;
NSPersistentStoreCoordinator *persistentStoreCoordinator;
NSManagedObjectContext *managedObjectContext;
NSManagedObjectContext *mainThreadManagedObjectContext;
NSMutableArray *willSaveManagedObjectContextBlocks;
NSMutableArray *didSaveManagedObjectContextBlocks;
@protected
NSString *databaseFileName;
NSDictionary *storeOptions;
NSUInteger saveThreshold;
NSUInteger saveCount;
BOOL autoRemovePreviousDatabaseFile;
BOOL autoRecreateDatabaseFile;
BOOL autoAllowExternalBinaryDataStorage;
dispatch_queue_t storageQueue;
void *storageQueueTag;
}
/**
* Initializes a core data storage instance, backed by SQLite, with the given database store filename.
* It is recommended your database filname use the "sqlite" file extension (e.g. "XMPPRoster.sqlite").
* If you pass nil, a default database filename is automatically used.
* This default is derived from the classname,
* meaning subclasses will get a default database filename derived from the subclass classname.
*
* If you attempt to create an instance of this class with the same databaseFileName as another existing instance,
* this method will return nil.
**/
- (id)initWithDatabaseFilename:(NSString *)databaseFileName storeOptions:(NSDictionary *)storeOptions;
/**
* Initializes a core data storage instance, backed by an in-memory store.
**/
- (id)initWithInMemoryStore;
/**
* Readonly access to the databaseFileName used during initialization.
* If nil was passed to the init method, returns the actual databaseFileName being used (the default filename).
**/
@property (readonly) NSString *databaseFileName;
/**
* Readonly access to the databaseOptions used during initialization.
* If nil was passed to the init method, returns the actual databaseOptions being used (the default databaseOptions).
**/
@property (readonly) NSDictionary *storeOptions;
/**
* The saveThreshold specifies the maximum number of unsaved changes to NSManagedObjects before a save is triggered.
*
* Since NSManagedObjectContext retains any changed objects until they are saved to disk
* it is an important memory management concern to keep the number of changed objects within a healthy range.
*
* Default 500
**/
@property (readwrite) NSUInteger saveThreshold;
/**
* Provides access to the the thread-safe components of the CoreData stack.
*
* Please note:
* The managedObjectContext is private to the storageQueue.
* If you're on the main thread you can use the mainThreadManagedObjectContext.
* Otherwise you must create and use your own managedObjectContext.
*
* If you think you can simply add a property for the private managedObjectContext,
* then you need to go read the documentation for core data,
* specifically the section entitled "Concurrency with Core Data".
*
* @see mainThreadManagedObjectContext
**/
@property (strong, readonly) NSManagedObjectModel *managedObjectModel;
@property (strong, readonly) NSPersistentStoreCoordinator *persistentStoreCoordinator;
/**
* Convenience method to get a managedObjectContext appropriate for use on the main thread.
* This context should only be used from the main thread.
*
* NSManagedObjectContext is a light-weight thread-UNsafe component of the CoreData stack.
* Thus a managedObjectContext should only be accessed from a single thread, or from a serialized queue.
*
* A managedObjectContext is associated with a persistent store.
* In most cases the persistent store is an sqlite database file.
* So think of a managedObjectContext as a thread-specific cache for the underlying database.
*
* This method lazily creates a proper managedObjectContext,
* associated with the persistent store of this instance,
* and configured to automatically merge changesets from other threads.
**/
@property (strong, readonly) NSManagedObjectContext *mainThreadManagedObjectContext;
/**
* The Previous Database File is removed before creating a persistant store.
*
* Default NO
**/
@property (readwrite) BOOL autoRemovePreviousDatabaseFile;
/**
* The Database File is automatically recreated if the persistant store cannot read it e.g. the model changed or the file became corrupt.
* For greater control overide didNotAddPersistentStoreWithPath:
*
* Default NO
**/
@property (readwrite) BOOL autoRecreateDatabaseFile;
/**
* This method calls setAllowsExternalBinaryDataStorage:YES for all Binary Data Attributes in the Managed Object Model.
* On OS Versions that do not support external binary data storage, this property does nothing.
*
* Default NO
**/
@property (readwrite) BOOL autoAllowExternalBinaryDataStorage;
@end