-
Notifications
You must be signed in to change notification settings - Fork 5
/
CoreDataManager.swift
233 lines (155 loc) · 7.38 KB
/
CoreDataManager.swift
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
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
//
// CoreDataManager.swift
// CoreDataManager Example
//
// Created by Manuel de la Mata on 13/06/2014.
// Copyright (c) 2014 MMS. All rights reserved.
//
import Foundation
import CoreData
class CoreDataManager: NSObject {
let kStoreName = "TNTCache.sqlite"
let kModmName = "CoreDataManager_Example"
var _managedObjectContext: NSManagedObjectContext? = nil
var _managedObjectModel: NSManagedObjectModel? = nil
var _persistentStoreCoordinator: NSPersistentStoreCoordinator? = nil
class var shared:CoreDataManager{
get {
struct Static {
static var instance : CoreDataManager? = nil
static var token : dispatch_once_t = 0
}
dispatch_once(&Static.token) { Static.instance = CoreDataManager() }
return Static.instance!
}
}
func initialize(){
self.managedObjectContext
}
// #pragma mark - Core Data stack
var managedObjectContext: NSManagedObjectContext{
if NSThread.isMainThread() {
if !_managedObjectContext {
let coordinator = self.persistentStoreCoordinator
if coordinator != nil {
_managedObjectContext = NSManagedObjectContext(concurrencyType: .MainQueueConcurrencyType)
_managedObjectContext!.persistentStoreCoordinator = coordinator
}
return _managedObjectContext!
}
}else{
var threadContext : NSManagedObjectContext? = NSThread.currentThread().threadDictionary["NSManagedObjectContext"] as? NSManagedObjectContext;
println(NSThread.currentThread().threadDictionary)
if threadContext == nil {
println("creating new context")
threadContext = NSManagedObjectContext(concurrencyType: .PrivateQueueConcurrencyType)
threadContext!.parentContext = _managedObjectContext
threadContext!.name = NSThread.currentThread().description
NSThread.currentThread().threadDictionary["NSManagedObjectContext"] = threadContext
NSNotificationCenter.defaultCenter().addObserver(self, selector:"contextWillSave:" , name: NSManagedObjectContextWillSaveNotification, object: threadContext)
}else{
println("using old context")
}
return threadContext!;
}
return _managedObjectContext!
}
// Returns the managed object model for the application.
// If the model doesn't already exist, it is created from the application's model.
var managedObjectModel: NSManagedObjectModel {
if !_managedObjectModel {
let modelURL = NSBundle.mainBundle().URLForResource(kModmName, withExtension: "momd")
_managedObjectModel = NSManagedObjectModel(contentsOfURL: modelURL)
}
return _managedObjectModel!
}
// Returns the persistent store coordinator for the application.
// If the coordinator doesn't already exist, it is created and the application's store added to it.
var persistentStoreCoordinator: NSPersistentStoreCoordinator {
if !_persistentStoreCoordinator {
let storeURL = self.applicationDocumentsDirectory.URLByAppendingPathComponent(kStoreName)
var error: NSError? = nil
_persistentStoreCoordinator = NSPersistentStoreCoordinator(managedObjectModel: self.managedObjectModel)
if _persistentStoreCoordinator!.addPersistentStoreWithType(NSSQLiteStoreType, configuration: nil, URL: storeURL, options: self.databaseOptions(), error: &error) == nil {
abort()
}
}
return _persistentStoreCoordinator!
}
// #pragma mark - fetches
func executeFetchRequest(request:NSFetchRequest)-> Array<AnyObject>?{
var results:Array<AnyObject>?
self.managedObjectContext.performBlockAndWait{
var fetchError:NSError?
results = self.managedObjectContext.executeFetchRequest(request, error: &fetchError)
if let error = fetchError {
println("Warning!! \(error.description)")
}
}
return results
}
func executeFetchRequest(request:NSFetchRequest, completionHandler:(results: Array<AnyObject>?) -> Void)-> (){
self.managedObjectContext.performBlock{
var fetchError:NSError?
var results:Array<AnyObject>?
results = self.managedObjectContext.executeFetchRequest(request, error: &fetchError)
if let error = fetchError {
println("Warning!! \(error.description)")
}
completionHandler(results: results)
}
}
// #pragma mark - save methods
func save() {
var context:NSManagedObjectContext = self.managedObjectContext;
if context.hasChanges {
context.performBlockAndWait{
var saveError:NSError?
let saved = context.save(&saveError)
if !saved {
if let error = saveError{
println("Warning!! Saving error \(error.description)")
}
}
if context.parentContext != nil {
context.parentContext.performBlockAndWait{
var saveError:NSError?
let saved = context.parentContext.save(&saveError)
if !saved{
if let error = saveError{
println("Warning!! Saving parent error \(error.description)")
}
}
}
}
}
}
}
func contextWillSave(notification:NSNotification){
let context : NSManagedObjectContext! = notification.object as NSManagedObjectContext
var insertedObjects : NSSet = context.insertedObjects
if insertedObjects.count != 0 {
var obtainError:NSError?
context.obtainPermanentIDsForObjects(insertedObjects.allObjects, error: &obtainError)
if let error = obtainError {
println("Warning!! obtaining ids error \(error.description)")
}
}
}
// #pragma mark - Utilities
func deleteEntity(object:NSManagedObject)-> () {
object.managedObjectContext .deleteObject(object)
}
// #pragma mark - Application's Documents directory
// Returns the URL to the application's Documents directory.
var applicationDocumentsDirectory: NSURL {
let urls = NSFileManager.defaultManager().URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask)
return urls[urls.endIndex-1] as NSURL
}
func databaseOptions() -> Dictionary <String,Bool> {
var options = Dictionary<String,Bool>()
options[NSMigratePersistentStoresAutomaticallyOption] = true
options[NSInferMappingModelAutomaticallyOption] = true
return options
}
}