iOS Location based reminder - iphone

i am making an application which has a feature that allows users to create location based notifications to turn the application on/off when they arrive/leave a certain location.
Reminders are created (as indicated by the first picture), but are not triggered upon arriving/leaving.
If on the other hand the user click on the reminder, it kind of adds the address (shown on picture number 2) and is from there on triggered
I was wondering if there is a way to make the Reminder app recognize the address or any other suggestion, that might help me in solving this peculiar problem.
Thank you in advance,
BR,
Rok
The code that i use is:
EKReminder *reminder = [EKReminder reminderWithEventStore:_eventStore];
reminder.calendar = [_eventStore defaultCalendarForNewReminders];
EKStructuredLocation *location;
NSError *error = nil;
EKAlarm *alarm = [[EKAlarm alloc]init];
reminder.title = #"Turn off Test App";
location = [EKStructuredLocation locationWithTitle:self.addressTextField.text];
[self.addressTextField resignFirstResponder];
alarm.proximity = EKAlarmProximityEnter;
alarm.structuredLocation = location;
[reminder addAlarm:alarm];
[_eventStore saveReminder:reminder commit:YES error:&error];

The problem is that you are failing to set your EKStructuredLocation's geolocation and radius. All it has is a title. That isn't enough to tell the alarm where on earth it is supposed to be!
Example:
location.geoLocation =
[[CLLocation alloc] initWithLatitude:latit longitude:longit];
location.radius = 10*1000; // metres

See CLLocationManager -startMonitoringForRegion:, and the CLRegion class reference.

Related

Geocode + MKPointAnnotation not playing nicely

