I am creating simple application that has ability to add events into iPhone Calendar. So I am playing with EKEvent's recurrenceRule. There is a class EKRecurrenceRule with very long constructor:
(id)initRecurrenceWithFrequency:(EKRecurrenceFrequency)
typeinterval:(NSInteger)interval
daysOfTheWeek:(NSArray *)days
daysOfTheMonth:(NSArray *)monthDays
monthsOfTheYear:(NSArray *)months
weeksOfTheYear:(NSArray *)weeksOfTheYear
daysOfTheYear:(NSArray*)daysOfTheYear
setPositions:(NSArray *)setPositions
end:(EKRecurrenceEnd*)end
So for example, if I am trying to create a event that will be repeated every work day in the week (except Sunday), I will use this init:
initRecurrenceWithFrequency:EKRecurrenceFrequencyDaily
interval:1
daysOfTheWeek:[NSArray arrayWithObjects:
[EKRecurrenceDayOfWeek dayOfWeek:2],
[EKRecurrenceDayOfWeek dayOfWeek:3],
[EKRecurrenceDayOfWeek dayOfWeek:4],
[EKRecurrenceDayOfWeek dayOfWeek:5],
[EKRecurrenceDayOfWeek dayOfWeek:6],
[EKRecurrenceDayOfWeek dayOfWeek:7], nil]
daysOfTheMonth:nil
monthsOfTheYear:nil
weeksOfTheYear:nil
daysOfTheYear:nil
setPositions:nil
end:nil
but it is not working, it just repeat event every day :S
When I try use EKRecurrenceFrequencyMonthly, then it works. It repeats event every month, but not on Sunday. I reported bug to Apple, because it seems that they have a bug.
Or you have other idea?
Creating A Complex Recurrence Rule
"Days of the week. For all recurrence rules besides daily recurrence rules, you can provide an array of EKRecurrenceDayOfWeek objects that indicate the days of the week on which the event occurs.
For example, you can provide an array containing EKRecurrenceDayOfWeek objects with day of week values of EKTuesday and EKFriday to create a recurrence that occurs every Tuesday and Friday."
In other words, what you want to do is use Monday to Friday and then repeat that WEEKLY. Repeating Monday to Friday every day makes no sense.
Apple documentation says:
#method initRecurrenceWithFrequency:interval:daysOfTheWeek:daysOfTheMonth:monthsOfTheYear:weeksOfTheYear:daysOfTheYear:setPositions:end:
#abstract The designated initializer.
#discussion This can be used to build any kind of recurrence rule. But be aware that certain combinations make no sense and will be ignored. For example, if you pass daysOfTheWeek for a daily recurrence, they will be ignored.
I think, we can't say it daily and say not on Sunday. Please let me know if I am mistaken.
Thanks.
initRecurrenceWithFrequency:EKRecurrenceFrequencyDaily
interval:1
daysOfTheWeek:[NSArray arrayWithObjects:
[EKRecurrenceDayOfWeek dayOfWeek:2],
[EKRecurrenceDayOfWeek dayOfWeek:3],
[EKRecurrenceDayOfWeek dayOfWeek:4],
[EKRecurrenceDayOfWeek dayOfWeek:5],
[EKRecurrenceDayOfWeek dayOfWeek:6],
[EKRecurrenceDayOfWeek dayOfWeek:7], nil]
daysOfTheMonth:nil
monthsOfTheYear:nil
weeksOfTheYear:nil
daysOfTheYear:nil
setPositions:nil
end:nil
In this code you are using EKRecurrenceFrequencyDaily and again specifying the days of a week. Instead of this try to execute with EKRecurrenceFrequencyWeekly
EKRecurrenceDayOfWeek *weekReferecne=[[EKRecurrenceDayOfWeek alloc]initWithDayOfTheWeek:2 weekNumber:0];
and create EKRecurrenceDayOfWeek objects with week number 0(zero) so that the EKAlarm repeats every day until you specify the enddate.. This code works. Have a Happy coding
Related
I am working on Homekit based application, In That Homekit supports Triggers which fires on a specific date and it can be scheduled to fire repetitively by minutes, hour, days, week and month.
I want to schedule the Trigger to fire on specific days which is selected by user like mon,tue,wed,thu only or weekends (sat, sun).
I have set the recurrence using NSDateComponents but not able to set the repeat it for specific days.
Is there any way to schedule it by recurrenceCalendar object?
HMTimerTrigger's method has this object which can be passed as parameter.
HMTimerTrigger *newTrigger = [[HMTimerTrigger alloc] initWithName:#"Morning Schedule"
fireDate:self.fireDate
timeZone:nil
recurrence:recurranceComp
recurrenceCalendar:nil];
I have times that I would like to compare to the current time for each day of the week. From what I've come across, it sounds like the best thing to do would be to have an array for each day of the week with the given times I want. For example:
mondayTimes(2:00:00, 5:00:00, 9:00:00, 14:00:00)
tuesdayTimes(3:00:00, 6:00:00, 10:00:00, 15:00:00)
etc...
I want to find out the given day of the week using the current date, and then depending on what day it is, use the array of times for that given day. Then use the current time to find which time is next in the array.
Basically it is like an "alarm clock" that always has set times for every day of the week.
Do I use NSStrings to populate the dates in each array and convert them so I am able to compare them to the current time? What is the best route to go about this?
Thanks!
To get the current date, use NSDate currentDate = [NSDate date];
Then, to extract the weekday: initialize a NSCalendar of your choice, then call [calendar components:NSWeekdayCalendarUnit fromDate:currentDate];, where calendar is your calendar instance.
This produces a number between 1 and 7 (for the Gregorian calendar) where 1 is Sunday and 7 is Saturday. I would then advise you put all of your times in an array of arrays, with the 1 index containing an array of your sundayTimes, 2 containing an array of mondayTimes, ... 7 containing an array of your saturdayTimes.
Then using [allTimes objectAtIndex weekday] will return a NSArray of your times. All that's left is to compare the times, which I'm sure you can figure out.
Is there a framework or API to give time time interval like 2m, 3h, Tuesday, 2014-06-01 from a given NSDate to current NSDate. It's widely used in iMessages and Mail App. It's also used in other apps, I am just seeing if there is a framework before I try to write one for myself.
I suggest to use this category. It is very helpful for what you are looking for.
For example this line of code:
NSString *displayString = [NSDate stringForDisplayFromDate:date];
produces the following kinds of output:
- ‘3:42 AM’ – if the date is after midnight today
- ‘Tuesday’ – if the date is within the last seven days
- ‘Mar 1’ – if the date is within the current calendar year
- ‘Mar 1, 2008’ – else ;-)
I'm not sure how this would work, but what I'd like is something similar to Apple's alarm clock that comes with the iPhone. It basically just lets you pick a time of an alarm, name the alarm, and then you can choose how often you want it to repeat (Sunday - Saturday). Based on what you choose, the alarm fires once, or at a repeated interval.
In my Core Data model, I wasn't sure how to model that. If I were thinking in terms of just plain old objects, I would think I would have some alarm object, and one of its properties would be an array. In that array I could have the day values of Sunday-Sautrday. Then when a new alarm object is created, I would schedule a UILocalNotification for the time selected, and the days chosen. To model that in terms of database objects, I'm not sure what I'm supposed to do. I was thinking something like:
Alarm - (name/string)
Day - (Sunday - Saturday/represented by integers 0-6, 1 to many relationship from Alarm to Day)
Assuming that is ok in the database, then I'm not sure how I should go about scheduling the UILocalNotifications since I thought you could only have 64 per app. I'm thinking that I could have some mechanism to schedule the first 64 alarms possible, then when the app is opened, it would just reschedule the next upcoming 64 events. Is that how I would do that? Thanks.
Using 2 entities is overkill. I would just have the Alarm entity and have a single integer attribute on it to hold the alarm days. Outside of the entity, I would have an enumeration which defines how the alarm days number is interpreted. Something like:
typedef AlarmDays {
Monday = 0,
Tuesday = 1 << 0,
Wednesday = 1 << 1,
Thursday = 1 << 2,
Friday = 1 << 3,
Saturday = 1 << 4,
Sunday = 1 << 5
} AlarmDays;
Then you can test which days it should be on using:
if (alarm.alarmDays & Monday) {
// the alarm should fire on mondays
}
And you can use the features of UILocalNotification, such as repeatInterval so you don't need to explicitly add gazillions of notifications to the system.
Is there any way using NSCalender you can get same day of last month?
I am using a calender which shows user 1 month like the iPad calender when they click on the button I want to move to previous month but should select the same day as before.
I want to just do
[components setMonth:([components month] - 1)];
but this will create problems when I are moving from a month with 31 days to month with 30 days and selected day is 31st.
I was able to find examples for android but not iOS.
android example
Any help would be appreciated
Check out this link.
It's about adding one month, but you could probably do the same with subtracting.
Change
[dateComponents setMonth:1];
into
[dateComponents setMonth:-1];
Seems there is no obvious "right" answer and no "built-in" answer.
As Chris's "simple" idea may lead to invalid dates, you may have to handle the edge-cases.
Pseudocode to deal with day-month-year:
if month = December start with day-1-(year-1), else
day-(month-1)-year [using dateComponents]
check if this a valid date (using NSDateFormatter like in this question
repeat subtracting one day until you reach a valid date
Another idea:
prevMonthDate = startDate;
Repeat
prevMonthDate = prevMonthDate - 1 day
Until (Month(prevMonthDate) < Month(startDate) Or Year(prevMonthDate) < Year(startDate))
And (Day(prevMonthDate) <= Day(startDate))
This requires working with NSDate and NSDateComponents, check out the Date and Time Programming Guide.