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

Swift中如何从Core Data的EntityDate实体获取指定属性

问题分析与解决方案

我一眼就看出问题出在哪了——你每次调用addToCoreData都会新建一个EntityDate实体对象,而不是在同一个对象里同时设置date和time属性。从你给出的输出就能看出来:

[<EntityDate: 0x6000034fc2d0> (entity: EntityDate; id: 0xc229f3dcff76efb1 x-coredata://2E6F1D46-F49D-436C-9608-FEC59EEB21E6/EntityDate/p18; data: { date = "2/21/20"; time = nil; }), <EntityDate: 0x6000034fc320> (entity: EntityDate; id: 0xc229f3dcff72efb1 x-coredata://2E6F1D46-F49D-436C-9608-FEC59EEB21E6/EntityDate/p19; data: { date = nil; time = "13:46"; })]

这两个EntityDate实例是完全独立的:第一个是你存date时创建的,第二个是存time时创建的,所以它们各自只有一个属性有值,另一个自然是nil。


修复方案:创建或更新同一实体对象

我们需要修改数据操作逻辑,让它可以找到已存在的实体并更新属性,而不是每次都新建对象。这里假设你希望date和time属于同一条记录(比如同一个日期对应一个时间),可以按以下步骤修改:

1. 优先使用Core Data生成的实体子类

首先建议你给EntityDate生成NSManagedObject子类(Xcode中选择实体 → Editor → Create NSManagedObject Subclass...),这样可以直接用属性访问(比如entity.date),比value(forKey:)更安全易读。

2. 编写「创建/更新」二合一的函数

替换你原来的addToCoreData,用这个函数来处理数据存储:

func addOrUpdateEntityDate(date: String?, time: String?) {
    let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
    
    // 假设用date作为查询条件,找对应的实体(可根据你的业务逻辑调整)
    let request: NSFetchRequest<EntityDate> = EntityDate.fetchRequest()
    if let targetDate = date {
        request.predicate = NSPredicate(format: "date == %@", targetDate)
    }
    
    do {
        let results = try context.fetch(request)
        let targetEntity: EntityDate
        
        if let existingEntity = results.first {
            // 找到已有实体,更新属性
            targetEntity = existingEntity
            targetEntity.date = date ?? targetEntity.date
            targetEntity.time = time ?? targetEntity.time
        } else {
            // 没有找到,创建新实体
            targetEntity = EntityDate(context: context)
            targetEntity.date = date
            targetEntity.time = time
        }
        
        try context.save()
        print("数据保存/更新成功")
    } catch {
        print("保存/更新失败: \(error.localizedDescription)")
    }
}

3. 正确调用函数存储数据

  • 第一次存日期时:
    addOrUpdateEntityDate(date: getDateFormatted(), time: nil)
    
  • 之后存对应时间时:
    addOrUpdateEntityDate(date: getDateFormatted(), time: getFormattedTime())
    

这样操作后,date和time就会存在同一个EntityDate实例里了。


正确提取数据

修改你的查询函数,直接返回EntityDate类型的数组(比NSManagedObject更直观):

func getEntityDates() -> [EntityDate] {
    let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
    let request: NSFetchRequest<EntityDate> = EntityDate.fetchRequest()
    request.returnsObjectsAsFaults = false
    
    do {
        return try context.fetch(request)
    } catch {
        print("查询失败: \(error.localizedDescription)")
        return []
    }
}

提取所有日期和时间

如果要分别获取所有非空的date和time,可以用compactMap过滤掉nil值:

let allEntityDates = getEntityDates()
let allDates = allEntityDates.compactMap { $0.date }
let allTimes = allEntityDates.compactMap { $0.time }

print("所有日期: \(allDates)")
print("所有时间: \(allTimes)")

提取单条记录的日期和时间

如果要获取某条记录的对应属性:

if let firstEntity = allEntityDates.first {
    if let date = firstEntity.date {
        print("日期: \(date)")
    }
    if let time = firstEntity.time {
        print("时间: \(time)")
    }
}

内容的提问来源于stack exchange,提问作者firozaqiwu

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 17:22:27