How to start Tracking POIs with Skobbler - ios

This is my code for creating trackable POIs and starting a POI tracking.
This code is placed just before I would calculate a route and start navigation
-(void)createTrackablePOIs
{
// Go through the route array and create POIs out of all added exits and locations
if ([Constants shared].routeArray.count>2){
_trackablePOIs = [[NSMutableArray alloc] init];
for (int i=1; i<[Constants shared].routeArray.count-1; i++) {
if ([[Constants shared].routeArray[i] isKindOfClass:[Exit class]]){
Exit *e = [Constants shared].routeArray[i];
SKTrackablePOI* poi = [[SKTrackablePOI alloc] init];
poi.poiID = e.idExit;
poi.type = 1;
poi.coordinate = CLLocationCoordinate2DMake(e.lat, e.lon);
[self.trackablePOIs addObject:poi];
}else{
RoutePoint* rp = [Constants shared].routeArray[i];
SKTrackablePOI *poi = [[SKTrackablePOI alloc] init];
poi.poiID = rp.pointID;
poi.type = 2;
poi.coordinate = CLLocationCoordinate2DMake(rp.x,rp.y);
[self.trackablePOIs addObject:poi];
}
}
NSLog(#"%d POIs created and added to array",_trackablePOIs.count);
self.poiTracker = [[SKPOITracker alloc] init];
self.poiTracker.dataSource = self;
self.poiTracker.delegate = self;
// Create POI Tracking rules
SKTrackablePOIRule *rule = [SKTrackablePOIRule trackablePOIRule];
rule.routeDistance = 5000;
rule.aerialDistance = 5000;
[_poiTracker setRule:rule forPOIType:1];
// Start POI tracking
[_poiTracker startPOITrackerWithRadius:5000 refreshMargin:0.1 forPOITypes:#[#1,#2]];
}
}
-(NSArray*)poiTracker:(SKPOITracker *)poiTracker trackablePOIsAroundLocation:(CLLocationCoordinate2D)location inRadius:(int)radius withType:(int)poiType
{
return [self.trackablePOIs copy];
}
- (void)poiTracker:(SKPOITracker *)poiTracker didDectectPOIs:(NSArray *)detectedPOIs{
[detectedPOIs enumerateObjectsUsingBlock:^(SKDetectedPOI *detectedPOI, NSUInteger index, BOOL *stop){
NSLog(#"Detected: %#",[detectedPOI description]);
}];
NSLog(#"POI detected");
}
But POI delegate method is never called. No matter how much I played with trackable POI rules.
Also, another question, what exactly does the margin stands for in
[_poiTracker startPOITrackerWithRadius:5000 refreshMargin:0.1 forPOITypes:#[#1,#2]];

Related

Is it possible to increase destination point radius? [duplicate]

This is my code for creating trackable POIs and starting a POI tracking.
This code is placed just before I would calculate a route and start navigation
-(void)createTrackablePOIs
{
// Go through the route array and create POIs out of all added exits and locations
if ([Constants shared].routeArray.count>2){
_trackablePOIs = [[NSMutableArray alloc] init];
for (int i=1; i<[Constants shared].routeArray.count-1; i++) {
if ([[Constants shared].routeArray[i] isKindOfClass:[Exit class]]){
Exit *e = [Constants shared].routeArray[i];
SKTrackablePOI* poi = [[SKTrackablePOI alloc] init];
poi.poiID = e.idExit;
poi.type = 1;
poi.coordinate = CLLocationCoordinate2DMake(e.lat, e.lon);
[self.trackablePOIs addObject:poi];
}else{
RoutePoint* rp = [Constants shared].routeArray[i];
SKTrackablePOI *poi = [[SKTrackablePOI alloc] init];
poi.poiID = rp.pointID;
poi.type = 2;
poi.coordinate = CLLocationCoordinate2DMake(rp.x,rp.y);
[self.trackablePOIs addObject:poi];
}
}
NSLog(#"%d POIs created and added to array",_trackablePOIs.count);
self.poiTracker = [[SKPOITracker alloc] init];
self.poiTracker.dataSource = self;
self.poiTracker.delegate = self;
// Create POI Tracking rules
SKTrackablePOIRule *rule = [SKTrackablePOIRule trackablePOIRule];
rule.routeDistance = 5000;
rule.aerialDistance = 5000;
[_poiTracker setRule:rule forPOIType:1];
// Start POI tracking
[_poiTracker startPOITrackerWithRadius:5000 refreshMargin:0.1 forPOITypes:#[#1,#2]];
}
}
-(NSArray*)poiTracker:(SKPOITracker *)poiTracker trackablePOIsAroundLocation:(CLLocationCoordinate2D)location inRadius:(int)radius withType:(int)poiType
{
return [self.trackablePOIs copy];
}
- (void)poiTracker:(SKPOITracker *)poiTracker didDectectPOIs:(NSArray *)detectedPOIs{
[detectedPOIs enumerateObjectsUsingBlock:^(SKDetectedPOI *detectedPOI, NSUInteger index, BOOL *stop){
NSLog(#"Detected: %#",[detectedPOI description]);
}];
NSLog(#"POI detected");
}
But POI delegate method is never called. No matter how much I played with trackable POI rules.
Also, another question, what exactly does the margin stands for in
[_poiTracker startPOITrackerWithRadius:5000 refreshMargin:0.1 forPOITypes:#[#1,#2]];

Downloading calendar data in Objective-C

I am trying to download google calendar data.
I am following a tutorial this link according to which implementing some of the GoogleOAuth delegate methods will let me get my desired data.
First I converted the response JSON data into an NSDictionary object and after that, I, NSLog this dictionary, to see the way the returned data is formed which is as shown below.
calendarInfoDict is {
etag = "\"1436255371893000\"";
items = (
{
accessRole = owner;
backgroundColor = "#9a9cff";
colorId = 17;
defaultReminders = (
{
method = popup;
minutes = 30;
}
);
etag = "\"1436255371893000\"";
foregroundColor = "#000000";
id = "sabiranthapa#gmail.com";
kind = "calendar#calendarListEntry";
notificationSettings = {
notifications = (
{
method = email;
type = eventCreation;
},
{
method = email;
type = eventChange;
},
{
method = email;
type = eventCancellation;
},
{
method = email;
type = eventResponse;
}
);
};
primary = 1;
selected = 1;
summary = "sabiranthapa#gmail.com";
timeZone = "Asia/Calcutta";
},
{
accessRole = reader;
backgroundColor = "#92e1c0";
colorId = 13;
defaultReminders = (
);
description = "Displays birthdays of people in Google Contacts and optionally \"Your Circles\" from Google+. Also displays anniversary and other event dates from Google Contacts, if applicable.";
etag = "\"1436255358367000\"";
foregroundColor = "#000000";
id = "#contacts#group.v.calendar.google.com";
kind = "calendar#calendarListEntry";
summary = Birthdays;
timeZone = "Asia/Calcutta";
}
);
kind = "calendar#calendarList";
nextSyncToken = 00001436255371893000;
}
According to tutorial there is a block containing a bunch of information regarding every calendar I have created in Google Calendars inside curly bracket. But I am not getting any events that I have saved which can be seen in Google Calendar after signing in gmail but not in my apps where I need to work with it.
My code is
-(void)responseFromServiceWasReceived:(NSString *)responseJSONAsString andResponseJSONAsData:(NSData *)responseJSONAsData{
NSError *error;
if ([responseJSONAsString rangeOfString:#"calendarList"].location != NSNotFound) {
NSDictionary *calendarInfoDict = [NSJSONSerialization JSONObjectWithData:responseJSONAsData options:NSJSONReadingMutableContainers error:&error];
NSLog(#"calendarInfoDict is %#", calendarInfoDict);
if (error) {
NSLog(#"%#", [error localizedDescription]);
}
else{
NSArray *calendarsInfo = [calendarInfoDict objectForKey:#"items"];
if (_arrGoogleCalendars == nil) {
_arrGoogleCalendars = [[NSMutableArray alloc] init];
}
for (int i=0; i<[calendarsInfo count]; i++) {
NSDictionary *currentCalDict = [calendarsInfo objectAtIndex:i];
NSArray *values = [NSArray arrayWithObjects:[currentCalDict objectForKey:#"id"],
[currentCalDict objectForKey:#"summary"],
nil]; NSArray *keys = [NSArray arrayWithObjects:#"id", #"summary", nil];
[_arrGoogleCalendars addObject:
[[NSMutableDictionary alloc] initWithObjects:values forKeys:keys]];
}
_dictCurrentCalendar = [[NSDictionary alloc] initWithDictionary:[_arrGoogleCalendars objectAtIndex:0]];
[_barItemPost setEnabled:YES];
[_barItemRevokeAccess setEnabled:YES];
[self showOrHideActivityIndicatorView];
But I always end up with condition
if (_arrGoogleCalendars == nil) {
_arrGoogleCalendars = [[NSMutableArray alloc] init];
}
without able to access my events.
How can I download (or access) my Events from google calendar?

Using a string as name to set property values

I have these big huge repetitive chunks of code in my project I am attempting to shrink them down. Take this piece example:
self.Day11.delegate = (id)self;
self.Day12.delegate = (id)self;
self.Day13.delegate = (id)self;
self.Day14.delegate = (id)self;
self.Day15.delegate = (id)self;
self.Day16.delegate = (id)self;
self.Day17.delegate = (id)self;
self.Day18.delegate = (id)self;
self.Day19.delegate = (id)self;
What I would like to do is make it that I can use a for loop or something similar to shrink it down like this:
for (int i = 1 ; i<=9; i++) {
NSString *var = [NSString stringWithFormat:#"Day1%d",i];
self.var.delegate = (id)self;
}
I know this doesn't work is there a possible way to do something like this?
No, no, no.
#property (nonatomic,strong) NSArray *arrayOfDays;
Now get rid of all those day objects and fill that self.arrayOfDays with whatever all those individual day objects are...
Then...
for(int i=0; i<[self.arrayOfDays count]; ++i) {
[[self.arrayOfDays objectAtIndex:i] setDelegate: self];
}
Or even better, if all those objects are of the same type (I'll assume they're of type Day), we can do:
for(Day *day in self.arrayOfDays) {
day.delegate = self;
}
Best (per Daij-Dan's comment):
[self.arrayOfDays setValue:self forKeyPath:#"delegate"];

My method won't work

I'm a total noob and need help with a method I'm writing.
The method creates a deck of cards (using NSMutableArray). I'm first experimenting with loading the array with numbers 1-13 randomly (each number appearing once).
When I run a simple test program to print the values in the array, I get a "Build Successful" but an error once the program starts. The error says "[__NSArrayM insertObject:atIndex:]: object cannot be nil".
Once I understand what I'm doing wrong, I can then expand on the method properly. Thanks!
NB: This is my first post. Is this type of question ok?
- (void) createDeck {
int r;
BOOL same;
deck = [[NSMutableArray alloc]init];
NSNumber *randNum;// = nil;
randNum = [[NSNumber alloc]init];
[randNum initWithInt: (arc4random()%13)+1];
[deck addObject: randNum]; // First card added to deck
same = FALSE;
while (!same) {
for (int i=1; i<13; i++) {
same = FALSE;
for (r=0; r<=i; r++) {
[randNum initWithInt: (arc4random()%13)+1];
if ([deck objectAtIndex:r] == [deck objectAtIndex:i]) {
same = TRUE;
}
[deck addObject: randNum]; // Next card added to deck
}
}
}
}
you cannot re-init randNum:
NSNumber *randNum;// = nil;
randNum = [[NSNumber alloc]init];
[randNum initWithInt: (arc4random()%13)+1];
and the third line is missing the assignment anyway. just do:
NSNumber *randNum = [[NSNumber alloc] initWithInt:(arc4random()%13)+1];
and put that inside the inner for loop, like this:
BOOL same = FALSE;
NSMutableArray *deck = [[NSMutableArray alloc] initWithCapacity:13];
[deck addObject:[[NSNumber alloc] initWithInt:(arc4random()%13)+1]]; // First card added to deck
while (!same) {
for (int i = 1; i < 13; i++) {
same = FALSE;
for (int r = 0; r <= i; r++) {
NSNumber *randNum = [randNum initWithInt:(arc4random()%13)+1]; // modern ObjC will assign a register for this outside the while loop, but restrict the variable's scope to the inner-most loop
if ([deck objectAtIndex:r] == [deck objectAtIndex:i])
same = TRUE;
[deck addObject: randNum]; // Next card added to deck
}
}
Note that I haven't thought through the logic of what you are trying to do here, I've only attempted to resolve the NULL object reference. The error was referring to the first line [deck addObject: randNum] outside of the loop.
Try to use this line of code where you using NSNumber
NSNumber * randNum = [NSNumber numberWithInt: (arc4random%13)+1];
Instead of
[[NSNumber alloc] initWithInt: ]

how to alter NSMutableArray in an specific array

I have a NSMutableArray wich holds a Custom class of MKMapkit.
MapPoint *placeObject = [[MapPoint alloc] initWithTitle:title subtitle:subtitle coordinate:loc description:description storeImage:storeImage];
[annotationArray addObject:placeObject];
My routine fills the placeObject without the image because they will load asynchronously and finished after a couple of seconds. Now my questions is: Is there a way to alter the placeObject which is within the annotationArray?
EDIT
To display my issue in a better way here some code parts:
if (annotationArray == nil)
{
[self setAnnotationArray:[[NSMutableArray alloc] init]];
}
for (NSDictionary *locationDetails in parser.items)
{
__block NSData *storeImageData;
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0);
dispatch_async(queue, ^{
storeImageData = [NSData dataWithContentsOfURL:storeImageURL];
dispatch_sync(dispatch_get_main_queue(), ^{
UIImage *storeImageTMP = [UIImage imageWithData:storeImageData];
counterBlock ++;
NSLog(#"async: %d", counterBlock);
[imageArray addObject:storeImageTMP];
});
});
MapPoint *placeObject = [[MapPoint alloc] initWithTitle:title subtitle:subtitle coordinate:loc description:description storeImage:storeImage];
[annotationArray addObject:placeObject];
}
[mapView addAnnotations:annotationArray];
after this is done: dispatch_queue_t will start working. So I check every 2 seconds if its fully loaded. Then i start to alter annotationArray and refresh my annotations (remove all -> add to map witch additional image)
- (void) checkMap
{
if (counterBlock == 547)
{
for (int i=0; i<=counterBlock; i++)
{
MapPoint *point = annotationArray[i];
point.storeImage = imageArray[i];
}
if(timer)
{
[timer invalidate];
timer = nil;
}
[mapView removeAnnotations:mapView.annotations];
[mapView addAnnotations:annotationArray];
}
}
All you need to do is get a reference to one of the MapPoint objects in the array. Then you can set properties and/or call methods on the object as needed.
MapPoint *point = annotationArray[x]; // x is whatever index you need
point.image = ... // some image
You can retrieve from your mutable array, the object you want to alter with the objectAtIndex method
NSInteger indexofMyObject = 0;
MapPoint *point = [myArray objectAtIndex:indexofMyObject];
Your MapPoint instance placeObject is a pointer. So adding it to the array does not copy placeObject by value, but actually holds its address. Getting the address of the object from the array will allow you to manipulate it.
annotationArray[objectIndex].anything = anything you want

Resources