如何传递计算属性作为 CloudKit 同步的绑定?

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

我一直在试图弄清楚如何将我的计算属性作为绑定从 foreach 循环传递到另一个视图,但我似乎无法弄清楚。我正在为 foreach 循环使用计算属性 b/c 它用于搜索栏。

问题是当我删除应用程序并重新安装它并且我在 albumView 中时,它不会刷新/更新,因为 CloudKit 正在将数据同步回应用程序。

首先让我展示我的 swift 数据模型。

import SwiftUI
import SwiftData

@Model
class Album: Identifiable {
    var id: UUID = UUID()
    var isPublicAlbum: Bool = false
    var title: String = ""
    var timeStamp: Date = Date()
    
    @Relationship(deleteRule: .cascade, inverse: \Media.album) var media: [Media]?
    
    init(isPublicAlbum: Bool, title: String, timeStamp: Date = Date()) {
        self.isPublicAlbum = isPublicAlbum
        self.title = title
        self.timeStamp = timeStamp
    }
}

import SwiftUI
import SwiftData

@Model
class Media: Identifiable {
    var id: UUID = UUID()
    var albumID: UUID = UUID()
    @Attribute(.externalStorage) var asset: Data? = nil
    var isCover: Bool = false
    var contentType: String = ""
    var timeStamp: Date = Date()
    //var album: Album?
    
    @Relationship(deleteRule: .nullify) var album: Album?
    
    init(albumID: UUID = UUID(), asset: Data? = nil, isCover: Bool = false, contentType: String = "", timeStamp: Date = Date()) {
        self.albumID = albumID
        self.asset = asset
        self.isCover = isCover
        self.contentType = contentType
        self.timeStamp = timeStamp
    }
}

我将这样的上下文传递给所有子视图:

import SwiftData

class ModelContainerManager {
    static let shared = ModelContainerManager()
    let container: ModelContainer

    private init() {
        do {
            container = try ModelContainer(for: User.self, Album.self, Media.self)
        } catch {
            fatalError(error.localizedDescription)
        }
    }
}

ContentView(……)
    .modelContainer(ModelContainerManager.shared.container)

我希望能够将 albumID 作为绑定传递到 albumView,这样我就可以在 albumView 中使用

@Query
,希望我的 albumView 在与 Cloudkit 同步时能够实时更新。例如新的应用程序安装并且媒体正在下载。

这是相关代码。

struct MainView: View {
    @Environment(\.modelContext) private var dbContext
    @Environment(\.horizontalSizeClass) var horizontalSizeClass
    @Environment(\.colorScheme) var colorScheme
    @Query(filter: #Predicate<Album> { $0.isPublicAlbum == false }, sort: \Album.title, order: .forward) private var listAlbums: [Album]
    @State private var searchString: String = ""
    
    private var filteredAlbums: [Album] {
        if searchString.isEmpty {
            return listAlbums
        } else {
            return listAlbums.filter { album in
                album.title.localizedStandardContains(searchString)
            }
        }
    }

    //...

    var body: some View {
        VStack {
            CustomSearchBar(text: $searchString, placeholder: NSLocalizedString("Search Private Albums", comment: "This is a search bar to search for private albums"))
            //...
            ForEach(filteredAlbums) { album in
                VStack(spacing: 0) {
                    ZStack(alignment: .topTrailing) {
                        NavigationLink(destination: AlbumView(album: album)) {
                            //...
                        }
                    } 
                }
            }
            //...
        }
    }
}

无论我尝试了什么,我似乎都无法在没有编译器错误的情况下将专辑作为绑定传递,或者只是超时。我不想将其传递为

.constant(album)
b/c 我需要我的子视图实时更新,这是我的最终目标。

我目前在

let album: Album
中定义了
anlbumView
,并在 foreach 循环中使用
album.media
。关于如何实现这一目标有什么想法吗?

swiftui cloudkit swiftdata
1个回答
0
投票

绑定用于写访问,因此您不应该使用它,因为 ID 永远不应该更改。你只需要

let album: Album

因为Album是一个模型,当你使用的任何属性发生变化时,body都会被调用。

一般来说,为 View 提供整个对象是一个坏主意,相反,您应该只传递 View 需要的内容,通过计算变量进行转换。这样,无需丰富的模型类型就可以预览视图。例如,将标题和艺术家传递给某些 LargeInfoView。

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