You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为同一SwiftData模型创建两个独立存储?

在SwiftData中为同一模型创建独立存储的方案

核心思路

SwiftData支持为同一模型类创建多个独立的ModelContainer,每个容器对应单独的存储文件,以此实现数据的隔离。你可以通过配置不同的ModelConfiguration(指定名称或存储路径)来区分不同的存储容器。

步骤1:更新模型(可选但推荐)

为了实现“最近查看10条”的需求,需要给模型添加时间属性用于排序:

@Model
class BasicTrainInfo {
    @Attribute(.unique) let number: String
    @Attribute(.unique) let technicalNumber: String
    @Attribute var createdAt: Date = Date() // 新增:记录数据添加时间
    
    init(number: String, technicalNumber: String) {
        self.number = number
        self.technicalNumber = technicalNumber
    }
}

步骤2:创建两个独立的ModelContainer

通过指定ModelConfiguration的name参数,让SwiftData自动生成独立的存储文件:

// 收藏列车的容器
let favoriteTrainContainer: ModelContainer = {
    let schema = Schema([BasicTrainInfo.self])
    let config = ModelConfiguration(name: "FavoriteTrains", schema: schema)
    do {
        return try ModelContainer(for: schema, configurations: config)
    } catch {
        fatalError("初始化收藏容器失败:\(error)")
    }
}()

// 最近查看列车的容器
let recentTrainContainer: ModelContainer = {
    let schema = Schema([BasicTrainInfo.self])
    let config = ModelConfiguration(name: "RecentTrains", schema: schema)
    do {
        return try ModelContainer(for: schema, configurations: config)
    } catch {
        fatalError("初始化最近查看容器失败:\(error)")
    }
}()

步骤3:在视图中使用对应容器的数据

方式1:环境注入ModelContext

在父视图中为不同子视图注入对应容器的ModelContext,子视图的@Query会自动使用该上下文查询数据:

struct MainView: View {
    var body: some View {
        TabView {
            FavoriteTrainsListView()
                .environment(\.modelContext, favoriteTrainContainer.mainContext)
                .tabItem {
                    Label("收藏", systemImage: "star.fill")
                }
            
            RecentTrainsListView()
                .environment(\.modelContext, recentTrainContainer.mainContext)
                .tabItem {
                    Label("最近查看", systemImage: "clock.fill")
                }
        }
    }
}

// 收藏列车列表
struct FavoriteTrainsListView: View {
    @Query private var favoriteTrains: [BasicTrainInfo]
    
    var body: some View {
        List(favoriteTrains) { train in
            Text(train.number)
        }
    }
}

// 最近查看列车列表(限制显示10条,按时间倒序)
struct RecentTrainsListView: View {
    @Query(sort: \.createdAt, order: .reverse, limit: 10) private var recentTrains: [BasicTrainInfo]
    
    var body: some View {
        List(recentTrains) { train in
            Text(train.number)
        }
    }
}

方式2:直接在@Query中指定容器

如果不想依赖环境注入,可以在初始化@Query时直接指定对应的容器:

struct FavoriteTrainsListView: View {
    @Query private var favoriteTrains: [BasicTrainInfo]
    
    init() {
        _favoriteTrains = Query(model: BasicTrainInfo.self, container: favoriteTrainContainer)
    }
    
    var body: some View {
        List(favoriteTrains) { train in
            Text(train.number)
        }
    }
}

步骤4:操作对应存储的数据

添加或删除数据时,使用对应容器的ModelContext:

// 添加到收藏
func addToFavorites(train: BasicTrainInfo) {
    let context = favoriteTrainContainer.mainContext
    context.insert(train)
    try? context.save()
}

// 添加到最近查看(避免重复)
func addToRecent(train: BasicTrainInfo) {
    let context = recentTrainContainer.mainContext
    let existing = try? context.fetch(FetchDescriptor<BasicTrainInfo>(predicate: #Predicate { $0.number == train.number })).first
    if existing == nil {
        context.insert(train)
        try? context.save()
    }
}

内容的提问来源于stack exchange,提问作者José María

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 22:15:14