How to create ios LocalNotification from array of dates? - ios

I have an array of dates
NSArray *datesArray=[NSArray arrayWithObjects: #"2014-09-14 00:00:00",#"2014-08-21 07:12:36",#"2014-08-14 00:00:00",#"2014-07-14 00:00:00",#"2014-06-14 00:00:00",#"2015-01-01 10:00:00",#"2014-06-14 00:00:00",#"2014-05-14 11:24:15", nil];
now i want to fire one day before the date available in array
How to implement it?
I was trying this
NSDateFormatter *Formatter1 = [[NSDateFormatter alloc] init];
[Formatter1 setLocale:[[NSLocale alloc] initWithLocaleIdentifier:NSLocaleIdentifier]];
[Formatter1 setTimeZone:[NSTimeZone timeZoneWithName:#"UTC"]];
[Formatter1 setDateFormat:#"yyyy-MM-dd HH:mm:ss"];
UILocalNotification *localNotif = [[UILocalNotification alloc] init];
NSDate *date1 =[NSDate date];
NSString *string =[Formatter1 stringFromDate:date1];
NSLog(#"sring %#",string);
NSDate *todaydate =[Formatter1 dateFromString:string];
NSLog(#"2day date is %#",todaydate);
for (int i=0;i<datesArray.count;i++)
{
NSDate *_date =[Formatter1 dateFromString:[datesArray objectAtIndex:i ]];
NSLog(#"date is %#",_date);
if(_date == todaydate){
localNotif.fireDate = _date;
localNotif.alertBody = #"festival";
localNotif.alertAction=#"Show me";
localNotif.applicationIconBadgeNumber = 1;
localNotif.soundName = UILocalNotificationDefaultSoundName;
[[UIApplication sharedApplication] scheduleLocalNotification:localNotif];
}

You can subtract a day by using the NSCalendar functions, specifically dateByAddingComponents
NSArray *datesArray = #[#"2014-09-14 00:00:00",#"2014-08-21 07:12:36",#"2014-08-14 00:00:00",#"2014-07-14 00:00:00",#"2014-06-14 00:00:00",#"2015-01-01 10:00:00",#"2014-06-14 00:00:00",#"2014-05-14 11:24:15"];
NSCalendar *calendar = [NSCalendar currentCalendar];
NSDateComponents *dateComponents = [[NSDateComponents alloc] init];
[dateComponents setDay:-1];
NSDateFormatter *Formatter1 = [[NSDateFormatter alloc] init];
[Formatter1 setLocale:[[NSLocale alloc] initWithLocaleIdentifier:NSLocaleIdentifier]];
[Formatter1 setTimeZone:[NSTimeZone timeZoneWithName:#"UTC"]];
[Formatter1 setDateFormat:#"yyyy-MM-dd HH:mm:ss"];
[datesArray enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
UILocalNotification *localNotif = [[UILocalNotification alloc] init];
localNotif.fireDate = [calendar dateByAddingComponents:dateComponents toDate:[Formatter1 dateFromString:obj] options:0];
localNotif.alertBody = #"festival";
localNotif.alertAction = #"Show me";
localNotif.applicationIconBadgeNumber = 1;
localNotif.soundName = UILocalNotificationDefaultSoundName;
[[UIApplication sharedApplication] scheduleLocalNotification:localNotif];
}];
W

Related

How to connect viewcontroller to NSObject class file?

I want to connect and pass the action from ViewController to NSObject class file. In my viewcontroller, there is UISwitch Button and if I switch I want to work it in NSObject class file.
When switch is ON from viewcontroller (UIView) then the action have to work in NSObject class file.
I'm coding with Objective-C.
Here is my ViewController.m and I did this in only ViewController file. Not connected to NSOBject class file.
- (void)viewDidLoad{
[super viewDidLoad];
//UISwitch work at viewDidload
[self.mySwitch addTarget:self
action:#selector(stateChanged:) forControlEvents:UIControlEventValueChanged]; }
- (void)stateChanged:(UISwitch *)switchState{
NSLog(#"current calendar: %#", [[NSCalendar currentCalendar] calendarIdentifier]);
//get the date today
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateStyle:NSDateFormatterMediumStyle];
[formatter setCalendar:[NSCalendar currentCalendar]];
NSString *dateToday = [formatter stringFromDate:[NSDate date]];
NSLog(#"Today Date is: %#", [NSDate date]);
self.myLabel.text=dateToday;
if ([switchState isOn]) {
//[formatter setLocale:[[NSLocale alloc] initWithLocaleIdentifier:#"en_US#calendar=japanese"]];
[formatter setCalendar:[[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierJapanese]];
[formatter setDateFormat:#"yyyy-MM-dd HH:mm:ss"];
[formatter setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0]];
NSString *dateToday = [formatter stringFromDate:[NSDate date]];
UILabel *dtDate = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 320.0f, 20.0f)];
[dtDate setText:dateToday];
self.myLabel.text =dateToday;
NSString *locale = [[NSLocale currentLocale] localeIdentifier];
NSLog(#"current date is: %#", dateToday);
NSLog(#"current locale: %#", locale);
} else {
//[formatter setLocale:[[NSLocale alloc] initWithLocaleIdentifier:#"en_US"]];
[formatter setCalendar:[NSCalendar autoupdatingCurrentCalendar]];
[formatter setDateFormat:#"yyyy-MM-dd HH:mm:ss"];
[formatter setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0]];
NSString *dateToday = [formatter stringFromDate:[NSDate date]];
UILabel *myLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 320.0f, 20.0f)];
[myLabel setText:dateToday];
self.myLabel.text =dateToday;
// NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
// [formatter setDateStyle:NSDateFormatterMediumStyle];
NSString *locale = [[NSLocale currentLocale] localeIdentifier];
NSLog(#"current locale: %#", locale);
NSLog(#"%#", [formatter stringFromDate: [NSDate date]]);
}
}
If you need just an action then use class methods else create a global variable or a notification observer in NSObject extended class when you get call back from the switch.
- (void)callback:(id)sender
{
[MyObject switchState:sender.state];
}

PHFetchOptions predicate with NSDate compare

Hello I had been working with Photos.framework but now I am stuck with predicate comparison of PHFetchOptions class in documents I see that we can use startDate to use in predicate. So my code is this
#interface ViewController ()
{
NSMutableArray * moments;
}
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
moments = [NSMutableArray array];
if([PHPhotoLibrary authorizationStatus] == PHAuthorizationStatusNotDetermined)
{
[PHPhotoLibrary requestAuthorization:^(PHAuthorizationStatus status) {
[self loadCollections];
}];
}else
{
[self loadCollections];
}
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
[self loadCollections];
}
- (NSDate*)dateAddingDays:(NSInteger)days ToDate:(NSDate*)argDate
{
NSCalendar * gregorian = [NSCalendar currentCalendar];
NSDateFormatter * formatter = [[NSDateFormatter alloc]init];
[formatter setDateFormat:#"dd.MM.yyyy"];
NSString * dateString = [formatter stringFromDate:argDate];
NSDate * toWorkDate = [formatter dateFromString:dateString];
NSDateComponents *comps = [[NSDateComponents alloc] init];
[comps setDay:days];
NSDate *date = [gregorian dateByAddingComponents:comps toDate:toWorkDate options:0];
NSLog(#"%#",[formatter stringFromDate:date]);
return date;
}
- (void)loadCollections
{
PHFetchOptions * options = [[PHFetchOptions alloc]init];
options.predicate = [NSComparisonPredicate predicateWithFormat:#"startDate > CAST(%d,\"NSDate\")",[self dateAddingDays2:-1 ToDate:[NSDate date]].timeIntervalSince1970];
PHFetchResult * result = [PHAssetCollection fetchMomentsWithOptions:options];
if(result != nil)
{
NSLog(#"%i",result.count);
for (int i = 0; i < result.count; i++) {
NSLog(#"%#",[result objectAtIndex:i]);
[moments addObject:[result objectAtIndex:i]];
}
}
}
So my problem is this, I need fetch fotos from one day ago, I can make this work!! any help will be appreciated.
This is the answer, basically I replaced
- (NSDate*)dateAddingDays:(NSInteger)days ToDate:(NSDate*)argDate
{
NSCalendar * gregorian = [NSCalendar currentCalendar];
NSDateFormatter * formatter = [[NSDateFormatter alloc]init];
[formatter setDateFormat:#"dd.MM.yyyy"];
NSString * dateString = [formatter stringFromDate:argDate];
NSDate * toWorkDate = [formatter dateFromString:dateString];
NSDateComponents *comps = [[NSDateComponents alloc] init];
[comps setDay:days];
NSDate *date = [gregorian dateByAddingComponents:comps toDate:toWorkDate options:0];
NSLog(#"%#",[formatter stringFromDate:date]);
return date;
}
by
- (NSDate*)yesterday
{
NSCalendar * gregorian = [NSCalendar currentCalendar];
return [gregorian startOfDayForDate:[gregorian dateByAddingUnit:NSCalendarUnitDay value:-1 toDate:[NSDate date] options:NSCalendarWrapComponents]];
}
and also replace this
options.predicate = [NSComparisonPredicate predicateWithFormat:#"startDate > CAST(%d,\"NSDate\")",[self dateAddingDays2:-1 ToDate:[NSDate date]].timeIntervalSince1970];
by this
options.predicate = [NSComparisonPredicate predicateWithFormat:#"(startDate > %#)",[self yesterday]];
and now is working!!! thanks to #Larme

Display a local notification at a fixed time, ios?

I am using the below code to display the notification at a fixed time. However it just does not fit my output.
- (IBAction)bt_set:(id)sender {
// Setting all the information about our date
int hour = 8;
int minutes = 19;
int day = 19;
int month = 10;
int year = 2014;
NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSDateComponents *components = [[NSDateComponents alloc] init];
[components setDay:day];
[components setMonth:month];
[components setYear:year];
[components setMinute:minutes];
[components setHour:hour];
NSDate *myNewDate = [calendar dateFromComponents:components];
//[components release];
//[calendar release];
[self scheduleNotificationForDate:myNewDate];
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Note"
message:#"Alarm has been set"
delegate:self
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alert show];
}
This is the notfication code
- (void)scheduleNotificationForDate:(NSDate *)date
{
// Here we cancel all previously scheduled notifications
[[UIApplication sharedApplication] cancelAllLocalNotifications];
UILocalNotification *localNotification = [[UILocalNotification alloc] init];
localNotification.fireDate = date;
NSLog(#"%#",date);
NSLog(#"Notification will be shown on: %#",localNotification.fireDate);
localNotification.timeZone = [NSTimeZone defaultTimeZone];
localNotification.alertBody = [NSString stringWithFormat:#"Your notification message"];
localNotification.alertAction = NSLocalizedString(#"View details", nil);
/* Here we set notification sound and badge on the app's icon "-1"
means that number indicator on the badge will be decreased by one
- so there will be no badge on the icon */
localNotification.soundName = UILocalNotificationDefaultSoundName;
localNotification.applicationIconBadgeNumber = -1;
[[UIApplication sharedApplication] scheduleLocalNotification:localNotification];
}
This is the date I get in the log
Notification will be shown on: 2014-10-19 02:49:00 +0000
I guess it has something to do with the time zone.
I have the time zone of GMT+5:30
Please help me out
You have some (NSDate *)date----
Add below code to get the appropriate system time:
NSTimeZone* sourceTimeZone = [NSTimeZone timeZoneWithAbbreviation:#"GMT"];
NSTimeZone* destinationTimeZone = [NSTimeZone systemTimeZone];
NSInteger sourceGMTOffset = [sourceTimeZone secondsFromGMTForDate:sourceDate];
NSInteger destinationGMTOffset = [destinationTimeZone secondsFromGMTForDate:sourceDate];
NSTimeInterval interval = destinationGMTOffset - sourceGMTOffset;
NSDate* destinationDate = [[NSDate alloc] initWithTimeInterval:interval sinceDate:sourceDate];

Location Notification matching current date to date of object

I have several objects inside an array, each object has it's own date.
I want to fire a local notification whenever the the current date == object date.
I have some code, i would like someone to tell me if it makes sense and if it should work, i have taken care of the delegates and reloadData method.
Here is the code:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"LiveIdent";
LiveViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
LiveMatchObject *item = [tableDataLiveMatch objectAtIndex:(int)([indexPath row]/2)];
if ([item isKindOfClass:[LiveMatchObject class]]) {
NSString * dateString = [NSString stringWithFormat: #"%#",item.matchDate];
NSDateFormatter* dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"yyyy-MM-dd'T'HH:mm:ssZ"];
NSDate* myDate = [dateFormatter dateFromString:dateString];
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:#"'Hoje ás' HH:mm 'horas"];
NSString *stringFromDate = [formatter stringFromDate:myDate];
//// starts here the notification code
// create a timer to keep track of the current date
NSDate *now = [NSDate date];
NSDateFormatter *daterFormatter = [[NSDateFormatter alloc] init];
[daterFormatter setTimeZone:[NSTimeZone systemTimeZone]];
// if current date = date stored in the object then do this
if (myDate == now){
UILocalNotification* localNotification = [[UILocalNotification alloc] init];
localNotification.fireDate = myDate;
localNotification.alertBody = #"Início da partida";
localNotification.alertAction = #"Show me the item";
localNotification.timeZone = [NSTimeZone defaultTimeZone];
[[UIApplication sharedApplication] scheduleLocalNotification:localNotification];
[[NSNotificationCenter defaultCenter] postNotificationName:#"reloadData" object:self];
}
NSArray *localNotifications = [[UIApplication sharedApplication] scheduledLocalNotifications];
UILocalNotification *localNotification = [localNotifications objectAtIndex:indexPath.row];
[cell.textLabel setText:localNotification.alertBody];
[cell.detailTextLabel setText:[localNotification.fireDate description]];
return cell;
}
Should this work or this is a total disaster?
P.S - i cannot test, because i reads from live events which actually will occur tomorrow, so i'll have to wait, to see it for myself.
Thank you.
Yes your code is looking good but you can test your local-notification by setting some near time instead of waiting for tomorrow here is the code which I used in my project:
NSCalendar *calendar = [NSCalendar currentCalendar];
NSDateComponents *components = [[NSDateComponents alloc] init];
[components setDay: 16];
[components setMonth: 3];
[components setYear: 2014];
[components setHour: 10];
[components setMinute:32];
[components setSecond: 0];
[calendar setTimeZone: [NSTimeZone defaultTimeZone]];
NSDate *dateToFire = [calendar dateFromComponents:components];
Hope this will helps you.

iOS sort an NSArray of Time NSString's

I need to sort an NSArray containing time NSString's such as,
NSMutableArray *times = [[NSMutableArray alloc]initWithObjects:#"09:00 AM",#"07:30 AM",#"06:45 PM",#"05:00 PM",#"12:45 AM",#"12:45 PM",#"01:00 AM",#"01:15 PM", nil];
What I need is to sort the array in ascending order of time.
Is there any way to do such a thing?
NSMutableArray *times = [[NSMutableArray alloc]initWithObjects:#"09:00 AM",#"07:30 AM",#"06:45 PM",#"05:00 PM",#"12:45 AM",#"12:45 PM",#"01:00 AM",#"01:15 PM", nil];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"hh:mm a"];
NSArray *sortedTimes = [times sortedArrayUsingComparator:^NSComparisonResult(NSString *obj1, NSString *obj2)
{
NSDate *date1 = [dateFormatter dateFromString:obj1];
NSDate *date2 = [dateFormatter dateFromString:obj2];
return [date1 compare:date2];
}];
optimized version:
NSMutableArray *times = [[NSMutableArray alloc]initWithObjects:#"09:00 AM",#"07:30 AM",#"06:45 PM",#"05:00 PM",#"12:45 AM",#"12:45 PM",#"01:00 AM",#"01:15 PM", nil];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"hh:mm a"];
NSMutableArray *dates = [NSMutableArray arrayWithCapacity:times.count];
for (NSString *timeString in times)
{
NSDate *date = [dateFormatter dateFromString:timeString];
[dates addObject:date];
}
[dates sortUsingSelector:#selector(compare:)];
NSMutableArray *sortedTimes = [NSMutableArray arrayWithCapacity:dates.count];
for (NSDate *date in dates)
{
NSString *timeString = [dateFormatter stringFromDate:date];
[sortedTimes addObject:timeString];
}
You can try this code:
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:#"hh:mm a"];
[times sortUsingComparator:^NSComparisonResult(NSString* obj1, NSString *obj2) {
NSDate *firstDate = [formatter dateFromString:obj1];
NSDate *secondDate = [formatter dateFromString:obj2];
return [firstDate compare:secondDate];
}];
As these are strings it will be sored as
01:15, 12:25, 05:00....
And they are not either NSDate.
So you need to do is that Create a parallel array having NSDate from these strings, sort the array, and extract these values.
While implementing I solved it by novice-way
NSMutableArray *times = [[NSMutableArray alloc]initWithObjects:#"09:00 AM",#"07:30 AM",#"06:45 PM",#"05:00 PM",#"12:45 AM",#"12:45 PM",#"01:00 AM",#"01:15 PM", nil];
NSMutableArray *dates=[NSMutableArray new];
NSDateFormatter *dateFormatter=[NSDateFormatter new];
[dateFormatter setDateFormat:#"hh:mm a"];
for (NSString *stringDate in times) {
NSDate *date=[dateFormatter dateFromString:stringDate];
[dates addObject:date];
}
NSSortDescriptor *descriptor = [[NSSortDescriptor alloc] initWithKey:#"self" ascending:YES];
NSArray *descriptors = [NSArray arrayWithObject: descriptor];
NSArray *reverseOrder = [dates sortedArrayUsingDescriptors:descriptors];
[times removeAllObjects];
for (NSDate *date in reverseOrder) {
NSString *string=[dateFormatter stringFromDate:date];
[times addObject:string];
}
NSLog(#"%#",times);
For NSDate Comparison use this:
+ (BOOL)isDate:(NSDate *)date1 smallerThanAnotherDate:(NSDate *)date2
{
NSDate* enddate = date1;
NSDate* currentdate = date2;
NSTimeInterval distanceBetweenDates = [enddate timeIntervalSinceDate:currentdate];
double secondsInMinute = 60;
NSInteger secondsBetweenDates = distanceBetweenDates / secondsInMinute;
if (secondsBetweenDates <= 0)
return YES;
else
return NO;
}
So If you do not want to convert your hours to NSDate do this alone it works for me
NSArray *sortedTimes = [times sortedArrayUsingSelector:#selector(localizedStandardCompare:)];

Resources