Scheduling weekly repeatable local notification with fire date from date picker in Swift 3

So I'm currently building a schedule app and I'm trying to create a local notification to fire on specific time on specific day of the week, every week. So the first thing I do is get the date value of the start time of the event, then I subtract 5 minutes from the start time value and then schedule the notification. Previously it was very easy just had to type: notification.repeatInterval = CalendarUnit.WeekOfYear but now the command is deprecated in Swift 3 and yeah, so the only way I found is:

 let someMinutesEarlier = Calendar.current.date(byAdding: .minute, value: -5, to: startTimePicker.date)

        let contentOfNotification = UNMutableNotificationContent()

        let interval = someMinutesEarlier?.timeIntervalSinceNow

        contentOfNotification.title = "Event starting"
        contentOfNotification.body = "Some notes"
        contentOfNotification.sound = UNNotificationSound.default()

        let trigger = UNTimeIntervalNotificationTrigger.init(timeInterval: interval!, repeats: true)
        let request = UNNotificationRequest.init(identifier: notificationIdentifier, content: contentOfNotification, trigger: trigger)

        let center = UNUserNotificationCenter.current()
        center.add(request) { (error) in
            print(error as Any)
        }

but this only schedules the notification only once (no matter that the repeat boolean is set to true), because of the year in the someMinutesEarlier...or it's may be something else? Any idea?

Upvotes: 2

Views: 2240

Answers (2)

Mark
Mark

Reputation: 7409

As McNight mentionned, you can use UNCalendarNotificationTrigger like so:

let interval = 60 * 60 * 24 * 7 - 300 // One week minus 5 minutes.
let alarmTime = Calendar.current.date(byAdding: .second, value: interval, to: Date())!
let components = Calendar.current.dateComponents([.weekday, .hour, .minute], from: alarmTime)
let trigger = UNCalendarNotificationTrigger(dateMatching: components, repeats: true)

(I haven't tested this code, but this should get you on the right path).

More information here.

Edit: Fixed time interval calculation suggested by SwiftyCruz.

Edit 2: Updated to use a Calendar to perform the time shift as suggested by RickiG.

Upvotes: 5

Arjun Patel
Arjun Patel

Reputation: 1510

// Swift2.3

func setLNotification(weekDay:Int , hour:Int, min:Int, second:Int, alertBody:String, type:String, isRepeate:Bool){

    let calender = NSCalendar(identifier: NSCalendarIdentifierGregorian)
    let dateComp: NSDateComponents?

    dateComp = calender?.components([.Year,.WeekOfMonth,.Month], fromDate: NSDate())
    dateComp?.hour = hour
    dateComp?.minute = min
    dateComp?.second = 00
    dateComp?.weekday = weekDay
    dateComp!.timeZone = NSTimeZone.localTimeZone()

    print(calender?.dateFromComponents(dateComp!))


    let SetCustomDate = calender?.dateFromComponents(dateComp!)

    print(SetCustomDate)

    let notification = UILocalNotification()
    if isRepeate == true{

        switch type {
        case "Weekly":

            notification.fireDate = SetCustomDate!.dateByAddingTimeInterval(60*60*24*7)
            notification.repeatInterval = NSCalendarUnit.Weekday

        case "2 Weekly":

            notification.fireDate = SetCustomDate!.dateByAddingTimeInterval(60*60*24*14)
            notification.repeatInterval = NSCalendarUnit.Day
        case "Monthly":
            notification.fireDate = SetCustomDate!.dateByAddingTimeInterval(60*60*24*28)
            notification.repeatInterval = NSCalendarUnit.Day

        default:
            break;
        }

        notification.soundName = UILocalNotificationDefaultSoundName
        notification.repeatCalendar = calender
    }
    notification.alertTitle = "STATS"
    notification.alertBody = "Please update your Stats detail"
    notification.userInfo = ["uid":"reminder"]

    print(notification)

   UIApplication.sharedApplication().scheduleLocalNotification(notification)



}

Upvotes: 0

Related Questions