当前,我有两个不同的类,Alarm和AlarmMO,其中AlarmMO是NSManagedObject的子类。如果可能的话,我试图将两者合并为一个对象类,但遇到了一些麻烦。如何做到这一点的最佳方法?
这是我目前所拥有的,并且遇到各种错误:
class Alarm: NSManagedObject {
//MARK: Properties
@NSManaged var alarmTime: Double
@NSManaged var alarmNumber: Int
@NSManaged var startTimeInterval: Double
@NSManaged var endTimeInterval: Double
@NSManaged var note: String
@NSManaged var notificationUuids: [String]
@NSManaged var recurrenceIndex: Int
var recurrence: RecurrenceOptions = .today
let NUMBER_OF_ALLOWED_NOTIFICATIONS_CREATED_AT_ONE_TIME = 10
}
extension Alarm {
convenience init?(alarmNumber: Int, timeIntervals: TimeIntervals, note: String, recurrence: RecurrenceOptions) {
self.alarmNumber = alarmNumber
self.note = note
self.recurrence = recurrence
self.notificationUuids = [String]()
let date = Date()
let calendar = Calendar.current
let currentDateComponents = calendar.dateComponents([.year, .month, .day, .timeZone, .hour, .minute], from: date)
var dateComponents = DateComponents()
dateComponents.year = currentDateComponents.year
dateComponents.month = currentDateComponents.month
dateComponents.timeZone = currentDateComponents.timeZone
dateComponents.day = currentDateComponents.day
let startInterval = Alarm.convertToTimeDouble(hour: timeIntervals.hourStartInterval, minute: timeIntervals.minuteStartInterval)
let endInterval = Alarm.convertToTimeDouble(hour: timeIntervals.hourEndInterval, minute: timeIntervals.minuteEndInterval)
self.startTimeInterval = startInterval
self.endTimeInterval = endInterval
if endInterval < startInterval {
os_log("Error: Alarm time endInterval is before startInterval", log: OSLog.default, type: .info)
return nil
}
self.alarmTime = Double.random(in: startInterval ... endInterval)
let hour = Alarm.extractHourFromTimeDouble(alarmTimeDouble: self.alarmTime)
let minute = Alarm.extractMinuteFromTimeDouble(alarmTimeDouble: self.alarmTime)
os_log("Attempting to create alarm with time %d:%02d", log: OSLog.default, type: .info, hour, minute)
createNotifications(dateComponents: dateComponents)
}
public static func convertToTimeDouble(hour: Int, minute: Int) -> Double {
return Double(hour) + (Double(minute) / 60.0)
}
public static func extractHourFromTimeDouble(alarmTimeDouble: Double) -> Int {
return Int(floor(alarmTimeDouble))
}
public static func extractMinuteFromTimeDouble(alarmTimeDouble: Double) -> Int {
return Int(round((alarmTimeDouble - floor(alarmTimeDouble)) * 60))
}
func createNotifications(dateComponents: DateComponents) {
switch (self.recurrence) {
case .today:
self.createNotification(for: dateComponents)
case .tomorrow:
self.createNotification(for: self.day(after: dateComponents))
case .daily:
var numberOfCreatedNotifications = 0
var currentDay: DateComponents? = dateComponents
while numberOfCreatedNotifications < self.NUMBER_OF_ALLOWED_NOTIFICATIONS_CREATED_AT_ONE_TIME {
self.createNotification(for: currentDay)
currentDay = self.day(after: currentDay)
numberOfCreatedNotifications += 1
}
}
}
//MARK: Private functions
private func createNotification(for dateComponents: DateComponents?) {
let center = UNUserNotificationCenter.current()
let content = UNMutableNotificationContent()
content.title = "Random Alarm"
content.subtitle = "It's time!"
content.body = self.note
content.sound = UNNotificationSound.default
guard let dateComponents = dateComponents else {
os_log("Could not unwrap dateComponents in createNotification() in Alarm.swift", log: OSLog.default, type: .debug)
return
}
let trigger = UNCalendarNotificationTrigger(dateMatching: dateComponents, repeats: false)
let uuidString = UUID().uuidString
let request = UNNotificationRequest(identifier: uuidString, content: content, trigger: trigger)
self.notificationUuids.append(uuidString)
guard let day = dateComponents.day else {
os_log("Could not unwrap dateComponents.day in createNotification() in Alarm.swift", log: OSLog.default, type: .debug)
return
}
guard let hour = dateComponents.hour else {
os_log("Could not unwrap dateComponents.hour in createNotification() in Alarm.swift", log: OSLog.default, type: .debug)
return
}
guard let minute = dateComponents.minute else {
os_log("Could not unwrap dateComponents.minute in createNotification() in Alarm.swift", log: OSLog.default, type: .debug)
return
}
os_log("Creating notification for day: %d, time: %d:%02d, with uuid=%s", log: OSLog.default, type: .debug, day, hour, minute, uuidString)
center.add(request) { (error) in
if let err = error {
print("error \(err.localizedDescription)")
}
}
}
private func day(after dateComponents: DateComponents?) -> DateComponents? {
let calendar = Calendar.autoupdatingCurrent
guard let dateComponents = dateComponents,
let date = calendar.date(from: dateComponents),
let tomorrow = calendar.date(byAdding: .day, value: 1, to: date)
else {
os_log("Could not calculate tomorrow in Alarm.swift", log: OSLog.default, type: .debug)
return nil
}
let newDateComponents = calendar.dateComponents([.year, .month, .day, .timeZone, .hour, .minute], from: tomorrow)
return newDateComponents
}
}
答案 0 :(得分:1)
如果AlarmMO
是您在Core Data中的实体,则应为您创建AlarmMO
对象。您可以使用扩展程序添加所需的其他任何行为。
虽然您可以创建一个新的初始化程序,但我可能会使用一种使用静态函数的工厂方法:
extension AlarmMO {
static func newAlarm(context: NSManagedObjectContext, alarmNumber: Int, timeIntervals: TimeIntervals, note: String, recurrence: RecurrenceOptions) -> AlarmMO? {
let startInterval = Alarm.convertToTimeDouble(hour: timeIntervals.hourStartInterval, minute: timeIntervals.minuteStartInterval)
let endInterval = Alarm.convertToTimeDouble(hour: timeIntervals.hourEndInterval, minute: timeIntervals.minuteEndInterval)
if endInterval < startInterval {
os_log("Error: Alarm time endInterval is before startInterval", log: OSLog.default, type: .info)
return nil
}
let newAlarm = AlarmMO(context: context)
newAlarm.alarmNumber = alarmNumber
newAlarm.note = note
newAlarm.recurrence = recurrence
newAlarm.notificationUuids = [String]()
newAlarm.alarmTime = Double.random(in: startInterval ... endInterval)
newAlarm.startTimeInterval = startInterval
newAlarm.endTimeInterval = endInterval
return newAlarm
}
var recurrence: RecurrenceOptions {
get {
return RecurrenceOptions(rawValue: self.recurrenceIndex)!
}
set {
self.recurrenceIndex = newValue.rawValue
}
}
var hour: Int {
return Int(floor(self.alarmTime))
}
var minute: Int {
return Int(round((self.alarmTime - floor(self.alarmTime)) * 60))
}
func scheduleNotification() {
os_log("Attempting to create alarm with time %d:%02d", log: OSLog.default, type: .info, self.hour, self.minute)
let date = Date()
let calendar = Calendar.current
let currentDateComponents = calendar.dateComponents([.year, .month, .day, .timeZone, .hour, .minute], from: date)
var dateComponents = DateComponents()
dateComponents.year = currentDateComponents.year
dateComponents.month = currentDateComponents.month
dateComponents.timeZone = currentDateComponents.timeZone
dateComponents.day = currentDateComponents.day
createNotifications(dateComponents: dateComponents)
}
// Note: This probably should be in TimeIntervals, rather than here
public static func convertToTimeDouble(hour: Int, minute: Int) -> Double {
return Double(hour) + (Double(minute) / 60.0)
}
}