#ios #swift #core-data #nsfetchrequest
#iOS #swift #core-data #nsfetchrequest
Вопрос:
У меня есть таблица базы данных с именем UVHour, которая имеет следующую структуру
Мое приложение заполнит таблицу UVHour из JSON, которая выглядит следующим образом
[
{
"ORDER": 1,
"DATE_TIME": "SEP/04/2020 04 AM",
"UV_VALUE": 0
},
{
"ORDER": 2,
"DATE_TIME": "SEP/04/2020 05 AM",
"UV_VALUE": 0
}
]
Текущий запрос NSFetchRequest
static var uvIndexNowRequest: NSFetchRequest<UVHour>
{
let dateTimeNow = Date()
let formatter = DateFormatter()
formatter.dateFormat = "MMM/d/yyyy hh a"
let dateHourStr = formatter.string(from: dateTimeNow)
let request: NSFetchRequest = UVHour.fetchRequest()
request.sortDescriptors = [NSSortDescriptor(key: "order", ascending: true)]
// Below code will throw 'NSInvalidArgumentException', reason: 'Unable to parse the format string "date_time == Sep/4/2020 08 PM"
// request.predicate = NSPredicate(format: "date_time == (dateHourStr)")
return request
}
Вопрос
Как я могу написать предикат, который будет извлекать UVHour с текущей датой и временем, соответствующими текущему часу?
Пример
Допустим, что текущая дата — 4 сентября 2020 года, 04:10 утра.
Основываясь на приведенном выше JSON, я бы выбрал UVHour, который является следующим
[
{
"ORDER": 1,
"DATE_TIME": "SEP/04/2020 04 AM",
"UV_VALUE": 0
}
]
Как я могу это сделать?
Ответ №1:
Я смог обновить uvIndexNowRequest, чтобы найти свое решение. Смотрите приведенный ниже код
static var uvIndexNowRequest: NSFetchRequest<UVHour>
{
let dateTimeNow = Date()
let formatter = DateFormatter()
formatter.timeZone = .current
formatter.dateFormat = "MMM/d/yyyy hh a"
// Find date String from 'formatter.dateFormat'
let dateHourStr = formatter.string(from: dateTimeNow)
// Get date from dateHourStr
let someDateTimeOpt = formatter.date(from: dateHourStr)
let request: NSFetchRequest = UVHour.fetchRequest()
request.sortDescriptors = [NSSortDescriptor(key: "order", ascending: true)]
if let someDate = someDateTimeOpt {
request.predicate = NSPredicate(format: "date_time == %@", someDate as CVarArg)
}
return request
}
Ответ №2:
Более короткой альтернативой является расширение NSDate
(!) для получения часа. Преимущество в том, что вы можете использовать вычисляемое свойство в качестве ключевого пути.
extension NSDate {
dynamic var isInCurrentHour : Bool {
return Calendar.current.isDate(self as Date, equalTo: Date(), toGranularity: .hour)
}
}
static var uvIndexNowRequest: NSFetchRequest<UVHour>
{
let request: NSFetchRequest = UVHour.fetchRequest()
request.sortDescriptors = [NSSortDescriptor(key: "order", ascending: true)]
request.predicate = NSPredicate(format: "date_time.isInCurrentHour == TRUE")
return request
}
Комментарии:
1. Я добавил ваш код, но получил исключение NSUnknownKeyException с ошибкой ..»этот класс не соответствует кодированию значения ключа для ключевого часа» Я думаю, что это как-то связано с вашим
NSPredicat(format:"date_time.hour== %ld", currentHour)
2. Пожалуйста, попробуйте это с
dynamic
3.
dynamic
делает свойство совместимым с кодированием ключевого значения4. Спасибо, чувак. Я понятия не имел, что смогу сделать это таким образом!
5. Хотел сообщить вам обновление. То, как вы запрашиваете core data, больше не выдает мне ошибок, но когда я запускаю fetchRequest, я больше не извлекаю правильные данные. Я изучу это подробнее и дам вам обновление.