Question

I've got a class method that wants to use CLLocationManager and some of its delegate methods.

What is the best way to access the delegate methods from the class method, since I don't have a true instance level "self"? I could instantiate a self and use as the delegate, which would let the delegate methods run, but doesn't show how to get the data out. What's the best approach?

// desired end function, which runs a block when location is found
[SFGeoPoint geoPointForCurrentLocationInBackground:^(SFGeoPoint *geoPoint, NSError *error) {
    if (!error) {
        // do something with the new geoPoint
        NSLog(@"GeoPoint: %@", geoPoint);
    }
}];


// SFGeoPoint class, key points
static CLLocationManager *_locationManager = nil;

// get geo point for current location and call block with it
+ (void) geoPointForCurrentLocationInBackground:( void ( ^ )( SFGeoPoint*, NSError* ) ) locationFound {

    SFGeoPoint *point = [[SFGeoPoint alloc] init];

    _locationManager = [[CLLocationManager alloc] init];

    // ?????????
    _locationManager.delegate = self;  // this gives a warning about incompatible pointer type assigning Delegate from Class; 
    _locationManager.delegate = point;  // could work, but how to get feedback?  

    _locationManager.distanceFilter = kCLDistanceFilterNone; // whenever we move
    _locationManager.desiredAccuracy = kCLLocationAccuracyBest;
    [_locationManager startUpdatingLocation];

    [_locationManager startUpdatingLocation];
    locationFound(point, nil);
}


/////////// Core Location Delegate
+ (void)locationManager:(CLLocationManager *)manager
didUpdateToLocation:(CLLocation *)newLocation
       fromLocation:(CLLocation *)oldLocation {

    [_locationManager stopUpdatingLocation];

    if (_locationBlock) {
        _locationBlock(newLocation);
    }
}
Was it helpful?

Solution

I would rework what you're doing and not use class methods. Instead, use a shared instance singleton, which will allow you to write your code almost identically but gives you an instance to work with and therefore store variables and assign delegates.

Just in case you are unfamiliar with the syntax:

+ (instancetype) shared
{
    static dispatch_once_t once;
    static id sharedInstance;
    dispatch_once(&once, ^{
        sharedInstance = [[self alloc] init];
    });
    return sharedInstance;
}

Then just change all of your + (class) methods to be - (instance) methods and access your class with [[MyClass shared] doWhatever];

edit with optional wrapper:

If you really wanna call the method without an instance you can write a wrapper that would do something like this:

+ (void) doWhatever
{
    [[self shared] doWhatever];
}

That said I would generally not recommend doing this because you are not saving much code and adding possible confusion in the future as to what kind of method this actually is from the caller's perspective.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top