william_0353 2024-07-24 21:32 采纳率: 33.3%
浏览 39
已结题

swiftui @query 报错

swiftUI 尝试构建一个笔记类的app,用户可以导入pdf,然后在pdf添加笔记,但是现在遇到一个编译报错如下:
== PREVIEW UPDATE ERROR:

SchemeBuildError: Failed to build the scheme “AIreader”

'Element' is not a member type of generic enum '[AIreader.ContentModel]?'

Emitting module for AIreader:
/var/folders/wb/hw9lz_yj2cl78nrb0tvfrh1w0000gn/T/swift-generated-sources/@__swiftmacro_8AIreader11ContentViewV12contentModel33_48E5B9AF3FB619EEEC334395AF9ABA5CLL5QueryfMp_.swift:1:66: error: 'Element' is not a member type of generic enum '[AIreader.ContentModel]?'
private (set) var _contentModel: SwiftData.Query<[ContentModel]?.Element, [ContentModel]?> = .init()
                                                 ~~~~~~~~~~~~~~~ ^
/Users/xx/Library/Mobile Documents/com~apple~CloudDocs/app_AiReader/AIreader/AIreader/Views/ContentView.swift:16:5: note: in expansion of macro 'Query' on property 'contentModel' here
    @Query private var contentModel: [ContentModel]?
    ^                  ~~~~~~~~~~~~
Swift.Optional:1:21: note: 'Optional' declared here
@frozen public enum Optional<Wrapped> : ExpressibleByNilLiteral {
                    ^

这是报错代码:


struct ContentView: View {
    let fileURL: URL
    let onClose: () -> Void
    
    @State private var isDrawing: Bool = false
    @State private var currentPage: Int = 0  // 当前页码
    @State private var currentNotes: [Note] = []
    @State private var currentCards: [Card] = []
    @State private var currentOutlines: [Outline] = []
    
    @Environment(\.modelContext) private var modelContext: ModelContext
    @Query private var contentModel: [ContentModel]?
    
    init(fileURL: URL, onClose: @escaping () -> Void) {
        self.fileURL = fileURL
        self.onClose = onClose
        
        print("contentview iunit")
        _contentModel = Query(filter: #Predicate<ContentModel> { $0.fileName == fileURL.lastPathComponent })
    }
    

报错位置在query这里:

img

model结构如下,供参考

@Model
final class ContentModel {
    @Attribute(.unique) var fileName: String
    var currentPage: Int?
    var outlineList: [Outline]?
    var noteList: [Note]?
    var cardList: [Card]?
    
    
    init(fileName: String,
         currentPage: Int? = nil,
         outlineList: [Outline]? = nil,
         noteList: [Note]? = nil,
         cardList: [Card]? = nil) {
        
        self.fileName = fileName
        self.currentPage = currentPage
        self.noteList = noteList
        self.outlineList = outlineList
        self.cardList = cardList
    }
    
}

  • 写回答

31条回答 默认 最新

  • 叫兽-郭老师 新星创作者: Java技术领域 2024-07-24 21:33
    关注
    获得1.00元问题酬金

    🕗晚上好,题主!目前:🟢[在线]
    📢参考通义千问、由郭老师整理提供!
    📣今日诗号:尽挹西江沧溟,步行云,青虹影深。扣舷独舒啸,肝胆冰雪,了无尘心。

    报错信息提示你在 @Query 中使用了 Element,但 [AIreader.ContentModel]? 泛型枚举类型没有 Element 成员。这是因为 @Query 返回的是一个 Query 对象,而不是直接返回结果数组。

    你需要修改代码,以便正确地使用 @QueryQuery 对象:

    struct ContentView: View {
        let fileURL: URL
        let onClose: () -> Void
    
        // ... other properties ...
    
        @Environment(\.modelContext) private var modelContext: ModelContext
        @Query private var contentModels: [ContentModel]
    
        init(fileURL: URL, onClose: @escaping () -> Void) {
            self.fileURL = fileURL
            self.onClose = onClose
            print("ContentView init")
            // 初始化 Query,过滤条件为文件名匹配
            _contentModels = Query(filter: #Predicate<ContentModel> { $0.fileName == fileURL.lastPathComponent })
        }
    
        var body: some View {
            // ... your view code ...
    
            // 使用 contentModels.results 访问查询结果
            List(contentModels.results, id: \.fileName) { contentModel in 
                // ... your view code for each contentModel ...
            }
    
            // ... your view code ...
        }
    }
    

    代码解释:

    1. 声明 @Query 属性:

      • @Query 属性名改为 contentModels,因为它表示可能有多个匹配的 ContentModel 对象。
      • @Query 属性的类型现在是 [ContentModel],而不是 [ContentModel]?,因为 @Query 已经处理了可选值。
    2. init 方法中初始化 Query:

      • 使用 _contentModels 来初始化 Query 属性。
      • 使用 #Predicate 设置过滤条件,查找文件名与 fileURL.lastPathComponent 匹配的 ContentModel
    3. body 中使用 contentModels.results:

      • Query 对象有一个 results 属性,它是一个数组,包含所有匹配查询条件的 ContentModel 对象。
      • 使用 List 视图遍历 contentModels.results,并为每个 contentModel 创建视图。

    其他建议:

    • 确保你的 ContentModel 模型类符合 SwiftData 的要求,例如使用 @Model 宏标记。
    • 使用 Xcode 的调试工具来检查 contentModels.results 是否包含预期的数据。

    通过以上修改,你应该能够解决 @Query 报错,并在 SwiftUI 视图中正确地使用查询结果。

    评论

报告相同问题?

问题事件

  • 系统已结题 8月1日
  • 创建了问题 7月24日