GMSGeoCoder reverseGeocodeCoordinate: completionHandler: on background thread
Restructure your code to proceed after the async tasks are done:
This also has the benefit that you don't actively wait for stuff and block the main thread
e.g.:
- (void)checkCitiesWithCompletionBlock:(void (^)(BOOL same))
//Checking user's city
[[GMSGeocoder geocoder]reverseGeocodeCoordinate:self.locationManager.location.coordinate completionHandler:^(GMSReverseGeocodeResponse *response, NSError *error) {
if (error) {
NSLog(@"%@",[error description]);
}
id userCity=[[[response results] firstObject] locality];
//Checking store's city
[[GMSGeocoder geocoder]reverseGeocodeCoordinate:arounder.radiusCircularRegion.center completionHandler:^(GMSReverseGeocodeResponse *response, NSError *error) {
if (error) {
NSLog(@"%@",[error description]);
}
id arounderCity=[[[response results] firstObject] locality];
same ([userCity isEqualToString:arounderCity]);
}];
}];
}
Find the ios device current location using geolocation
Objective-C
CLLocation *location = [[CLLocation alloc]
initWithLatitude:+38.4112810
longitude:-122.8409780f];
CLGeocoder*myGeocoder = [[CLGeocoder alloc] init];
[myGeocoder
reverseGeocodeLocation:location
completionHandler:^(NSArray *placemarks, NSError *error) {
if (error == nil && placemarks.count > 0){
CLPlacemark *placemark = placemarks[0];
NSLog(@"Country = %@", placemark.country);
NSLog(@"Postal Code = %@", placemark.postalCode);
NSLog(@"Locality = %@", placemark.locality);
}
else if (error == nil && placemarks.count == 0){
NSLog(@"No results were returned.");
}
else if (error != nil) {
NSLog(@"An error occurred = %@", error);
}
}];
Swift
func gecode(location:CLLocation)
{
let geoCoder = CLGeocoder()
geoCoder.reverseGeocodeLocation(location, completionHandler: { (placemarks, error) -> Void in
if(error != nil)
{
return
}
if let placeMark = placemarks?[0] {
if let country = placeMark.addressDictionary!["Country"] as? String {
if country == "India" {
//
}
}
}
})
}
Comparing 2 cities from 2 locations in background
Do it like this:
-(BOOL)checkIfUserInRadiusForLocation:(SavedLocation*)location userCity: (NSString *) userCity locationCity: (NSString *) locationCity
{
if(location.radiusString isEqualToString:@“1KM”)
{
if(location.circularRegion containsCoordinate:self.locationManager.location.coordinate)
{
return YES;
}
}else if(location.radiusString isEqualToString:@“5KM”)
{
if(location.circularRegion containsCoordinate:self.locationManager.location.coordinate)
{
return YES;
}
//Important part:
}else if(location.radiusString isEqualToString:@“City”)
{
if([userCity isEqual: locationCity])
{
return YES;
}
}
return NO;
}
-(void)sendNotificationIfNeeded
{
if (self.muteEnabled==YES) { //Check if the user muted the app
NSLog(@"Mute enabled");
return;
}
SavedLocation* location = [self.savedLocations objectAtIndex:0];
[[GMSGeocoder geocoder]reverseGeocodeCoordinate:self.locationManager.location.coordinate completionHandler:^(GMSReverseGeocodeResponse *response, NSError *error) {
if (error) {
NSLog(@"%@",[error description]);
}
NSString *userCity=[[[response results] firstObject] locality];
[[GMSGeocoder geocoder]reverseGeocodeCoordinate:location.circularRegion.center completionHandler:^(GMSReverseGeocodeResponse *response, NSError *error) {
if (error) {
NSLog(@"%@",[error description]);
}
NSString *savedLocationCity=[[[response results] firstObject] locality];
if([self checkIfUserInRadiusForLocation:location userCity: userCity locationCity: savedLocationCity])
{
UILocalNotification *notification=[self createNotification];
[self sendNotification:notification];
}
}];
}];
}
Why do we call completion on main thread in asynchronous function?
Yes, but it's often convenient to call completion handlers on the main queue, since it's common to want to update the UI, and calling UI updaters on the wrong queue is a common bug.
It is not required, nor even universally recommended, to make general-purpose async functions call back on the main queue. But for certain systems where the use cases are well-known, it's very convenient and helps prevent bugs.
The above example, of course, is not useful, and would be very unlikely to be found in production code. But that doesn't change the utility in specialized cases. Another common pattern is for the caller to pass a completion queue. That's also fine, particularly for very general-purpose tools (such as URLSession, which uses this approach).
Related Topics
Is There a Public API for Card View UI That Can Be Seen Across iOS 10
How to Get Distance of Object from iPhone Camera Using Image Exif Meta Data
Using Convertpoint to Get the Relative Position Inside a Parent Uiview
Invalid Update: Invalid Number of Items on Uicollectionview
Uitextview Disabling Text Selection
How to Adjust the Height of a Textview to His Content in Swift
How to Integrate Linphone into an Existing Project (Sip in iOS)
How to Make Cmake Use Specific Compiler and Flags When Final Compilation Stage Instead of Detection
Why Are My Variables Empty When I Cast Them in My iOS Application
How to Change Font of Uibutton with Swift
Launch a Local Notification at a Specific Time in iOS
Auto Layout to Dynamically Size Uilabel Width
Facebook Share Content Only Shares Url in iOS 9
Status Bar Showing Black Text, Only on iPhone 6 iOS 8 Simulator