2014-09-29 41 views
2

我想在我的iOS應用中使用核心數據,該應用使用UINavigationController和故事板上的第一個視圖控制器。然後,我想將AppDelegate.h中的NSManagedObjectContextNSPersistentStoreCoordinator傳遞給UINavigationController中的第一個視圖控制器。所以我第一次寫了下面的代碼(注意,我還使用UISplitViewController):如何正確設置Core Data Stack到iOS和Swift中的第一個視圖控制器?

var splitViewController = self.window!.rootViewController as UISplitViewController 
var navigationController: UINavigationController! 
if splitViewController.viewControllers.count == 2 { 
    navigationController = splitViewController.viewControllers[1] as UINavigationController 
} else { 
    navigationController = splitViewController.viewControllers[0] as UINavigationController 
} 
var firstViewController = navigationController.topViewController 
firstViewController.managedObjectContext = managedObjectContext 

但是,編譯說UIViewController不具備這樣的特性managedObjectContext。但是,這很奇怪因爲當我試圖通過println(firstViewController)記錄它,它說,它是FirstViewController,不UIViewController實例......但無論如何,我將向下轉換它改成了以下內容:

var firstViewController = navigationController.topViewController as FirstViewController 

然而,然後構建工作正常,但它立即崩潰的錯誤:"Swift dynamic cast failed"在運行時。

那麼我怎麼能通過NSManagedObjectContext(和NSPersistentStoreCoordinator)到第一個視圖控制器?

我在iOS(iPad)應用程序中使用Xcode 6.1 Beta 2和Swift。

回答

1

您應該爲核心數據定義一個單獨的類並將其用於核心數據。下面是一個例子類:

class CoreDataHelper { 

// MARK: - Properties 

    private lazy var applicationDocumentsDirectory: NSURL = { 
     let urls = NSFileManager.defaultManager().URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask) 
     return urls[urls.count - 1] as NSURL 
    }() 

    lazy var managedObjectModel: NSManagedObjectModel? = { 
     if let modelURL = NSBundle.mainBundle().URLForResource("YOUR_MODEL_NAME", withExtension: "momd") { 
      return NSManagedObjectModel(contentsOfURL: modelURL) 
     } else { 
      println("Error: can't create managed object model") 
      return nil 
     } 
    }() 

    lazy var persistentStoreCoordinator: NSPersistentStoreCoordinator? = { 
     if let managedObjectModel = self.managedObjectModel { 
      let coordinator = NSPersistentStoreCoordinator(managedObjectModel: managedObjectModel) 
      let url = self.applicationDocumentsDirectory.URLByAppendingPathComponent("YOUR_MODEL_NAME.sqlite") 

      var error: NSError? = nil 

      let options = [NSMigratePersistentStoresAutomaticallyOption: true, NSInferMappingModelAutomaticallyOption: true] 
      coordinator.addPersistentStoreWithType(NSSQLiteStoreType, configuration: nil, URL: url, options: options, error: &error) 


      if let error = error { 
       println("Error: Can't add persistent store type to persistent store coordinate") 
       return nil 
      } else { 
       return coordinator 
      } 
     } else { 
      println("Error: Can't create persistant store coordinator. Because managed object model is not valid.") 
      return nil 
     } 
    }() 

    lazy var managedObjectContext: NSManagedObjectContext? = { 
     if let coordinator = self.persistentStoreCoordinator { 
      let managedObjectContext = NSManagedObjectContext() 
      managedObjectContext.persistentStoreCoordinator = coordinator 

      return managedObjectContext 
     } else { 
      println("Error: Can't create managed object context. Persistent store coordinator is not valid") 
      return nil 
     } 
    }() 

}

1

我只是在Xcode 6.0中創建一個主從應用程序,並檢查了包括CoreData框。模板中的代碼不正是你想要的...

你的代碼的第一個塊:

var firstViewController = navigationController.topViewController 
firstViewController.managedObjectContext = managedObjectContext 

系統不會在編譯時間,因爲工作,哪怕是topViewController是一個UIViewController,更多的東西在運行時特定。這就是爲什麼你需要演員。

至於爲什麼你downcast不工作​​...要麼navigationController是空的,或者其topViewController是空的。前者比後者更可能。

嘗試在一些if let小號包裝你的最後幾行,看看會發生什麼:

if let nav = navigationController { 
    if let firstViewController = navigationController.topViewController as? FirstViewController { 
     firstViewController.managedObjectContext = managedObjectContext 
    } 
    else { 
     println("navigationController.topViewController is not a FirstViewController") 
    } 
} 
else { 
    println("navigationController is empty") 
} 
+0

兩個'navigationController'和'topViewController'不爲空,但它返回'navigationController.topViewController不是FirstViewController'。所以它沒能將'topViewController'向下翻到'FirstViewController',但我不知道爲什麼。 – Blaszard 2014-10-30 06:57:42

相關問題