2016-05-25 3 views
4

TL; DR. Для упрощения всего описания, как реализовать интерфейс пользовательских интерфейсов представления не зависящих от вида таблицы, когда свойства базового объекта данных часто обновляются в фоновом режиме. И с этим визуальное представление данных необходимо немедленно обновить. [В Tableview очень легко обрабатывать, использовать КОПЫ и просто перезагрузить строку, когда обновление объекта, с помощью методов FRCS делегата.]Как сделать плотную связь между данными о корреляциях coredata/NSManagedObject с пользовательским интерфейсом приложений?


Я знаю о NSFetchedResultsController и отображение через что пользовательский интерфейс. Но это только тогда, когда интерфейс пользователя основан на списке.

В моем случае несколько аппаратных средств подобного типа подключены к моему приложению через bluetooth (BLE), и каждый обычно обеспечивает обновления частотой 1 секунду в целом. Например, температура, заряд меняется.

Так вот пример потока пользовательского интерфейса,

Список -> Подробнее

Подробности

  1. Здоровье
  2. Активность
  3. Notification Установка

Подробнее просто представляет собой связанные с оборудованием данные (серийный номер, версию прошивки, дату производства и т. д.), и он имеет 3 кнопки, названные выше, которые при нажатии на нажатия на соответствующие контроллеры.

Модель Entity также разработана соответствующим образом, вот проблеск, у меня есть первичная сущность, допустим, ABC. Затем ABC имеет взаимно-однозначное отношение с другими объектами, такими как HealthDetails, Activity, NotificationSetting и HardwareDetails. ABC имеет несколько атрибутов, таких как identifier, connected, name и т.д.

ListViewController является UITableViewController и, следовательно, я использую NSFetchedResultsController. Теперь оставшиеся все остальные контроллеры представлений - это просто обычные контроллеры представлений, а только титры Title, такие как «последняя заряженная дата», которая является статичной и «меткой описания» ниже, которая показывает данные. Другие контроллеры вида также заполнены просто кнопками, надписями и т. Д.

Обновление контроллера списка с помощью кнопки NSFetchedResultsController.

[Когда строка/клетка касании пользователя, я просто получить объект, используя indexpath из FRC и ввожу его в контроллер вида назначения.]

Однако другие контроллеры вида не представление таблицы на основе. Поэтому я использую уведомление для управления другими обновлениями UI контроллера.

Для примера, когда мой BluetoothManager получает обновление от оборудования, относящегося к признаку, я перенаправляю идентификатор и данные в свой DatabaseHelper, который затем декодирует данные и вставляет их в соответствующий управляемый объект, и в этот момент я просто сгенерировать уведомление с идентификатором объекта, который был обновлен.

Все UIViewController s в иерархии, находящиеся в стеке навигации, подписываются как наблюдатели. И если идентификатор в уведомлении соответствует объекту объекта, отображаемому в настоящее время, я обновляю пользовательский интерфейс. В настоящее время все это прекрасно работает.

Но, я чувствую, что это очень неуклюжий, обрабатывая множество уведомлений. Является ли это единственным способом или существуют ли более эффективные методы, существующие там, чтобы тесно связать отдельные модели данных ядра с пользовательскими интерфейсами?


Я вижу несколько замечаний, которые предлагает обрабатывать все только через КОП, но я не уверен, если FRC может использоваться в представлении пользовательского интерфейса на основе не TableView. Я искал и не нашел много. Если кто-либо знает какой-либо учебник/блог с даже теоретическим описанием, это будет большой помощью.

Другое дело, что предложения по FRC для обработки всех, я не получил его полностью, мне нужно разместить один контроллер FRC для каждого контроллера? Разве нет другого пути?

+0

FRC не только для интерфейсов на основе списков, вы рассмотрели, как его можно использовать для других экранов? Вы действительно не объяснили свою модель данных или ваши экраны и почему вы думаете, что FRC не подходит ... – Wain

+0

@Wain Здравствуйте, wain, я был слишком занят, чтобы написать более подробный вопрос. Ничего больше. Однако я просто дал несколько дополнительных моментов в том, как я обрабатываю структуру. Можете ли вы заглянуть в нее и ответить, если у вас есть лучшее решение? Дайте мне знать, если этого еще недостаточно. –

