13

I have two CLLocation objects and I would like the show the distance between them in a nice and pretty format. Like "22 feet", "58 yards", or "2.3 miles"

CLLocation *location1 = [[CLLocation alloc] initWithLatitude:42.333297 longitude:-71.588858];
CLLocation *location2 = [[CLLocation alloc] initWithLatitude:42.353297 longitude:-71.578858];

float target = [location1 getDistanceFrom:location2];

Basically, is there anything in the iOS library that can convert a distance to a pretty string or do I have to do this manually?

coudron
  • 317
  • 2
  • 10

6 Answers6

47

iOS 7 (and OS X 10.9) introduced MKDistanceFormatter that does exactly what you need:

CLLocationDistance distance = 1320.0;
MKDistanceFormatter *df = [[MKDistanceFormatter alloc]init];
df.unitStyle = MKDistanceFormatterUnitStyleFull;

NSString *prettyString = [df stringFromDistance:distance];

Swift version:

let distance = 1320.0
let df = MKDistanceFormatter()
df.unitStyle = .Full

let prettyString = df.stringFromDistance(distance)

Swift 5.4.2:

import MapKit

let distance = 1320.0
let df = MKDistanceFormatter()
df.unitStyle = .full
let prettyString = df.string(fromDistance: distance)
Klaas
  • 22,394
  • 11
  • 96
  • 107
19

I just wanted to note, that, as with the release of iOS8 there will be new NSFormatters for exactly this kind of problem.

There will be NSLengthFormatter, NSMassFormatter and NSEnergyFormatter which are very easy to use – see this iOS8 NSFormatter tutorial. Here is an example using the LengthFormatter with swift:

let lengthFormatter = LengthFormatter()
print("Kilometer: ", lengthFormatter.string(fromValue:1000, unit: .kilometer)) //Kilometer: 1,000 km

Like with DateFormatter, you will no longer necessarily have to use NSLocale for printing the unit itself.

Axel Guilmin
  • 11,454
  • 9
  • 54
  • 64
Alexander
  • 7,178
  • 8
  • 45
  • 75
  • As Klaas noted nearly a year prior to this answer, [MKDistanceFormatter](https://developer.apple.com/library/ios/documentation/MapKit/Reference/MKDistanceFormatter_class/) was added in iOS 7 and is exactly suited for this purpose. – Quinn Taylor Mar 15 '15 at 06:28
  • 3
    `NSLengthFormatter` gives better options for the formatting of the numerical value, while not giving the correct output for locales where they use the metric system except for distances. `MKDistanceFormatter` unfortunately doesn't give you numerical formatting options and appears to round the numerical value. – ThomasW Sep 02 '15 at 10:31
12

Unfortunately, you have to do this manually.

And if you do so, please don't forget to check:

[[[NSLocale currentLocale] objectForKey:NSLocaleUsesMetricSystem] boolValue]

The rest of the world would appreciate.

Nicolas Bachschmidt
  • 6,475
  • 2
  • 26
  • 36
4
import Foundation

extension Double {
  var prettyDistance: String {
    guard self > -.infinity else { return "?" }

    let formatter = LengthFormatter()
    formatter.numberFormatter.maximumFractionDigits = 2

    if self >= 1000 {
      return formatter.string(fromValue: self / 1000, unit: LengthFormatter.Unit.kilometer)
    } else {
      let value = Double(Int(self))
      return formatter.string(fromValue: value, unit: LengthFormatter.Unit.meter)
    }
  }
}

Double(1).prettyDistance // 1 m
Double(10).prettyDistance // 10 m
Double(100).prettyDistance // 100 m
Double(999).prettyDistance // 999 m
Double(1000).prettyDistance // 1 km
Double(1111).prettyDistance // 1.11 km
Double(5555).prettyDistance // 5.56 km
Double(9999).prettyDistance // 10 km
Double(10000).prettyDistance // 10 km
Double(99999).prettyDistance // 100 km
Double(100000).prettyDistance // 100 km
Double(555555).prettyDistance // 555.56 km
Double(999999).prettyDistance // 1,000 km
Double(1000000).prettyDistance // 1,000 km
Double(1234567890).prettyDistance // 1,234,567.89 km
Hun
  • 3,652
  • 35
  • 72
4

TTTLocationFormatter from FormatterKit might be exactly what you are looking for. If it isn't you can probably use it as a starting point.

sroske
  • 191
  • 1
  • 3
0

You can use string formatting to accomplish this:

//distance to 2 decimal places
NSString *target = [NSString stringWithFormat:@"%.2f miles", distance];

But there's no functionality for converting between distance measurements or anything like that.

Casey
  • 2,393
  • 1
  • 20
  • 22
  • I was doing the same thing, but this is not recommended. When I expanded my app to other countries, I had to change it. So you should use MKDistanceFormatter class. – Anand Apr 28 '20 at 09:16