trigger local notification on specific week day - swift

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

Related

How to fetch day, month and hour from NSDate in Swift

I have an NSDate object called reservationDate and I want to fetch day, month and hour from the Date. However, I'm getting wrong values. How can I get these values?
The value of the reservationDate object
reservationDate NSDate 2016-08-05 21:00:00 UTC
thus I expect to get 5 as a day and 21 as a hour however I'm receiving 6 as a day and 0 as a hour. Should I expect something else?
let unitFlags: NSCalendarUnit = [.Hour, .Day, .Month, .Year]
let components = NSCalendar.currentCalendar().components(unitFlags, fromDate: reservationDate)
let day = components.day
let hour = components.hour
You have not set Time zone. Please assign it "UTC".
NSCalendar.currentCalendar().timeZone = NSTimeZone(name: "UTC")!
Try to set timezone with Calendar object with UTC
let unitFlags: NSCalendarUnit = [.Hour, .Day, .Month, .Year]
let calendar = NSCalendar.currentCalendar()
calendar.timeZone = NSTimeZone(name: "UTC")!
let components = calendar.components(unitFlags, fromDate: NSDate())
let day = components.day
let hour = components.hour
let currentDate = NSDate()
let dateFormatter = NSDateFormatter()
dateFormatter.dateStyle = NSDateFormatterStyle.FullStyle
var convertedDate = dateFormatter.stringFromDate(currentDate)
dateFormatter.dateFormat = "EEEE, MMMM dd, yyyy, HH:mm"
convertedDate = dateFormatter.stringFromDate(currentDate)

how to make daily local notification depending on specific time in CVcalendar?

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)
}

Date Picker, User cannot go back to previous date Swift

I have Date Picker
I already set the current Date, and i want to make User cannot scroll back to previous date? is it allowed?
As the documentation says here
you have just to set the option minimumDate of your UIDatePicker.
This is an example
var datePicker = UIDatePicker() //your UIDatePicker
datePicker.minimumDate = Date() //the minimum date is now. Only future date is allowed
Another case is the following
var datePicker = UIDatePicker() //your UIDatePicker
//create a gregorian calendar
let calendar = NSCalendar(calendarIdentifier: NSCalendarIdentifierGregorian)!
// set the timezone
calendar.timeZone = NSTimeZone(name: "UTC")!
// create and set the component (for your minimum date value)
let components: NSDateComponents = NSDateComponents()
components.calendar = calendar
components.year = -100
// obtain the minimum NSDate, according to the defined components
//it will result as the difference of the years (components.year) from now (NSDate())
let minDate100YearsAgo: NSDate = calendar.dateByAddingComponents(components, toDate: NSDate(), options: NSCalendarOptions(rawValue: 0))!
//then you add this to the UIDatePicker
datePicker.minimumDate = minDate100YearsAgo
This is an example to how to do it in Swift 2.2:
// a global var
var datePicker = UIDatePicker()
// UIDatePicker settings:
let currentDate: NSDate = NSDate()
let calendar: NSCalendar = NSCalendar(calendarIdentifier: NSCalendarIdentifierGregorian)!
calendar.timeZone = NSTimeZone(name: "UTC")!
let components: NSDateComponents = NSDateComponents()
components.calendar = calendar
components.year = -18
let minDate: NSDate = calendar.dateByAddingComponents(components, toDate: currentDate, options: NSCalendarOptions(rawValue: 0))!
components.year = -150
let maxDate: NSDate = calendar.dateByAddingComponents(components, toDate: currentDate, options: NSCalendarOptions(rawValue: 0))!
datePicker.dateOfBirthUIDatePicker.minimumDate = minDate
datePicker.dateOfBirthUIDatePicker.maximumDate = maxDate
At Swift 3:
var datePicker = UIDatePicker()
datePicker.minimumDate = Date()

Swift NSDate create var with hour and minute only

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
}
....

NSDateFormatter subtracting a day when removing time

I am trying to remove time from date using NSDateFormatter. This is the code:
func dateWithOutTime( datDate: NSDate?) -> NSDate {
let formatter = NSDateFormatter()
formatter.dateFormat = "dd-MM-yyyy"
let stringDate: String = formatter.stringFromDate(datDate!)
let dateFromString = formatter.dateFromString(stringDate)
return dateFromString!
}
If i send in ex 04-01-2016 12:00:00, the return is 03-01-2016 23:00:00
I have tried changing the dateFormat, but it still keeps to subtracting a day from the date... Why? Please Help :)
The easiest way is to use startOfDayForDate of NSCalendar
Swift 2:
func dateWithOutTime( datDate: NSDate) -> NSDate {
return NSCalendar.currentCalendar().startOfDayForDate(datDate)
}
Swift 3+:
func dateWithOutTime(datDate: Date) -> Date {
return Calendar.current.startOfDay(for: datDate)
}
or to adjust the time zone to UTC/GMT
Swift 2:
func dateWithOutTime( datDate: NSDate) -> NSDate {
let calendar = NSCalendar(identifier: NSCalendarIdentifierGregorian)!
calendar.timeZone = NSTimeZone(forSecondsFromGMT: 0)
return calendar.startOfDayForDate(datDate)
}
Swift 3+:
func dateWithOutTime(datDate: Date) -> Date {
var calendar = Calendar(identifier: .gregorian)
calendar.timeZone = TimeZone(secondsFromGMT: 0)!
return calendar.startOfDay(for: datDate)
}
Two things:
(a) This can be done without using NSDateFormatter. (b) Calling print(aDate) will give you the UTC time, not in your local time. After losing too many brain cells trying to mentally convert back and forth, I decided to make an extension to NSDate to print it in my local timezone.
// NSDateFormatter is expensive to create. Create it once and reuse
let dateFormatter = NSDateFormatter()
dateFormatter.locale = NSLocale.currentLocale()
dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss ZZZZ"
extension NSDate {
// This will print the date in the local timezone
var localTime: String {
return dateFormatter.stringFromDate(self)
}
}
func dateWithOutTime(datDate: NSDate?) -> NSDate {
let calendar = NSCalendar.currentCalendar()
let components = calendar.components([.Year, .Month, .Day], fromDate: datDate!)
return calendar.dateFromComponents(components)!
}
let datDate = NSCalendar.currentCalendar().dateWithEra(1, year: 2016, month: 1, day: 4, hour: 12, minute: 0, second: 0, nanosecond: 0)
let result = dateWithOutTime(datDate)
print(result.localTime)