I am creating a map application in Objective-C, for iPhone. I know how to get the current location of the user, and the destination location. As a user travels, his coordinates (latitude and longitude) change.
How can I save the latitude and longitude of the user in an SQLite database every five minutes as the user travels?
I doubt you really always want to store the coordinates every 5 minutes. When using Core Location you subscribe to events that the user has changed position (and you can set accuracy) so you can get notified when the user has moved at all, and then choose to store the coordinates in a database. If you don't get events, then you know the user hasn't changed position.
You can use a timer and set time interval to 300, as shown below
[NSTimer scheduledTimerWithTimeInterval:300 target:self selector:#selector(*savetodatabase*) userInfo:nil repeats:YES];
Make one function which is called every 5 mins and save it to database.
NOTE: Here 300 is in seconds
You can call a method by using NSTimer which will add lat and long do database.
[NSTimer scheduledTimerWithTimeInterval:<(NSTimeInterval)ti> target:<(id)aTarget> selector:<(SEL)aSelector> userInfo:<(id)userInfo> repeats:<(BOOL)yesOrNo>]
you can use timer that after every 5 min a call to SAVEDATABASEFILE method
Related
I'm programming a data logging application. I need to be able to store a time interval typed in by the user using Core Data. For instance, if the user completes a task in seven minutes and twenty-three seconds, he/she can type 7:28 into the NSTextField and that will be part of the data.
What class should I use to store the time? NSDate seems to be the right way of doing it, but it does not seem to store time intervals. I see that there is an NSTimeInterval class. However, with no particular reference for it, I do not know how to use it.
Also, when this time interval is stored in objects within Core Data, I need to be able to retrieve those items and sort them (using NSSortDescriptor); in order to retrieve the entry that logged the lowest time interval. This is just additional information to help figure out what I need to do here.
From the docs: NSDate objects represent a single point in time.
From your use case it sounds like you want the user to log a relative time, and then to be able to sort by which is the smallest. In that case, NSDate is not a good option. The best solution is to just store the time interval as an NSUInteger, where the integer represents your value in seconds, and then do the appropriate conversions on either end.
If the user types in 7:28, could you convert this into seconds (448 seconds) and store it in a NSUInteger? That would make sorting it easily because you would not have to deal with separate minute and second values.
Here's what I think you should do:
Have two fields for user input: one for minutes and one for seconds.
Have some code like this:
NSInteger totalTime1 = 0;
totalTime += [minuteField.text integerValue]*60;
totalTime += [secondField.text integerValue];
Now store totalTime1 using Core Data. To retrieve the times and sort them, do something like this:
//Retrive times
NSArray *retrievedTimes = [NSArray arrayWithObjects: time1FromCoreDataAsNSNumber, time2FromCoreDataAsNSNumber, etc, nil];
NSArray *sortedRetrievedTimes = [retrievedTimes sortedArrayUsingSelector:#selector(compare:)];
//Now the array is sorted from lowest to highest
NSInteger lowestValue = [[sortedRetrievedTimes objectAtIndex:0] integerValue];
Hope this helps!
I'm trying to access the remaining time of an NSTimer X. I want to update the title of a button every second to reflect remaining mm:ss until zero. I couldn't find anything here.
For example: [btY setTitle:[What to insert here?] forState:UIControlStateSelected];
Or would you rather solve this in a different way?
You can use fireDate
NSTimer *timer = [NSTimer timerWithInterval:1.0 target:self selector:#selector(updateButton) userInfo:nil repeats:YES];
- (void)updateButton:(NSTimer*)timer
{
float timeRemaining = timer.fireDate.timeIntervalSinceNow;
// Format timeRemaining into your preferred string form and
// update the button text
}
This is generally not how you would solve this.
Create a repeating NSTimer set to the resolution at which you want to update the button instead.
So for instance, if you want your button to change every second until zero, create a NSTimer like so:
NSTimer *timer = [NSTimer timerWithInterval:1.0 target:self selector:#selector(updateButton) userInfo:nil repeats:YES];
Then implement updateButton; basically have a counter for remaining seconds, and every time updateButton gets called, decrease the counter by one, and update the title of the button.
You will not be able to get this kind of information, instead you will need to run the timer several times, for example, if you want to update the button with a text one time each 30 seconds, instead of starting a timer with 30 seconds start a timer with 1 sec and repeat it 30 times
I'm currently working on an app that will show a label that will start at zero, and count up to a number I specify. I wanted to do this using a simple loop like this one.
for (counterInt = 0; counterInt < 10; counterInt++)
{
NSLog(#"%i",counterInt);
}
The problem is, that this loop executes in less time than it takes for the view to appear on screen. My console logs 1-9 before the view finally loads with the label with showing 9. I've been researching for several hours trying to find a way to specify a duration for the loop and I can't seem to find any thing on this.
So my overall question is, is it possible to specify how long the loop should take to execute? If so, if anyone can point me in the right direction here it would be greatly appreciated!
Even if you slowed down the loop, it still wouldn't work. UI elements are only updated at the end of the run loop. You need to set up a timer and update the label in the method fired by the timer.
You're using the wrong approach. Try an NSTimer.
[NSTimer scheduledTimerWithTimeInterval:5.0
target:self
selector:#selector(incrementLabel:)
userInfo:nil
repeats:YES];
Then create a method called incrementLabel and have it increment an instance variable and update the label accordingly.
You can sleep a thread:
[NSThread sleepForTimeInterval:1];
However, jrturton and james supply the correct approach. I would place James' code in the viewDidAppear method so your label starts where you want it and the counter begins when the view appears.
I am trying to create an NSTimer that counts up from 00:00:00 to whenever the user presses stop. I have created an NSDateInterval of 1 second, but I can't get it to count up from 00:00:00, only the current date or a date that I set.
What is the best way to do this? And is NSTimer the best way to do this or should I just get the difference between the time the user presses the first button ([NSDate date] to set it) and the time at that second (a selector fired off by NSTimer)? I want to make sure there is as little accuracy fault as possible, and I am aware of NSTimer's problems with accuracy sometimes.
Save the time the timer starts with [NSDate date], and then record the time it stops as well. The display time will be the difference, displayed as you listed. The NSTimer will be used just to trigger an update, and you can set the interval fairly small, say 1/10th of a second. Something like:
[NSTimer scheduledTimerWithTimeInterval: 0.1f target: self
selector: #selector(updateTimeDisplay) userInfo: nil repeats: YES];
I got an table which is filled with VM's and i have 2 variable of the datatype NSIndexPath called:
selectedindexpath(the row the user clicks on) and
selectedindexpathFortheVMtoTurnOn(so it knows which row to reload when the VM went on);
which is both made in the .h as #paramters(retain) ..
i got a function that turns on the VM's and a function that CHECKS every 1 sec with a NSTimer if the guest is finally on then it reloads the row of selectedindexpathFortheVMtoTurnOn
im doing the same for OFF/REBOOT but i have got a problem with this.. im not able to request an action for more then 1 VM.. because it is overwriting the selectedindexpathFortheVMtoTurnOn value with the last row which i sent an action to and by doing so the table responds wierd and the app crashes..
so thats why i want to give the indexpath.row value as parameters with the NSTimer to the function that checks every 1 sec i have tried a few things but none have worked.. below the code of how i am giving the parameters
timertocallguest=[NSTimer scheduledTimerWithTimeInterval:1
target:self
selector:#selector(gettheguestyouaskedforTOTURNON:)
userInfo:selectedindexpathFortheVMtoTurnOn
repeats:YES];
and the function:
-(void)gettheguestyouaskedforTOTURNON:(NSIndexPath *)therow
and when i try to do a NSLog("%d",therow.row); it crashes...
and with NSLog("%d",therow); i get a whole diffrent value of the selectedindexpathFortheVMtoTurnOn that it used to had..
what am i doing wrong.?
sorry if its a wall of text. but i realy need to fix this problem as this is getting released as BETA nextweek in the appstore for the company where my traineeperiode is.
ty in advance.
EDIT:
i will try to show it with pictures this time.
At first im at the view with VM's
http://imageshack.us/photo/my-images/194/schermafbeelding2011052l.png/
after that i can press on the button with the arrow and i get to choose what i want to do.
http://imageshack.us/photo/my-images/822/schermafbeelding2011052r.png/
an activity indicator appears and it stops when the action is done.(which has to do with the NStimer that checks every 1 sec)
http://imageshack.us/photo/my-images/828/schermafbeelding2011052y.png/
http://imageshack.us/photo/my-images/811/schermafbeelding2011052t.png/
but when i try to do an action at 2 or more VM's the activity indicator on the last row i selected spins *x faster(depends on how manny actions i send.. 2 actions means it spins 2 times faster..(so weird)
.. i hope this is enough for you to understand what i mean now =)
The method triggered by an NSTimer object always has the timer as the argument. You can get the row like this.
-(void)gettheguestyouaskedforTOTURNON:(NSTimer *)timer {
NSIndexPath *indexPath = (NSIndexPath*)[timer userInfo];
NSLog(#"%d", indexPath.row);
}