PHAsset CLLocation is not giving location same as photos app - ios

We are fetching the latitude and longitude from PHAsset properties we are using CLGeocoder to reverseGeocodeLocation using following method.
CLGeocoder * geoCoder = [CLGeocoder new];
[geoCoder reverseGeocodeLocation:loc completionHandler:^(NSArray<CLPlacemark *> * _Nullable placemarks, NSError * _Nullable error) {
CLPlacemark *placeInfo = placemarks[0];
}
we are getting placeInfo object but thoroughfare and subThoroughfare are always coming nil.
For the same photo photosapp is able to fetch thoroughfare and subThoroughfare.
Thank You in advance.

thoroughfare and subThoroughfare property that might not contain data for some places. So instead of creatying address string using thoroghfare and subThoroghfare, use addressdictionary as follow:
NSString *address = ABCreateStringWithAddressDictionary(placeInfo .addressDictionary, NO);

Related

convert NSArray to MKPlacemark

I have a forward geocode block. like this:
[_geoCoder geocodeAddressString:searchString completionHandler:^(NSArray *placemarks, NSError *error) {....}];
As is, the geocode data stores in the NSArray * placemarks. Now I would like to do some annotation to the map, The addAnnotation method requires a MKPlacemark, so how do I convert the place mark in NSArrayinto a MKPlacemark? Thanks.
Here's what you want to do: Iterate through the parameters array - meaning, fetch each item from the array. As we're fetching the items, we want to create MKPlacemark objects using the data the items contain.
The Objective-C language gives us a special tool that allows us to iterate through the array - the "forin" loop:
for (CLPlacemark *placemark in placemarks)
{
// insert code here
}
Now, we want to create an MKPlacemark object from "placemark": (Note: An MKPlacemark object is a CLPlacemark object)
MKPlacemark *mkPlacemark = [MKPlacemark initWithCoordinate:(CLLocationCoordinate2D)coordinate
addressDictionary:(NSDictionary<NSString *,id> *)addressDictionary;]

Convert a place String to a CLLocation

I'm having a bug with the convertion of an NSString (which contains a place from a UITextField input) to a CLLocation.
Here is the method supposed to process the convertion:
- (void)geoCodeForAddress:(NSString *)address {
CLGeocoder *geocoder = [[CLGeocoder alloc] init];
[geocoder geocodeAddressString:address completionHandler:^(NSArray* placemarks, NSError* error){
dispatch_async(dispatch_get_main_queue(), ^{
CLPlacemark *placeMark = [placemarks lastObject];
if (placeMark.location != nil) {
self.actionLocation = placeMark.location;
} else {
self.actionLocation = nil;
}
if(self.event)
[self.tableView reloadData];
});
}];
}
My problem is, this method returns the wrong location for some specific strings. For instance, whenever I try to use "la patache paris" as an input, it returns a location in the wrong city though when I try the same exact string in Maps, it's finding the right place.
The method geocodeAddressString:completionHandler: is a CoreLocation method from the CLGeocoder class so there is no way I can see what's going on in it.
Would someone have some lead to find out why this is behaving weirdly ?
Thank you.

how can I send coordinates to parse and save it as parse PFGeopoint

How can i send coordinates to Parse fetched by CLLocation and save it there as PFGeoPoint's latitude and longitude?
I am able to get the coordinates from CLLocation and I want to send it to Parse. In Parse I have a column named "coordinates" of type PFGeoPoint which has two fields.Now I want to save the coordinates which I have got from CLLocation to Parse Column coordinates.
can anyone please help me with this?
I am new to iOS and Parse.
Two steps:
Convert CLLocation to PFGeoPoint
//SWIFT
let point = PFGeoPoint(location: currentLoc)
//Obj-c
[PFGeoPoint *point = PFGeoPoint geoPointWithLocation:(PF_NULLABLE CLLocation *)location];
Now save it.
//SWIFT
object["coordinates"] = point
object.saveInBackgroundWithBlock {
(success: Bool, error: NSError?) -> Void in
if (success) {
// The object has been saved.
} else {
// There was a problem, check error.description
}
}
//Obj-c
object["coordinates"] = point;
[object saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
if (succeeded) {
// The object has been saved.
} else {
// There was a problem, check error.description
}
}];

How to convert PFGeoPoint to CLLocation

Is it possible to convert the PFGeoPoint with Parse to a CLLocation?
Reason being I'm trying to get the names of places from PFGeoPoint like so:
CLGeocoder *geocoder;
CLPlacemark *placemark;
PFGeoPoint *point = [object objectForKey:#"location"];
[geocoder reverseGeocodeLocation:point completionHandler:^(NSArray *placemarks, NSError *error) {
NSLog(#"Found placemarks: %#, error: %#", placemarks, error);
if (error == nil && [placemarks count] > 0)
{
placemark = [placemarks lastObject];
NSLog(#"%#", placemarks);
}
}];
Error I get obviously is:
Incompatiable pointer types sending 'PFGeoPoint *' to parameter of type 'CLLocation *'
As Wain said there is no convenient method to convert from PFGeoPoint to a CLLocation however you can make your own and extend PFGeoPoint using the following
import Parse
extension PFGeoPoint {
func location() -> CLLocation {
return CLLocation(latitude: self.latitude, longitude: self.longitude)
}
}
now you can easily return a CLLocation object by doing
let aLocation: CLLocation = yourGeoPointObject.location()
You need to explicitly create the CLLocation instance using initWithLatitude:longitude: with the latitude and longitude from the PFGeoPoint. There is only a convenience method for creating a PFGeoPoint from a CLLocation, not the other way round.
Based on Justin Oroz's answer (see the answer below):
Also a great idea could be to create the extension in the CLLocation side so it can be created using a convenience init which receives the PFGeoPoint:
extension CLLocation {
convenience init(geoPoint: PFGeoPoint) {
self.init(latitude: geoPoint.latitude, longitude: geoPoint.longitude)
}
}
You could always get the PFGeoPoint and then add it to a CLLocationCoordinate2D like this:
//get all PFObjects
let parseLocation = ParseObject["location"]
let location:CLLocationCoordinate2D = CLLocationCoordinate2D(latitude: parseLocation.latitude, longitude: parseLocation.longitude)

Checking Proximity of two Locations in IOS

I have an array of locations and when I add another I want to be able to check if the other locations in the array are within a block of the new one. This is the Code I have to find the current location:
//Geocoding Block
[self.geoCoder reverseGeocodeLocation: locationManager.location completionHandler:
^(NSArray *placemarks, NSError *error) {
//Get nearby address
CLPlacemark *placemark = [placemarks objectAtIndex:0];
//String to hold address
locatedAt = [[placemark.addressDictionary valueForKey:#"FormattedAddressLines"] componentsJoinedByString:#", "];
The array has yet to be created because I want to figure this out first, I dont know what should be held in the array (string...). I know how to do a search I just need to know how to compare the locations.
You can get the distance between two locations using the distanceFromLocation: method on CLLocation. (You can get a CLLocation out of a CLPlacemark with myPlacemark.location.) So if you have an array of CLLocation objects, and you want to find the ones that are within one block (1/20 mile, or about 80 meters), you can do this:
NSMutableArray *locationsWithinOneBlock = [NSMutableArray new];
for (CLLocation *location in myLocations) {
if ([location distanceFromLocation:targetLocation] <= 80.0)
[locationsWithinOneBlock addObject:location];
}
This assumes you have an array myLocations of CLLocation objects that you want to filter against a single CLLocation called targetLocation.

Resources