Stanford CS193p 지정 (PhotoMania)의 Swift 버전을 구현 중입니다.IOS ObjectContext가 True를 반환 함에도 불구하고 영구 저장소에 저장되지 않음
내 NSObjectContext 저장 명령이 내가 만든 것으로 생각하는 영구 저장소에 저장되지 않는 이유에 대해 혼란스러워합니다.
앱의 목적은 두 개의 탭 막대를 사용하는 것입니다. - 탭 막대 # 1에 최근 Flickr의 사진이 포함되어 있습니다. - 탭 모음 # 2는 가장 최근에 본 사진을 포함합니다. 즉, 사용자가 Flickr 사진 셀을 탭하여 이미지를 볼 때마다 이미지의 정보를 영구 저장 구조에 저장하여 탭 막대 # 2에서 액세스해야합니다. 여기
앱이 구성되어 방법은 다음과 같습니다
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은 AppDelegate에에서 컨텍스트를 유도 할 수있는 jQuery과 서브 클래스가 :
이1 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이 반환됩니다.
fetchController에서 콘텐츠를 가져 오기로되어있는 탭 모음 # 2 (최근 사진) 컨트롤러입니다. 나는 (저장을 채워야하는) 이미지를 눌러 후에도마다 전무 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 버전을 구현했기 때문에 이것이 내 문제의 근원이 될 것이라고 기대하지 않습니다. .
그래서 내가 실수로 Context 객체를 만들었다는 것이 맞습니다. 이제는 각 컨트롤러가 appdelegate에서 컨텍스트를 호출하도록 해당 호출을 제거했습니다. 그리고 createMainQueueManagedObjectContext는 응용 프로그램 시작시 대리자에서 호출됩니다. 그러나 객체는 여전히 상점에 삽입되지 않습니다. 재정의 FUNC의 viewDidLoad에() { self.objectContext = self.appDelegate.objectContext super.viewDidLoad() } – Laurent
내가 여러 상황에 맞는 문제를 해결하는 방법을 보여 코드의 예입니다 문제를 진단 할 수있는 정보가 충분하지 않습니다. 이 수업을 단계별로 실행하고 관찰 할 수있는 내용을 확인하십시오. 그 대상이 어떻게 구원 받았다는 것을 어떻게 알 수 있습니까? 두 번째 컨트롤러가 언제 페치 요청을합니까? 두 번째 컨트롤러가 언제 테이블보기를 새로 고 칩니 까? 객체가 두 번째 컨트롤러에서 사용할 수 없다는 것을 어떻게 알 수 있습니까? 이제 관리 대상 객체 컨텍스트가 어떻게 구성됩니까? – Laurent
아마 '돈 : 여기 그런데 – Jonah