I'm developing an application that makes the user call a specific number depending on their current position using NSDictionary. This position is displayed on a label. Now, if the user is in a position that is not included in the NSDictionary, it calls "6588". How do I change that number to a number of my choice?
placemark = [placemarks lastObject];
_addressLabel.text = [NSString stringWithFormat:#"%# %#\n%# %#\n%#\n%#",
placemark.thoroughfare, placemark.subThoroughfare,
placemark.postalCode, placemark.locality,
placemark.administrativeArea,
placemark.country];
- (IBAction)phone { [[UIApplication sharedApplication] openURL: [NSURL URLWithString:#"tel:%#"]];
NSDictionary *localityToPhoneNumber = #{#"London": #"123456",};
NSString *phoneNumber = [localityToPhoneNumber objectForKey:placemark.locality];
NSString *tel = [NSString stringWithFormat:#"tel:%#", phoneNumber];
[[UIApplication sharedApplication] openURL: [NSURL URLWithString:tel]];
Thank you very much in advance.
You can check is the key in the dictionary exists and if it doesn't exist you can call the default number, which is in your case 6588.
Something like this:
if (![localityToPhoneNumber objectForKey:placemark.locality]) {
// Call default number
} else {
// Call the number for the locality
}
Related
I have an array of addresses that I need to convert to Lat/Long using Google's Geocode api. I am feeding an address and the city into the Google Geocode URL, which forms a correct connection url.
Basically I want to be able to use a for loop to create multiple NSURLConnection requests, returning multiple responses.
-(void)setString{
for (int i = 0; i < [businessArray count]; i ++)
{
NSString *address = [addressArray objectAtIndex:0];
NSString *city = [locationDict valueForKey:#"city"];
NSString *geocodeURL = [NSString stringWithFormat:#"http://maps.googleapis.com/maps/api/geocode/json?address=%#,+%#,&sensor=true", address, city];
geocodeURL = [geocodeURL stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:geocodeURL]
cachePolicy:NSURLRequestUseProtocolCachePolicy
timeoutInterval:10];
NSLog(#"%#", request);
geoCodeConnection = [[NSURLConnection alloc] initWithRequest:request delegate:self startImmediately:YES];
if (geoCodeConnection)
{
responseData = [NSMutableData data];
connectionIsActive = YES;
NSLog(#"connection active");
} else {
NSLog(#"connection failed");
connectionIsActive = NO;
}
}
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
NSString *responseString = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding];
NSError *jsonError = nil;
SBJsonParser *json = [[SBJsonParser alloc] init];
NSDictionary *parsedJSON = [json objectWithString:responseString error:&jsonError];
NSString *lat= [[[[parsedJSON valueForKey:#"results"] valueForKey:#"geometry"] valueForKey:#"location"] valueForKey:#"lat"];
NSString *lng= [[[[parsedJSON valueForKey:#"results"] valueForKey:#"geometry"] valueForKey:#"location"] valueForKey:#"lng"];
NSLog(#"lat = %# long= %#", lat, lng);
connectionIsActive = NO;
[geoCodeLatArray addObject:lat];
[geoCodeLngArray addObject:lng];
NSLog(#"geoCodeArrayLat: %#", geoCodeLatArray);
}
Right now the code returns only the last address' lat and long. How can I send multiply requests and return multiply responses with JSON?
Try this I am using this,
for(int i=0;i< businessArray.count;i++)
{
NSString *address = [addressArray objectAtIndex:i];
NSString *city = [locationDict valueForKey:#"city"];
NSString *address = [NSString stringWithFormat:#"%#,%#", address, city];
CLLocationCoordinate2D location = [self geoCodeUsingAddress:address];
// then here store the location.latitude in lat array and location.longitude in long array.
}
- (CLLocationCoordinate2D) geoCodeUsingAddress:(NSString *)address
{
NSString *esc_addr = [address stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSString *req = [NSString stringWithFormat:#"http://maps.google.com/maps/api/geocode/json?sensor=false&address=%#", esc_addr];
NSDictionary *googleResponse = [[NSString stringWithContentsOfURL: [NSURL URLWithString: req] encoding: NSUTF8StringEncoding error: NULL] JSONValue];
NSDictionary *resultsDict = [googleResponse valueForKey: #"results"];
NSDictionary *geometryDict = [resultsDict valueForKey: #"geometry"];
NSDictionary *locationDict = [geometryDict valueForKey: #"location"];
NSArray *latArray = [locationDict valueForKey: #"lat"];
NSString *latString = [latArray lastObject];
NSArray *lngArray = [locationDict valueForKey: #"lng"];
NSString *lngString = [lngArray lastObject];
CLLocationCoordinate2D location;
location.latitude = [latString doubleValue];
location.longitude = [lngString doubleValue];
return location;
}
Update to the above function:
- (CLLocationCoordinate2D) geoCodeUsingAddress:(NSString *)address
{
double latitude = 0, longitude = 0;
NSString *esc_addr = [address stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSString *req = [NSString stringWithFormat:#"http://maps.google.com/maps/api/geocode/json?sensor=false&address=%#", esc_addr];
NSString *result = [NSString stringWithContentsOfURL:[NSURL URLWithString:req] encoding:NSUTF8StringEncoding error:NULL];
if (result) {
NSScanner *scanner = [NSScanner scannerWithString:result];
if ([scanner scanUpToString:#"\"lat\" :" intoString:nil] && [scanner scanString:#"\"lat\" :" intoString:nil]) {
[scanner scanDouble:&latitude];
if ([scanner scanUpToString:#"\"lng\" :" intoString:nil] && [scanner scanString:#"\"lng\" :" intoString:nil]) {
[scanner scanDouble:&longitude];
}
}
}
CLLocationCoordinate2D location;
location.latitude = latitude;
location.longitude = longitude;
return location;
}
This worked for me.
You might approach the problem using an asynchronous method that performs the request and has a completion block which will be called when the result is available. This completion block provides a parameter result which is the result of the connection request.
This method may be declared as follows:
typedef void (^completion_block_t) (id result);
- (void) fetchGeoCoordinateForAddress:(NSString*)address
completionHandler:(completion_block_t)completionHandler;
Say, if the request succeeds the parameter result in the block is a JSON representation of the response data. Otherwise, result is an NSError object indicating the error. But the exact details depend on how you implement the method fetchGeoCoordinateForAddress:completionHandler:.
Now you can setup the loop as follows:
for (NSString* address in addresses)
{
[self fetchGeoCoordinateForAddress:address completionHandler:^(id result) {
if (![result isKindOfError:[NSError class]]) // check if result is an error
{
// Note: result is not nil and is a NSDictionary representation of JSON.
// Retrieve the "location" from the response:
NSDictionary* location = result[#"results"][#"geometry"][#"location"];
// Multiple request can occur at the same time! Thus, we need to
// synchronize access to the result array "myLocations" through
// accessing it *exclusively and everywhere* on the main thread:
dispatch_async(dispatch_get_main_queue(), ^{
[self.myLocations addObject:location];
});
}
else {
// got error
DebugLog(#"ERROR: %#", result);
}
}
}
Note: your actual code may differ slightly depending on the actual JSON and other details.
Regarding the implementation of method fetchGeoCoordinateForAddress:completionHandler: you have a few options:
Use a third party library and implement a simple convenience wrapper fetchGeoCoordinateForAddress:completionHandler:.
Create your own "MyHTTPConnectionOperation" class that encapsulates a NSURLConnection and the response data and couple of other useful state info in a dedicated class. This class executes the request asynchronously via start method and has a completion handler. Basically, all third party network libraries will use this approach. Then implement the wrapper.
Use NSURLConnection's asynchronous convenient method if it is sufficient and works in your context. This is the fastest to implement, but least flexible approach and may not work in all cases and may also work only suboptimal.
Edit:
A couple of hints:
If possible, use NSJSONSerialization for parsing JSON and creating a Foundation representation. Other third party libraries only offer a slight advantage if you have special requirements, e.g. you need "chunked parsing with NSData objects" - which is useful when you want to download and parse simultaneously. Or you need to create other representations than Foundation - say a C++ container or you want directly create a Model with SAX style parsing. Or, you need better performance and lower memory food print since you are receiving ultra large strings which you want to save to disk. NSJSONSerialization became quite fast recently, so "performance" alone shouldn't be an argument today.
The timeout for the request shall be not that low as 10 seconds. In a cellular connection, this is too less. Leave it at the default.
If you plan to implement your own "HTTPConnectionOperation" class, I've put a very limited sample on gist here which can give you a jump start.
I think you have to start with AFNetworking
AFNetworking1
AFNetworking2
because AFNetworking gives a lot of power and flexibility in terms of scheduling and queueing requests as well as pausing and cancelling requests.
My aim is to open a map application from ios application with directions, I am able to open maps application but it is not showing directions, i have written the code as follows
NSString *mystr=[[NSString alloc] initWithFormat:#"http://maps.apple.com/maps?saddr=Current+Location&daddr=Newyork"];
NSURL *myurl=[[NSURL alloc] initWithString:mystr];
[[UIApplication sharedApplication] openURL:myurl];
Can any one please help me how figure out how to pass parameters to this url and any other?
CLLocationCoordinate2D coordinate = CLLocationCoordinate2DMake(self.location.latitude,self.location.longitude);
//create MKMapItem out of coordinates
MKPlacemark* placeMark = [[MKPlacemark alloc] initWithCoordinate:coordinate addressDictionary:nil];
MKMapItem* destination = [[MKMapItem alloc] initWithPlacemark:placeMark];
if([destination respondsToSelector:#selector(openInMapsWithLaunchOptions:)])
{
//using iOS6 native maps app
if(_mode == 1)
{
[destination openInMapsWithLaunchOptions:#{MKLaunchOptionsDirectionsModeKey:MKLaunchOptionsDirectionsModeWalking}];
}
if(_mode == 2)
{
[destination openInMapsWithLaunchOptions:#{MKLaunchOptionsDirectionsModeKey:MKLaunchOptionsDirectionsModeDriving}];
}
if(_mode == 3)
{
[destination openInMapsWithLaunchOptions:#{MKLaunchOptionsDirectionsModeKey:MKLaunchOptionsDirectionsModeTransit}];
}
} else{
//using iOS 5 which has the Google Maps application
NSString* url = [NSString stringWithFormat: #"http://maps.google.com/maps?saddr=Current+Location&daddr=%f,%f", self.location.latitude, self.location.longitude];
[[UIApplication sharedApplication] openURL: [NSURL URLWithString: url]];
}
If you mean taking the user to the maps application based on two points, then you can do it like this:
Create an NSURL that looks like this:
NSURL *URL = [NSURL URLWithString:#"http://maps.google.com/maps?saddr=%f,%f&daddr=%f,%f"];
You plug in your starting address and destination (in lat. and long.) appropriately.
Tell your application to open the URL
[[UIApplication sharedApplication] openURL:URL];
It should take you to the maps application automatically!
I'm wanting to create a link in my application that essentially will be labelled "Take Me Home". When pressed, I want it to open Apple Maps, route from current location to home, and start turn by turn navigation.
I have found this scheme, but it does not do everything I was hoping for:
http://maps.apple.com/maps?saddr=%f,%f&daddr=%f,%f
Here is a working code for opening Maps with routes (including the option to show Google maps for iOS5)
-(IBAction)showMapApp:(id)sender
{
CLLocationCoordinate2D coordinate = CLLocationCoordinate2DMake(self.location.latitude,self.location.longitude);
//create MKMapItem out of coordinates
MKPlacemark* placeMark = [[MKPlacemark alloc] initWithCoordinate:coordinate addressDictionary:nil];
MKMapItem* destination = [[MKMapItem alloc] initWithPlacemark:placeMark];
if([destination respondsToSelector:#selector(openInMapsWithLaunchOptions:)])
{
//using iOS6 native maps app
if(_mode == 1)
{
[destination openInMapsWithLaunchOptions:#{MKLaunchOptionsDirectionsModeKey:MKLaunchOptionsDirectionsModeWalking}];
}
if(_mode == 2)
{
[destination openInMapsWithLaunchOptions:#{MKLaunchOptionsDirectionsModeKey:MKLaunchOptionsDirectionsModeDriving}];
}
if(_mode == 3)
{
[destination openInMapsWithLaunchOptions:#{MKLaunchOptionsDirectionsModeKey:MKLaunchOptionsDirectionsModeDriving}];
}
} else{
//using iOS 5 which has the Google Maps application
NSString* url = [NSString stringWithFormat: #"http://maps.google.com/maps?saddr=Current+Location&daddr=%f,%f", self.location.latitude, self.location.longitude];
[[UIApplication sharedApplication] openURL: [NSURL URLWithString: url]];
}
}
Use this For me its working fine::
NSString* url = [NSString stringWithFormat: #"http://maps.apple.com/maps?saddr=44.521358,11.374080&daddr=44.518640,11.362665"];
[[UIApplication sharedApplication] openURL: [NSURL URLWithString: url]];
I was trying to show the address in google map in my iphone app.
I tried to use
NSString * theAddressString =......;
NSString * query = [NSString stringWithFormat:#"http://maps.google.com/maps?q=%#",theAddressString];
NSString * urlString = [query stringByAddingPercetntEscapesUsingEncoding:NSUTF8StringEncoding];
[UIApplication sharedApplication] openURL:[NSURL URLWithString:urlString];
Google map can not find some addresses we provided.(Some Japanese or Chinese addresses) But if I saved the address to iPhone contacts. And then pressed
the contact's address link. It will jump to google maps,though google map first alerted that "can not locate the address", after I confirmed the alert message, another view would display the location in the google map or show the address in the nearby.
So iPhone's "Contact" app may use other apis to filter the address string to locate the address or using some king of "fuzzy search".
Does anybody know how do they achieve it?
I really appreciate your help.
Try out the following one and let me about the status of solution.
NSString * theAddressString =......;
NSString *latlong = [[myLatitude stringByAppendingString:#","]stringByAppendingString:myLongitude];
NSString * query = [NSString stringWithFormat:#"http://maps.google.com/maps?q=%##%#",[theAddressString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding], [latlong stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
//NSString * urlString = [query stringByAddingPercetntEscapesUsingEncoding:NSUTF8StringEncoding];
[UIApplication sharedApplication] openURL:[NSURL URLWithString:urlString];
New Code with give address:
NSString *theAddressString = #"東村山市野口町1-3-49 アマドムス 102, 東京都, 日本";
NSString *urlString=[NSString stringWithFormat:#"http://maps.google.com/maps/geo?q=%#&output=csv",[theAddressString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
NSString *locationString = [NSString stringWithContentsOfURL:[NSURL URLWithString:urlString]];
NSArray *listItems = [locationString componentsSeparatedByString:#","];
float latitude=0.0;
float longitude=0.0;
if([listItems count] >=4 && [ [listItems objectAtIndex:0] isEqualToString:#"200"]){
latitude = [[listItems objectAtIndex:2] doubleValue];
longitude = [[listItems objectAtIndex:3] doubleValue];
}
else{
NSLog(#"Error");
}
NSString *myLatitude = [NSString stringWithFormat:#"%f",latitude];
NSString *myLongitude = [NSString stringWithFormat:#"%f",longitude];
NSString *latlong = [[myLatitude stringByAppendingString:#","]stringByAppendingString:myLongitude];
NSString * query = [NSString stringWithFormat:#"http://maps.google.com/maps?q=%##%#",[theAddressString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding], [latlong stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:query]];
I have checked the query string with google map and it is showing me the pin in Google map.
I'd like to make a button call a phone number entered by the user inside the text field. I have a code but it doesn't work.
NSString * phoneNumber = [NSString stringWithFormat:#"%#%#", #"tel://", phoneNumber.text];
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:phoneNumber]];
Anyone has a similar approach to this? Thanks.
I think it's tel: instead of tel://. See this Apple document. Try giving this a shot:
NSString *pn = [#"tel:" stringByAppendingString:phoneNumber.text];
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:pn]];
See my answer to another question for some sample code to handle cases with invalid input.
Basically you do this:
NSString *cleanedString = [[phoneNumber componentsSeparatedByCharactersInSet:[[NSCharacterSet characterSetWithCharactersInString:#"0123456789-+()"] invertedSet]] componentsJoinedByString:#""];
NSString *escapedPhoneNumber = [cleanedString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSURL *telURL = [NSURL URLWithString:[NSString stringWithFormat:#"tel://%#", escapedPhoneNumber]];
Update: I noticed that the string you created shares the some name ("phoneNumber") as the text field from which you try to get the text. You may want to rename either of those two.