I have been testing this code to add a calendar to IOS Cal App, and also add some events to that specific calendar in the app.
I have an Ipad with IOS7, iCloud disabled.
First problem is when I create calendar I can't see newly created calendar in iPad's iCal App,Isn't that app supposed to show all calendars even if they are not added to iCloud?
second problem is my code keep adding same events every time I call that code.
Lets say I call the add function and it adds 3 events successfully firs time, next time when call that function with same events it supposed to skip adding but it adds that 3 events to calendar again now I have duplicate events, and so on...
-(void) initCalendar:(NSDictionary *)dataDict
{
self.eventStore = [[EKEventStore alloc] init];
if([self.eventStore respondsToSelector:#selector(requestAccessToEntityType:completion:)]) {
// iOS 6 and later
[self.eventStore requestAccessToEntityType:EKEntityTypeEvent completion:^(BOOL granted, NSError *error) {
if (granted){
//---- codes here when user allow your app to access theirs' calendar.
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
self.isCalendarAccepted=YES;
NSLog(#"self.isCalendarAccepted=YES;");
if ([defaults objectForKey:#"Calendar"] == nil) // Create Calendar if Needed
{
EKSource *theSource = nil;
for (EKSource *source in self.eventStore.sources) {
if (source.sourceType == EKSourceTypeCalDAV && [source.title isEqualToString:#"iCloud"]) {
theSource = source;
NSLog(#"iCloud Store Source");
break;
} else {
for (EKSource *source in self.eventStore.sources) {
if (source.sourceType == EKSourceTypeLocal) {
theSource = source;
NSLog(#"ios Local Store Source");
break;
}
}
}
}
//EKCalendar *calendar = [EKCalendar calendarWithEventStore:self.eventStore];
EKCalendar *calendar =[EKCalendar calendarForEntityType:EKEntityTypeEvent eventStore:self.eventStore];
calendar.title = #"My App Name";
if (theSource) {
calendar.source = theSource;
} else {
NSLog(#"Error: Local source not available");
return;
}
NSError *errorCalendar = nil;
BOOL result = [self.eventStore saveCalendar:calendar commit:YES error:&errorCalendar];
if (result) {
NSLog(#"Saved calendar to event store.");
[[NSUserDefaults standardUserDefaults] setObject:calendar.calendarIdentifier forKey:#"Calendar"];
[[NSUserDefaults standardUserDefaults] synchronize];
} else {
NSLog(#"Error saving calendar: %#.", errorCalendar);
}
}
//start adding event to calendar
[self addSelectedOwnEventsToCalendar:dataDict];
}
}];
}
}
-(void)addSelectedOwnEventsToCalendar:(NSDictionary *)dataDict
{
// Create a new event... save and commit
NSError *error = nil;
EKEvent *myEvent = [EKEvent eventWithEventStore:self.eventStore];
myEvent.allDay = NO;
myEvent.availability = EKEventAvailabilityFree;
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"yyyy-MM-dd HH:mm:ss"];
NSDate *startDate = [[NSDate alloc] init];
NSString *startDateFormatted=[NSString stringWithFormat:#"%# %#",[dataDict objectForKey:#"start_date"],[dataDict objectForKey:#"starts"]];
startDate = [dateFormatter dateFromString:startDateFormatted];
NSDateFormatter *dateFormatter1 = [[NSDateFormatter alloc] init];
[dateFormatter1 setDateFormat:#"yyyy-MM-dd HH:mm:ss"];
NSDate *endDate = [[NSDate alloc] init];
NSString *endDateFormatted=[NSString stringWithFormat:#"%# %#",[dataDict objectForKey:#"end_date"],[dataDict objectForKey:#"ends"]];
endDate = [dateFormatter1 dateFromString:endDateFormatted];
//compare dates
NSComparisonResult result = [startDate compare:endDate];
if (result == NSOrderedAscending) {
} else if (result == NSOrderedDescending) {
} else {
//the same
endDate=[startDate dateByAddingTimeInterval:60];
}
myEvent.startDate=startDate;
myEvent.endDate = endDate;
myEvent.title = [dataDict objectForKey:#"event_id"];
myEvent.calendar = [self.eventStore calendarWithIdentifier:[[NSUserDefaults standardUserDefaults] objectForKey:#"Calendar"]];
myEvent.location=[dataDict objectForKey:#"location"];
NSArray *cals = [self.eventStore calendarsForEntityType: EKEntityTypeEvent];
NSPredicate *predicateForEventsOnHolidayDate = [self.eventStore predicateForEventsWithStartDate:startDate endDate:endDate calendars:cals]; // nil will search through all calendars
NSArray *eventsOnHolidayDate = [self.eventStore eventsMatchingPredicate:predicateForEventsOnHolidayDate];
//NSLog(#"eventsOnHolidayDate %#",eventsOnHolidayDate);
BOOL eventExists = NO;
for (EKEvent *eventToCheck in eventsOnHolidayDate) {
NSLog(#"eventToCheck.title %#",eventToCheck.title);
NSLog(#"event_id %#",[dataDict objectForKey:#"event_id"]);
if ([eventToCheck.title isEqualToString:[dataDict objectForKey:#"event_id"]]) {
eventExists = YES;
NSLog(#"Event Already Exists");
}
}
//save eventts
if (eventExists == NO) {
[self.eventStore saveEvent:myEvent span:EKSpanThisEvent commit:YES error:&error];
if (!error) {
// NSLog(#"the event saved and committed correctly with identifier %#", myEvent.eventIdentifier);
} else {
NSLog(#"there was an error saving and committing the event");
NSLog(#"Error %#",error);
error = nil;
}
}
}
When I first run the code NSlog says (#"ios Local Store Source");
What am I missing?
Note: Code is working on simulator(Ipad ios 7) most of the time, I assuming something wrong with [NSUserDefaults] ?
First, see the discussion points about duplicates in the calendarItemExternalIdentifier documentation and determine if any of them apply.
Then, take a look at the following suggestions:
The calendar identifier can change. Ensure that the saved version for key Calendar in NSUserDefaults is the same as the one being accessed in addSelectedOwnEventsToCalendar:.
When retrieving the calendar identifier from the NSUserDefaults make sure that it’s valid.
Try using the saveEvent:span:error: method without the commit parameter. I’ve had problems using the save event method that takes a commit argument in the past.
Lastly, I believe that iOS calendar access authorization can only be tested on an iOS device, which is probably why it’s working in the simulator.
Related
I have three subscription plans in in-app-purchase 1 month,6 months,1 year so i want to check the users current subscription plan and date of expire so what i am doing right now is from receipt getting latest_receipt_info in that I am using the last object.
from the last object, I am taking product_id and using it as a current subscription plan and expires_date used to check active or not.
Below is the block of code I am using.
So is this the correct approach?
if([dict[#"status"] integerValue] == 0) {
if([dict.allKeys containsObject:#"latest_receipt_info"]) {
NSArray *iapReceipts = dict[#"latest_receipt_info"];
if(iapReceipts) {
if(iapReceipts.count > 0) {
NSDictionary *latestReceipt = [iapReceipts lastObject];
if(latestReceipt) {
_currentIAPID = latestReceipt[#"product_id"];
NSDate *expireDate = latestReceipt[#"expires_date"];
if(expireDate) {
NSInteger days = DaysBetween(NSDate.date, expireDate);
if(days >= 0) {
NSLog(#"days %ld",(long)days);
status = SubscriptionStatusActive;
} else {
NSLog(#"Subs :NEGATIVE DAYS");
status = SubscriptionStatusExpired;
}
}
}
}
}
}
}
Any suggestions would be more helpful.
No, it's not a correct approach. You shouldn't get last object because that array is not sorted. It contains all your transactions including all renewals. This example code doesn't take into account cancellation_date:
- (void)parseResponse:(NSDictionary*)dict{
if ([dict[#"status"] integerValue] != 0) {return;}
NSArray *iapReceipts = dict[#"latest_receipt_info"];
NSDateFormatter *formatter = [NSDateFormatter new];
formatter.dateFormat = #"yyyy-MM-dd HH:mm:ss VV";
for (NSDictionary *iapReceipt in iapReceipts){
NSString *productID = iapReceipt[#"product_id"];
NSDate *date = [formatter dateFromString:iapReceipt[#"expires_date"]?:#""];
if (date && [date timeIntervalSinceDate:[NSDate date]] > 0){
[[NSUserDefaults standardUserDefaults] setObject:date forKey:productID];
}
}
}
- (BOOL)isSubscriptionActive:(NSString*)productID {
NSDate *date = [[NSUserDefaults standardUserDefaults] objectForKey:productID];
if (date && [date timeIntervalSinceDate:[NSDate date]] > 0){
return YES;
} else {
return NO;
}
}
I am new to iOS so pardon me when i make mistake. i want call a person from my application and i wrote these code for that :-
- (IBAction)onClickCallIcon:(id)sender {
NSString *phoneNumber =_lblLeadMobileNumber.text;
NSURL *phoneUrl = [NSURL URLWithString:[#"telprompt://" stringByAppendingString:phoneNumber]];
NSURL *phoneFallbackUrl = [NSURL URLWithString:[#"tel://" stringByAppendingString:phoneNumber]];
if ([UIApplication.sharedApplication canOpenURL:phoneUrl]){
[UIApplication.sharedApplication openURL:phoneUrl];
} else if ([UIApplication.sharedApplication canOpenURL:phoneFallbackUrl]){
[UIApplication.sharedApplication openURL:phoneFallbackUrl];
}
}
and i want to know, Is call has been made or not? if possible how much length of call. how can achieve it?
You can make Call by:
tel:// try to call direct the phone number
telprompt:// shows you an alert to confirm call
if you want to know the user press Call button or Cancel button then can use completionHandler status for it.
Swift Code:
let phoneNumber = "XXXXXXXXXX" // Your phone number here
if let url = URL(string: "tel://\(phoneNumber)") {
if #available(iOS 10.0, *) {
UIApplication.shared.open(url, options: [:], completionHandler: { (status) in
if status{
print("User Press Call Button")
}else{
print("User Press Cancel Button")
}
})
} else {
// Fallback on earlier versions
}
}
Objective-C Code
NSString *phoneNumber = #"XXXXXXXXXX";
NSURL *phoneUrl = [NSURL URLWithString:[#"tel://" stringByAppendingString:phoneNumber]];
NSDictionary *options = [NSDictionary new];
if ([UIApplication.sharedApplication canOpenURL:phoneUrl])
{
[UIApplication.sharedApplication openURL:phoneUrl options:options completionHandler:^(BOOL success) {
if (success){
NSLog(#"User Press Call Button");
}else{
NSLog(#"User Press Cancel Button");
}
}];
}
For your another question "possible how much length of call", the answer is NO, You can't get Call duration, there is no public API for this.
Refer Screenshot with running code:
Find Attached Running Project
#Anbu.karthik & #Rocky for helping me.
i used allKit/CXCallObserver to observe the call which is the answer of second part of my question and from that part i also get answer of first i.e call is connected or not. by using following code:-
In viewdidload:
CXCallObserver *callObserver = [[CXCallObserver alloc] init];
[callObserver setDelegate:self queue:nil];
self.callObserver = callObserver;
and a method:
- (void)callObserver:(CXCallObserver *)callObserver callChanged:(CXCall *)call {
if (call.isOutgoing == YES && call.hasConnected == NO) {
NSLog(#"CXCallState : Dialing");
}
if (call.isOutgoing == NO && call.hasConnected == NO && call.hasEnded == NO && call != nil) {
NSLog(#"CXCallState : Incoming");
}
if (call.hasConnected == YES && call.hasEnded == NO) {
NSLog(#"CXCallState : Connected");
startDate = [NSDate date];
}
if (call.hasConnected == YES && call.hasEnded == YES){
NSLog(#"********** voice call disconnected **********/n");
endDate = [NSDate date];
NSDateComponents *components = [[NSCalendar currentCalendar] components: NSCalendarUnitSecond
fromDate: startDate toDate: endDate options: 0];
NSInteger second = [components second];
NSLog(#"call duration == %ld",(long)second);
NSDateFormatter *formatter = [[NSDateFormatter alloc]init];
formatter.locale = [[NSLocale alloc] initWithLocaleIdentifier:#"en_US_POSIX"];
[formatter setDateFormat:#"MM/dd/yyyy hh:mm:ss"];
NSString *startDateFormatted = [formatter stringFromDate: startDate];
NSString *endDateFormatted = [formatter stringFromDate: endDate];
NSMutableDictionary *Dict = [[NSMutableDictionary alloc] init];
[Dict setValue:startDateFormatted forKey:#"startDate"];
[Dict setValue:endDateFormatted forKey:#"endDate"];
[Dict setValue:[NSString stringWithFormat:#"%ld", (long)second] forKey:#"interval"];
[currentShowingData updateCommunications:Dict];
}
these give me all what i wanted. thanks again who helped me.
I am adding an event in iOS calendar using EventKit. The event is recurring event. I am setting recurring rules for the event programmatically. Event is getting added in calendar successfully but the dates shown on calendar are not same as I set them.
Event details
Recurring rules.
After event is successfully added to calendar this is what I get in calendar entry
My event is being show for 2017 but I didn't set the end date to 2017 it was 2016.
I tried adding the event with iOs calendar and got the same result.
Below is the code I am using.
/*!
* This method, called added event to the calendar
*/
- (void)addEventToCalendar
{
#try {
/* Event added to device calendar */
[SINGLETON.eventStore requestAccessToEntityType:EKEntityTypeEvent completion:^(BOOL granted, NSError *error) {
if (granted) {
[SINGLETON.event_Dateformat setDateFormat:[self dateFormatForSelectedLanguage]];
EKEvent *event = [EKEvent eventWithEventStore:SINGLETON.eventStore];
event.title = _event.eventTitle;
event.startDate = [SINGLETON.event_Dateformat dateFromString:eventInfo.eventActualStartDate];
event.endDate = [SINGLETON.event_Dateformat dateFromString:eventInfo.eventActualEndDate];
event.notes = flattenHTML(eventInfo.eventDescription);
// Get notification 2 hours before the event start time.
[event addAlarm:[EKAlarm alarmWithRelativeOffset:-(2*60*60)]];
[event setCalendar:[SINGLETON.eventStore defaultCalendarForNewEvents]];
/* Here opening Event edit view controller */
EKEventEditViewController *controller = [[EKEventEditViewController alloc] init];
controller.event = event;
controller.eventStore = SINGLETON.eventStore;
controller.editViewDelegate = self;
// Event is recurring mark it is repeat in calendar.
// List of days on which a particular event occurs.
NSMutableArray <EKRecurrenceDayOfWeek *> *daysOfTheWeek = [[NSMutableArray alloc] init];
if (_event.eventRecurrence &&
! [_event.eventDays containsString:#"N/A"]) {
for (NSString *dayName in [_event.eventDays componentsSeparatedByString:#","]) {
EKRecurrenceDayOfWeek *aDay = [EKRecurrenceDayOfWeek dayOfWeek:[self weekDayForDayName:dayName]];
[daysOfTheWeek addObject:aDay];
}
}
// When to stop reminding user for the event.
EKRecurrenceEnd *endDate = [EKRecurrenceEnd recurrenceEndWithEndDate:event.endDate];
EKRecurrenceRule *repeatRule = [[EKRecurrenceRule alloc] initRecurrenceWithFrequency:[self recurrenceFrequencey:_event.eventType] interval:1 daysOfTheWeek:daysOfTheWeek daysOfTheMonth:nil monthsOfTheYear:nil weeksOfTheYear:nil daysOfTheYear:nil setPositions:nil end:endDate];
event.allDay = NO;
event.recurrenceRules = #[repeatRule];
//[event addRecurrenceRule:repeatRule];
dispatch_async(dispatch_get_main_queue(), ^{
//NSError *erroOnSave = nil;
// [SINGLETON.eventStore saveEvent:event span:EKSpanFutureEvents commit:YES error:&erroOnSave];
[MBProgressHUD hideAllHUDsForView:self.view animated:YES];
[self presentViewController:controller animated:YES completion:nil];
});
}else{
dispatch_async(dispatch_get_main_queue(), ^{
[MBProgressHUD hideAllHUDsForView:self.view animated:YES];
[SINGLETON alertViewTitle:#""
message:NSLocalizedString(#"Calendar setting alert", nil)
cancelTitle:NSLocalizedString(#"OK", nil)
doneTitle:nil
tag:0];
});
}
}];
}
#catch (NSException *exception) {
DLog(#"%#",exception);
}
}
Below is the event details I get in debugger:
EKEvent <0x7f94b1f19d00>
{
EKEvent <0x7f94b1f19d00>
{ title = TBW ;
location = ;
calendar = EKCalendar <0x7f94b439d280> {title = Calendar; type = Local; allowsModify = YES; color = #1BADF8;};
alarms = (
"EKAlarm <0x7f94b4352fe0> {triggerInterval = -7200.000000}"
);
URL = (null);
lastModified = 2016-04-25 05:18:27 +0000;
startTimeZone = Asia/Kolkata (GMT+5:30) offset 19800;
startTimeZone = Asia/Kolkata (GMT+5:30) offset 19800
};
location = ;
structuredLocation = (null);
startDate = 2015-09-20 18:30:00 +0000;
endDate = 2016-05-31 18:30:00 +0000;
allDay = 0;
floating = 0;
recurrence = EKRecurrenceRule <0x7f94b43e7110> RRULE FREQ=WEEKLY;INTERVAL=1;UNTIL=20160531T183000Z;BYDAY=MO,TH;
attendees = (null);
travelTime = (null);
startLocation = (null);
};
Please suggest what I am using wrong or I am missing something.
I have found a solution of this question with help of this answer
iOS calendar is behaving strangly
I was setting the Ends parameter in wrong way. It should be on same date as Starts. Time should be different.
Now my event screen looks like this
I have created custom calendar with the help of MBCalender kit and I have add events for some specific dates now, how can I create reminder for those specific dates?
By using EKReminder
- (void)createReminder:(NSDate*) objDate {
EKReminder *reminder = [EKReminder
reminderWithEventStore:objEventStore];
// objEventStore is the object of EKEventStore if you create that global that will be good
reminder.title = #"title";
reminder.notes = #"note";
reminder.calendar = [objAppDelegate.eventStore defaultCalendarForNewReminders];
EKAlarm *alarm = [EKAlarm alarmWithAbsoluteDate:objDate];
[reminder addAlarm:alarm];
NSError *error = nil;
BOOL status = [objAppDelegate.eventStore saveReminder:reminder commit:YES error:&error];
if (status == NO) {
_strUDID = nil;
}
else {
_strUDID = [NSMutableString stringWithFormat:#"%#",reminder.calendarItemIdentifier];
}
}
I'm trying to add an event into calendar with recurrence rule RRULE:FREQ=YEARLY;BYMONTH=6,7;BYDAY=1TH
So according to this rule the event should be added yearly, each 1st thursday of june and july until expire date, which I've set in my project.
In my project, events are created but not according to the recurrence rule. With the following code the events added only on each 1st thursday of june. Why the events are not added on 1st thursday of each july also?
Here is .m file code
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
[self createEvent];
}
- (void)createEvent
{
EKEventStore *eventStore = [[EKEventStore alloc] init];
EKEvent *event = [EKEvent eventWithEventStore:eventStore];
event.title = #"testRecurrenceRule";
event.location = #"Dhaka";
[event setCalendar:[eventStore defaultCalendarForNewEvents]];
event.startDate = [self dateFromString:#"2013-06-18T21:00:00+06:00"];
event.endDate = [self dateFromString:#"2013-06-18T22:00:00+06:00"];
id recurrenceRule = [self recurrenceRuleForEvent];
if(recurrenceRule != nil)
[event addRecurrenceRule:recurrenceRule];
if ([eventStore respondsToSelector:#selector(requestAccessToEntityType:completion:)])
{
// iOS 6 and later
[eventStore requestAccessToEntityType:EKEntityTypeEvent completion:^(BOOL granted, NSError *error) {
if (granted)
{
dispatch_async(dispatch_get_main_queue(), ^{
[self saveTheEvent:event eventStore:eventStore];
//[eventStore saveEvent:event span:EKSpanThisEvent error:error];
});
}
else
{
dispatch_async(dispatch_get_main_queue(), ^{
//do nothing
});
}
}];
}
else
{
[self saveTheEvent:event eventStore:eventStore];
}
textView.text = [NSString stringWithFormat:#"Event has been added with recurrence rule %#",recurrenceRule];
}
- (void)saveTheEvent:(EKEvent *)aEvent eventStore:(EKEventStore *)aStore
{
[aStore saveEvent:aEvent span:EKSpanThisEvent error:NULL];
}
- (EKRecurrenceRule *)recurrenceRuleForEvent
{
//just creating a recurrence rule for RRULE:FREQ=YEARLY;BYMONTH=6,7;BYDAY=1TH
// setting the values directly for testing purpose.
//FREQ=YEARLY
EKRecurrenceFrequency recurrenceFrequency = EKRecurrenceFrequencyYearly;
NSInteger recurrenceInterval = 1;
EKRecurrenceEnd *endRecurrence = nil;
NSMutableArray *monthsOfTheYearArray = [NSMutableArray array];
NSMutableArray *daysOfTheWeekArray = [NSMutableArray array];
NSMutableArray *daysOfTheMonthArray = [NSMutableArray array];
NSMutableArray *weeksOfTheYearArray = [NSMutableArray array];
NSMutableArray *daysOfTheYearArray = [NSMutableArray array];
NSMutableArray *setPositionsArray = [NSMutableArray array];
//BYMONTH=6,7
[monthsOfTheYearArray addObject:[NSNumber numberWithInt:6]];
[monthsOfTheYearArray addObject:[NSNumber numberWithInt:7]];
//BYDAY=1TH
[daysOfTheWeekArray addObject:[EKRecurrenceDayOfWeek dayOfWeek:5 weekNumber:1]];
endRecurrence = [EKRecurrenceEnd recurrenceEndWithEndDate:[self dateFromString:#"2018-12-15T22:30+06:00"]];
EKRecurrenceRule *recurrence = [[EKRecurrenceRule alloc] initRecurrenceWithFrequency:recurrenceFrequency
interval:recurrenceInterval
daysOfTheWeek:daysOfTheWeekArray
daysOfTheMonth:daysOfTheMonthArray
monthsOfTheYear:monthsOfTheYearArray
weeksOfTheYear:weeksOfTheYearArray
daysOfTheYear:daysOfTheYearArray
setPositions:setPositionsArray
end:endRecurrence];
return recurrence;
}
- (NSDate *)dateFromString:(NSString *)string
{
//check if the date string in null
if ([string length] == 0)
return nil;
NSString *dateString = nil;
NSString *modifiedString = nil;
BOOL secSpotMissing = false;
NSRange range = [string rangeOfCharacterFromSet:[NSCharacterSet characterSetWithCharactersInString:#"T"]];
if (range.location != NSNotFound)
{
dateString = [string substringFromIndex:range.location];
range = [dateString rangeOfCharacterFromSet:[NSCharacterSet characterSetWithCharactersInString:#"+-Z"]];
if (range.location != NSNotFound)
{
//seperate the time portion of date string and checking second field is missing or not. like is it HH:mm or HH:mm:ss?
if ([[[dateString substringToIndex:range.location] componentsSeparatedByString:#":"] count] < 3)
secSpotMissing = true;
//seperate the time zone portion and checking is there any extra ':' on it. It should like -0600 not -06:00. If it has that extra ':', just replacing it here.
dateString = [dateString substringFromIndex:range.location];
if([dateString hasSuffix:#"Z"])
modifiedString = [dateString stringByReplacingOccurrencesOfString:#"Z" withString:#"+0000"];
else
modifiedString = [dateString stringByReplacingOccurrencesOfString:#":" withString:#""];
string = [string stringByReplacingOccurrencesOfString:dateString withString:modifiedString];
}
}
else
return nil;
// converting the date string according to it's format.
NSDateFormatter* dateFormatter = [[NSDateFormatter alloc] init];
if (secSpotMissing)
[dateFormatter setDateFormat:#"yyyy-MM-dd'T'HH:mmZZZ"];
else
[dateFormatter setDateFormat:#"yyyy-MM-dd'T'HH:mm:ssZZZ"];
return [dateFormatter dateFromString:string];
}
Can somebody please help me regarding this?
This seems a repeat of another question. Basically, according to "BYDAY" rule, the 1st for YEARLY frequency means the first week in the year - instead of 1st week each month.
#Shuvo, I did not read rfc. But here is Apple document EKRecurrenceDayOfWeek.
The EKRecurrenceDayOfWeek class represents a day of the week for use with an EKRecurrenceRule object. A day of the week can optionally have a week number, indicating a specific day in the recurrence rule’s frequency. For example, a day of the week with a day value of Tuesday and a week number of 2 would represent the second Tuesday of every month in a monthly recurrence rule, and the second Tuesday of every year in a yearly recurrence rule.
When you say "1st Thursday", that is correct - except in the context of yearly, it is 1st thursday of the year.
The bug was confirmed by Apple, at least until iOS 7.1.3 (which is the latest available version at this moment).