具有多对多关系的 SwiftData 谓词

问题描述 投票:0回答:1

我正在构建一个照片管理应用程序,它使用标签来帮助过滤图像。我决定使用 SwiftData,因为它使通过 CloudKit 同步图像变得非常容易。但是,我无法根据照片的标签获取照片。我的模型看起来像这样:

@Model
final class Photo {
    var id: String? = ""

    @Attribute(.externalStorage) var imageData: Data?
    @Attribute(.externalStorage) var thumbnailData: Data?
    var width: CGFloat?
    var height: CGFloat?
    var scale: CGFloat?

    @Relationship(inverse: \Tag.photos)
    var tags: [Tag]?

    init(parent: Folder?, title: String?) {
        id = UUID().uuidString
    }
}
@Model
final class Tag {
    var id: UUID?
    var title: String?
    var lastUsed: Date?
    var photos: [Photo]?

    init(title: String) {
        id = UUID()
        self.title = title
        lastUsed = Date()
    }
}

当我尝试编写谓词来获取基于标签的图像时,我遇到了多个问题,这些问题要么导致编译时错误,要么导致运行时崩溃。这是我尝试过的一些事情:

// Compile time error: Cannot convert value of type ... to closure result type 'any StandardPredicateExpression<Bool>'
return #Predicate<Photo> { photo in
    photo?.contains(tags) == true
}

// Crashes with error: error: SQLCore dispatchRequest: exception handling request: <NSSQLFetchRequestContext: 0x6000013e4540> , to-many key not allowed here with userInfo 
#Predicate<Photo> { photo in
    photo?.contains {
        $0.title == "some tag"
    } == true
}

// Crashes with error: error: SQLCore dispatchRequest: exception handling request: <NSSQLFetchRequestContext: 0x6000013e4540> , to-many key not allowed here with userInfo of (null)
#Predicate<Photo> { photo in
    photo.tags.flatMap {
        $0.contains {
            $0.title == "some tag"
        }
    } == true
}

我似乎在这里遇到了几个问题:

  1. Predicate 似乎不喜欢可选值。由于我使用的是 CloudKit,因此这些关系必须是可选的。我也尝试过强制展开,但它只会导致相同的错误
  2. Predicate 似乎不喜欢多对多关系。我不知道还能如何解决这个问题,因为我也想要一种简单的方法来获取唯一标签以及每个标签的照片数量。

我现在想知道这是否是 SwiftData 的硬限制,或者我是否只是缺少一些可以让它工作的东西。

swift cloudkit predicate swift-data
1个回答
0
投票

SwiftData 谓词似乎不喜欢在其主体中的多对多和一对多关系属性上使用选项。我遇到了同样的问题,并通过某种解决方法得到了答案。请点击此链接:https://developer.apple.com/forums/thread/743243

© www.soinside.com 2019 - 2024. All rights reserved.