【问题标题】:Swift, CoreData and many-to-many-relationship: how to access order of subitems?Swift、CoreData 和多对多关系:如何访问子项的顺序?
【发布时间】:2021-01-30 20:05:36
【问题描述】:

我有以下关系:

播放列表可能包含一对多的歌曲,并且 歌曲可能属于一对多播放列表。

我的问题在于获取特定播放列表中歌曲的顺序 - 例如,

  • 在播放列表 1 中,顺序可能是 3,
  • 在播放列表 2 中,顺序可能为 1,
  • 在播放列表 3 中,顺序可能是 5,等等。

此外,播放列表中歌曲的顺序可以更改,因为它们在表格视图中列出。

我现在想跟踪订单。

我尝试了以下方法:

  1. 为 Song 实体创建一个新属性“PlaylistOrders” - 使用代表订单的 NSSet(播放列表的订单和 ManagedObjectId),
  2. 创建一个名为“PlaylistOrders”的新实体并将其连接到“Song”。此新实体还包含一个可转换的 objectId (ManagedObjectId)。

这两种方法似乎都非常容易出错 - 此外,我经常收到警告,例如“'NSKeyedUnarchiveFromData' 不应用于取消归档,将在未来的版本中删除”。

有没有更好、更复杂的方法在不同的播放列表中存储和检索歌曲的顺序?

【问题讨论】:

  • 一个播放列表可能包含许多歌曲 - 因此:在这种情况下,我应该在播放列表中存储多个订单,代表歌曲 1 ...歌曲 n - 对我来说,这没有意义。或者我拿一本字典——但正如我上面提到的,这会引起很多麻烦

标签: ios swift core-data nsmanagedobjectcontext nsmanagedobjectid


【解决方案1】:

在数据模型中Playlist 实体的songs 关系属性中,勾选“有序”复选框。届时,它们将以NSOrderedSet 的形式提供,而不是NSSet

【讨论】:

  • 好的,我确实在数据模型中检查了“ordered” - 但出现的问题是:歌曲是根据什么标准排序的?时间戳、ID、订单号——还是其他什么?我想明确设置顺序,即取决于表视图中的行。我有一个表格视图,我可以拖放到其中 - 除了(在编辑模式下),我将更改歌曲的顺序 - 所以 CoreData 必须在 snyc
  • 您通常如何使用NSArray?什么定义了元素的顺序?相同的答案适用于数据模型的有序关系中的顺序,即您将新歌曲添加到播放列表关系的顺序,或者您分配给关系的NSOrderedSet 中的顺序。
  • 好的,我可以为 Song 设置一个新属性,即“ordeInPlaylist”。在这种情况下,我将只代表一个播放列表 - 但是一首歌曲在多个播放列表中以不同的顺序表示这一事实呢?
  • 由于您提到歌曲可以与许多播放列表相关,因此尚不清楚该属性将应用于哪个播放列表。
  • 这就是我推荐你使用“有序”关系的原因。关系中歌曲的顺序信息不会存储在歌曲实体本身中,您可以将不同位置的同一首歌曲添加到不同的播放列表中。
【解决方案2】:

感谢 Eugene,它现在可以工作了 - 我的意思是使用 NSOrderedSet 的方法。

关于在 tableview 中重新排序歌曲项目的一个提示 - 以下代码 sn-p 显示了如何重新排列 NSOrderedSet 中的项目并将它们存储到 CoreData - 我们只需要一个 NSMutableOrderedSet:

func moveSongItemInPlaylist(playlist: Playlist, item: SongItem, fromOrder: Int, toOrder: Int) {
    
    let orderedSet = playlist.mutableOrderedSetValue(forKey: "songItems")
    
    let indices = IndexSet(integer: fromOrder)
    
    if (fromOrder > toOrder) {
        // we're moving up
        orderedSet.moveObjects(at: indices, to: toOrder)
    } else {
        // we're moving down
        orderedSet.moveObjects(at: indices, to: toOrder - indices.count)
    }
    
    do {
        try self.managedObjectContext.save()
    } catch {
        print(error)
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-08-10
    • 2014-09-05
    • 1970-01-01
    • 2012-11-09
    • 2011-06-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多