I need to return the longitude and latitude from this method. This is from the locationManager code. When I log the lat, longt they give the correct values.
What I have been unable to do is to work out you to export/return the variables out of this method. How should I go about changing it?
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation {
int degrees = newLocation.coordinate.latitude;
double decimal = fabs(newLocation.coordinate.latitude - degrees);
int minutes = decimal * 60;
double seconds = decimal * 3600 - minutes * 60;
self.lat = [NSString stringWithFormat:#"%d° %d' %1.4f\"", degrees, minutes, seconds];
NSLog(#"Current Latitude : %#",self.lat);
degrees = newLocation.coordinate.longitude;
decimal = fabs(newLocation.coordinate.longitude - degrees);
minutes = decimal * 60;
seconds = decimal * 3600 - minutes * 60;
self.longt = [NSString stringWithFormat:#"%d° %d' %1.4f\"", degrees, minutes, seconds];
NSLog(#"Current Longitude : %#",self.longt);
[manager stopUpdatingLocation];
}
You don't need to return the location from that method because you're not going to call that method yourself -- the Location Manager will call that method to give you an updated location. What you should do is to store the new location so that your code can use it later. Usually, that just means updating your instance variables, but you can do whatever you want with the location -- update you data model, write it out to a text file, etc. Storing it in ivars makes it easy to access the location whenever you need it in your code.
Related
There are MANY Q&A's for limiting to only 2 decimal places, to the point of over saturation.
However, I would like to format my float to only get the decimal value.
I'm making a stopwatch, and currently have this...
#implementation HudLayer
{
CCLabelTTF *_label;
float timer;
}
-(void)update:(ccTime)delta { if (_isTimerActive)
{
timer += delta;
NSNumber *theDouble = [NSNumber numberWithDouble:timer];
float miliseconds = timer;
int inputSeconds = [theDouble intValue];
int hours = inputSeconds / 3600;
int minutes = ( inputSeconds - hours * 3600 ) / 60;
NSString *theTime = [NSString stringWithFormat:#"%.2d:%.2d:%.2f", hours, minutes, miliseconds];
[_label setString:[NSString stringWithFormat:#"Time: %#", theTime]];
}
}
However, the issue I'm having is that the timer reads out put on to the label showing the full seconds...
00:14:865.35
Instead it should just be:
00:14:05.35
HH:MM:SS.ms
My first thought was to just drop the decimal from the outputted float, and manually calculate seconds as i do hours and minutes...
Any advice? Thanks...
Try following
timer += delta;
float float_seconds = timer;
int seconds = float_seconds;
int hours = seconds / 3600;
int minutes = seconds / 60 % 60;
NSString *theTime = [NSString stringWithFormat:#"%.2d:%.2d:%05.2f", hours, minutes, float_seconds - ( seconds / 60) * 60];
NSLog(theTime);
[_label setString:[NSString stringWithFormat:#"Time: %#", theTime]];
I'm new to objective C.
i've been playing around with a countdown for some time now and i cant seem to make it work.
i've connecting very thing in storyboard and the buttons react, but it seems like its just randomly counting down.
why i isnt it counting down like 10:00 to 09:59.
- (void)showActivity{
int currentTime = [time.text intValue];
int newTime = currentTime - 1;
int seconds = newTime % 60;
int minutes = (newTime / 60) % 60;
time.text = [NSString stringWithFormat:#"%02d:%02d", minutes, seconds];
}
If time.text is "10:00", then calling [time.text intValue] is just going to return the integer 10.
I'd recommend creating a separate variable (perhaps an NSTimeInterval) that keeps track of how many seconds are left, and then make the time text label just responsible for displaying that as minutes:seconds.
e.g.
#property NSTimeInterval time;
#property UILabel *timeLabel; // "time" in your original code
- (void)showActivity {
NSTimeInterval newTime = self.time - 1;
int minutes = floor(newTime / 60);
int seconds = round(newTime - (minutes * 60));
self.timeLabel.text = [NSString stringWithFormat:#"%02d:%02d", minutes, seconds];
self.time = newTime;
}
My actual problem is - How to obtain a CLLocation Object when the coordinate value on the map is available in Degree-Minute-Second form (as a String), instead of Double.
So, I am Looking for a way to convert Degree-Minute-Second to Double, which i can use to form a CLLocation object.
I came up with a bit of a cleaner answer when figuring this out
// split the string to deal with lat and lon separately
NSArray *parts = [dmsString componentsSeparatedByString:#","];
NSString *latStr = parts[0];
NSString *lonStr = parts[1];
// convert each string
double lat = [self degreesStringToDecimal:latStr];
double lon = [self degreesStringToDecimal:lonStr];
// init your location object
CLLocation *loc = [[CLLocation alloc] initWithLatitude:lat longitude:lon];
The magic
- (double)degreesStringToDecimal:(NSString*)string
{
// split the string
NSArray *splitDegs = [string componentsSeparatedByString:#"\u00B0"]; // unicode for degree symbol
NSArray *splitMins = [splitDegs[1] componentsSeparatedByString:#"'"];
NSArray *splitSecs = [splitMins[1] componentsSeparatedByString:#"\""];
// get each segment of the dms string
NSString *degreesString = splitDegs[0];
NSString *minutesString = splitMins[0];
NSString *secondsString = splitSecs[0];
NSString *direction = splitSecs[1];
// convert degrees
double degrees = [degreesString doubleValue];
// convert minutes
double minutes = [minutesString doubleValue] / 60; // 60 degrees in a minute
// convert seconds
double seconds = [secondsString doubleValue] / 3600; // 60 seconds in a minute, or 3600 in a degree
// add them all together
double decimal = degrees + minutes + seconds;
// determine if this is negative. south and west would be negative values
if ([direction.uppercaseString isEqualToString:#"W"] || [direction.uppercaseString isEqualToString:#"S"])
{
decimal = -decimal;
}
return decimal;
}
Note that I've only tested this with coordinates in Wisconsin, which is North and West. I'm using this tool to verify my calculations.
Let's say you have a the coordinate value in a String -
Split the String To obtain Degree-Minute-Second values in separate strings.
NSString *longlat= #"+39° 44' 39.28", -104° 50' 5.86" "(find a way to escape the " in the string)
//separate lat and long
NSArray *splitLonglat = [longlat componentsSeparatedByString:#","];
//separate Degree-Minute-Seconds
NSArray *arrayLat = [[splitLonglat objectAtIndex:0] componentsSeparatedByString:#" "];
double latitude,longitude;
if([arrayLat count]==3){
//get the double value for latitude
latitude= [self convertDMSToDD_deg:(NSString *)[arrayLat objectAtIndex:0]//degree
min:(NSString *)[arrayLat objectAtIndex:1]//minute
sec:(NSString *)[arrayLat objectAtIndex:2]//seconds
];
}else{
//some values could be in decimal form in the String already, instead of Degree-Minute-Second form and we might not need to convert them.
NSLog(#"latitude in decimal for %#",locationModelObject.name);
latitude=[[splitLonglat objectAtIndex:0]doubleValue];
}
NSArray *arrayLong= [[splitLonglat objectAtIndex:1] componentsSeparatedByString:#" "];
if([arrayLong count]==4){
//get the double value for longitude
longitude= [self convertDMSToDD_deg:(NSString *)[arrayLong objectAtIndex:1]//degree
min:(NSString *)[arrayLong objectAtIndex:2]//minute
sec:(NSString *)[arrayLong objectAtIndex:3]//seconds
];
}else{
//some values could be in decimal form in the String already, instead of Degree-Minute-Second form and we might not need to convert them.
NSLog(#"longitude in decimal for %#",locationModelObject.name);
longitude=[[splitLonglat objectAtIndex:1]doubleValue];
}
//add latitude longitude to the model object
locationModelObject.latitude=latitude;
locationModelObject.longitude=longitude;
The Method which does the conversion
-(double) convertDMSToDD_deg:(NSString*)degrees min:(NSString* )minutes sec:(NSString*)seconds {
int latsign=1;
double degree=[degrees doubleValue];
double minute=[minutes doubleValue];
double second=[seconds doubleValue];
if (degree<0){
latsign = -1;
}
else{
latsign=1;
}
double dd = (degree + (latsign* (minute/60.)) + (latsign* (second/3600.) ) ) ;
return dd;
}
I´m following the http://www.switchonthecode.com/tutorials/getting-your-location-in-an-iphone-application tutorial, but I can´t not get mi latitude and longitude in my Xcode SDK.
- (void)viewDidLoad {
[super viewDidLoad];
locationManager = [[CLLocationManager alloc] init];
locationManager.delegate = self;
[locationManager startUpdatingLocation];
}
- (void)locationManager:(CLLocationManager *)manager
didUpdateToLocation:(CLLocation *)newLocation
fromLocation:(CLLocation *)oldLocation
{
int degrees = newLocation.coordinate.latitude;
double decimal = fabs(newLocation.coordinate.latitude - degrees);
int minutes = decimal * 60;
double seconds = decimal * 3600 - minutes * 60;
NSString *lat = [NSString stringWithFormat:#"%d° %d' %1.4f\"",
degrees, minutes, seconds];
//latLabel.text = lat;
degrees = newLocation.coordinate.longitude;
decimal = fabs(newLocation.coordinate.longitude - degrees);
minutes = decimal * 60;
seconds = decimal * 3600 - minutes * 60;
NSString *longt = [NSString stringWithFormat:#"%d° %d' %1.4f\"",
degrees, minutes, seconds];
NSLog(#"%# %#",longt, lat);
}
It don´t show me the latitude and longitude in the Console.
Help me please.
Your code looks fine. If it does not work - the issue is not here.
Make sure:
You running it on a device (not emulator)
Your device has SIM installed and connected to cellular network
It's very good idea to have the device connected to WiFi with Internet access.
All these things will help GPS to fix the position faster using assisted GPS.
Also, take into account that Core Location returns last known position almost immediately. It's stale and may be wrong, but provided immediately. If do not getting anything at all - it looks like the issue with Core Location on your device, not with the application.
Also, it's good idea to implement locationManager:didFailWithError: method to catch possible errors. Like disabled GPS.
Here is example for this method:
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error
{
NSLog(#"GPS Error: %#", [error localizedDescription]);
}
GPS position fixing may take few minutes for 3Gs and early, and about 10 seconds for 4 and 4S (assuming clear sky view in both cases)
I'm creating a countdown timer and I need to printout the time left (hour:minute:seconds) until a specific date. I've found how to get the time interval between Now and the target date but I don't know how to format the time interval as a string. Does NSDateFormater work on NSTimeInterval?
NSTimeInterval is in seconds, use divide and remainder to break it up and format (code untested):
NSString *timeIntervalToString(NSTimeInterval interval)
{
long work = (long)interval; // convert to long, NSTimeInterval is *some* numeric type
long seconds = work % 60; // remainder is seconds
work /= 60; // total number of mins
long minutes = work % 60; // remainder is minutes
long hours = work / 60 // number of hours
// now format and return - %ld is long decimal, %02ld is zero-padded two digit long decimal
return [NSString stringWithFormat:#"%ld:%02ld:%02ld", hours, minutes, seconds];
}
You would first compare two NSDate objects to retrieve the difference in seconds between the two, the NSDate method you should use is
- (NSTimeInterval)timeIntervalSinceDate:(NSDate *)anotherDate
Then you could simply write a function to parse the seconds into hours/minutes/seconds, for example you could use this (untested):
-(NSDictionary*)createTimemapForSeconds:(int)seconds{
int hours = floor(seconds / (60 * 60) );
float minute_divisor = seconds % (60 * 60);
int minutes = floor(minute_divisor / 60);
float seconds_divisor = seconds % 60;
seconds = ceil(seconds_divisor);
NSDictionary * timeMap = [NSDictionary dictionaryWithObjects:[NSArray arrayWithObjects:[NSNumber numberWithInt:hours], [NSNumber numberWithInt:minutes], [NSNumber numberWithInt:seconds], nil] forKeys:[NSArray arrayWithObjects:#"h", #"m", #"s", nil]];
return timeMap;
}
This is code from my project:
-(NSString*)timeLeftString
{
long seconds = [self msLeft]/1000;
if( seconds == 0 )
return #"";
if( seconds < 60 )
return [NSString stringWithFormat:
pluralString(seconds,
NSLocalizedString(#"en|%ld second left|%ld seconds left", #"")), seconds];
long minutes = seconds / 60;
seconds -= minutes*60;
if( minutes < 60 )
return [NSString stringWithFormat:
NSLocalizedString(#"%ld:%02ld left",#""),
minutes, seconds];
long hours = minutes/60;
minutes -= hours*60;
return [NSString stringWithFormat:
NSLocalizedString(#"%ld:%02ld:%02ld left",#""),
hours, minutes, seconds];
}
msLeft --- my function that returns time in milliseconds
pluralString --- my function that provides different parts of format string depending on the value (http://translate.sourceforge.net/wiki/l10n/pluralforms)
Function returns different format for different timer values (1 second left, 5 seconds left, 2:34 left, 1:15:14 left).
In any case, progress bad should be visible during long operation
One more thought: In case that time left is "small" (less then a minute?), probably time left should not be shown --- just progress bar left to reduce interface "visual noise".