Realm – удаление и добавление объектов из списка

Это продолжение этого вопроса, поскольку я могу делать что-то неправильно.

У меня есть видеопроигрыватель в моем приложении. В виде коллекции под названием FavoritesVC есть список видео. Если вы нажмете на одну из ячеек, появится новый контроллер вида PlayerVC , который воспроизводит выбранное видео. Кроме того, вы можете просматривать все видео из коллекции в этом новом контроллере PlayerVC потому что весь список передан.

Здесь все отлично.

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

Добавьте свойство isDeleted в класс Video. Когда пользователь отключил видео, удалите объект Video из FavoriteList.videos, установите для этого свойства значение true, но оставьте его в Realm. Позже (либо когда приложение закрывается, либо диспетчер представлений отклоняется), вы можете затем выполнить общий запрос для всех объектов, где isDeleted является истинным, и затем удалить их (это решает проблему без головы).

Я могу заставить это работать только в том случае, если в FavoritesVC когда ячейка прослушивается, я конвертирую List PlayerVC array Swift и использую этот array для включения PlayerVC . Если я этого не сделаю, и я удаляю объект из List и я пытаюсь перебирать List , я получаю Index out of range error...

Решение, которое я должен преобразовать List в array Swift и передать его в PlayerVC но кажется неправильным при использовании Realm. Лучшая практика – никогда не делать это преобразование, но в этом случае я не знаю, как просто использовать List

Это мой код для списка:

 /// Model class that manages the ordering of `Video` objects. final class FavoriteList: Object { // MARK: - Properties /// `objectId` is set to a static value so that only /// one `FavoriteList` object could be saved into Realm. dynamic var objectId = 0 let videos = List<Video>() // MARK: - Realm Meta Information override class func primaryKey() -> String? { return "objectId" } } 

