2016-04-09 19 views
2

Bir OS X uygulaması için Core Data ile oynuyorum. Dil Swift. Cocoa için çalışma şekli hakkında garip bir şey var. Aşağıdaki, Xcode'un yarattığı kısa versiyonudur.Swift - Çekirdek Verileri Kakao İle Kullanma

class AppDelegate: NSObject, NSApplicationDelegate { 
    func applicationDidFinishLaunching(aNotification: NSNotification) { 
     // Insert code here to initialize your application 
    } 

    func applicationWillTerminate(aNotification: NSNotification) { 
     // Insert code here to tear down your application 
    } 

    // MARK: - Core Data stack 
    lazy var persistentStoreCoordinator: NSPersistentStoreCoordinator = { 
     // The persistent store coordinator for the application. This implementation creates and returns a coordinator, having added the store for the application to it. (The directory for the store is created, if necessary.) This property is optional since there are legitimate error conditions that could cause the creation of the store to fail. 
     let fileManager = NSFileManager.defaultManager() 
     var failError: NSError? = nil 
     var shouldFail = false 
     var failureReason = "There was an error creating or loading the application's saved data." 

     // Make sure the application files directory is there 
     do { 
      let properties = try self.applicationDocumentsDirectory.resourceValuesForKeys([NSURLIsDirectoryKey]) 
      if !properties[NSURLIsDirectoryKey]!.boolValue { 
       failureReason = "Expected a folder to store application data, found a file \(self.applicationDocumentsDirectory.path)." 
       shouldFail = true 
      } 
     } catch { 
      let nserror = error as NSError 
      if nserror.code == NSFileReadNoSuchFileError { 
       do { 
        try fileManager.createDirectoryAtPath(self.applicationDocumentsDirectory.path!, withIntermediateDirectories: true, attributes: nil) 
       } catch { 
        failError = nserror 
       } 
      } else { 
       failError = nserror 
      } 
     } 
    }() 
} 

Ve Core Data için bir SQLite dosyası, bir varlığa yeni bir kayıt ekledikten sonra bulunamaz. Yukarıdaki kodda bir SQLite dosyasına işaretçi yok. Aşağıdaki bir iOS karşılığıdır.

class AppDelegate: UIResponder, UIApplicationDelegate { 
    // MARK: - Core Data stack 
    lazy var persistentStoreCoordinator: NSPersistentStoreCoordinator = { 
     // The persistent store coordinator for the application. This implementation creates and returns 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 
     let coordinator = NSPersistentStoreCoordinator(managedObjectModel: self.managedObjectModel) 
     let url = self.applicationDocumentsDirectory.URLByAppendingPathComponent("SingleViewCoreData.sqlite") 
     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 { 
      // 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 as NSError 
      let wrappedError = 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 \(wrappedError), \(wrappedError.userInfo)") 
      abort() 
     } 

     return coordinator 
    }() 
} 

Yukarıdaki kod bir SQLite dosyasına işaret eder. Yani bir varlığa kayıt eklemekte sorun yaşıyorum.

Xcode kullanıyorum 7.2.1 Yanlış bir şeyler yapıyorum? Yoksa bu bir Xcode hatası mı?

+0

Soruna neden oluyor. Yukarıdaki kod, Xcode'un oluşturduğu otomatik oluşturulan uygulama temsilcisi malzemelerine benziyor. Kodunuz, kayıt eklemeye çalıştığınız nerede? – BLE

+1

Veritabanını doğrudan düzenleyeceğiniz için bir SQLite dosyasına işaretçiye ihtiyacınız olduğunu söylüyorsanız, Core Data'nın nasıl çalıştığını ve nasıl kullanmanız gerektiğini temel olarak yanlış anlamışsınızdır. Kodunuzda ne olmasını beklediğinizi ve gerçekte neyi gözlemlediğinizi açıklayabilir misiniz? –

+0

Neden Xcode sizin için oluşturulan kodu kullanmıyorsunuz? – vadian

cevap

2

Burada gönderdiğiniz kod, yalnızca bir İşlevsel Çekirdek Veri yığınının bir parçasıdır ve Çekirdek Verileri başlatmada yetersiz kalmaktadır.

import CoreData 
class DataController: NSObject { 
    var managedObjectContext: NSManagedObjectContext 
    init() { 
     // This resource is the same name as your xcdatamodeld contained in your project. 
     guard let modelURL = NSBundle.mainBundle().URLForResource("DataModel", withExtension:"momd") else { 
      fatalError("Error loading model from bundle") 
     } 
     // The managed object model for the application. It is a fatal error for the application not to be able to find and load its model. 
     guard let mom = NSManagedObjectModel(contentsOfURL: modelURL) else { 
      fatalError("Error initializing mom from: \(modelURL)") 
     } 
     let psc = NSPersistentStoreCoordinator(managedObjectModel: mom) 
     managedObjectContext = NSManagedObjectContext(concurrencyType: .MainQueueConcurrencyType) 
     managedObjectContext.persistentStoreCoordinator = psc 
     dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0)) { 
      let urls = NSFileManager.defaultManager().URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask) 
      let docURL = urls[urls.endIndex-1] 
      /* The directory the application uses to store the Core Data store file. 
      This code uses a file named "DataModel.sqlite" in the application's documents directory. 
      */ 
      let storeURL = docURL.URLByAppendingPathComponent("DataModel.sqlite") 
      do { 
       try psc.addPersistentStoreWithType(NSSQLiteStoreType, configuration: nil, URL: storeURL, options: nil) 
      } catch { 
       fatalError("Error migrating store: \(error)") 
      } 
     } 
    } 
} 

Apple'dan Initialising the Core Data Stack bakınız:

Bu

Çekirdek Data Stack initialising Apple'ın güncel örnek kodudur.

+0

Tamam. Teşekkürler. Yani SQLite dosya yolunu içerir. Neden anlamıyorum, biliyor musun? Xcode sürümünüz nedir? –

1

@DuncanBabbage çözeltisinin Swift 3 sürümü: Tam olarak bunu yapmaya çalıştığımız şey

class DataController: NSObject { 
    var managedObjectContext: NSManagedObjectContext 
    override init() { 
     // This resource is the same name as your xcdatamodeld contained in your project. 
     guard let modelURL = Bundle.main.url(forResource: "DataModel", withExtension:"momd") else { 
      fatalError("Error loading model from bundle") 
     } 
     // The managed object model for the application. It is a fatal error for the application not to be able to find and load its model. 
     guard let mom = NSManagedObjectModel(contentsOf: modelURL) else { 
      fatalError("Error initializing mom from: \(modelURL)") 
     } 
     let psc = NSPersistentStoreCoordinator(managedObjectModel: mom) 
     managedObjectContext = NSManagedObjectContext(concurrencyType: .mainQueueConcurrencyType) 
     managedObjectContext.persistentStoreCoordinator = psc 

     DispatchQueue.global(qos: DispatchQoS.QoSClass.background).async { 
      let urls = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask) 
      let docURL = urls[urls.endIndex-1] 
      /* The directory the application uses to store the Core Data store file. 
      This code uses a file named "DataModel.sqlite" in the application's documents directory. 
      */ 
      let storeURL = docURL.appendingPathComponent("DataModel.sqlite") 
      do { 
       try psc.addPersistentStore(ofType: NSSQLiteStoreType, configurationName: nil, at: storeURL, options: nil) 
      } catch { 
       fatalError("Error migrating store: \(error)") 
      } 
     } 
    } 
}