我刚刚开始在我的Swift 2.0 iOS应用程序中实现一个小部件功能,经过大量研究后,我发现SwiftWidget github链接使用了CoreDataStore文件,该文件包含通常包含在App Delegate plus中的所有Core Data函数将它设置为主队列或私有队列的能力很好。
我的问题是,我真的需要在App Delegate之外设置它,因为我的应用程序只使用基本的核心数据功能,并且无论如何都不是一个大型数据库。我只是因为我创建了我的应用程序的克隆版本来试验更改并尝试使用修改后的SwiftWidget中的文件来包含我的所有应用信息。
对于那些对此文件使用的实际代码感兴趣的人,我已将其链接到下面:
import Foundation
import CoreData
public class CoreDataStore {
class var sharedInstance : CoreDataStore {
struct Static {
static let instance : CoreDataStore = CoreDataStore()
}
return Static.instance
}
// MARK: - Notifications
func contextDidSavePrivateQueueContext(notification: NSNotification) {
if let context = self.mainQueueCtxt {
self.synced(self, closure: { () -> () in
context.performBlock({() -> Void in
context.mergeChangesFromContextDidSaveNotification(notification)
})
})
}
}
func contextDidSaveMainQueueContext(notification: NSNotification) {
if let context = self.privateQueueCtxt {
self.synced(self, closure: { () -> () in
context.performBlock({() -> Void in
context.mergeChangesFromContextDidSaveNotification(notification)
})
})
}
}
func synced(lock: AnyObject, closure: () -> ()) {
objc_sync_enter(lock)
closure()
objc_sync_exit(lock)
}
// MARK: - Core Data stack
lazy var applicationDocumentsDirectory: NSURL = {
// The directory the application uses to store the Core Data store file. This code uses a directory named "com.xxx.Appname" in the application's documents Application Support directory.
let urls = NSFileManager.defaultManager().URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask)
return urls[urls.count-1]
}()
lazy var managedObjectModel: NSManagedObjectModel = {
// The managed object model for the application. This property is not optional. It is a fatal error for the application not to be able to find and load its model.
let modelURL = NSBundle.mainBundle().URLForResource("Appname", withExtension: "momd")!
return NSManagedObjectModel(contentsOfURL: modelURL)!
}()
lazy var persistentStoreCoordinator: NSPersistentStoreCoordinator? = {
// The persistent store coordinator for the application. This implementation creates and return a coordinator, having added the store for the application to it. This property is optional since there are legitimate error conditions that could cause the creation of the store to fail.
// Create the coordinator and store
var coordinator: NSPersistentStoreCoordinator? = NSPersistentStoreCoordinator(managedObjectModel: self.managedObjectModel)
let directory = NSFileManager.defaultManager().containerURLForSecurityApplicationGroupIdentifier("group.xxx.Appname")
let url = directory?.URLByAppendingPathComponent("Appname.sqlite")
var error: NSError? = nil
var failureReason = "There was an error creating or loading the application's saved data."
do {
try coordinator!.addPersistentStoreWithType(NSSQLiteStoreType, configuration: nil, URL: url, options: nil)
} catch var error1 as NSError {
error = error1
coordinator = nil
// Report any error we got.
var dict = [String: AnyObject]()
dict[NSLocalizedDescriptionKey] = "Failed to initialize the application's saved data"
dict[NSLocalizedFailureReasonErrorKey] = failureReason
dict[NSUnderlyingErrorKey] = error
error = NSError(domain: "YOUR_ERROR_DOMAIN", code: 9999, userInfo: dict)
// Replace this with code to handle the error appropriately.
// abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
NSLog("Unresolved error \(error), \(error!.userInfo)")
abort()
} catch {
fatalError()
}
return coordinator
}()
// MARK: - NSManagedObject Contexts
public class func mainQueueContext() -> NSManagedObjectContext {
return self.sharedInstance.mainQueueCtxt!
}
public class func privateQueueContext() -> NSManagedObjectContext {
return self.sharedInstance.privateQueueCtxt!
}
lazy var mainQueueCtxt: NSManagedObjectContext? = {
// Returns the managed object context for the application (which is already bound to the persistent store coordinator for the application.) This property is optional since there are legitimate error conditions that could cause the creation of the context to fail.
var managedObjectContext = NSManagedObjectContext(concurrencyType:.MainQueueConcurrencyType)
managedObjectContext.persistentStoreCoordinator = self.persistentStoreCoordinator
return managedObjectContext
}()
lazy var privateQueueCtxt: NSManagedObjectContext? = {
// Returns the managed object context for the application (which is already bound to the persistent store coordinator for the application.) This property is optional since there are legitimate error conditions that could cause the creation of the context to fail.
var managedObjectContext = NSManagedObjectContext(concurrencyType:.PrivateQueueConcurrencyType)
managedObjectContext.persistentStoreCoordinator = self.persistentStoreCoordinator
return managedObjectContext
}()
// MARK: - Core Data Saving support
public class func saveContext (context: NSManagedObjectContext?) {
if let moc = context {
var error: NSError? = nil
if moc.hasChanges {
do {
try moc.save()
} catch let error1 as NSError {
error = error1
// Replace this implementation with code to handle the error appropriately.
// abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
NSLog("Unresolved error \(error), \(error!.userInfo)")
abort()
}
}
}
}
}
// MARK: - NSManagedObject Extension
extension NSManagedObject {
public class func createInContext(entityName: String, context: NSManagedObjectContext) -> AnyObject {
let entity = NSEntityDescription.entityForName(entityName, inManagedObjectContext: context)
return NSManagedObject(entity: entity!, insertIntoManagedObjectContext: context)
}
public class func findAllInContext(entityName: String, context: NSManagedObjectContext) -> [AnyObject]? {
let request = NSFetchRequest(entityName: entityName)
var error: NSError?
let result: [AnyObject]?
do {
result = try context.executeFetchRequest(request)
} catch let error1 as NSError {
error = error1
result = nil
}
return result
}
}
再次重复主要问题,我可以使用App Delegate内部的App Delegate函数或将这些函数转移到.swift文件,从主要应用程序和今天的扩展中有效地读取/写入核心数据?如果没有和这种类型的文件是我需要的,我将能够使用相同的获取命令并保存命令,如在app委托中或我需要重写我的所有视图控制器代码获取和保存以调用指定createincontext或findallincontext的功能?如果我现在不是真正获取在线数据或导出在线数据,我应该只使用应用代表的堆栈构建吗?
MagicRecord是实现这些功能的更好方式,并且仍然允许未来实现获取和发送在线数据的能力吗?我已经将大部分代码写入了与app delegate相关的函数。
答案 0 :(得分:0)
AppDelegate的工作是处理应用程序启动,退出和后台/前台转换。您的核心数据堆栈的工作是处理您的数据模型。这些是不同的职责范围,属于不同的类别。
是的,您可以将所有内容混杂到AppDelegate中。对于一个玩具项目,你会侥幸逃脱。但这是一种邋practice的做法。如果要将数据模型代码拉出并在另一个项目中使用它,您会怎么做?或者将项目从iOS移植到tvOS或OS X?