Я конвертирую List в массив и создаю PlayerVC следующим образом:

 class FavoritesViewController: UIViewController { func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { if let playerVC = self.storyboard?.instantiateViewController(withIdentifier: "playerVC") as? PlayerViewController { // I convert the `List` to a Swift `array` here. playerVC.videos = Array(favoritesManager.favoriteList.videos) playerVC.currentVideoIndex = indexPath.row self.parent?.present(playerVC, animated: true, completion: nil) } } } 

Это фрагмент PlayerVC . Это создается, когда используется ячейка в FavoritesVC :

 class PlayerViewControllerr: UIViewController { // Array passed from `FavoritesVC`. I converted this from the `List`. var videos = [Video]() var currentVideoIndex: Int! var currentVideo: Video { return videos[currentVideoIndex] } // HELP // Example of how to cycle through videos. This cause crash if I use the `List` instead of Swift `array`. func playNextVideo() { if (currentVideoIndex + 1) >= videos.count { currentVideoIndex = 0 } else { currentVideoIndex = currentVideoIndex + 1 } videoPlaybackManager.video = currentVideo } // This is where I add and remove videos from the `List` @IBAction func didToggleFavoriteButton(_ sender: UIButton) { favoritesManager.handleFavoriting(currentVideo, from: location) { [weak self] error in if let error = error { self?.present(UIAlertController.handleErrorWithMessage(error.localizedDescription, error: error), animated: true, completion: nil) } } } } 

Наконец, код для добавления и удаления объекта из List :

 class FavoritesManager { let favoriteList: FavoriteList init(favoriteList: FavoriteList) { self.favoriteList = favoriteList } /// Adds or removes a `Video` from the `FavoriteList`. private func handleAddingAndRemovingVideoFromFavoriteList(_ video: Video) { if isFavorite(video) { removeVideoFromFavoriteList(video) } else { addVideoToFavoriteList(video) } } /// Adds a `Video` to the `FavoriteList`. /// /// Modifies `Video` `isDeleted` property to false so no garbage collection is needed. private func addVideoToFavoriteList(_ video: Video) { let realm = try! Realm() try! realm.write { favoriteList.videos.append(video) video.isDeleted = false } } /// Removes a `Video` from the `FavoriteList`. /// /// Modifies `Video` `isDeleted` property to true so garbage collection is needed. /// Does not delete the `Video` from Realm or delete it's files. private func removeVideoFromFavoriteList(_ video: Video) { let predicate = NSPredicate(format: "objectId = %@", video.objectId) guard let index = favoriteList.videos.index(matching: predicate) else { return } let realm = try! Realm() try! realm.write { favoriteList.videos.remove(objectAtIndex: index) video.isDeleted = true } } } 

Есть предположения?

Это все еще трудно ответить кратко, так как я все еще не уверен, что вы хотите, когда пользователь «незаметен» видео.

Для лучшего удобства пользователей я бы предположил, что нежелательное видео по-прежнему позволяет воспроизводить его на экране, но после того, как диспетчер представлений отклонен или начнется следующее видео, видео было полностью удалено из объекта favoriteList . Это означает, что даже когда он удаляется из videos , объект Video необходимо придерживаться, пока пользователь явно не отклонит его.

Я предполагаю, почему преобразование videos в массив Swift работает, потому что даже если видео удалено из videos , его ссылка остается в массиве Swift, поэтому значение currentVideoIndex остается синхронным.

Должно быть возможно напрямую использовать объект videos , но поскольку вы мутируете его, когда пользователь нажимает кнопку «неприглядный», вы не можете надежно хранить «currentIndex», поскольку это, очевидно, изменится.

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

Контроллеру просмотра проигрывателя просто нужен менеджер избранного и текущее видео, которое пользователь прослушивал

 class FavoritesViewController: UIViewController { func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { if let playerVC = self.storyboard?.instantiateViewController(withIdentifier: "playerVC") as? PlayerViewController { playerVC.favoritesManager = favoritesManager playerVC.currentVideo = favoritesManager.favoritesList.videos[indexPath.row] self.parent?.present(playerVC, animated: true, completion: nil) } } } 

И игрок будет логически разрабатывать, какие видео в очереди, даже если они будут удалены из списка videos позже:

 class PlayerViewControllerr: UIViewController { var favoritesManager: FavoriteManager var currentVideo: Video? { didSet { setUpVideos() } } var nextVideo: Video? var previousVideo: Video? func playNextVideo() { currentVideo = nextVideo videoPlaybackManager.video = currentVideo } func playPreviousVideo() { currentVideo = previousVideo videoPlaybackManager.video = currentVideo } func setUpVideos() { let videos = favoritesManager.favoritesList.videos let index = videos.index(of: currentVideo) var previousIndex = index - 1 if previousIndex < 0 { previousIndex = videos.count - 1 } previousVideo = videos[previousIndex] var nextIndex = index + 1 if nextIndex >= videos.count { nextIndex = 0 } nextVideo = videos[nextIndex] } } 

Это работает в предположении, что пользователь «может» удалять currentVideo videos из videos , но пользователь не может удалить nextVideo или previousVideo videos , пока они не станут currentVideo . В любом случае, теперь, когда сам контроллер представления сильно ссылается на этот видеообъект, отдельно от индекса, мы надеемся сделать ненужным скопирование videos в массив Swift.

  • Ошибка: невозможно прочитать содержимое карты модуля из «Целевых файлов поддержки в iOS
  • Как встраивать UITableView в пользовательский вид
  • Кнопки для приложений для социальных сетей не работают - Swift
  • FirebaseUI: фатальная ошибка: неожиданно найден nil при развертывании необязательного значения Использование раскадровки и метки пользовательского интерфейса
  • Почему исключение поддержки Swift не поддерживается?
  • Как вызвать `setViewControllers: animated:` в Swift?
  • как запустить команду
  • Прокрутите до стола Просмотр Верх заголовка
  • Назначить одно перечисление Тип другому перечислению Тип
  • Проверьте, обладает ли UIView свойством
  • Горизонтальный scrollView не прокручивает
  • Давайте будем гением компьютера.