Разрешение конфликтов версии документа
В мире iCloud, когда пользователь установил основанное на документе приложение на многократных устройствах или настольных системах, могут быть конфликты между различными версиями того же документа. Вспомните, что обновления приложения файл документа в локальном контейнерном каталоге и тех изменениях тогда передается — обычно сразу — к iCloud. Но что, если эта передача не непосредственна? Например, Вы редактируете документ с помощью версии Mac OS X приложения, но Вы также отредактировали тот же документ с помощью версии iPad приложения — и Вы сделали так, в то время как устройство было в Авиарежиме. Когда Вы выключаете Авиарежим, локальное изменение в документе передается iCloud. iCloud замечает конфликт и уведомляет приложение.
Приобретение знаний о конфликтах версии документа
Как Контролирующий Изменения состояния документа и Ошибки из-за неправильного обращения описывает, Ваше приложение узнает конфликты версии документа путем наблюдения UIDocumentStateChangedNotification
уведомление. Если documentState
свойство изменяется на UIDocumentStateInConflict
, существуют многократные версии того же документа. Приложение ответственно за разрешение тех конфликтов как можно скорее, с или без справки пользователя.
Вы узнаете о конфликтных версиях документа через два метода класса NSFileVersion
класс. currentVersionOfItemAtURL:
метод возвращается NSFileVersion
представление объекта, что упоминается как текущий файл; текущий файл выбран iCloud на некоторой основе как текущий “победитель конфликта” и является тем же через все устройства. Путем вызова unresolvedConflictVersionsOfItemAtURL:
метод, Вы получаете массив NSFileVersion
объекты; эти объекты вызывают версиями конфликта, и каждый представляет неразрешенный конфликт версий для файла, расположенного в указанном URL. NSFileVersion
объекты могут дать Вам информацию, полезную в разрешении конфликтов, таких как даты модификации, локализованные названия документа и локализованные имена сохранения компьютеров.
Стратегии разрешения конфликтов версии документа
Ваше приложение может следовать одной из трех стратегий разрешения конфликтов версии документа:
Объедините изменения от конфликтных версий.
Выберите одну из версий документа на основе некоторого подходящего фактора, таких как версия с последней датой модификации.
Позвольте пользователю просмотреть конфликтные версии документа и выбрать тот для использования.
То, которое стратегия является лучшей для использования, зависит много от данных документа. Если можно объединить содержание различных версий документа, не представляя противоречащие элементы, затем следовать той стратегии. Или выберите версию документа с последней датой модификации, если Ваше приложение не несет потери данных в результате.
Обычно необходимо попытаться разрешить конфликт, не вовлекая пользователя, но для некоторых приложений, которые не могли бы быть возможными. Если приложение проявляет ориентированный на пользователя подход, оно должно осторожно сообщить пользователю о конфликте версий и представить кнопку или другое управление, инициирующее процедуру разрешения. Пример: Разрешение Пользовательскому Выбору, Версия исследует код приложения, позволяющего пользователю выбрать версию документа для использования.
Как Сказать iOS, Что Разрешен Конфликт Версии документа
Когда Ваше приложение или его пользователи разрешают конфликт версии документа путем выбора версии документа, приложение должно завершить следующие шаги:
Если выбранная версия является версией конфликта, замените файл текущего документа файлом документа версии конфликта.
К к этому, вызовите
replaceItemAtURL:options:error:
метод наNSFileVersion
объект, представляющий версию, передающую в текущем файле документа URL.Если выбранная версия является версией конфликта, вернитесь документ так, чтобы это вывело на экран новые данные в файле документа
Чтобы сделать это, вызовите
UIDocument
методrevertToContentsOfURL:completionHandler:
на объекте документа, передающем в текущем файле документа URL.Разъедините все версии конфликта с файлом документа URL.
Чтобы сделать это, вызовите
NSFileVersion
метод классаremoveOtherVersionsOfItemAtURL:error:
, передача в файле документа URL.Отметьте каждую версию конфликта, как разрешено так, чтобы iOS не повышал ее снова как конфликтную версию.
Чтобы сделать это, установите
resolved
свойство каждогоNSFileVersion
объект, представляющий версию конфликтаYES
. Этот шаг должен всегда выполняться в последний раз.Удалите разрешенные версии документа.
Для любых версий Вы больше не нуждаетесь, вызываете
removeAndReturnError:
методNSFileVersion
предъявлять претензии в отношении хранения для файла. Версии документа остаются на сервере, пока Вы не удаляете их.
Пример: разрешение пользовательскому выбору версия
Наше демонстрационное основанное на документе приложение является простым текстовым редактором. Для такого приложения было бы трудно определить местоположение и объединить текстовые различия в конфликтных версиях документа, и даже если бы это сделало, то итоговый документ не мог бы быть тем, что хочет пользователь. Приложение могло выбрать версию документа с новой датой модификации, но с другой стороны нет никакого способа быть уверенным, что это - версия, которую хочет пользователь. Хорошая стратегия разрешения конфликтов в этом случае должна позволить пользователю, который является самым знакомым с содержанием документа, выберите версию, которую она или он хочет.
Вы могли бы вспомнить код, показанный в Перечислении 6-1 от Контроля Изменений состояния документа и Ошибок из-за неправильного обращения. Этот код показывает метод контроллера представления документа, обрабатывающего UIDocumentStateChangedNotification
уведомление, отправленное UIDocument
когда существует изменение в состоянии документа. Если новое состояние документа UIDocumentStateInConflict
, контроллер представления показывает кнопку Resolve Conflicts в пользовательском представлении состояния. (Это также выбирает цвет индикатора состояния к красному.)
Перечисление 6-1 , Обнаруживающее конфликт в версиях документа
-(void)documentStateChanged { |
UIDocumentState state = _document.documentState; |
[_statusView setDocumentState:state]; |
if (state & UIDocumentStateEditingDisabled) { |
[_textView resignFirstResponder]; |
} |
if (state & UIDocumentStateInConflict) { |
[self showConflictButton]; // <------ Shows "Resolve Conflicts" button |
} |
else { |
[self hideConflictButton]; |
[self dismissModalViewControllerAnimated:YES]; |
} |
} |
Когда пользователь касается кнопки, UIKit вызывает метод в Перечислении 6-2. Этот метод выводит на экран модально представление пользовательского контроллера представления механизма разрешения конфликтов.
Перечисление 6-2 , Показывающее пользовательский интерфейс для разрешения конфликтов версии документа
-(void)conflictButtonPushed |
{ |
ConflictResolverViewController* conflictResolver = [[ConflictResolverViewController alloc] |
initWithURL:_document.fileURL delegate:self]; |
[self presentViewController:conflictResolver animated:YES completion:nil]; |
[conflictResolver release]; |
} |
ConflictResolverViewController
объект создает контроллер просмотра (UIPageViewController
объект), который позволяет пользователю странице между и исследует, документ текущего файла и каждый документ версии конфликта. На панели инструментов каждого документа представление является кнопкой Select Version. Если пользователь касается той кнопки, один из двух пользовательских методов делегации, показанных в Перечислении 6-3, вызывают, в зависимости от того, является ли выбранный документ документом текущего файла или документом версии конфликта.
Перечисление 6-3 , Разрешающее конфликт версии документа
-(void)conflictResolver:(ConflictResolverViewController *)conflictResolver |
didResolveWithFileVersion:(NSFileVersion *)fileVersion { |
[self dismissViewControllerAnimated:YES completion:nil]; |
[fileVersion replaceItemAtURL:_document.fileURL options:0 error:nil]; |
[NSFileVersion removeOtherVersionsOfItemAtURL:_document.fileURL error:nil]; |
[_document revertToContentsOfURL:_document.fileURL completionHandler:nil]; |
NSArray* conflictVersions = [NSFileVersion unresolvedConflictVersionsOfItemAtURL:_document.fileURL]; |
for (NSFileVersion* fileVersion in conflictVersions) { |
fileVersion.resolved = YES; |
} |
} |
-(void)conflictResolverDidResolveWithCurrentVersion:(ConflictResolverViewController*)conflictResolver { |
[self dismissViewControllerAnimated:YES completion:nil]; |
[NSFileVersion removeOtherVersionsOfItemAtURL:_document.fileURL error:nil]; |
NSArray* conflictVersions = [NSFileVersion unresolvedConflictVersionsOfItemAtURL:_document.fileURL]; |
for (NSFileVersion* fileVersion in conflictVersions) { |
fileVersion.resolved = YES; |
} |
} |
Эти методы иллюстрируют шаги, описанные в том, Как Сказать iOS, Что Разрешен Конфликт Версии документа. Если выбранный документ является версией конфликта, вызовами делегата replaceItemAtURL:options:error:
на переданном - в NSFileVersion
возразите для замены файла документа в каталоге контейнера iCloud с выбранным документом. Делегат тогда перечисляет массив, содержащий NSFileVersion
объекты, представляющие все версии конфликта документа и наборов resolved
свойство каждого объекта к YES
. Это тогда спрашивает NSFileVersion
удалить все другие версии конфликта документа связало с файлом документа URL и вызовы revertToContentsOfURL:completionHandler:
вернуться выведенный на экран документ новому содержанию файла документа.
Второй метод делегации, вызванный, когда файл текущего документа выбран, намного более прост. Это устанавливает resolved
свойство всех NSFileVersion
объекты, представляющие версии конфликта YES
и удаляет все версии конфликта, связанные с файлом документа URL.