I'm having the weirdest issue, and it's doing my head in. A global variable which I've set up within a Singleton is reporting correctly from within the function it's set in, then as NULL from within the very next function (which is where I need to access it), but as correct from another View! So the variable is correctly set, but it's not behaving within a certain function. There is also a weird error warning being generated by the offending line (which I've marked between *).
The warning is:
Property access result unused - getters should not be used for side effects.
Apologies for the very spotty code. I'm prototyping and learning as I go, so it's a mishmash of things I've cobbled from the net. What the code does is recognise a long tap on a mapview, and then places a pin at the location (while recording the location), and I'm trying to use Geocode to show the address at the pin position.
The first function is as follows:
- (void)handleLongPress:(UIGestureRecognizer *)gestureRecognizer
{
if (gestureRecognizer.state != UIGestureRecognizerStateBegan)
return;
CGPoint touchPoint = [gestureRecognizer locationInView:self.fullMapView];
CLLocationCoordinate2D touchMapCoordinate =
[self.fullMapView convertPoint:touchPoint toCoordinateFromView:self.fullMapView];
//save new birthplace in global variable
globalsSingle.gblBirthplace = touchMapCoordinate;
//place user location and record it
MKUserLocation *location = fullMapView.userLocation;
globalsSingle.gblCurrentLocation = location.coordinate;
//first remove any previous birthplace pin
[self removeAllPinsButUserLocation];
[self reverseGeocode];
//place new birthplace pin
MKPointAnnotation *birthPlacePin = [[MKPointAnnotation alloc] init];
birthPlacePin.coordinate = touchMapCoordinate;
birthPlacePin.title = #"My Birthplace";
**** birthPlacePin.subtitle = #"%#", globalsSingle.gblAddress; ****
[self.fullMapView addAnnotation:birthPlacePin];
NSLog(#"gblAddress = %#", globalsSingle.gblAddress);
}
The above function calls the next:
-(void)reverseGeocode {
CLGeocoder *ceo = [[CLGeocoder alloc]init];
CLLocation *loc = [[CLLocation alloc]initWithLatitude:globalsSingle.gblBirthplace.latitude longitude:globalsSingle.gblBirthplace.longitude]; //insert your coordinates
[ceo reverseGeocodeLocation: loc completionHandler:
^(NSArray *placemarks, NSError *error) {
CLPlacemark *placemark = [placemarks objectAtIndex:0];
//String to hold address
NSString *locatedAt = [[placemark.addressDictionary valueForKey:#"FormattedAddressLines"] componentsJoinedByString:#", "];
// save the address text
globalsSingle.gblAddress = locatedAt;
NSLog(#"addressDictionary %#", placemark.addressDictionary);
NSLog(#"placemark %#",placemark.region);
NSLog(#"placemark %#",placemark.country); // Give Country Name
NSLog(#"placemark %#",placemark.locality); // Extract the city name
NSLog(#"location %#",placemark.name);
NSLog(#"location %#",placemark.ocean);
NSLog(#"location %#",placemark.postalCode);
NSLog(#"location %#",placemark.subLocality);
NSLog(#"location %#",placemark.location);
//Print the location to console
NSLog(#"I am currently at %#",locatedAt);
NSLog(#"gblAddress from reverse Geocode = %#", globalsSingle.gblAddress);
}
];
}
What's even weirder (to me) is that the NSLog's from within reverseGeocode are all printing correctly, but the NSLog from the first function is reporting NULL, and is printing before the one from reverseGeocode even though it's (I assume) being executed second! For example, a debug output is:
2013-05-21 23:41:04.662 Project Name[5659:c07] gblAddress = (null)
2013-05-21 23:41:04.808 Project Name[5659:c07] gblAddress from reverse Geocode = Januária - MG, Brazil
Any help anyone could be bothered to offer I'd appreciate, as I'm bamboozled :)
The method reverseGeocodeLocation:completionHandler: is executed asynchronously, which means that it will move on to the next lines before it finishes.
Asynchronous vs synchronous execution, what does it really mean?
It is called asynchronously because the method reverseGeocodeLocation:completionHandler: might need some time to do it, and when it is finished, the completion block is called.
You should place the new birthplace pin only after the completion block of the reverseGeocodeLocation is called, for example inside the completion block, to ensure you have got the placemark data first before placing the pin. Or you can just update the subtitle of the newly added pin inside the completion block.
[ceo reverseGeocodeLocation: loc completionHandler:
^(NSArray *placemarks, NSError *error) {
CLPlacemark *placemark = [placemarks objectAtIndex:0];
//String to hold address
NSString *locatedAt = [[placemark.addressDictionary valueForKey:#"FormattedAddressLines"] componentsJoinedByString:#", "];
// save the address text
globalsSingle.gblAddress = locatedAt;
//place new birthplace pin
MKPointAnnotation *birthPlacePin = [[MKPointAnnotation alloc] init];
birthPlacePin.coordinate = globalsSingle.gblBirthplace;
birthPlacePin.title = #"My Birthplace";
birthPlacePin.subtitle = globalsSingle.gblAddress;
[self.fullMapView addAnnotation:birthPlacePin];
}
];
}
When you are calling [self reverseGeocode]; the rest of handleLongPress will continue to run without waiting for reverseGeocode to finish. This is why you are seeing the print functions being called in an order you weren't expecting.
[self performSelectorOnMainThread:#selector(reverseGeocode) withObject:nil waitUntilDone:YES];
If handleLongPress is running on the main thread, the above line can replace [self reverseGeocode] and should produce the expected results.

MapKit in iOS 6 - How to Find Places Nearby...?

Using MapKit in iOS 6, how am I'm supposed to get nearby locations without having their specific coordinates? I'm also unsure if it's still possible...err...allowed...to use Google Maps API to accomplish this goal, as this is the only way I can think of to do this. I know everything is still in beta, but I've still found no information anywhere about this topic, on forums, in Apple's new MapKit Documentation, anywhere. All I want to do is perform a search for locations (let's say, parks, for example) within 'x' miles of the user's location.
It seems that since Apple has developed their own Maps application, they should have a way to accomplish this using MapKit or Core Location...right?
Try with this code. This may help to you.
URLManager *urlmanager = [[URLManager alloc] init];
urlmanager.delegate = self;
urlmanager.responseType = JSON_TYPE;
urlmanager.commandName = #"Search";
NSString *locationString = [NSString stringWithFormat:#"%f,%f",latitude,longitude];
//Location where you want to search
NSString *key = #"AIzaSyCNRpero6aM451X0IfgFHAd-Y3eJUssqoa8`enter code here`0E";
//This is the secret key which you will get from the Google API Console when you register your app.
NSString *radiuos = #"15000";
//This is the area within which you want to search
NSString *keyword = #"Hotel";//Search keyword you want to search
NSMutableDictionary *arguments = [[NSMutableDictionary alloc] init]; // zero argument
[arguments setValue:key forKey:#"key"];
[arguments setValue:locationString forKey:#"location"];
[arguments setValue:radiuos forKey:#"radius"];
[arguments setValue:#"true" forKey:#"sensor"];
[arguments setValue:keyword forKey:#"keyword"];
NSLog(#"Arguments are %#",arguments);
[urlmanager urlCallGetMethod:[NSString stringWithFormat:#"https://maps.googleapis.com/maps/api/place/search/json"] withParameters:arguments];

Invoking Alarm for certain time in ios

I am working on App which will set an alarm on ios for a time depending on user input.
Meaning: if a user selects row 1 of table then it will look into dictionary (which may say 20 minutes),,, then it should set an alarm in ios for (currrent time+ 20 minutes).
Can someone please tell me the best way to approach this.
You can use UILocalNotification:
UILocalNotification *local = [[UILocalNotification alloc] init];
// create date/time information
local.fireDate = [NSDate dateWithTimeIntervalSinceNow:20*60]; //time in seconds
local.timeZone = [NSTimeZone defaultTimeZone];
// set notification details
local.alertBody = #"Alarm!";
local.alertAction = #"Okay!";
local.soundName = [NSString stringWithFormat:#"Default.caf"];
// Gather any custom data you need to save with the notification
NSDictionary *customInfo =
[NSDictionary dictionaryWithObject:#"ABCD1234" forKey:#"yourKey"];
local.userInfo = customInfo;
// Schedule it!
[[UIApplication sharedApplication] scheduleLocalNotification:local];
[local release];

Can't get data from Google Places

I am trying to get the google places API to work on my iPhone project. Now, I had it working about an hour ago, but I can't seem to figure out what I did to make it stop working. Any help would be appreciated.
Here is what I have so far:
- (NSString *)searchString {
// this mutable string allows me to dynamically create the search string
// we start with the static part of the api search URL
NSMutableString *result = [NSMutableString stringWithString:#"https://maps.googleapis.com/maps/api/place/search/json?location="];
// since I need to get the user's location, I need to create a location manager
CLLocationManager *locationManager = [[CLLocationManager alloc] init];
// we need to now update the current location,
// otherwise there will be no coordinates
[locationManager startUpdatingLocation];
// now that it's updated, we stop it because I
// am not tracking anything
[locationManager stopUpdatingLocation];
// this appends the lattitude/longitude, as double values, into the URL
[result appendFormat:#"%g,%g", [[locationManager location] coordinate].latitude, [[locationManager location] coordinate].longitude];
// release the location manager for memory management
[locationManager release];
// if a filter is present, add the keyword item to try to filter
// the results
if([[self filterString] length] > 0) {
[result appendFormat:#"&keyword=%#", filterString];
}
// add the rest of the validated URL now
//[result appendString:#"&types=food|meal_delivery|meal_takeaway|restaurant&rankby=distance&sensor=true&key=AIzaSyBmO_f6h4_Q0xArw6tdxUF7TH7rZpaiFfQ"];
[result appendString:#"&types=food&rankby=distance&sensor=true&key=mykey"];
// log the result for testing
NSLog(#"Completed Search String: %#", result);
return result;
}
Now, when I look at my log, copy the 'completed search string' into Safari, it brings up the results that I need.
But if I use the following code, the app hangs:
- (void)performSearch {
NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:[self searchString]]]; // hangs on this line!
NSDictionary *jsonDictionary = [data objectFromJSONData];
NSArray *resultsArray = [jsonDictionary objectForKey:#"results"];
currentList = [ARGooglePlace placesWithArray:resultsArray];
[self.tableView reloadData];
}
I think I should mention that I am using the JSONKit to do the JSON parsing. Also, the ARGooglePlace is a custom class that isn't relevant right now (it doesn't even get there...)
Thanks for any help that you can provide.
Pull the location manager and the lat/long out of the searchString method... just put it in the performSearch method. And instead, pass the lat/long as received from location manager into searchString.
It sounds like a timing issue with your location manager. It could have been working earlier b/c location manager had previously cached location data... and was able to grab the correct coords.
2+ Possible scenarios:
1) problem with location manager not updating it's coords and just hanging there
2) google website being the culprit (maybe loading too much data??)
Pulling location manager out of the searchString method will help isolate cause... and one can just pass lat/long values directly to test google website as well.

iphone: how to detect last caller number programmatically?

Is there any way to detect last caller number & call duration on iPhone, I am able to get all notification (Core Telephony) but don't know how to get caller number.
You can't, the API will not allow you to do this.
I think apple will never allow this due to privacy concerns.
According to api you cant do it... but here something which might help you ... though I haven't tried it myself...
http://iosstuff.wordpress.com/2011/08/19/accessing-iphone-call-history/
Apple officially don't allow.You cann't access the database of the other application then your one.
You can use this
if ([name isEqualToString:#"kCTCallIdentificationChangeNotification"])
{
// CTCallCenter *center = [[CTCallCenter alloc] init];
// center.callEventHandler = ^(CTCall *call) {
// NSLog(#”call:%#”, [call description]);
// };
//NSDictionary *info = (NSDictionary *)userInfo;
CTCall *call = (CTCall *)[info objectForKey:#"kCTCall"];
NSString *caller = CTCallCopyAddress(NULL, call);
NSLog(#"caller:%#",caller);
//CTCallDisconnect(call);
/* or one of the following functions: CTCallAnswer
CTCallAnswerEndingActive
CTCallAnswerEndingAllOthers
CTCallAnswerEndingHeld
*/
//if ([caller isEqualToString:#"+1555665753"])
if ([caller isEqualToString:#"+918740061911"])
{
NSLog(#"disconnecting call");
//disconnect this call
CTCallDisconnect(call);
}
}