Bronze challenge


#1

Is the CLLocationManager property you want us to use the distanceFilter property?

Is there some place you have posted the answers to all of the bronze and silver challenges?


#2

That is the solution. We haven’t posted anything anywhere, and were hoping the solutions would come together organically here on this board, leaving room for discussion and alternate solutions.


#3

I have another solution which is more than 50 meters but not as accurate down to the meter:

I looked this up in the documentation and this seems to be one of the default settings for accuracy.


#4

This is how I solved it:

WhereAmIViewController.h:

#import <UIKit/UIKit.h>
#import <CoreLocation/CoreLocation.h>

@interface WhereAmIViewController : UIViewController
<CLLocationManagerDelegate>
{
    CLLocationManager *locationManager;
}

@property(assign, NS_NONATOMIC_IPHONEONLY) CLLocationDistance distanceFilter;

@end

WhereAmIViewController.m

[code]#import “WhereAmIViewController.h”

@implementation WhereAmIViewController
@synthesize distanceFilter;

  • (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
    {
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];

    if (self){
    // Create location manager object
    locationManager = [[CLLocationManager alloc] init];

      [locationManager setDelegate:self];
      
      // We want it to be as accurate as possible, regadless of how much time/power
      // it takes 
      [locationManager setDesiredAccuracy:kCLLocationAccuracyBest];
      
      // Tell manager to start looking for its location immediately
      [locationManager startUpdatingLocation];
      [locationManager setDistanceFilter:50.0];
    

    }

    return self;
    }[/code]

I think this is how it’s supposed to work. It compiles without error. What do you think? I can’t test it on my phone yet.


#5

Yup, this will work!


#6

this solution doesn’t work, after setDistanceFilter:50.0 locationManager still sends locationManager:didUpdateToLocation:fromLocation: method one by one and does"t depend on distance.


#7

Works for me, and whether or not the call to the setDistanceFilter: method is before or after the startUpdatingLocation method.

I did try some different distances (like 5000000.0) so that it would only show an update if the move was more than 5000km, since the different location simulations in the iPhone Simulator are major cities around the world. However, I found that it took , essentially, to work it out, I suppose since it keeps trying to work out the location and then trying to determine if that location is a long way away from the prior location. Probably would be easier to trial this using a real phone and just moving around the street! :slight_smile:


#8

In addition to

        [locationManager setDistanceFilter:50];

You can add below line to confirm if it is more or equal to 50 in the

[code]

  • (void) locationManager:(CLLocationManager*) manager
    didUpdateToLocation:(CLLocation *)newLocation
    fromLocation:(CLLocation *)oldLocation
    {
    if (manager.distanceFilter >=50) {
    NSLog(@“newlocation - %@”,newLocation);
    }

}[/code]


#9

Is the setDistanceFilter supposed to be done inside the init file?

[code]-(id)initWithNibName:(NSString *)nibNameOrNil
bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];

if (self){
    locationManager = [[CLLocationManager alloc] init];
    [locationManager setDelegate:self];
    
    [locationManager setDesiredAccuracy:kCLLocationAccuracyBest];
    
    [locationManager setDistanceFilter:50];
    
    [locationManager startUpdatingLocation];
}
return self;

}[/code]

Or elsewhere?


#10

WhereamiViewController.m

