2016-04-23 5 views
0

Я пытаюсь настроить страницу контактов, где я могу добавлять/редактировать контакты. Тем не менее, я получаю нулевое значение, когда пытаюсь вызвать свой CoreDataStack.context.Управляемый контекст из CoreDataStack не сохраняется через навигационную панель

Здесь берет свое начало в AppDelegate

lazy var coreDataStack = CoreDataStack() 


func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool { 
    // Override point for customization after application launch. 
    UINavigationBar.appearance().barTintColor = navigationMainColor 
    UINavigationBar.appearance().tintColor = navigationMainItemColor 

    let navigationController = window!.rootViewController as! UINavigationController 
    let listViewController = navigationController.topViewController as! ViewController 
    listViewController.coreDataStack = coreDataStack 

    return true 
} 

я передать его в мой первый контроллер представления и внутри RootViewController У меня есть кнопка, которая посылает меня в другой контроллер представления. В rootViewController контекст CoreDataStack все еще существует, когда я вызываю print (coreDataStack). Поэтому я знаю, что он существует в первом представлении. Кнопка, которую я нажимаю для перехода на страницу контактов, представляет собой кнопку на панели инструментов.

Возможная проблема 1 может заключаться в том, что я не перемещаюсь с помощью панели навигации и не с нее, однако все представления встроены в стек навигационной панели.

Нужно ли мне подготовитьForSegue внутри первого контроллера представления, чтобы передать NSManagedObjectContext?

Существует также контроллер навигации между контактами и новым контроллером управления контактами. Но, похоже, ноль возвращается, прежде чем это произойдет. В контактах просмотра КОНТРОЛЛЕР prepareForSegue, который проверяет, если пользователь пытается добавить контакт найден здесь

else if segue.identifier == "AddContact" { 
     let navigationController = segue.destinationViewController as! UINavigationController 
     let addViewController = navigationController.topViewController as! NewContactViewController 
     let contactEntity = NSEntityDescription.entityForName("Contact", inManagedObjectContext: coreDataStack.context) 

     let newContact = Contact(entity: contactEntity!, insertIntoManagedObjectContext: coreDataStack.context) 

     addViewController.contact = newContact 
     addViewController.context = newContact.managedObjectContext 
     addViewController.delegate = self 
    } 

И ошибка я получаю то, что coreDataStack.context, когда я пытаюсь создать новый контакт возвращая ноль. Я часами и часами прогонял это, и я думаю, что у меня что-то действительно малое или большое. В любом случае, я просто хочу изучить Core Data и стать лучше.

ответ

0

Нужно ли мне prepareForSegue внутри первого контроллера представления для того, чтобы передать NSManagedObjectContext?

Да, это именно то, что у вас есть. Вам нужно сделать инъекцию вашей DEPENDENCY себя, так как Apple, не может предсказать, где вы хотите вещи :)

Если входящий (назначения) контроллер представления заворачивают в навигационном контроллере можно смело предположить, что указывает, что topViewController Ваше мнение контроллер (и вы можете проверить это) и ввести его.

Так что просто получите контроллер навигации, а затем получите контроллер назначения? Это просто вопрос destinationcontroller.context = self.context в файле подготовки для первого контроллера представления?

Другой путь раунд:

func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) { 
    guard let destinationNavController = segue.destinationViewController as? UINavigationController else { 
     print("Unexpected view controller: \(seque.destinationViewController.self)") 
    } 
    guard let myViewController = destinationNavController.topViewController as? MyViewController else { 
     print("Unexpected view controller: \(destinationNavController.topViewController.self)") 
    } 
    myViewController.context = context 
} 

Заменить части с именами классов, как это необходимо.

Да, я понял, теперь я получаю странную ошибку, которую я не могу заставить подавить свой ContactViewController в UINavigationController. Возможно ли, что мой ContactViewController не находится в стеке навигации?

ok, уровень задний. Если вы только pop'ing контроллеры просмотра в стеке нав то, что вы получаете ваш ContactViewController непосредственно в качестве пункта назначения, и вы можете пропустить контроллер нав так:

func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) { 
    guard let myViewController = segue.destinationViewController as? MyViewController else { 
     print("Unexpected view controller: \(destinationNavController.topViewController.self)") 
    } 
    myViewController.context = context 
} 

Если переход указывает на NEWUINavigationController то есть что-то еще не так.

+0

Так просто получить контроллер навигации, а затем получить контроллер назначения? Это просто вопрос destinationcontroller.context = self.context в файле подготовки для первого контроллера представления? – ggworean

+0

Ответ обновлен, чтобы продемонстрировать, о чем я говорю. –

+0

О, так что этот prepareforsegue находится во втором контроллере представления, где его получают тип подготовки. Awesome, thanks – ggworean

0

Ваш coredatastack должен быть объектом класса singleton. Теперь, если вы создадите новое приложение coredata, Apple сама создаст для вас файл сантехники в AppDelegate. Поскольку AppDelegate - это одноэлементный класс, вы можете получить доступ к coredatastack как AppDelegate.coredatastack в любом месте вашего приложения. Поскольку вы также определен coredatastack в AppDelegate вы не должны передать его в своих viewcontrollers, можно получить прямой доступ с помощью

let delegate = UIApplication.sharedApplication().delegate as AppDelegate 
delegate.coredatastack 
+1

Singletons действительно должен ** НЕ ** использоваться в этой ситуации или любой другой. Шаблон Apple - очень плохой пример и не предлагает создать синглтон. Кроме того, ваш ответ не поможет OP решить настоящую проблему. –

+0

В запросах указывается, что контекст coredatastack не сохраняется. Контекст Coredata должен быть одноэлементным. Apple и все другие учебники основаны только на этом. Сама Apple сама по себе создает его как singleton в AppDelegate. –

+0

Неправильно. Шаблон Apple продемонстрировал создание стека основных данных в AppDelegate. Во-первых, AppDelegate ** NOT ** Singleton. Просто потому, что есть один экземпляр объекта, это не означает, что он является одиночным. Во-вторых, шаблон от Apple - это * плохой пример использования этого стека и старый код. Вы можете проверить это, просмотрев [Руководство по программированию основных данных] (https://developer.apple.com/library/watchos/documentation/Cocoa/Conceptual/CoreData/index.html), который был обновлен в марте этого года. –

Смежные вопросы