简体   繁体   中英

Making a Local notification that only repeats on a specific day

I am working on a local notification for an app that should only fire on a specific day and repeat on that day until the user decided to remove it. An example notification is on that fires every Wednesday at 11:00am.

The function - scheduleLocalNotification is triggered when the user presses done on the Time picker.

在此处输入图片说明

在此处输入图片说明

    var sundayNotification : UILocalNotification!
    var mondayNotification : UILocalNotification!
    var tuesdayNotification : UILocalNotification!
    var wednesdayNotification : UILocalNotification!
    var thursdayNotification : UILocalNotification!
    var fridayNotification : UILocalNotification!
    var saturdayNotification : UILocalNotification!


func scheduleLocalNotification() {

        //Check the Dayname and match fireDate
        if dayName == "Sunday" {

            sundayNotification = UILocalNotification()

            //timeSelected comes from the timePicker i.e. timeSelected = timePicker.date
            sundayNotification.fireDate = fixNotificationDate(timeSelected)
            sundayNotification.alertTitle = "Sunday's Workout"
            sundayNotification.alertBody = "This is the message from Sunday's workout"
            sundayNotification.alertAction = "Snooze"
            sundayNotification.category = "workoutReminderID"
            let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
            appDelegate.saveContext()
            UIApplication.sharedApplication().scheduleLocalNotification(sundayNotification)


        } else if dayName == "Monday" {

            mondayNotification = UILocalNotification()
            mondayNotification.fireDate = fixNotificationDate(timeSelected)
            mondayNotification.alertTitle = "Monday's Workout"
            mondayNotification.alertBody = "This is the message from Monday's workout"
            mondayNotification.alertAction = "Snooze"
            mondayNotification.category = "workoutReminderID"
            let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
            appDelegate.saveContext()
            UIApplication.sharedApplication().scheduleLocalNotification(mondayNotification)

        } else if ..... }

}


func fixNotificationDate(dateToFix: NSDate) -> NSDate {


        let dateComponets: NSDateComponents = NSCalendar.currentCalendar().components([NSCalendarUnit.Hour, NSCalendarUnit.Minute], fromDate: dateToFix)

        dateComponets.second = 0

        if dayName == "Sunday" {

            dateComponets.weekday = 1 //n = 7

        } else if dayName == "Monday" {

            dateComponets.weekday = 2

        } else if dayName == "Tuesday" {

            dateComponets.weekday = 3

        } else if dayName == "Wednesday" {

            dateComponets.weekday = 4

        } else if dayName == "Thursday" {

            dateComponets.weekday = 5

        } else if dayName == "Friday" {

            dateComponets.weekday = 6

        } else if dayName == "Saturday" {

            dateComponets.weekday = 7

        }


        let fixedDate: NSDate! = NSCalendar.currentCalendar().dateFromComponents(dateComponets)

        return fixedDate
    }

After doing a check of the day to assign the notification the right UILocalNotification, this still strangely does not work eg setting different times on a different days (Sunday at 10:10am and Monday at 10:15am) for the notification does not change anything. The notification still fires on a day I did not select, ie Today at both those times instead of those days.

Any clues on what I could be doing wrong or missing? Thanks in advance. :)

After some work, I came up with this. We start by changing the date to the first fire date the user selects.

func setNotificationDay(today: NSDate, selectedDay: Int) -> NSDate {
    let daysToAdd: Int!
    let calendar = NSCalendar.currentCalendar()
    let weekday = calendar.component(.Weekday, fromDate: today)

    if weekday > selectedDay {
        daysToAdd = (7 - weekday) + selectedDay
    } else {
        daysToAdd = (selectedDay - weekday)
    }

    let newDate = calendar.dateByAddingUnit(.Weekday, value: daysToAdd, toDate: today, options: [])

    return newDate! //if you don't have a date it'll crash
}

You can just use NSDate() instead of requiring it as a parameter. I'll leave that up to you.

Now, we need to set the notification. I didn't do anything with your fixNotificationDate() , but you can add it in easily. The key point here is to set notification.repeatInterval = .Weekday or it won't repeat. I also added a dictionary to set the day name. It's better than repeating the code as much as you did.

It does create a second call to NSCalendar , but you can probably find a way to avoid doing that in your code.

func scheduleLocalNotification(date: NSDate) {
    let dayDic = [1:"Sunday",
        2:"Monday",
        3:"Tuesday",
        4:"Wednesday",
        5:"Thursday",
        6:"Friday",
        7:"Saturday"]

    let calendar = NSCalendar.currentCalendar()
    let weekday = calendar.component(.Weekday, fromDate: date)

    let notification = UILocalNotification()
    notification.fireDate = date
    notification.repeatInterval = .Weekday
    notification.alertTitle = String(format: "%@'s Workout", dayDic[weekday]!)
    notification.alertBody = String(format: "This is the message from %@'s workout", dayDic[weekday]!)
    notification.alertAction = "Snooze"
    notification.category = "workoutReminderID"
    notification.soundName = UILocalNotificationDefaultSoundName
    UIApplication.sharedApplication().scheduleLocalNotification(notification)
}

And that should solve your problem. I didn't test it because it would take at least a week! ;)

Hope that helps!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM