I am using this code to do geocodeaddressstring, but each time it gives me same latitude longitude with different addresses.
I checked the placemark count and it was 1, so it was going through it completely.
I am using this format (this is not complete) to get my address and I checked the address comes as a string.
NSString *address = [NSString stringWithFormat:#"%# %# %# %#"
I would appreciate your help, thanks.
[self.geocoderDes geocodeAddressString:address completionHandler:^(NSArray *placemarks2, NSError *error) {
if ([placemarks2 count] > 0) {
CLPlacemark *placemark = [placemarks objectAtIndex:0];
CLLocation *location = placemark.location;
CLLocationCoordinate2D coordination = location.coordinate;
NSLog(#" location latitude %f, location longitude %f",coordination.latitude, coordination.longitude);
}else {
NSLog(#"%#", error.debugDescription);
}
}];
Add this key in your info.plist
<key>NSLocationAlwaysUsageDescription</key>
<string>Your Description</string>
1) You Can Try By Changing One Line In Your Existing Code
CLPlacemark *placemark = [placemarks2 lastObject];
2) Using Geocoder Try This
[self.geocoderDes geocodeAddressString:address completionHandler:^(NSArray *placemarks2, NSError *error)
{
if ([placemarks2 count] > 0) {
CLPlacemark *placemark = [placemarks2 lastObject];
NSArray *lines = placemark.addressDictionary[#"FormattedAddressLines"];
CLLocation *location = placemark.location;
NSString *str_lat = [NSString stringWithFormat: #"%f", location .coordinate.latitude];
NSString *str_long = [NSString stringWithFormat: #"%f", location.coordinate.longitude];
NSString *finalAddress = [NSString stringWithFormat:#" %#, %#, %#", lines, str_lat , str_long ];
NSLog(#" Address %#", finalAddress );
}
if(error) {
NSLog(#"Error");
return;
}
}];
3)Without Geocoder
This method is for getting lattitude and longitude based user location like state name, city name, country name.
-(CLLocationCoordinate2D) getLocationFromAddressStr: (NSString*) addressStr {
double lat = 0, longi = 0;
NSString *escapAddr = [addressStr stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSString *reqst = [NSString stringWithFormat:#"http://maps.google.com/maps/api/geocode/json?sensor=false&address=%#", escapAddr ];
NSString *finalResult = [NSString stringWithContentsOfURL:[NSURL URLWithString:reqst] encoding:NSUTF8StringEncoding error:NULL];
if (finalResult) {
NSScanner *scanner = [NSScanner scannerWithString:finalResult];
if ([scanner scanUpToString:#"\"lat\" :" intoString:nil] && [scanner scanString:#"\"lat\" :" intoString:nil]) {
[scanner scanDouble:&lat];
if ([scanner scanUpToString:#"\"lng\" :" intoString:nil] && [scanner scanString:#"\"lng\" :" intoString:nil]) {
[scanner scanDouble:&longi];
}
}
}
CLLocationCoordinate2D center;
center.latitude=lat;
center.longitude = longi;
NSLog(#"Location Logitute : %f",center.latitude);
NSLog(#"Location Latitute : %f",center.longitude);
return center;
}
Call This Method Where You Want
CLLocationCoordinate2D center;
center=[self getLocationFromAddressStr:#"mumbai"];
double latFrom=¢er.latitude;
double longFrom=¢er.longitude;
NSLog(#"Logitute : %f",latFrom);
NSLog(#"Latitute : %f",longFrom);
Related
I'm trying to get the data for a selected marker using the following code:
-(void)viewDidLoad {
NSMutableDictionary *viewParams3 = [NSMutableDictionary new];
[viewParams3 setValue:#"breweries" forKey:#"view_name"];
[DIOSView viewGet:viewParams3 success:^(AFHTTPRequestOperation *operation, id responseObject) {
self.breweryLocations = [responseObject mutableCopy];
int index = 0;
for (NSMutableDictionary *brewInfo in self.breweryLocations) {
NSString *location = brewInfo[#"address"];
NSString *userNames = brewInfo[#"node_title"];
NSString *firstRemoved = [userNames stringByReplacingOccurrencesOfString:#"'" withString:#""];
NSString *userBio = brewInfo[#"body"];
CLGeocoder *geocoderFriend = [[CLGeocoder alloc] init];
[geocoderFriend geocodeAddressString:location
completionHandler:^(NSArray* placemarks, NSError* error){
if (placemarks && placemarks.count > 0) {
CLPlacemark *topResult = [placemarks objectAtIndex:0];
MKPlacemark *placemark = [[MKPlacemark alloc] initWithPlacemark:topResult];
CLLocationCoordinate2D position = placemark.coordinate;
GMSMarker *marker = [GMSMarker markerWithPosition:position];
marker.title = firstRemoved;
marker.icon = [UIImage imageNamed:#"brewIconMax"];
marker.map = self.mapView;
marker.userData = self.breweryLocations;
marker.map.selectedMarker.zIndex = index + 1;
}
}
];
}
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Failure: %#", [error localizedDescription]);
}];
}
- (BOOL) mapView: (GMSMapView *)mapView didTapMarker:(GMSMarker *)marker
{
self.venueCategory.text = marker.userData[mapView.selectedMarker.zIndex][#"type"];
}
That said, this line of code
self.venueCategory.text = marker.userData[mapView.selectedMarker.zIndex][#"type"];
returns the data from the first dictionary in my array no matter which marker I tap (zIndex is always returned as 0). I can't seem to find the correct code to obtain the selected marker's array data anywhere.
Any idea what that line should look like instead?
It's not clear to me whether "type" is an element of the brewery location dictionary, so I'm taking some guesses here.
I'd suggest setting marker.userData to the brewInfo dictionary, and not the entire breweryLocations array.
marker.userData = brewInfo;
Then this to get the "type" from the brewInfo dictionary.
self.venueCategory.text = marker.userData[#"type"];
I am trying to write a program using Objective-C/XCode that backs up one directory (source dir) into another (dest dir).
When I test the program on a small directory on my local machine, it works as expected. But when I try a large directory, or anything over a network, the program beachballs. I know that threading is the answer. Given the following code one can tell I have been fiddling with various methods to do this. Can anyone help out? I can't seem to get this working properly.
Here is the code/method in question:
- (void)doSync:(NSString *)sURL {
bStopCopy = NO;
NSString *sSource = [[pcSource URL] path];
NSString *sDestination = [[pcDestination URL] path];
NSString *sSourcePath = [sSource stringByAppendingString:#"/"];
NSString *sDestinationPath = [sDestination stringByAppendingString:#"/"];
NSString *sSourceFile;
NSString *sDestinationFile;
NSString* file;
NSDirectoryEnumerator* enumerator = [[NSFileManager defaultManager] enumeratorAtPath:sURL];
while ((file = [enumerator nextObject]) && (bStopCopy == NO)) {
[btMainWindowStopQuitButton setTitle: #"Stop..."];
[btMainWindowStopQuitButton setTag:1];
bCopyInProgress = YES;
__block NSError *eErrorMessage;
sSourceFile = [sSourcePath stringByAppendingString:file];
sDestinationFile = [sDestinationPath stringByAppendingString:file];
// check if it's a directory & exists at destination
BOOL isDirectory = NO;
BOOL isFileExistingAtDestination = NO;
__block BOOL isThereAnError = NO;
[[NSFileManager defaultManager] fileExistsAtPath: [NSString stringWithFormat:#"%#/%#",sURL,file]
isDirectory: &isDirectory];
isFileExistingAtDestination = [[NSFileManager defaultManager] fileExistsAtPath: sDestinationFile];
if (!isDirectory) {
if (!isFileExistingAtDestination) {
// dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{
// if (![[NSFileManager defaultManager] copyItemAtPath:sSourceFile toPath:sDestinationFile error: &eErrorMessage]) {
// NSLog(#"File Copy Error: %#", eErrorMessage);
// isThereAnError = YES;
// }
// });
//[oqFileCopy addOperationWithBlock:^{
dispatch_queue_t copyQueue = dispatch_queue_create("Copy File", NULL);
dispatch_async(copyQueue, ^{
if (![[NSFileManager defaultManager] copyItemAtPath:sSourceFile toPath:sDestinationFile error: &eErrorMessage]) {
NSLog(#"File Copy Error: %#", eErrorMessage);
isThereAnError = YES;
}
//[oqMain addOperationWithBlock:^{
dispatch_async(dispatch_get_main_queue(), ^{
llFileSize = [[[NSFileManager defaultManager] attributesOfItemAtPath: sDestinationFile error: Nil] fileSize];
[[[tvDialogueLabel textStorage] mutableString] setString:
[NSString stringWithFormat:#"%#\nCopied to: %# (%qu bytes)", [[tvDialogueLabel textStorage] string], sDestinationFile, llFileSize]];
NSRange endPoint = NSMakeRange ([[tvDialogueLabel string] length], 0);
[tvDialogueLabel scrollRangeToVisible: endPoint];
llTotalFileSize = llTotalFileSize + llFileSize;
});
});
// NSLog(#"%#", sSourceFile);
// NSLog(#"%#", sDestinationFile);
} else if (isFileExistingAtDestination) {
[[[tvDialogueLabel textStorage] mutableString] setString:
[NSString stringWithFormat:#"%#\nFile: %# | Already Synced.", [[tvDialogueLabel textStorage] string], sDestinationFile]];
NSRange endPoint = NSMakeRange ([[tvDialogueLabel string] length], 0);
[tvDialogueLabel scrollRangeToVisible: endPoint];
}
}
else if (isDirectory) {
if (!isFileExistingAtDestination) {
if (![[NSFileManager defaultManager] createDirectoryAtPath:sDestinationFile withIntermediateDirectories:YES attributes:nil error: &eErrorMessage]){
NSLog(#"Directory Create Failed: %#", eErrorMessage);
isThereAnError = YES;
}
[[[tvDialogueLabel textStorage] mutableString] setString:
[NSString stringWithFormat:#"%#\nCreated Directory: %#", [[tvDialogueLabel textStorage] string], sDestinationFile]];
NSRange endPoint = NSMakeRange ([[tvDialogueLabel string] length], 0);
[tvDialogueLabel scrollRangeToVisible: endPoint];
// NSLog(#"%#", sSourceFile);
// NSLog(#"%#", sDestinationFile);
} else if (isFileExistingAtDestination) {
[[[tvDialogueLabel textStorage] mutableString] setString:
[NSString stringWithFormat:#"%#\nDirectory: %# | Already Exists.", [[tvDialogueLabel textStorage] string], sDestinationFile]];
NSRange endPoint = NSMakeRange ([[tvDialogueLabel string] length], 0);
[tvDialogueLabel scrollRangeToVisible: endPoint];
}
[self doSync: file];
}
if (isThereAnError) {
NSLog(#"There was an error!");
//[_wDialogue setTitle: #"Error while syncing..."];
break;
}
// NSLog(#"%#", #"==================================================");
}
}
The easiest way to do this might be to remove all the block code from your method, and simply make your call to doSync: using performSelectorInBackground:withObject:. For example:
[foo performSelectorInBackground:#selector(doSync:) withObject:myURL];
Another easy way of doing this, if you're using OSX 10.6 and up, would be to throw all this code to Grand Central Dispatch. The while loop is what needs to be on a different thread, that's the one that's holding up the main thread. By wrapping the whole thing into a dispatch_async(), you're moving that while loop on a different thread as well.
- (void)doSync:(NSString *)sURL {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{
// your doSync code goes here
});
}
I make some method, that takes digits and operands from stack and display it in a more user friendly style. The problem is with descriptionString variable, it return null in part when topOfStack is "+". I show a log below.
+(NSString *)descriptionOfTopOfStack:(NSMutableArray *)stack
{
NSString *descriptionString;
id topOfStack = [stack lastObject];
NSString *secondInStack;
NSString *thirdInStack;
if (topOfStack)
[stack removeLastObject];
if ([topOfStack isKindOfClass:[NSNumber class]]) {
descriptionString = [topOfStack stringValue];
}
else if([topOfStack isKindOfClass:[NSString class]]){
if(([topOfStack isEqualToString:#"+"]) || ([topOfStack isEqualToString:#"—"])){
secondInStack = [self descriptionOfTopOfStack:stack];
thirdInStack = [self descriptionOfTopOfStack:stack];
descriptionString = [descriptionString stringByAppendingFormat:#"%# %# %#",thirdInStack,topOfStack,secondInStack];
NSLog(#"description is %#",descriptionString);
}
}
return descriptionString;
}
i made example with 2 + 6, this is log:
2012-02-21 22:09:39.983 Calculator[12536:f803] stack = (
2,
6,
"+"
)
2012-02-21 22:09:39.983 Calculator[12536:f803] description is (null)
Why descriptionString is null? Where i made a mistake? Thanks
In the line:
descriptionString = [descriptionString stringByAppendingFormat:#"%# %# %#",thirdInStack,topOfStack,secondInStack];
The variable descriptionString is nil. Replace that line with the following.
descriptionString = [NSString stringWithFormat:#"%# %# %#",thirdInStack,topOfStack,secondInStack];
I suspect you are not setting a value to the descriptionString variable in the other branch of the if, so you are appending string to null. You could set the variable, or you could use [NSString stringWithFormat:format]:
if ([topOfStack isKindOfClass:[NSNumber class]]) {
descriptionString = [topOfStack stringValue];
}
else if([topOfStack isKindOfClass:[NSString class]]){
if(([topOfStack isEqualToString:#"+"]) || ([topOfStack isEqualToString:#"—"])){
secondInStack = [self descriptionOfTopOfStack:stack];
thirdInStack = [self descriptionOfTopOfStack:stack];
descriptionString = [NSString stringWithFormat:#"%# %# %#",thirdInStack,topOfStack,secondInStack];
NSLog(#"description is %#",descriptionString);
}
}
im trying to get the same value on xmlDictionary and dicionarioXML but, my dicionarioXML its allway (null), any help?
#synthesize xmlDictionary;
-(NSString*)buscaDados:(NSData*) dados
{
NSString * responseContent = [[NSString alloc] initWithBytes:[dados bytes] length:[dados length] encoding:NSUTF8StringEncoding];
NSError *parseError = nil;
xmlDictionary = [XMLReader dictionaryForXMLString:responseContent error:&parseError];
[responseContent release];
NSString* sucesso=[xmlDictionary valueForKeyPath:#"receitas.total.text"];
NSLog(#"xmlDictionary: %#",xmlDictionary);
return sucesso;
}
-(NSDictionary*)trataDados
{
NSDictionary* dicionarioXML = [self xmlDictionary];
NSLog(#"dicionarioXML: %#",dicionarioXML);
return dicionarioXML;
}
Null means something doesn't exist. What error are you getting back?
NSLog(#"Error: %#", parseError);
I am trying to find and set the location as shown below but I keep getting the error 'Invalid Initializer'
CLLocationCoordinate2D location =[self.mapView addressLocation];
Where addressLocation method is as show below
-(CLLocationCoordinate2D) addressLocation {
NSString *urlString = [NSString stringWithFormat:#"http://maps.google.com/maps/geo?q=%#&output=csv",
[searchBar.text stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
//NSString *locationString = [NSString stringWithContentsOfURL:[NSURL URLWithString:urlString]];
NSError* error;
NSString *locationString = [NSString stringWithContentsOfURL:[NSURL URLWithString:urlString] encoding:NSASCIIStringEncoding error:&error];
NSArray *listItems = [locationString componentsSeparatedByString:#","];
double latitude = 0.0;
double longitude = 0.0;
if([listItems count] >= 4 && [[listItems objectAtIndex:0] isEqualToString:#"200"]) {
latitude = [[listItems objectAtIndex:2] doubleValue];
longitude = [[listItems objectAtIndex:3] doubleValue];
}
else {
//Show error
}
CLLocationCoordinate2D location;
location.latitude = latitude;
location.longitude = longitude;
return location;
}
Can you advise why I am getting the 'Invalid initializer' error? I have already imported the corelocation location framework and also imported the header files. So not sure what is wrong.
You are invoking [self.mapView addressLocation]. Shouldn't it be [self addressLocation]? I'm presuming mapView is the MKMapView in your class and doesn't have any addressLocation method.