ответ

2

Вы ничего не должны терять. Делегат в NSFetchedResultsController расскажет вам, когда что-то обновляется. Если у вас есть видимый пользовательский интерфейс, ваш пользовательский интерфейс будет обновляться. Если у вас нет видимого пользовательского интерфейса или вы его не хотите, вы все равно можете связать этот FRC с вашим подклассом NSManagedObject для деталей работоспособности, а затем предпринять любые действия, соответствующие тому факту, что что-то изменилось.

В зависимости от того, что вы делаете, это может быть столь же просто, как внедрение controllerDidChangeContent(_:)

Если это не отвечает на беспокойство, вы будете иметь, чтобы предоставить более подробную информацию относительно того, что конкретный вопрос ,

+0

Благодарим вас за ответ. Я полностью понимаю, что вы здесь говорите. Однако делегирование - это один к одному. Поэтому, если я вытолкнул свой диспетчер view, List> Health> Activity> Settings, тогда верхний диспетчер представлений - Настройки сейчас.Так что в соответствии с вашим ответом в настоящее время диспетчер представлений параметров является делегатом. Но когда я возвращаюсь назад, я хочу, чтобы все пользовательские интерфейсы (Activity, Health and List) также обновлялись. Не могли бы вы объяснить, как справиться с этим? Если вам нужна еще подробная информация, пожалуйста, сообщите, что еще, я обновлю вопрос. –

+0

Теперь можно сказать, что я просто передаю модель вниз по иерархии из списка> Здравоохранение> Активность> Настройки, не пытаясь извлечь их в каждый контроллер представления. –

+0

Вам следует передать свой NSManagedObjectContext и, возможно, сущность или две, но не всю вашу модель вниз по вашей цепочке. Вероятно, вы хотите, чтобы каждый контроллер представления имел свой собственный NSFetchedResultsController, который просто управляет частями, на которые смотрит определенный контроллер. У вас может быть даже более одного в каждом контроллере представления, это нормально! – Gargoyle

2

Вы упомянули об изменении «ViewControllers», поэтому я предполагаю, когда вы нажимаете, как вы сказали в комментариях «Список> Здоровье> Деятельность> Настройки», каждый из которых - это классы UIViewController, не так ли? Если это так, реализуйте метод viewWillAppear в каждом из них и убедитесь, что вы выполняете всю инициализацию своего интерфейса. Поступая таким образом, вы гарантируете, что, когда поп произойдет, этот метод будет вызван, и ваш пользовательский интерфейс будет обновлен (b/c у вас есть логика в этом методе для обновления). Я использовал инициализацию UI в viewDidLoad, но имел ту же проблему, с которой вы сейчас сталкиваетесь. Перемещение его на viewWillAppear было решением в моей ситуации.

После этого, если вы все еще не видите правильные значения в пользовательском интерфейсе, установите точки останова в методе viewWillAppear и проверите данные, находящиеся в вашей модели. Возможно, модель неверна - в этом случае, возможно, вы выполняете запрос (поиск), чтобы вытащить то, что вам нужно снова. Этот не должен быть проблемой, если вы не используете контексты родителя/ребенка и не выполняете изменения дочернего контекста до родителя.

Но я чувствую, что это очень неуклюжие, обрабатывая множество уведомлений. Есть ли способ или какие-либо более эффективные методы существуют там, чтобы плотно соединить отдельные модели данных ядра с пользовательскими интерфейсами.

Честно говоря, я не думаю, что есть лучшая модель, поскольку вы не используете FRC для других видов. И если вы не используете представления таблиц для перезагрузки или получения новых данных, вам определенно не нужно использовать FRC (хотя я пока не буду говорить, что вы не должны, потому что я не могу твердо вернуться это вверх).

Я использую эту точную модель в своем приложении, которое имеет несколько разных видов, которые получают уведомление через наблюдателей - так же, как и вы. Если это не работает, есть еще один вариант рассмотрения.

+0

