I keep running into a pretty frustrating error in Xcode after implementing a date picker. The error in the debugger is: "Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Invalid parameter not satisfying: date"
I've been going through my code for hours now, and can't find the issue. It may be because I'm not checking for nil, there is no date the first time the app installs and launches, so that may be causing the crash. If it is, how do I check for nil in this code? I'm still very new at programming, any help would be much appreciated. Here is the code:
#import "DatePickerViewController.h"
#implementation DatePickerViewController
#synthesize datePicker;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]) {
// Initialization code
}
return self;
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning]; // Releases the view if it doesn't have a superview
// Release anything that's not essential, such as cached data
}
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
UILocalNotification *localNotif = [[UILocalNotification alloc] init];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"mm'/'dd'/'yyyy"];
NSDate *eventDate = [[NSUserDefaults standardUserDefaults] objectForKey:#"DatePickerViewController.selectedDate"];
localNotif.fireDate = [eventDate dateByAddingTimeInterval:-13*60*60];
localNotif.timeZone = [NSTimeZone defaultTimeZone];
localNotif.alertBody = #"Tomorrow!";
localNotif.alertAction = nil;
localNotif.soundName = UILocalNotificationDefaultSoundName;
localNotif.applicationIconBadgeNumber = 0;
[[UIApplication sharedApplication]presentLocalNotificationNow:localNotif];
return YES;
}
- (void)viewDidLoad {
NSDate *storedDate = [[NSUserDefaults standardUserDefaults]
objectForKey:#"DatePickerViewController.selectedDate"];
[self.datePicker setDate:storedDate animated:NO];
}
- (IBAction)dateChanged:(id)sender {
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSDate *selectedDate = [self.datePicker date];
[defaults setObject:selectedDate forKey:#"DatePickerViewController.selectedDate"];
}
You don't check if date is null, before using it, in ex.
(void)viewDidLoad {
NSDate *storedDate = [[NSUserDefaults standardUserDefaults]
objectForKey:#"DatePickerViewController.selectedDate"];
// add this check and set
if (storedDate == nil) {
storedDate = [NSDate date];
}
// ---
[self.datePicker setDate:storedDate animated:NO];
}
I've find a Debug way may help you debug where is the exception occurred and may help someone to debug with exception.
navigate to breakpoint
Click the add button, and choose exception Breakpoint
Add breakpoint and make exception type to Objective-C
Run the code
It will stop at the line which make crash happened!
Hope this help~
Related
I am using local notifications in my app. It's firing ok, but when I open the app from the notification, I can't access notification's userinfo. This is how I am scheduling the notification:
UILocalNotification *notification = [[UILocalNotification alloc] init];
notification.userInfo = #{#"eventId" : eventID};
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
NSLocale *enUSPOSIXLocale = [[NSLocale alloc] initWithLocaleIdentifier:[[NSLocale preferredLanguages] objectAtIndex:0]];
[dateFormatter setLocale:enUSPOSIXLocale];
[dateFormatter setDateFormat:#"yyyy-MM-dd HH:mm:ss.S"];
NSDate *dateStart = [dateFormatter dateFromString: [eventDictionary valueForKey:#"time_start"]];
NSDate *newDate = [[NSDate date] dateByAddingTimeInterval:15];
notification.fireDate = newDate;
notification.timeZone = [NSTimeZone defaultTimeZone];
notification.alertAction = #"Open";
notification.alertBody = #"Some title";
notification.soundName = UILocalNotificationDefaultSoundName;
//cfilipi: todo: verify if event date is bigger than today
if ([newDate timeIntervalSinceNow] > 0) {
[[UIApplication sharedApplication] scheduleLocalNotification:notification];
}
This is how I am handling when I open the app from the notification (AppDelegate.m):
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
if ([launchOptions objectForKey:UIApplicationLaunchOptionsLocalNotificationKey] != nil){
//even when I cast to NSDictionary, it gets other class type (UIConcreteLocalNotification, I can't find any information about this class)
NSDictionary * aPush = (NSDictionary *)[launchOptions objectForKey:UIApplicationLaunchOptionsLocalNotificationKey];
[self handleLocalNotification:aPush];
}
}
-(void)handleLocalNotification:(NSDictionary *)localNotification{
NSDictionary *userInfo = [localNotification objectForKey:#"userinfo"];
NSString *eventId = [userInfo objectForKey:#"eventId"];
if ([eventId length] >= 1) {
//I use this key in some parts of my code
[[NSUserDefaults standardUserDefaults] setObject:eventId forKey:#"eventId"];
[[NSUserDefaults standardUserDefaults] synchronize];
}
}
And this is what I get from LLDB when I am debugging didFinishLaunchingWithOptions:
(lldb) po aPush
<UIConcreteLocalNotification: 0x145b2ba0>{fire date = quinta-feira, 18 de dezembro de 2014 08:47:13 Horário de Verão de Brasília, time zone = America/Sao_Paulo (BRST) offset -7200 (Daylight), repeat interval = 0, repeat count = UILocalNotificationInfiniteRepeatCount, next fire date = (null), user info = {
eventId = 21;
}}
My question is: what am I doing wrong? Is there any way to convert this UIConcreteLocalNotification to NSDictionary? I have tried to convert it to UILocalNotification too, but I had no success.
Regards!
Do like this and it will work fine:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
UILocalNotification *notification = [launchOptions objectForKey:UIApplicationLaunchOptionsLocalNotificationKey];
if ( notification != nil )
{
[self handleLocalNotification:[notification userInfo]];
}
}
You have not implemented
-(void) application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification
Implement this method and try.
I have two view controllers, both connected via Segue and using Storyboard.
In view controller 1 I have an NSTimer counting up and updating a UILabel.
When I switch to view controller 2 and back to 1 the uilabel is no longer updated.
Here is some code:
headerfile
NSString *timerTicksForCounter;
- (void)viewDidLoad
{
[super viewDidLoad];
[self updateTimerLabel];
}
-(void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
[self updateTimerLabel];
}
- (void) startLastConUpdater
{
lastCTimer = [NSTimer scheduledTimerWithTimeInterval:1
target:self
selector:#selector(updateTimer)
userInfo:nil
repeats:YES];
}
-(void) updateTimerLabel
{
NSLog(#"timer: %#", timerTicksForCounter);
if (timerTicksForCounter) {
NSLog(#"timer not null");
mainTimerLabel.text = timerTicksForCounter;
}
}
- (void)updateTimer
{
NSDate *currentDate = [NSDate date];
NSTimeInterval timeInterval = [currentDate timeIntervalSinceDate:stopDate];
NSDate *timerDate = [NSDate dateWithTimeIntervalSince1970:timeInterval];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"mm:ss"];
timerTicksForCounter = [dateFormatter stringFromDate:timerDate];
[self updateTimerLabel];
}
What do you mean it's no longer updated ? Does this mean you lose what was displayed before switching or it doesn't update anymore. If it's not updating anymore it's because you don't start the timer in the appropriate method. You could do something like :
-(void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
[self startLastConUpdater];
}
This should solve both issues I mentioned above.
I have a simple app that has an NSTimer object in the appDelegate to be accessed by all views. The structure of the app is with a UINavigationController. When I fire the NSTimer object, my UILabel is being updated with the correct countdown function, but when I go back to the rootViewController and back to the countdown timer view, my UILabel is being updated with the current countdown time, but no subsequent updates to the UILabel happen. What am I missing? I have done research on making sure the UILabel object is not nil, that I call the function on the viewDidAppear method, and nothing seems to work! Here is the code:
AppDelegate.h
#interface AppDelegate : UIResponder <UIApplicationDelegate> {
}
#property (nonatomic, retain) NSTimer *countdownTimer;
AppDelegate.m
#implementation AppDelegate
#synthesize countdownTimer;
CountdownTimerViewController.h
#import "AppDelegate.h"
enter code here
#interface CountdownTimerViewController : UIViewController {
enter code here
AppDelegate *appdelegate;
}
#property (strong, nonatomic) IBOutlet UILabel *labelCountdownTimer;
#property (strong, nonatomic) IBOutlet UIButton *buttonStartTimer;
#property (strong, nonatomic) IBOutlet UIButton *buttonStopTimer;
- (IBAction)startTimer:(id)sender;
- (IBAction)stopTimer:(id)sender;
CountdownTimerViewController.m
#implementation CountdownTimerViewController
#synthesize labelCountdownTimer;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
//Instatiating Appdelegate
if(!appdelegate)
appdelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
}
- (void) viewDidAppear:(BOOL)animated {
if ([appdelegate.countdownTimer isValid]) {
[self countDown];
}
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - Button Action Methods
- (IBAction)startTimer:(id)sender {
[self updateCounter];
}
- (IBAction)stopTimer:(id)sender {
[appdelegate.countdownTimer invalidate];
labelCountdownTimer.text = #"00:00:00";
}
int countLimit=30; //seconds
NSDate *startDate;
- (void)countDown {
if([[NSDate date] timeIntervalSinceDate:startDate] >= countLimit) {
[appdelegate.countdownTimer invalidate];
return;
}
else {
NSDate *currentDate = [NSDate date];
NSTimeInterval timeInterval = -([currentDate timeIntervalSinceDate:startDate]);
NSDate *timerDate = [NSDate dateWithTimeIntervalSince1970:timeInterval];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"mm:ss"];
[dateFormatter setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0.0]];
NSString *timeString = [dateFormatter stringFromDate:timerDate];
NSLog(#"timeString: %#",timeString);
NSLog(#"labelCountdownTimer: %#",labelCountdownTimer);
labelCountdownTimer.text = timeString;
}
}
- (void)updateCounter {
labelCountdownTimer.text = #"00:00:00";
startDate = [NSDate date];
appdelegate.countdownTimer = [NSTimer scheduledTimerWithTimeInterval:1.0/10.0
target:self
selector:#selector(countDown)
userInfo:nil
repeats:YES];
}
Thanks to everyone for your comments. I actually solved it by performing a method that will go and retrieve the value that the NSTimer is updating in my AppDelegate, since the method firing the NSTimer is no longer in the main thread when I leave the view and come back to it. This method will loop as long as my NSTimer is valid. I also placed a delay, allowing for the UI to update the value, and then perform the method again. Here is the code in case it helps someone running into a similar issue. I got this idea from the suggestion provided by chandan, thanks!!
AppDelegate.h
#interface AppDelegate : UIResponder <UIApplicationDelegate> {
}
#property (nonatomic, retain) NSTimer *countdownTimer;
#property (nonatomic, retain) NSString *timeString;
AppDelegate.m
#interface AppDelegate : UIResponder <UIApplicationDelegate> {
}
#property (nonatomic, retain) NSTimer *countdownTimer;
#property (nonatomic, retain) NSString *timeString;
CountdownTimerViewController.h
#interface CountdownTimerViewController : UIViewController {
AppDelegate *appdelegate;
}
#property (strong, nonatomic) IBOutlet UILabel *labelCountdownTimer;
#property (strong, nonatomic) IBOutlet UIButton *buttonStartTimer;
#property (strong, nonatomic) IBOutlet UIButton *buttonStopTimer;
- (IBAction)startTimer:(id)sender;
- (IBAction)stopTimer:(id)sender;
CountdownTimerViewController.m
#implementation CountdownTimerViewController
#synthesize labelCountdownTimer;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
//Instatiating Appdelegate
if(!appdelegate)
appdelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
}
- (void) viewDidAppear:(BOOL)animated {
if ([appdelegate.countdownTimer isValid]) {
[self updateLabel];
} else {
labelCountdownTimer.text = #"00:00:00";
}
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - Button Action Methods
- (IBAction)startTimer:(id)sender {
[self updateCounter];
}
- (IBAction)stopTimer:(id)sender {
[appdelegate.countdownTimer invalidate];
labelCountdownTimer.text = #"00:00:00";
}
int countLimit=30; //seconds
NSDate *startDate;
- (void)updateCounter {
labelCountdownTimer.text = #"00:00:00";
startDate = [NSDate date];
appdelegate.countdownTimer = [NSTimer scheduledTimerWithTimeInterval:1.0/10.0
target:self
selector:#selector(countDown)
userInfo:nil
repeats:YES];
}
- (void)countDown {
if([[NSDate date] timeIntervalSinceDate:startDate] >= countLimit) {
[appdelegate.countdownTimer invalidate];
return;
}
else {
NSDate *currentDate = [NSDate date];
NSTimeInterval timeInterval = -([currentDate timeIntervalSinceDate:startDate]);
NSDate *timerDate = [NSDate dateWithTimeIntervalSince1970:timeInterval];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"mm:ss"];
[dateFormatter setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0.0]];
appdelegate.timeString = [dateFormatter stringFromDate:timerDate];
labelCountdownTimer.text = appdelegate.timeString;
}
}
- (void) updateLabel {
if ([appdelegate.countdownTimer isValid]) {
labelCountdownTimer.text = appdelegate.timeString;
[self performSelector:#selector(updateLabel) withObject:nil afterDelay:0.05];
}
}
Type casting like this:
appdelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
won't actually make the UIApplicationDelegate into your AppDelegate class and add your extra parameters. Hence there will be no pointer to the timer in this variable.
You need a different approach for storing the timer pointer.
Try to update text on UILabel on main thread. Sometimes updation in UILabel not working on backgound thread.
- (void) viewDidAppear:(BOOL)animated
{
if ([appdelegate.countdownTimer isValid])
{
[self performSelectorOnMainThread:#selector(countDown) withObject:nil waitUntilDone:NO];
}
}
If your appdelegate object is working fine and UILabel is being updated with the current countdown time, but no subsequent updates to the UILabel happen then apply UI changes on main thread like it
- (void)countDown {
[self performSelectorOnMainThread:#selector(changeCountDownValue) withObject:nil waitUntilDone:NO];
}
- (void)changeCountDownValue
{
if([[NSDate date] timeIntervalSinceDate:startDate] >= countLimit) {
[appdelegate.countdownTimer invalidate];
return;
}
else {
NSDate *currentDate = [NSDate date];
NSTimeInterval timeInterval = -([currentDate timeIntervalSinceDate:startDate]);
NSDate *timerDate = [NSDate dateWithTimeIntervalSince1970:timeInterval];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"mm:ss"];
[dateFormatter setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0.0]];
NSString *timeString = [dateFormatter stringFromDate:timerDate];
NSLog(#"timeString: %#",timeString);
NSLog(#"labelCountdownTimer: %#",labelCountdownTimer);
labelCountdownTimer.text = timeString;
}
}
please double check with NSTimer object. It should be working fine for UILabel updation. Please let me know if any problem still occurring.
I have set up a daily reminder local notification for my app. It works great when the app is in the background. However, when the app is closed/not running, when the user taps LAUNCH in the notification, the app launches the main screen, then goes back to the home screen.
I have tried numerous code solutions on here, most involvingsomething along these lines:
- (BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
UILocalNotification *notification = [launchOptions objectForKey:UIApplicationLaunchOptionsLocalNotificationKey];
if (notification) {
// handle your notification here.
}
}
But no matter where I put this, the app launches but now turns to black.
Here is my code, can anyone help me figure out what to do here?
Please not, I am using Dreamweaver/phonegap to build the app.
//
// assignmentAppDelegate.m
// assignment
//
// Created by Noel Chenier on 23 December, 2011.
// Copyright 2011. All rights reserved.
//
#import "assignmentAppDelegate.h"
#import "PhoneGapViewController.h"
#implementation assignmentAppDelegate
- (id) init
{
/** If you need to do any extra app-specific initialization, you can do it here
* -jm
**/
return [super init];
}
/**
* This is main kick off after the app inits, the views and Settings are setup here.
*/
- (void)applicationDidFinishLaunchingWithOptions:(UIApplication *)application
{
{
UILocalNotification *localNotification = [launchOptions objectForKey:UIApplicationLaunchOptionsLocalNotificationKey];
}
[[UIApplication sharedApplication]
registerForRemoteNotificationTypes:
UIRemoteNotificationTypeBadge |
UIRemoteNotificationTypeAlert |
UIRemoteNotificationTypeSound];
NSUserDefaults *defaults =[NSUserDefaults standardUserDefaults];
NSDictionary *appDefaults =[NSDictionary dictionaryWithObject:#"NO" forKey:#"enableNotifications"];
[defaults registerDefaults:appDefaults];
[defaults synchronize];
[ super applicationDidFinishLaunching:application ];
}
- (void)application:(UIApplication *)app didReceiveLocalNotification:(UILocalNotification *)notif {
}
-(id) getCommandInstance:(NSString*)className
{
/** You can catch your own commands here, if you wanted to extend the gap: protocol, or add your
* own app specific protocol to it. -jm
**/
if ([[NSUserDefaults standardUserDefaults] boolForKey:#"enableNotifications"]) {
[[UIApplication sharedApplication] cancelAllLocalNotifications];
[UIApplication sharedApplication].applicationIconBadgeNumber = 0;
NSCalendar *calender = [NSCalendar autoupdatingCurrentCalendar];
NSDate *currentDate = [NSDate date];
NSDateComponents *dateComponents = [calender components:(NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit | NSHourCalendarUnit | NSMinuteCalendarUnit)
fromDate:currentDate];
NSDateComponents *temp = [[NSDateComponents alloc]init];
[temp setYear:[dateComponents year]];
[temp setMonth:[dateComponents month]];
[temp setDay:[dateComponents day]];
[temp setHour: 9];
[temp setMinute:00];
NSDate *fireTime = [calender dateFromComponents:temp];
[temp release];
// set up the notifier
UILocalNotification *localNotification = [[UILocalNotification alloc]init];
localNotification.fireDate = fireTime;
localNotification.timeZone = [NSTimeZone defaultTimeZone];
localNotification.alertBody = #"Don't Forget Your 365 Day Photo Challenge!";
localNotification.alertAction = #"LAUNCH";
localNotification.soundName = UILocalNotificationDefaultSoundName;
localNotification.repeatInterval = NSMinuteCalendarUnit;
localNotification.applicationIconBadgeNumber = 0;
[[UIApplication sharedApplication]scheduleLocalNotification:localNotification];
[localNotification release];
}
else {[[UIApplication sharedApplication] cancelAllLocalNotifications];}
return [super getCommandInstance:className];
}
/**
Called when the webview finishes loading. This stops the activity view and closes the imageview
*/
- (void)webViewDidFinishLoad:(UIWebView *)theWebView
{
return [ super webViewDidFinishLoad:theWebView ];
}
- (void)webViewDidStartLoad:(UIWebView *)theWebView
{
return [ super webViewDidStartLoad:theWebView ];
}
/**
* Fail Loading With Error
* Error - If the webpage failed to load display an error with the reson.
*/
- (void)webView:(UIWebView *)theWebView didFailLoadWithError:(NSError *)error
{
return [ super webView:theWebView didFailLoadWithError:error ];
}
/**
* Start Loading Request
* This is where most of the magic happens... We take the request(s) and process the response.
* From here we can re direct links and other protocalls to different internal methods.
*/
- (BOOL)webView:(UIWebView *)theWebView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{
return [ super webView:theWebView shouldStartLoadWithRequest:request navigationType:navigationType ];
}
- (BOOL) execute:(InvokedUrlCommand*)command
{
return [ super execute:command];
}
- (void)dealloc
{
[ super dealloc ];
}
#end
For local notification,you need to add following things in :
- (void)applicationDidFinishLaunchingWithOptions:(UIApplication *)application
{
UILocalNotification *localNotification = [launchOptions objectForKey:UIApplicationLaunchOptionsLocalNotificationKey];
}
- (void)application:(UIApplication *)app didReceiveLocalNotification:(UILocalNotification *)notif {
}
As it turns out...
I'm not sure why it was crashing, but in the event anyone else having this problem comes across this, the notification will launch the app when your build for relase....it just doesnt appear to work when it's built/run for debug or another state.
So when you run, run for RELEASE and it should work just fine!
I have an app that generates prayer times (5 times a day) i want to create notfication for the 5 prayers but the issue is the times change everyday based on some calculations.
Edit:
The calculations are done based on GPS location so when the user changes to another city the times will be updated accordingly. I input the date,timezone, GPS coordinates into a method and I get prayer time values in (HH:mm) format for that given day/location. Now I need to setup the Notfications. I'm not sure where to set them up.
here is the code
#import "PrayerTimeViewController.h"
#import "PrayTime.h"
#implementation PrayerTimeViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
UITabBarItem *tbi = [self tabBarItem];
[tbi setTitle:NSLocalizedString(#"PrayerTimes", nil)];
UIImage *i = [UIImage imageNamed:#"11-clock"];
[tbi setImage:i];
[i release];
}
return self;
}
- (void)didReceiveMemoryWarning
{
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
#pragma mark - View lifecycle
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
UIColor *background = [[UIColor alloc] initWithPatternImage:[UIImage imageNamed:#"Madinah"]];
self.view.backgroundColor = background;
[background release];
locationManager = [[CLLocationManager alloc]init];
[locationManager setDelegate:self];
[locationManager setDesiredAccuracy:kCLLocationAccuracyBest];
[locationManager setDistanceFilter:kCLDistanceFilterNone];
[locationManager startUpdatingLocation];
}
- (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
{
NSTimeInterval t = [[newLocation timestamp] timeIntervalSinceNow];
if (t < -180) {
return;
}
PrayTime *prayerTime = [[PrayTime alloc]init];
[prayerTime setCalcMethod:0];
[prayerTime setFajrAngle:16];
[prayerTime setIshaAngle:14];
[prayerTime setAsrMethod:0];
NSDate *curentDate = [NSDate date];
NSCalendar* calendar = [NSCalendar currentCalendar];
NSDateComponents* compoNents = [calendar components:NSYearCalendarUnit|NSMonthCalendarUnit|NSDayCalendarUnit fromDate:curentDate];
CLLocationCoordinate2D currLoc = [newLocation coordinate];
NSMutableArray *prayerCal = [prayerTime getDatePrayerTimes:[compoNents year] andMonth:[compoNents month] andDay:[compoNents day] andLatitude:currLoc.latitude andLongitude:currLoc.longitude andtimeZone:[[NSTimeZone localTimeZone] secondsFromGMT]/3600];
[prayerTime release];
[fajer setText:[prayerCal objectAtIndex:0]];
// UILocalNotification *localNotification = [[UILocalNotification alloc] init];
NSString *time = [prayerCal objectAtIndex:0];
NSString *dates = [NSString stringWithFormat:#"%d-%d-%d %#",[compoNents year],[compoNents month],[compoNents day],time];
NSDateFormatter *dateText = [[NSDateFormatter alloc]init];
[dateText setDateFormat:#"yyyy-MM-dd HH:mm"];
[dateText setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:[[NSTimeZone localTimeZone] secondsFromGMT]]];
NSLog(#"%#",[dateText dateFromString:dates]);
[shrooq setText:[prayerCal objectAtIndex:1]];
[duhur setText:[prayerCal objectAtIndex:2]];
[aser setText:[prayerCal objectAtIndex:3]];
[maghreb setText:[prayerCal objectAtIndex:5]];
[isha setText:[prayerCal objectAtIndex:6]];
[prayerCal release];
}
#end
You can use the repeatInterval parameter to repeat your five notifications, making them appear at the same time every day. Unfortunately there's no way to adjust the time without running your app.
You can run a GPS app in the background, though that would be quite a drain on the battery just for setting some timers. (This background process is really designed for GPS tracker apps. I'm not sure what Apple would make of using it for a slightly different purpose.)
But the easiest way would be just to update when the app is launched. When it launches you would get the current notifications (using the scheduledLocalNotifications property of UIApplication), cancel them if they're incorrect or out of date and create new ones. Each notification has a dictionary payload that you can use to make it easier to identify your alarms.