From 0bae3630a39c9b4652030c6736d45c5bae9bffb4 Mon Sep 17 00:00:00 2001 From: Jose Cabal-Ugaz Date: Mon, 6 Jan 2014 16:28:54 -0500 Subject: [PATCH 1/3] frequency/daysInWeek/daysInMonth/daysInYear/weeksInMonth recurring event fixes and context checks --- sdk/internal/ANAdWebViewController.m | 114 ++++++++++++++++++++++----- 1 file changed, 96 insertions(+), 18 deletions(-) diff --git a/sdk/internal/ANAdWebViewController.m b/sdk/internal/ANAdWebViewController.m index 61863cbbe..a3af048e2 100644 --- a/sdk/internal/ANAdWebViewController.m +++ b/sdk/internal/ANAdWebViewController.m @@ -408,6 +408,7 @@ - (void)moviePlayerDidFinish:(NSNotification *)notification - (void)createCalendarEventFromW3CCompliantJSONObject:(NSString *)json{ NSError* error; NSDictionary* jsonDict = [NSJSONSerialization JSONObjectWithData:[json dataUsingEncoding:NSUTF8StringEncoding] options:kNilOptions error:&error]; + ANLogDebug(@"%@ %@ | NSDictionary from JSON Calendar Object: %@", NSStringFromClass([self class]), NSStringFromSelector(_cmd), jsonDict); NSString* description = [jsonDict objectForKey:@"description"]; NSString* location = [jsonDict objectForKey:@"location"]; @@ -460,7 +461,10 @@ - (void)createCalendarEventFromW3CCompliantJSONObject:(NSString *)json{ } else { event.endDate = [event.startDate dateByAddingTimeInterval:3600]; // default to 60 mins } - + + ANLogDebug(@"%@ %@ | JSON Object Start Date: %@, End Date: %@", NSStringFromClass([self class]), NSStringFromSelector(_cmd), start, end); + ANLogDebug(@"%@ %@ | Event Start Date: %@, End Date: %@", NSStringFromClass([self class]), NSStringFromSelector(_cmd), event.startDate, event.endDate); + if([df1 dateFromString:reminder]!=nil){ [event addAlarm:[EKAlarm alarmWithAbsoluteDate:[df1 dateFromString:reminder]]]; }else if([df2 dateFromString:reminder]!=nil){ @@ -484,10 +488,17 @@ - (void)createCalendarEventFromW3CCompliantJSONObject:(NSString *)json{ NSDictionary* repeat = [jsonDict objectForKey:@"recurrence"]; if ([repeat isKindOfClass:[NSDictionary class]]) { NSString* frequency = [repeat objectForKey:@"frequency"]; - EKRecurrenceFrequency frequency_ios = [frequency isEqualToString:@"daily"] ? EKRecurrenceFrequencyDaily: - ([frequency isEqualToString:@"weekly"]? EKRecurrenceFrequencyWeekly: - ([frequency isEqualToString:@"monthly"]?EKRecurrenceFrequencyMonthly: - ([frequency isEqualToString:@"yearly"]? EKRecurrenceFrequencyYearly:-1))); + EKRecurrenceFrequency frequency_ios; + + if ([frequency isEqualToString:@"daily"]) frequency_ios = EKRecurrenceFrequencyDaily; + else if ([frequency isEqualToString:@"weekly"]) frequency_ios = EKRecurrenceFrequencyWeekly; + else if ([frequency isEqualToString:@"monthly"]) frequency_ios = EKRecurrenceFrequencyMonthly; + else if ([frequency isEqualToString:@"yearly"]) frequency_ios = EKRecurrenceFrequencyYearly; + else { + ANLogError(@"%@ %@ | Invalid W3 frequency passed in: %@. Acceptable values are 'daily','weekly','monthly', and 'yearly'", NSStringFromClass([self class]), NSStringFromSelector(_cmd), frequency); + return; + } + int interval = [[repeat objectForKey:@"interval"] intValue]; if (interval < 1) { interval = 1; @@ -508,21 +519,88 @@ - (void)createCalendarEventFromW3CCompliantJSONObject:(NSString *)json{ * iOS Not supported * NSArray* exceptionDates = [repeat objectForKey:@"exceptionDates"]; */ - NSArray* daysInWeek = [repeat objectForKey:@"daysInWeek"]; - NSArray* daysInMonth = [repeat objectForKey:@"daysInMonth"]; - NSArray* daysInYear = [repeat objectForKey:@"daysInYear"]; - NSArray* weeksInMonth = [repeat objectForKey:@"weeksInMonth"]; - NSArray* monthsInYear = [repeat objectForKey:@"monthsInYear"]; + + NSArray* monthsInYear = [repeat objectForKey:@"monthsInYear"]; // Apple & W3 valid values from 1 to 12, inclusive. - EKRecurrenceRule* rrule = [[EKRecurrenceRule alloc] initRecurrenceWithFrequency:frequency_ios - interval:interval daysOfTheWeek:daysInWeek - daysOfTheMonth:daysInMonth - monthsOfTheYear:monthsInYear - weeksOfTheYear:weeksInMonth - daysOfTheYear:daysInYear - setPositions:nil end:end]; + NSMutableArray* daysInWeek = [[repeat objectForKey:@"daysInWeek"] mutableCopy]; // Need a mutable copy of the array in order to transform NSNumber => EKRecurrenceDayOfWeek + + for (NSInteger daysInWeekIndex=0; daysInWeekIndex < [daysInWeek count]; daysInWeekIndex++) { + NSInteger dayInWeekValue = [daysInWeek[daysInWeekIndex] integerValue]; // W3 value should be between 0 and 6 inclusive. + if (dayInWeekValue >= 0 && dayInWeekValue <= 6) { + daysInWeek[daysInWeekIndex] = [EKRecurrenceDayOfWeek dayOfWeek:dayInWeekValue++]; // Apple expects day of week value to be between 1 and 7 inclusive. + } else { + ANLogError(@"%@ %@ | Invalid W3 day of week passed in: %d. Value should be between 0 and 6 inclusive.", NSStringFromClass([self class]), NSStringFromSelector(_cmd), dayInWeekValue); + return; + } + } + + + NSMutableArray* daysInMonth = [[repeat objectForKey:@"daysInMonth"] mutableCopy]; + + for (NSInteger daysInMonthIndex=0; daysInMonthIndex < [daysInMonth count]; daysInMonthIndex++) { + NSInteger dayInMonthValue = [daysInMonth[daysInMonthIndex] integerValue]; // W3 value should be between -30 and 31 inclusive. + if (dayInMonthValue >= -30 && dayInMonthValue <= 31) { + if (dayInMonthValue <= 0) { // W3 reverse values from 0 to -30, Apple reverse values from -1 to -31 (0 and -1 meaning last day of month respectively) + daysInMonth[daysInMonthIndex] = [NSNumber numberWithInteger:dayInMonthValue--]; + } + } else { + ANLogError(@"%@ %@ | Invalid W3 day of month passed in: %d. Value should be between -30 and 31 inclusive.", NSStringFromClass([self class]), NSStringFromSelector(_cmd), dayInMonthValue); + return; + } + } + + NSMutableArray* daysInYear = [[repeat objectForKey:@"daysInYear"] mutableCopy]; + + for (NSInteger daysInYearIndex=0; daysInYearIndex < [daysInYear count]; daysInYearIndex++) { + NSInteger dayInYearValue = [daysInYear[daysInYearIndex] integerValue]; // W3 value should be between -364 and 365 inclusive. (W3 doesn't care about leap years?) + if (dayInYearValue >= -364 && dayInYearValue <= 365) { + if (dayInYearValue <= 0) { // W3 reverse values from 0 to -364, Apple reverse values from -1 to -366 + daysInYear[daysInYearIndex] = [NSNumber numberWithInteger:dayInYearValue--]; + } + } else { + ANLogError(@"%@ %@ | Invalid W3 day of year passed in: %d. Value should be between -364 and 365 inclusive.", NSStringFromClass([self class]), NSStringFromSelector(_cmd), dayInYearValue); + return; + } + } + + if (frequency_ios == EKRecurrenceFrequencyMonthly) { // Need to implement W3 weeksInMonth for monthly occurrences + NSArray* weeksInMonth = [repeat objectForKey:@"weeksInMonth"]; + NSMutableArray *updatedDaysInWeek = [[NSMutableArray alloc] init]; + + for (NSNumber* weekNumber in weeksInMonth) { + NSInteger weekNumberValue = [weekNumber integerValue]; + if (weekNumberValue >= -3 && weekNumberValue <= 4) { // W3 value should be between -3 and 4 inclusive. + for (EKRecurrenceDayOfWeek* day in daysInWeek) { + if (weekNumberValue <= 0) { // W3 reverse values from 0 to -3, Apple reverse values from -1 to -4 + weekNumberValue--; + } + ANLogDebug(@"%@ %@ | Adding EKRecurrenceDayOfWeek object with day number %d and week number %d", NSStringFromClass([self class]), NSStringFromSelector(_cmd), day.dayOfTheWeek, weekNumberValue); + [updatedDaysInWeek addObject:[EKRecurrenceDayOfWeek dayOfWeek:day.dayOfTheWeek weekNumber:weekNumberValue]]; + } + } else { + ANLogError(@"%@ %@ | Invalid W3 week of month passed in: %d. Value should be between -3 and 4 inclusive.", NSStringFromClass([self class]), NSStringFromSelector(_cmd), weekNumberValue); + return; + } + } - [event setRecurrenceRules:[NSArray arrayWithObjects:rrule, nil]]; + daysInWeek = updatedDaysInWeek; + } + + EKRecurrenceRule* rrule = [[EKRecurrenceRule alloc] initRecurrenceWithFrequency:frequency_ios + interval:interval + daysOfTheWeek:daysInWeek // Not valid for EKRecurrenceFrequencyDaily + daysOfTheMonth:daysInMonth // Only valid for EKRecurrenceFrequencyMonthly + monthsOfTheYear:monthsInYear // Only valid for EKRecurrenceFrequencyYearly + weeksOfTheYear:nil // Only valid for EKRecurrenceFrequencyYearly + daysOfTheYear:daysInYear // Only valid for EKRecurrenceFrequencyYearly + setPositions:nil + end:end]; + + if (rrule) { // EKRecurrenceRule will return nil if invalid values are passed in + [event setRecurrenceRules:[NSArray arrayWithObjects:rrule, nil]]; + } else { + ANLogError(@"%@ %@ | Invalid EKRecurrenceRule Values Passed In.", NSStringFromClass([self class]), NSStringFromSelector(_cmd)); + } } NSError* error = nil; From 37bc3b549d8343667b4427715e317b6b130b969b Mon Sep 17 00:00:00 2001 From: Jose Cabal-Ugaz Date: Mon, 6 Jan 2014 18:07:34 -0500 Subject: [PATCH 2/3] ANLogError in recurring calendar event function changed to ANLogWarn; Parameters computed and passed into initRecurrenceWithFrequency:interval:daysOfTheWeek:daysOfTheMonth:monthsOfTheYear:weeksOfTheYear:daysOfTheYear:setPositions:end: based on necessity to reduce potential for conflicts, errors, and exceptions. Code restructured around necessities based on frequency. --- sdk/internal/ANAdWebViewController.m | 110 +++++++++++++++------------ 1 file changed, 62 insertions(+), 48 deletions(-) diff --git a/sdk/internal/ANAdWebViewController.m b/sdk/internal/ANAdWebViewController.m index a3af048e2..6edf2af6a 100644 --- a/sdk/internal/ANAdWebViewController.m +++ b/sdk/internal/ANAdWebViewController.m @@ -129,16 +129,17 @@ - (void)webViewDidFinishLoad:(UIWebView *)webView { [webView firePlacementType:[self.mraidDelegate adType]]; [webView setIsViewable:(BOOL)!webView.hidden]; - [webView fireStateChangeEvent:ANMRAIDStateDefault]; - [webView fireReadyEvent]; - + self.adFetcher.loading = NO; self.completedFirstLoad = YES; + [webView fireStateChangeEvent:ANMRAIDStateDefault]; + [webView fireReadyEvent]; + ((ANWebView *)webView).safety = YES; - + ANAdResponse *response = [ANAdResponse adResponseSuccessfulWithAdObject:webView]; [self.adFetcher processFinalResponse:response]; - + //Set screen size [self setScreenSizeForMRAIDGetScreenSizeFunction:webView]; @@ -495,7 +496,7 @@ - (void)createCalendarEventFromW3CCompliantJSONObject:(NSString *)json{ else if ([frequency isEqualToString:@"monthly"]) frequency_ios = EKRecurrenceFrequencyMonthly; else if ([frequency isEqualToString:@"yearly"]) frequency_ios = EKRecurrenceFrequencyYearly; else { - ANLogError(@"%@ %@ | Invalid W3 frequency passed in: %@. Acceptable values are 'daily','weekly','monthly', and 'yearly'", NSStringFromClass([self class]), NSStringFromSelector(_cmd), frequency); + ANLogWarn(@"%@ %@ | Invalid W3 frequency passed in: %@. Acceptable values are 'daily','weekly','monthly', and 'yearly'", NSStringFromClass([self class]), NSStringFromSelector(_cmd), frequency); return; } @@ -519,54 +520,38 @@ - (void)createCalendarEventFromW3CCompliantJSONObject:(NSString *)json{ * iOS Not supported * NSArray* exceptionDates = [repeat objectForKey:@"exceptionDates"]; */ - - NSArray* monthsInYear = [repeat objectForKey:@"monthsInYear"]; // Apple & W3 valid values from 1 to 12, inclusive. NSMutableArray* daysInWeek = [[repeat objectForKey:@"daysInWeek"] mutableCopy]; // Need a mutable copy of the array in order to transform NSNumber => EKRecurrenceDayOfWeek for (NSInteger daysInWeekIndex=0; daysInWeekIndex < [daysInWeek count]; daysInWeekIndex++) { NSInteger dayInWeekValue = [daysInWeek[daysInWeekIndex] integerValue]; // W3 value should be between 0 and 6 inclusive. if (dayInWeekValue >= 0 && dayInWeekValue <= 6) { - daysInWeek[daysInWeekIndex] = [EKRecurrenceDayOfWeek dayOfWeek:dayInWeekValue++]; // Apple expects day of week value to be between 1 and 7 inclusive. + daysInWeek[daysInWeekIndex] = [EKRecurrenceDayOfWeek dayOfWeek:dayInWeekValue+1]; // Apple expects day of week value to be between 1 and 7 inclusive. } else { - ANLogError(@"%@ %@ | Invalid W3 day of week passed in: %d. Value should be between 0 and 6 inclusive.", NSStringFromClass([self class]), NSStringFromSelector(_cmd), dayInWeekValue); + ANLogWarn(@"%@ %@ | Invalid W3 day of week passed in: %d. Value should be between 0 and 6 inclusive.", NSStringFromClass([self class]), NSStringFromSelector(_cmd), dayInWeekValue); return; } } - - - NSMutableArray* daysInMonth = [[repeat objectForKey:@"daysInMonth"] mutableCopy]; - - for (NSInteger daysInMonthIndex=0; daysInMonthIndex < [daysInMonth count]; daysInMonthIndex++) { - NSInteger dayInMonthValue = [daysInMonth[daysInMonthIndex] integerValue]; // W3 value should be between -30 and 31 inclusive. - if (dayInMonthValue >= -30 && dayInMonthValue <= 31) { - if (dayInMonthValue <= 0) { // W3 reverse values from 0 to -30, Apple reverse values from -1 to -31 (0 and -1 meaning last day of month respectively) - daysInMonth[daysInMonthIndex] = [NSNumber numberWithInteger:dayInMonthValue--]; - } - } else { - ANLogError(@"%@ %@ | Invalid W3 day of month passed in: %d. Value should be between -30 and 31 inclusive.", NSStringFromClass([self class]), NSStringFromSelector(_cmd), dayInMonthValue); - return; - } - } - - NSMutableArray* daysInYear = [[repeat objectForKey:@"daysInYear"] mutableCopy]; - - for (NSInteger daysInYearIndex=0; daysInYearIndex < [daysInYear count]; daysInYearIndex++) { - NSInteger dayInYearValue = [daysInYear[daysInYearIndex] integerValue]; // W3 value should be between -364 and 365 inclusive. (W3 doesn't care about leap years?) - if (dayInYearValue >= -364 && dayInYearValue <= 365) { - if (dayInYearValue <= 0) { // W3 reverse values from 0 to -364, Apple reverse values from -1 to -366 - daysInYear[daysInYearIndex] = [NSNumber numberWithInteger:dayInYearValue--]; + + NSMutableArray* daysInMonth = nil; // Only valid for EKRecurrenceFrequencyMonthly + if (frequency_ios == EKRecurrenceFrequencyMonthly) { + NSMutableArray* daysInMonth = [[repeat objectForKey:@"daysInMonth"] mutableCopy]; + + for (NSInteger daysInMonthIndex=0; daysInMonthIndex < [daysInMonth count]; daysInMonthIndex++) { + NSInteger dayInMonthValue = [daysInMonth[daysInMonthIndex] integerValue]; // W3 value should be between -30 and 31 inclusive. + if (dayInMonthValue >= -30 && dayInMonthValue <= 31) { + if (dayInMonthValue <= 0) { // W3 reverse values from 0 to -30, Apple reverse values from -1 to -31 (0 and -1 meaning last day of month respectively) + daysInMonth[daysInMonthIndex] = [NSNumber numberWithInteger:dayInMonthValue-1]; + } + } else { + ANLogWarn(@"%@ %@ | Invalid W3 day of month passed in: %d. Value should be between -30 and 31 inclusive.", NSStringFromClass([self class]), NSStringFromSelector(_cmd), dayInMonthValue); + return; } - } else { - ANLogError(@"%@ %@ | Invalid W3 day of year passed in: %d. Value should be between -364 and 365 inclusive.", NSStringFromClass([self class]), NSStringFromSelector(_cmd), dayInYearValue); - return; } - } - - if (frequency_ios == EKRecurrenceFrequencyMonthly) { // Need to implement W3 weeksInMonth for monthly occurrences - NSArray* weeksInMonth = [repeat objectForKey:@"weeksInMonth"]; + + NSArray* weeksInMonth = [repeat objectForKey:@"weeksInMonth"]; // Need to implement W3 weeksInMonth for monthly occurrences NSMutableArray *updatedDaysInWeek = [[NSMutableArray alloc] init]; - + for (NSNumber* weekNumber in weeksInMonth) { NSInteger weekNumberValue = [weekNumber integerValue]; if (weekNumberValue >= -3 && weekNumberValue <= 4) { // W3 value should be between -3 and 4 inclusive. @@ -578,28 +563,57 @@ - (void)createCalendarEventFromW3CCompliantJSONObject:(NSString *)json{ [updatedDaysInWeek addObject:[EKRecurrenceDayOfWeek dayOfWeek:day.dayOfTheWeek weekNumber:weekNumberValue]]; } } else { - ANLogError(@"%@ %@ | Invalid W3 week of month passed in: %d. Value should be between -3 and 4 inclusive.", NSStringFromClass([self class]), NSStringFromSelector(_cmd), weekNumberValue); + ANLogWarn(@"%@ %@ | Invalid W3 week of month passed in: %d. Value should be between -3 and 4 inclusive.", NSStringFromClass([self class]), NSStringFromSelector(_cmd), weekNumberValue); return; } } daysInWeek = updatedDaysInWeek; } + + NSArray *monthsInYear = nil; + NSMutableArray* daysInYear = nil; + + if (frequency_ios == EKRecurrenceFrequencyYearly) { + monthsInYear = [repeat objectForKey:@"monthsInYear"]; // Apple & W3 valid values from 1 to 12, inclusive. + + for (NSNumber *monthInYear in monthsInYear) { + NSInteger monthInYearValue = [monthInYear integerValue]; + if (monthInYearValue < 0 && monthInYearValue > 12) { + ANLogWarn(@"%@ %@ | Invalid W3 month passed in: %d. Value should be between 1 and 12 inclusive.", NSStringFromClass([self class]), NSStringFromSelector(_cmd), monthInYearValue); + } + } + + daysInYear = [[repeat objectForKey:@"daysInYear"] mutableCopy]; + + for (NSInteger daysInYearIndex=0; daysInYearIndex < [daysInYear count]; daysInYearIndex++) { + NSInteger dayInYearValue = [daysInYear[daysInYearIndex] integerValue]; // W3 value should be between -364 and 365 inclusive. (W3 doesn't care about leap years?) + if (dayInYearValue >= -364 && dayInYearValue <= 365) { + if (dayInYearValue <= 0) { // W3 reverse values from 0 to -364, Apple reverse values from -1 to -366 + daysInYear[daysInYearIndex] = [NSNumber numberWithInteger:dayInYearValue-1]; + } + } else { + ANLogWarn(@"%@ %@ | Invalid W3 day of year passed in: %d. Value should be between -364 and 365 inclusive.", NSStringFromClass([self class]), NSStringFromSelector(_cmd), dayInYearValue); + return; + } + } + } EKRecurrenceRule* rrule = [[EKRecurrenceRule alloc] initRecurrenceWithFrequency:frequency_ios interval:interval - daysOfTheWeek:daysInWeek // Not valid for EKRecurrenceFrequencyDaily - daysOfTheMonth:daysInMonth // Only valid for EKRecurrenceFrequencyMonthly - monthsOfTheYear:monthsInYear // Only valid for EKRecurrenceFrequencyYearly - weeksOfTheYear:nil // Only valid for EKRecurrenceFrequencyYearly - daysOfTheYear:daysInYear // Only valid for EKRecurrenceFrequencyYearly + daysOfTheWeek:daysInWeek + daysOfTheMonth:daysInMonth + monthsOfTheYear:monthsInYear + weeksOfTheYear:nil + daysOfTheYear:daysInYear setPositions:nil end:end]; if (rrule) { // EKRecurrenceRule will return nil if invalid values are passed in [event setRecurrenceRules:[NSArray arrayWithObjects:rrule, nil]]; + ANLogWarn(@"%@ %@ | Created Recurrence Rule: %@", NSStringFromClass([self class]), NSStringFromSelector(_cmd), rrule); } else { - ANLogError(@"%@ %@ | Invalid EKRecurrenceRule Values Passed In.", NSStringFromClass([self class]), NSStringFromSelector(_cmd)); + ANLogWarn(@"%@ %@ | Invalid EKRecurrenceRule Values Passed In.", NSStringFromClass([self class]), NSStringFromSelector(_cmd)); } } From 3238797793dbb84783e4bc21c82fea09cab38013 Mon Sep 17 00:00:00 2001 From: Jose Cabal-Ugaz Date: Tue, 7 Jan 2014 10:20:09 -0500 Subject: [PATCH 3/3] Added return for invalid monthsInYear value --- sdk/internal/ANAdWebViewController.m | 1 + 1 file changed, 1 insertion(+) diff --git a/sdk/internal/ANAdWebViewController.m b/sdk/internal/ANAdWebViewController.m index 6edf2af6a..d1a6d420e 100644 --- a/sdk/internal/ANAdWebViewController.m +++ b/sdk/internal/ANAdWebViewController.m @@ -581,6 +581,7 @@ - (void)createCalendarEventFromW3CCompliantJSONObject:(NSString *)json{ NSInteger monthInYearValue = [monthInYear integerValue]; if (monthInYearValue < 0 && monthInYearValue > 12) { ANLogWarn(@"%@ %@ | Invalid W3 month passed in: %d. Value should be between 1 and 12 inclusive.", NSStringFromClass([self class]), NSStringFromSelector(_cmd), monthInYearValue); + return; } }