-(id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil{
    if (self=[super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]) {
        locationManager= [[CLLocationManager alloc] init];
        
        [locationManager setDelegate:self];//self is Whereamicontroller. The delegate pointer is of type id<CLLocationManagerDelegate> and is an ivar of CLLocationManager.
        [locationManager setDesiredAccuracy:kCLLocationAccuracyBest]; 
        if (locationManager setDistanceFilter:50) { //return CLLocationDistance which is typedef to double.
            [locationManager startUpdatingLocation];
        }
    
    }
    return self;
}

Note that in the if statement i have done assignment [locationManager setDistanceFilter]=50. The distanceFilter is set to 50. Had i done [locationManager distanceFilter]==50, the if statement wud not have worked since the default value of distanceFilter is -1.00 which is unequal to 50. So startUpdatingLocation message wud not have worked. So which one of the two approaches should be used? Right now the locations are getting updated, they show up in the console one by one.Please help me understand this.
Also does startUpdatingLocation method internally call “-(void)locationManager: didUpdateToLocation: fromLocation: oldLocation:”
Is this implementation suitable enough? .But how to simulate a case where the distance becomes more than 50 ? The location beacon icon in the console window is marked as - “Don’t simulate location”. How to simulate the “beyond 50” scenario.


#11

rahulbsb - In the same pop-up where you see that “Don’t simulate location” is checked, there are a bunch of different location choices. Check one of those, and the “Don’t simulate location” option becomes unchecked.

Now, originally the app was set to update the location info continuously. Once you pick a location, you’ll start seeing an NSLog (if you implemented that) about once per second. When you change the app to only update the location if you’ve changed by greater than 50 meters, then you’ll get one NSLog statement until you change to a different city.

Hope this helps.


#12

Yeah i tried it thanx for the help man. I chose some other location and the specific updated location was logging on the console. Then i chose some other location and that was logging on the console. But there’s one thing noteworthy here. Before i change the beacon icon from “Dont simulate location” to some other location, my output is this:-
2013-07-02 20:18:41.033 Whereami[620:c07] <+51.50998000,-0.13370000> +/- 5.00m (speed -1.00 mps / course -1.00) @ 7/2/13, 8:12:08 PM India Standard Time
2013-07-02 20:18:42.022 Whereami[620:c07] <+22.28468100,+114.15817700> +/- 5.00m (speed -1.00 mps / course -1.00) @ 7/2/13, 8:18:42 PM India Standard Time

The current location that i had set was Mumbai,India having co-ordinate-<+19.00,+72.856>. So how come the logging be starting with different coordinates(<+51.50998000,-0.13370000> and <+22.28468100,+114.15817700>).Well, it turns out that the last location that u set during the first run of the app becomes the current location in the second running of the app.
My first issue is —Is there a reason for my current location to be logged twice?? Plus i couldn’t understand this term (speed -1.00 mps / course -1.00). If speed is 1 mps, what is course?
Is 5.00 m the distance travelled. Why is it 5.00 m ? If I reset the distanceFilter from 50 meters to lets say 4000 meters ([locationManager setDistanceFIlter:4000]) I’m getting unexpected results. When i change the location from current one to a new one, despite the fact that the distanceFilter=4 kilo meters(4000m) now, the current location is not updating to the desired one. I mean,the dis btw any two countries is way way more than 4 kilo meters, so updating to a new country e.g. Mumbai,India to London,England shouldn’t be a problem. But guess what, the newer location after being selected isnt logging.Ask me if u want to see the Output.

After you resolve the above issue, please take a look at the second issue below.(I know I’m being a jerk asking too much):-

In “-(id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil” method ,i’ve made the following changes:-

 [locationManager setDistanceFilter:50];//setting up distance filter
        double maxDistance;
        NSLog(@"Enter the max distance after which location starts updating ");
        scanf("%lf",&maxDistance);
        
        if (maxDistance==[locationManager distanceFilter]) { //return CLLocationDistance which is typedef to double.
            NSLog(@"Distance Filter= %f",locationManager.distanceFilter);
            [locationManager startUpdatingLocation];
        }

Now, in my output- “Enter the max distance…” message is logged and after that when i’m inputting a value for “maxDistance” and hitting return, my if statement isnt working. I’ve put the value of maxDistance to be equal to that of distanceFilter i.e 50. It seems the control doesnt go into the if statement and start logging the locations. Here’s my output-

2013-07-02 19:49:11.765 Whereami[490:c07] Enter the max distance after which location starts updating
50

Note: 50==50, so the if statement should work but it doesn’t . Whats up with that??
It appears that the control is somehow skipping the scanf() line. I added an extra NSlog message after that for testing—
NSLog(@"Enter the max distance after which location starts updating "); scanf("%lf",&maxDistance); NSLog(@"Test");
The output was—

2013-07-03 16:30:29.605 Whereami[453:c07] Enter the max distance after which location starts updating
2013-07-03 16:30:29.607 Whereami[453:c07] Test

scanf() wasnt even processed. :astonished: :astonished:


#13

This is how I did it (in the initWithNibName:budnle: method of the WhereamiViewController):

locationManager.distanceFilter = 50;

Is it OK??