英文:
RealmSwift query API gives Query<Date> instead of Date
问题
我正在使用RealmSwift来查询特定日期的预约,所以方法看起来像这样:
func appointments(on date: Date) -> [Appointment] {
realm.objects(Appointment.self)
.filter("date == %@", date)
.map { $0 }
}
但是有两个问题:
- 无法将类型为'Query
'的值转换为预期的参数类型'Date'。看起来Realm对象的date属性是一个 Query<Date>而不是Date,我该如何从中获取实际的日期? - 无法将类型为'Bool'的值转换为闭包结果类型'Query
'。所以Realm期望一个 Query<Bool>而不是Bool,这与我在Realm的网站上关于查询API的阅读不符:https://www.mongodb.com/developer/products/realm/realm-swift-query-api/
可能出了什么问题?
谢谢!
英文:
I'm using RealmSwift to query for appointments on a specific day, so the method looks like:
func appointments(on date: Date) -> [Appointment] {
realm.objects(Appointment.self)
.where {
Calendar.current.isDate($0.date, inSameDayAs: date)
}
.map { $0 }
}
But there are two issues:
- Cannot convert value of type 'Query<Date>' to expected argument type 'Date'. Looks like the date property from Realm object is a
Query<Date>instead ofDate, how do I get the actual date from it? - Cannot convert value of type 'Bool' to closure result type 'Query<Bool>'. So realm expects a
Query<Bool>instead ofBool, which isn't what I read on Realm's website regarding the query API: https://www.mongodb.com/developer/products/realm/realm-swift-query-api/
What could possibly be wrong?
Thanks!
答案1
得分: 1
Realm查询仅支持在普通Swift中可以执行的操作的子集。请参阅此链接以获取其支持的操作列表。这是通过使用Query<T>类型来实施的-它仅声明了Realm支持的操作,如比较运算符、布尔运算、集合中的in等。你不能像普通的T一样传递Query<T>。
确定一个日期是否与另一个日期在同一天不是受支持的操作之一。你可以做的是找到date的开始和结束,并使用比较运算符来检查对象的date是否在它们之间。
let calendar = Calendar.current
let start = calendar.startOfDay(for: date)
let end = calendar.date(byAdding: DateComponents(day: 1), to: start)
.where { $0.date >= start && $0.date < end }
英文:
Realm queries only supports a subset of operations you can do in normal Swift. See this for a list of things it supports. This is enforced by using the Query<T> type - it only declares the Realm-supported operations, like comparison operators, boolean operations, in for collections, etc. You can't pass a Query<T> around, as if it were a normal T.
Determining whether a date is in the same day as another date is not one of the supported operations. What you can do instead is find the beginning and end of date, and use comparison operators to check if the object's date is between them.
let calendar = Calendar.current
let start = calendar.startOfDay(for: date)
let end = calendar.date(byAdding: DateComponents(day: 1), to: start)
.where { $0.date >= start && $.date < end }
答案2
得分: 0
有一个很好的答案来自@sweeper。另一个选项是将日期也作为字符串存储为另一个对象属性。
因此,Realm对象将如下所示:
class ApptClass: Object {
@Persisted var timestamp: Date!
@Persisted var dateString = ""
convenience init(withDate: Date) {
self.init()
self.timestamp = withDate
// 将日期转换为YYYY-MM-DD格式的字符串
self.dateString = convertDateToDateString(d: withDate) // 需要创建这个函数
}
}
然后,您可以直接查询特定日期:
let results = realm.objects(ApptClass.self).filter("dateString == %@", "2023-08-09")
编辑:根据@JoakimDanielson的注释:
如果日期发生变化,您还需要确保更新此属性
可以通过使用一个由timeStamp和dateString变量支持的非托管计算属性来实现。类似于以下伪代码:
class ApptClass: Object {
@Persisted var timestamp: Date!
@Persisted var dateString = ""
var useThisToSetTheDate: Date {
set {
设置timeStamp和dateString
}
get {
return timestamp
}
}
}
以上是要翻译的内容。
英文:
There's an excellent answer by @sweeper. Another option is store the date also as a string as another object property.
So the Realm object would look like this
class ApptClass: Object {
@Persisted var timestamp: Date!
@Persisted var dateString = ""
convenience init(withDate: Date) {
self.init()
self.timeStamp = withDate
//get the date as a YYYY-MM-DD formatted string
self.dateString = convertDateToDateString(d: withDate) //need to create this func
}
from there you can then do direct queries for specific dates
let results = realm.objects(ApptClass.self).where { $0.dateString == "2023-08-09" }
Edit: Per a note from @JoakimDanielson
> And you also need to make sure you update this property if the date
> changes
which, and one option, could be accomplished by using an unmanaged computed var that's backed by the timeStamp an dateString var. Something like this pseudo code
class ApptClass: Object {
@Persisted var timestamp: Date!
@Persisted var dateString = ""
var useThisToSetTheDate: Date {
set {
set the timeStamp and the dateString
}
get {
return timestamp
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论