Я запускаю настройку пользовательского интерфейса в viewWillAppear, но вопрос в том, как это сделать, когда вы находитесь в контроллере верхнего уровня (не на основе табличного представления), а свойства базового объекта данных часто обновляются в фоновом режиме. Вы видите суть. Вам нужно знать, как быть уведомленным, чтобы вызвать обновление. –

+0

@Rameswar, в этом случае ваша модель уведомлений _should_ будет работать. Можете ли вы подтвердить, что каждый вид подписан (загружен) получает уведомление (ы)? И когда вы получаете эти уведомления, что делает метод, получающий уведомление? – thephatp

2

Извините, у меня недостаточно репутации, чтобы добавить комментарий.

Я присоединяюсь к другим пользователям, предлагающим использовать FRC. Я не могу помочь вам в блоге/учебнике, но CoreStore ObjectMonitor - очень хороший пример того, что он может использоваться в другом (не табличном виде) контексте. Я уверен, что для вас это не проблема.

+0

Спасибо за ссылку, это выглядит многообещающе. Я просто просмотрел его, нужно поиграть некоторое время, чтобы понять реализацию. –

1

Прежде всего, я понимаю вашу озабоченность по поводу использования одного шаблона для этого. (Только для протокола: это не шаблон «один-к-одному», потому что делегат может быть делегатом многих делегирующих классов. В действительности это происходит.)

Образцы во многих случаях действительно являются уведомлениями: вещания. Но я не понимаю, почему у вас есть много уведомлений? Просто прослушайте контекст NSManagedObjectContextDidSaveNotification, который предоставит вам список измененных объектов. Контроллеру подробного представления должно быть легко подобрать отображаемый объект.

Я вас неправильно понял?

+0

И я верю в этот случай, если контроллер просмотра может выбрать объект, который он отображает, это нужно сделать, используя «objectID», который, я считаю, не изменен в течение жизненного цикла контекста управляемого объекта. Это так? –

+0

Он неизменен после первого сохранения (постоянный идентификатор). Это связано с тем, что в нем содержится первичный ключ для rDBMS, который не задан при создании. (CD создаст проблемы в противном случае, если вы создадите массу промежуточных объектов.) Но это не должно быть проблемой, потому что вы должны сохранять новые объекты сразу после создания и, следовательно, перед его первым отображением. Таким образом, ваш VC видит только постоянный идентификатор. Для CD одинаковые объекты идентичны и, конечно же, наоборот. '-isEqual:' сравнивает идентификатор объекта. –

2

Итак, у вас уже есть решение вашей проблемы с использованием уведомлений. Ничего особенного в этом нет. Его можно было бы улучшить, наблюдая только те идентификаторы, которые вы заинтересованы в VC, чтобы предотвратить обработку нескольких VC и проверку того, относится ли к ним уведомление. Это исправное решение.

FRC прост в использовании с таблицей/сеткой, но это не все, для чего это полезно, потому что оно предлагает конкретное наблюдение за контекстом. На самом высоком уровне это означает ответ только на обратный вызов делегатадля обновления пользовательского интерфейса. Это, как правило, лучше, чем ваше уведомление, потому что оно специфично, хотя оно немного дороже с точки зрения потребления памяти (это настолько незначительно, что не имеет значения).

Если ваши детали VC отображают несколько фрагментов информации, возможно, вы не можете использовать представление таблицы/коллекции, но по-прежнему существует макет стиля списка/сетки, а пути индекса FRC могут означать что-то, что связано с этим.

Альтернативный вариант, который не обсуждался, это KVO, который поддерживается всеми управляемыми объектами. Это наиболее подходящее решение для вас, потому что вам передают объект, и в результате вам не нужно делать более высокий уровень/контекстное наблюдение. Непосредственно работать с KVO иногда немного больно, поэтому вы хотите использовать некоторую вспомогательную библиотеку, например this one, поэтому вы можете использовать блоки для работы с специально обновленными элементами.

Использование KVO дает вам привязку данных, поэтому обновление базовых данных модели напрямую отражается на вашем пользовательском интерфейсе в результате подробного обратного вызова наблюдения.

+0

Обратите внимание, что если вы используете FRC, тогда да, каждый VC будет иметь свой собственный FRC – Wain