Reputation: 3771
I am currently pulling a list of "contest" objects that have location information tied to them. I want to monitor all contests that I am in the vicinity of.
for(Contest *contest in contests) {
NSMutableDictionary * fence1 = [NSMutableDictionary new];
[fence1 setValue:contest.event.name forKey:@"identifier"];
[fence1 setValue:[NSString stringWithFormat:@"%f", contest.location.latitude] forKey:@"latitude"];
[fence1 setValue:[NSString stringWithFormat:@"%f", contest.location.longitude] forKey:@"longitude"];
[fence1 setValue:@"1000" forKey:@"radius"];
//the below method returns a CLRegion object
CLRegion *region = [self dictToRegion:fence1];
//adding custom contest object to region
region.contest = contest;
[self.locationManager requestStateForRegion:region];
}
I ALSO want to tie a custom contest property to the region (as shown in the above code), but it doesn't seem to carry over in the delegate method didDetermineState:
-(void)locationManager:(CLLocationManager *)manager didDetermineState:(CLRegionState)state forRegion:(CLRegion *)region {
switch (state) {
case CLRegionStateUnknown:
NSLog(@"Unknown state!");
break;
case CLRegionStateInside:
NSLog(@"Inside state!");
//this comes back as null
NSLog(@"%@", region.contest.name);
break;
case CLRegionStateOutside:
NSLog(@"Outside state!");
break;
default:
break;
}
}
In the delegate method, region.contest returns as (null). Is there a better approach to take?
Appendix (my category for CLRegion): CLRegion+Contest.h:
#import <CoreLocation/CoreLocation.h>
#import "Event.h"
#import "Contest.h"
@interface CLRegion (Loopd)
@property (nonatomic, strong) Event *event;
@property (nonatomic, strong) Contest *contest;
@end
CLRegion+Contest.m:
#import "CLRegion+Loopd.h"
#import <objc/runtime.h>
static char defaultHashKey;
@implementation CLRegion (Loopd)
@dynamic event;
@dynamic contest;
-(Event* ) event {
return objc_getAssociatedObject(self, &defaultHashKey);
}
- (void) setEvent:(Event *)event {
objc_setAssociatedObject(self, &defaultHashKey, event, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
-(Contest* ) contest {
return objc_getAssociatedObject(self, &defaultHashKey);
}
- (void) setContest:(Contest *)event {
objc_setAssociatedObject(self, &defaultHashKey, event, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
@end
Upvotes: 0
Views: 87
Reputation: 1090
There are 2 problems with your category. 1. You're using same key for both properties. 2. defaultHashKey is initialized with 0 value.
objc_getAssociatedObject and objc_setAssociatedObject work mostly like setValue:forKey: and getValueForKey:. So you need to provide key which binds the value to the object. Try something like that:
#import "CLRegion+Loopd.h"
#import <objc/runtime.h>
static char* kEventKey = "kEventKey";
static char* kContestKey = "kContestKey";
@implementation CLRegion (Loopd)
@dynamic event;
@dynamic contest;
-(Event* ) event {
return objc_getAssociatedObject(self, kEventKey);
}
- (void) setEvent:(Event *)event {
objc_setAssociatedObject(kEventKey, event, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
-(Contest* ) contest {
return objc_getAssociatedObject(self, kContestKey);
}
- (void) setContest:(Contest *)event {
objc_setAssociatedObject(self, kContestKey, event, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
@end
This code should work, but would be much better to create separate object for storing this association (I'm not a great fan of using runtime for this kind of purposes).
EDIT: Your assigning value for contest multiple times in the for loop. So one of the contests (the last one) is assigned to the CLRegion object.
Upvotes: 1