英文:
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
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论