我正在實施Stanford CS193p Swift版本(PhotoMania)。IOS ObjectContext不保存到持久性存儲,儘管返回True
我很困惑,爲什麼我的NSObjectContext保存命令沒有保存到持久存儲我相信我已經創建。
該應用程序的目標是有兩個標籤欄: - 標籤欄#1包含來自Flickr的近期照片。 - 標籤欄#2包含我最近瀏覽過的照片。這意味着每次用戶點擊Flickr照片單元以查看圖像時,我都應該將該圖像的信息存儲在持久性存儲結構中,以在標籤欄#2中訪問它。
這裏的應用程序是如何構成的:
的AppDelegate中包含存儲設置說明:
import UIKit
import CoreData
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
var objectContext:NSManagedObjectContext?
func application(application: UIApplication!, didFinishLaunchingWithOptions launchOptions: NSDictionary!) -> Bool {
self.objectContext = self.createMainQueueManagedObjectContext()
self.testModel()
return true
}
func testModel(){
var photoModel: Photo? = NSEntityDescription.insertNewObjectForEntityForName("Photo", inManagedObjectContext: self.objectContext!) as? Photo
photoModel!.title = "hi"
photoModel!.subtitle = "subtitle"
self.objectContext!.insertObject(photoModel)
self.objectContext!.save(nil)
println(self.objectContext!.persistentStoreCoordinator.persistentStores[0].objects)
}
func createManagedObjectModel()-> NSManagedObjectModel{
var managedObjectModel:NSManagedObjectModel?
let modelURL:NSURL = NSBundle.mainBundle().URLForResource("PhotoModel", withExtension: "momd")
managedObjectModel = NSManagedObjectModel(contentsOfURL: modelURL)
return managedObjectModel!
}
func createPersistentStoreCoordinator()-> NSPersistentStoreCoordinator{
var persistentStoreCoordinator:NSPersistentStoreCoordinator?
var managedObjectModel:NSManagedObjectModel = self.createManagedObjectModel()
let storeURL:NSURL = self.applicationDocumentsDirectory().URLByAppendingPathComponent("MOC.sqlite")
var error:NSError?
persistentStoreCoordinator = NSPersistentStoreCoordinator(managedObjectModel: managedObjectModel)
if (persistentStoreCoordinator?.addPersistentStoreWithType(NSSQLiteStoreType as String, configuration: nil, URL: storeURL, options: nil, error: &error) == nil){
NSLog("unresolved error %@, %@", error!, error!.userInfo)
abort()
}
return persistentStoreCoordinator!
}
func applicationDocumentsDirectory()-> NSURL{
var hello:NSURL = NSFileManager().URLsForDirectory(NSSearchPathDirectory.DocumentDirectory, inDomains: NSSearchPathDomainMask.UserDomainMask).last as NSURL
return hello
}
func createMainQueueManagedObjectContext()->NSManagedObjectContext{
var managedObjectContext:NSManagedObjectContext?
var coordinator:NSPersistentStoreCoordinator = self.createPersistentStoreCoordinator()
if (coordinator != nil){
managedObjectContext = NSManagedObjectContext(concurrencyType: NSManagedObjectContextConcurrencyType.MainQueueConcurrencyType)
managedObjectContext!.persistentStoreCoordinator = coordinator
}
return managedObjectContext!
}
}
2.有一個UITableView子類,從AppDelegate中獲取上下文:
class MyViewController: UITableViewController {
@IBOutlet weak var refresher: UIRefreshControl?
let appDelegate:AppDelegate = UIApplication.sharedApplication().delegate as AppDelegate
var objectContext:NSManagedObjectContext?{
didSet{
self.fetchDatabasePhotos()
}
}
var fetchController:NSFetchedResultsController?{
didSet{
self.tableView.reloadData()
}
}
override func viewDidLoad() {
self.objectContext = self.appDelegate.objectContext
super.viewDidLoad()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func fetchDatabasePhotos(){
let request:NSFetchRequest = NSFetchRequest(entityName: "Photo")
request.predicate = nil
request.sortDescriptors = [NSSortDescriptor(key: "title", ascending: true)]
self.fetchController = NSFetchedResultsController(fetchRequest: request, managedObjectContext: self.objectContext, sectionNameKeyPath: nil, cacheName: nil)
println(self.fetchController!)
// println(self.fetchController!.fetchedObjects)
}
}
3。有一個管理Flickr下載的MyViewController的「JustPostedFlickr」子類。 Flickr下載部分工作正常。但我嘗試從表視圖控制器和圖像視圖控制器之間的prepareforsegue中調用的方法插入存儲器中的照片對象。這裏是被調用的方法:
override func prepareForSegue(segue: UIStoryboardSegue!, sender: AnyObject!) {
let indexPath:NSIndexPath = self.tableView.indexPathForCell(sender as UITableViewCell)
if (segue.identifier == "Display Photo"){
if (segue.destinationViewController.isKindOfClass(ImageViewController)){
self.prepareImageViewController(segue.destinationViewController as ImageViewController, photo: self.photos[indexPath.row] as NSDictionary)
}
}
}
func prepareImageViewController(ivc:ImageViewController, photo:NSDictionary){
ivc.imageURL = FlickrFetcher.URLforPhoto(photo, format: FlickrPhotoFormatLarge)
ivc.title = photo.valueForKeyPath(FLICKR_PHOTO_TITLE) as String
var photoModel: Photo! = NSEntityDescription.insertNewObjectForEntityForName("Photo", inManagedObjectContext: self.objectContext) as Photo
photoModel!.title = photo.valueForKeyPath(FLICKR_PHOTO_TITLE) as String
photoModel!.subtitle = photo.valueForKeyPath(FLICKR_PHOTO_DESCRIPTION) as String
photoModel!.photoURL = FlickrFetcher.URLforPhoto(photo, format: FlickrPhotoFormatLarge).absoluteString
photoModel!.created_date = NSDate()
println(self.objectContext!)
var theVar:Bool = self.objectContext!.save(nil)
println(theVar)
self.fetchDatabasePhotos()
}
self.objectContext!.save(xx)
總是返回true。 self.objectContext.registeredObjects
返回正確的照片模型結構和值 但是,當我獲取照片並打印提取的對象列表時,它始終返回nil。
控制器標籤欄#2(最近的照片),應該從fetchController中獲取內容。該fetchcontroller.fetchedObjects
方法返回零每次我在圖像上輕按即使(應該填充存儲):
import UIKit
class RecentPhotosController: MyViewController {
override func viewDidAppear(animated: Bool) {
self.objectContext = self.appDelegate.createMainQueueManagedObjectContext()
super.viewDidAppear(animated)
println("I just appeared")
}
override func numberOfSectionsInTableView(tableView: UITableView!) -> Int {
var sections:Int = 0
let fetchSections = self.fetchController!.sections
if (fetchSections != nil){
sections = fetchSections.count
}
return sections
}
override func tableView(tableView: UITableView!, numberOfRowsInSection section: Int) -> Int {
var rows:Int = 0
let fetchRows = self.fetchController!.fetchedObjects
if (fetchRows != nil){
rows = fetchRows.count
}
return rows
}
override func tableView(tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCell! {
let cell = tableView.dequeueReusableCellWithIdentifier("Recent Photo", forIndexPath: indexPath) as UITableViewCell
let photo:Photo = self.fetchController!.objectAtIndexPath(indexPath)! as Photo
cell.textLabel.text = photo.title as String
cell.detailTextLabel.text = photo.subtitle as String
return cell
}
}
最後:這裏是照片模式:
import Foundation
import CoreData
class Photo: NSManagedObject {
@NSManaged var title: String
@NSManaged var subtitle: String
@NSManaged var created_date: NSDate
@NSManaged var photoURL: String
}
我的問題是:爲什麼NSObjectContext中的對象是否未保存到存儲?
最後:我現在正在模擬器上測試,但我不認爲這是我的問題的來源,因爲我實現了CS193p的Photomania Swift版本(它使用核心數據和持久性存儲)並且工作正常。
所以你是正確的,我錯誤地創建了對象上下文。我現在已經移除了這些調用,以便每個控制器從appdelegate調用上下文 - 並且在應用程序啓動時從代理調用createMainQueueManagedObjectContext。但是這些物品還沒有被插入商店。 – Laurent 2014-08-30 07:48:09
通過這裏的方法是代碼的一個例子來說明我是如何解決的多上下文問題:覆蓋FUNC viewDidLoad中(){ self.objectContext = self.appDelegate.objectContext super.viewDidLoad() } – Laurent 2014-08-30 08:10:57
我大概穿上」現在沒有足夠的信息來診斷您的問題。通過這些課程,看看你可以觀察到的事情發生。你怎麼知道這個對象被保存了?第二個控制器何時對它進行獲取請求?第二個控制器什麼時候刷新它的表格視圖?你怎麼知道對象不可用於第二個控制器?現在如何配置管理對象上下文? – Jonah 2014-08-30 15:39:25