I'm trying to trigger notification on specific saved time in database and on specific day which is Friday as shown below, but every time I try to save new reminder it tells me unexpectedly found nil while unwrapping an Optional value and I'm sure it contains data and it's not nil even though I tried to handle nil, still the app crash, however when I try to fire notification without combining dates like this localNotification.fireDate = reminders.time! the app is not crashed and it works just fine.
I guess the problem in combineDate function, how I can solve this problem?
func combineDate(time: NSDate?) -> NSDate{
let gregorianCalendar: NSCalendar = NSCalendar(calendarIdentifier: NSCalendarIdentifierGregorian)!
let time: NSDateComponents = gregorianCalendar.components([.Hour, .Minute, .Second], fromDate: time!)
time.timeZone = NSTimeZone.systemTimeZone()
let timeCombiner: NSDateComponents = NSDateComponents()
timeCombiner.timeZone = NSTimeZone.systemTimeZone()
timeCombiner.hour = time.hour
timeCombiner.minute = time.minute
timeCombiner.second = 00
timeCombiner.weekday = 6
let combinedDate: NSDate = gregorianCalendar.dateFromComponents(components3)!
return combinedDate
}
func createLocalNotification(){
let localNotification = UILocalNotification()
localNotification.timeZone = NSTimeZone.systemTimeZone()
localNotification.fireDate = combineDate(reminders.time!)
localNotification.alertBody = reminders.name!
UIApplication.sharedApplication().scheduleLocalNotification(localNotification)
}
still the reason of causing all this mass unknown however I solved it by checking if reminder managed object is not equal to nil then try to fire notification
func createLocalNotification(){
let localNotification = UILocalNotification()
localNotification.timeZone = NSTimeZone.systemTimeZone()
if reminder != nil{
localNotification.fireDate = combineDate(reminders.time!)
}
localNotification.alertBody = reminders.name!
UIApplication.sharedApplication().scheduleLocalNotification(localNotification)
}
Related
My question is the same question that I linked below but I want to do that in swift 2, not in objective-c
Fire a notification at a specific day and time every week
The problem is that the date that I'm using is by default 1st January, because I haven't specified the month, the day of the month and the year, But if I specified them it would be useless because my app wouldn't work next year, or next month
Is very simple what I want.. Set a notification weekly on Sunday (For example)
but is not practical to specify the year or the month, because it should work any Sunday or any Saturday
please help me :( I've already tried a lot
let calendar = NSCalendar.currentCalendar()
let components = NSDateComponents()
components.hour = 2
components.minute = 54
components.weekday = 6
var newDate = calendar.dateFromComponents(components)
let notification = UILocalNotification()
notification.fireDate = newDate
notification.alertBody = "Swipe to unlock"
notification.alertAction = "You've got a class soon!"
notification.soundName = UILocalNotificationDefaultSoundName
notification.userInfo = ["CustomField1": "w00t"]
notification.timeZone = NSTimeZone.localTimeZone()
notification.repeatInterval = NSCalendarUnit.WeekOfYear
UIApplication.sharedApplication().scheduleLocalNotification(notification)
UPDATE:
I know it will only work on Mondays but I can fix later.
The problem here is that I set the hour and minute in 0 and then it returns the current time and I do not know how to set up the hour that I want.
var pickerDate = NSDate()
print(pickerDate)
var dateComponents: NSDateComponents? = nil
var calendar = NSCalendar.currentCalendar()
dateComponents = calendar.components(NSCalendarUnit.NSWeekdayCalendarUnit, fromDate: pickerDate)
var firstMondayOrdinal = 9 - dateComponents!.weekday
dateComponents = NSDateComponents()
dateComponents!.day = firstMondayOrdinal
dateComponents?.hour = 0
dateComponents?.minute = 0
var firstMondayDate = calendar.dateByAddingComponents(dateComponents!, toDate: pickerDate, options: NSCalendarOptions(rawValue: 0))
dateComponents = NSDateComponents()
dateComponents?.weekdayOrdinal = 1
let notification = UILocalNotification()
notification.fireDate = firstMondayDate
notification.alertBody = "Swipe to unlock"
notification.alertAction = "You've got a class soon!"
notification.soundName = UILocalNotificationDefaultSoundName
notification.userInfo = ["CustomField1": "w00t"]
notification.timeZone = NSTimeZone.localTimeZone()
notification.repeatInterval = NSCalendarUnit.WeekOfYear
UIApplication.sharedApplication().scheduleLocalNotification(notification)
Get the next Sunday or Monday date (SO answer), use calendar method dateBySettingHour to set the desired time to that date and use it as the firedate using the weekofyear repeat interval.
I am using cvcalendar and there is in everyday a different times for fajer, dohor , aser , maghreb , ishaa . for example i have selected the Adan for Fajer, so i want to get the adan in everyday and everyday has a different time. so when i get a notification in DidreceivedLocalNotification i want go to next day in calendar and get the time of the next day, knowing that am getting the times from CoreData .
in viewWillappear
let date = NSDate()
let dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "dd-MM-yyyy"
let calendar = NSCalendar.currentCalendar()
let calendarForDate = NSCalendar.currentCalendar()
let componentsForDate = calendar.components([.Day , .Month , .Year], fromDate: date)
let year = componentsForDate.year
let month = componentsForDate.month
let day = componentsForDate.day
//////////
//// Conditions after selecting the user (vibration, beep, Adan ) these conditions are testing the selected choice to send a notification to the user on his choice
//
if prayerCommingFromAdan.id == 0 && prayerCommingFromAdan.ringToneId != 0{
notificationId.id = 0
let hours = prayer0.time[0...1]
let minutes = prayer0.time[3...4]
let fajerTime = "\(month)-\(day)-\(year) \(hours):\(minutes)"
var dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "MM-dd-yyyy hh:mm"
dateFormatter.timeZone = NSTimeZone.localTimeZone()
// convert string into date
let dateValue = dateFormatter.dateFromString(fajerTime) as NSDate!
var dateComparisionResult:NSComparisonResult = NSDate().compare(dateValue)
if dateComparisionResult == NSComparisonResult.OrderedAscending
{
addNotificationAlarm(year, month: month, day: day, hour: prayer0.time[0...1], minutes: prayer0.time[3...4], soundId: prayerCommingFromAdan.ringToneId, notificationBody: "It is al fajr adan")
}
What should i do in DidreceivedLocalNotification in AppDelegate?
You can use this code for scheduling your daily notifications according to time.
func ScheduleMorning() {
let calendar: NSCalendar = NSCalendar(calendarIdentifier: NSCalendarIdentifierGregorian)!
var dateFire=NSDate()
var fireComponents = calendar.components([.Hour, .Minute, .Second], fromDate: dateFire)
if (fireComponents.hour >= 7) {
dateFire=dateFire.dateByAddingTimeInterval(86400) // Use tomorrow's date
fireComponents = calendar.components([.Hour, .Minute, .Second], fromDate: dateFire)
}
fireComponents.hour = 7
fireComponents.minute = 0
fireComponents.second = 0
// Here is the fire time you can change as per your requirement
dateFire = calendar.dateFromComponents(fireComponents)!
let localNotification = UILocalNotification()
localNotification.fireDate = dateFire // Pass your Date here
localNotification.alertBody = "Your Message here."
localNotification.userInfo = ["CustomField1": "w00t"]
localNotification.repeatInterval = NSCalendarUnit.Day
UIApplication.sharedApplication().scheduleLocalNotification(localNotification) }
for receiving
func application(application: UIApplication, didReceiveLocalNotification notification: UILocalNotification) {
// Do something serious in a real app.
print("Received Local Notification:")
print(notification.userInfo)
}
I'm trying to trigger local notification on specific day of weekday, but all my attempts have failed, the notification should be triggered on specific time of weekday, but instead it's triggered immediately, I searched all possible solutions in stack overflow but non of those answers have solved my problem, how I can solve this problem?
func combineDate(time:NSDate,dayIndex:Int) -> NSDate {
let calendar: NSCalendar = NSCalendar.currentCalendar()
let components: NSDateComponents = calendar.components([.Year, .Month, .WeekOfYear, .Weekday], fromDate: time)
let component1 = NSDateComponents()
component1.weekday = dayIndex
component1.minute = components.minute
component1.hour = components.hour
let combinedDate: NSDate = calendar.dateFromComponents(component1)!
return combinedDate
}
You just have to set the fireDate attribute in the local notification.
One way to create your custom date could be with NSDateFormatter
let stringDate = "2016-05-23 17:29:50 +0000"
let formatter = NSDateFormatter()
formatter.dateFormat = "yyyy-MM-dd HH:mm:ss Z"
let myDate = formatter.dateFromString(stringDate)
func saveLocalNotification(myDate : NSDate){
let localNotification = UILocalNotification()
localNotification.fireDate = myDate
...
UIApplication.sharedApplication().scheduleLocalNotification(localNotification)
}
To know how to get the weekdays you could take a look at this answer Get day of week using NSDate swift
I asked a question a moment ago about how to get the hour and minute of the current time and not worry about the year month day, and that question was solved. Im now trying to apply the same logic to creating a custom time (in the hour minute format) but im getting an error
i have
let time1 = NSDateComponents()
time1.hour = 8
time1.minute = 54
let date1: NSDate = calendar.dateFromComponents(time1)!
I tried using the previous answer to make it look like
let date1: NSDate = calendar.components([ .Hour, .Minute ], fromDate: time1())
but i get "ambiguous reference to member 'components'"
from there i remove the : NSDate...then im told to remove the () from the end....and i keep getting errors. Is there an easy fix to this?
Thanks
The quick way, getting the nsdate from your string elements and then convert the nsdate back to a string if you want to :
let formatter = NSDateFormatter()
formatter.dateFormat = "HH:mm"
let hour = 08
let minutes = 32
let time = formatter.dateFromString("\(hour):\(minutes)")!
let finalTime = formatter.stringFromDate(time)
print(time)
print(finalTime)
I think it's because you're not calling NSCalendar. Since you only want the hour and minutes, you could return a dictionary
func getHourMinutes(fromDate: NSDate) -> [String:Int] {
var timeDic = [String:Int]()
let dC = NSDateComponents()
let cC = NSCalendar.currentCalendar()
if let hour = Int(currentCalendar.component(NSCalendarUnit.Hour, fromDate: fromDate)) {
timeDic.append["hour":hour]
}
if let minutes = Int(currentCalendar.component(NSCalendarUnit.Minute, fromDate: fromDate)) {
timeDic.append["minutes":minutes
}
return timeDic
}
Then you can call the keys to set a new NSDate if you wish.
This is the solution my classmate helped me to achieve
....
let date6 = NSDateComponents()
date6.hour = 17
date6.minute = 3
datesArray = [date2, date3, date4, date5, date6]
datesArray.sortInPlace {
NSNumber(integer:($0.minute + ($0.hour * 60))).compare(NSNumber(integer: ($1.minute + ($1.hour * 60)))) == .OrderedAscending
}
....
How can I make a user choose a time by using a date picker and then send the user a local notification?
here is a simple code to schedule a local notification in swift:
let calendar: NSCalendar = NSCalendar.currentCalendar()
let fireDateOfNotification: NSDate = //The date which was picked from the picker
var notification = UILocalNotification()
notification.timeZone = NSTimeZone.localTimeZone()
notification.alertBody = "ALERT STRING"
notification.soundName = UILocalNotificationDefaultSoundName
notification.fireDate = fireDateOfNotification
notification.userInfo = ["UUID": "NotificationID"] //id for the local notification in case you want to cancel it
UIApplication.sharedApplication().scheduleLocalNotification(notification)
and if you want to cancel a local notification you should use the following function:
func cancelLocalNotificationsWithUUID(uuid: Int) {
for item in UIApplication.sharedApplication().scheduledLocalNotifications {
let notification = item as! UILocalNotification
if let notificationUUID = notification.userInfo?["UUID"] as? Int {
if notificationUUID == uuid {
UIApplication.sharedApplication().cancelLocalNotification(notification)
}
}
}
}
I hope this helps.