my problem is rather simple but I can not seem to figure it out.
I am trying to add a refresh button to my mapview that will go back to the server and retrieve new locations if there have been any updates. My code below can already make the first call to the server with viewdidload method and can plot all the locations on the server to the map. What I need now is for a button that will make this same call whenever pressed, I am using one class for all my code so please your simplest solution that will easily merge with the code will be very much appreciated.
I am also very new to ios programming so any advice on how to tidy up my code will be also appreciated.
This is my view controller that contains all my code.
//ViewController.m
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.mapView.delegate = self;
locationManager = [[CLLocationManager alloc] init];
[locationManager setDelegate:self];
[locationManager setDistanceFilter:kCLDistanceFilterNone];
[locationManager setDesiredAccuracy:kCLLocationAccuracyBest];
if (floor(NSFoundationVersionNumber) <= NSFoundationVersionNumber_iOS_7_1) {
[self.mapView setShowsUserLocation:YES];
} else {
[locationManager requestWhenInUseAuthorization];
}
NSURL *jsonFileUrl = [NSURL URLWithString:#"http://sample.name/service.php"];
NSURLRequest *urlRequest = [[NSURLRequest alloc] initWithURL:jsonFileUrl];
[NSURLConnection connectionWithRequest:urlRequest delegate:self];
}
#pragma mark NSURLConnectionDataProtocol Methods
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
_downloadedData = [[NSMutableData alloc] init];
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
[_downloadedData appendData:data];
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
NSMutableArray *_locations = [[NSMutableArray alloc] init];
NSError *error;
NSArray *jsonArray = [NSJSONSerialization JSONObjectWithData:_downloadedData options:NSJSONReadingAllowFragments error:&error];
CLLocationCoordinate2D coordinate;
for (int i = 0; i < jsonArray.count; i++)
{
NSDictionary *jsonElement = jsonArray[i];
MKPointAnnotation* marker = [[MKPointAnnotation alloc] init];
marker.title = jsonElement[#"Name"];
marker.subtitle = jsonElement[#"Address"];
coordinate.latitude = [jsonElement [#"Latitude"] doubleValue];
coordinate.longitude = [jsonElement [#"Longitude"] doubleValue];
marker.coordinate = coordinate;
[_locations addObject:marker];
}
[self.mapView addAnnotations:_locations];
}
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation
{
static NSString *identifier;
{
if (annotation == mapView.userLocation) return nil;
MKAnnotationView *annotationView;
if (annotationView == nil) {
annotationView = [[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:identifier];
annotationView.enabled = YES;
annotationView.canShowCallout = YES;
annotationView.image = [UIImage imageNamed:#"blue_pin.png"];
} else {
annotationView.annotation = annotation;
}
return annotationView;
}
return nil;
}
- (void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status {
if (status == kCLAuthorizationStatusAuthorizedWhenInUse) {
[self.mapView setShowsUserLocation:YES];
}
}
-(void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation
{
CLLocationCoordinate2D myLocation = [userLocation coordinate];
MKCoordinateRegion zoomRegion = MKCoordinateRegionMakeWithDistance(myLocation, 10000, 10000);
[self.mapView setRegion:zoomRegion animated:YES];
}
- (BOOL) shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)InterfaceOrientation
{
return (InterfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (IBAction)Refresh:(id)sender {
}
#end
You can find my solution with comment.
Remove your old data when you refresh or when you got the response.
- (IBAction)action_goToManageDevice:(id)sender
{
[self reloadData];
}
- (void)reloadData
{
// Remove old annotation
[self.mapView removeAnnotations:self.mapView.annotations];
// reload your data
NSURL *jsonFileUrl = [NSURL URLWithString:#"http://sample.name/service.php"];
NSURLRequest *urlRequest = [[NSURLRequest alloc] initWithURL:jsonFileUrl];
[NSURLConnection connectionWithRequest:urlRequest delegate:self];
}
Related
in my first iOS app I've got a map displaying annotations for several locations. It works perfectly in the simulator and looks like this:
But on all devices the annotations are not located right. They are all placed at latitude 0 and longitude 0.
Do you have any ideas?
Here is my Source Code:
MapViewController.m
//
// MapViewController.m
//
#import "MapViewController.h"
#import "AppDelegate.h"
#import "Location.h"
#import <MapKit/MapKit.h>
#import "Reachability.h"
#import "MyAnnotation.h"
#interface MapViewController ()
#end
#implementation MapViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
self.mapView.delegate = self;
//User location
self.locationManager = [[CLLocationManager alloc]init];
if ([self.locationManager respondsToSelector:#selector(requestWhenInUseAuthorization)]) {
[self.locationManager requestWhenInUseAuthorization];
}
[self.locationManager startUpdatingLocation];
[self loadOfflineMap];
[self addAnnotations:[(AppDelegate *)[[UIApplication sharedApplication] delegate] locations]];
//Set initial region
MKCoordinateRegion region = [self.mapView regionThatFits:MKCoordinateRegionMakeWithDistance(CLLocationCoordinate2DMake(53.868223, 10.689060), 3000, 3000)];
//Set initial locatoin if one is set
if(self.initialLocationName != nil){
for (id<MKAnnotation> annotation in [self.mapView annotations]) {
if([[annotation title] isEqualToString:self.initialLocationName]){
[self.mapView selectAnnotation:annotation animated:YES];
region = [self.mapView regionThatFits:MKCoordinateRegionMakeWithDistance([annotation coordinate], 500, 500)];
}
}
}
[self.mapView setRegion:region animated:YES];
//Layout stuff
self.locationName.font = [UIFont fontWithName:#"CenturyGothic" size:self.locationName.font.pointSize];
self.locationAddress.font = [UIFont fontWithName:#"CenturyGothic" size:self.locationAddress.font.pointSize];
}
-(void)addAnnotations:(NSMutableArray *)locations{
self.locationNameToAnnotation = [[NSMutableDictionary alloc] init];
for(Location *location in locations){
MyAnnotation *annotation = [[MyAnnotation alloc] initWithTitle:location.name AndCoordinate:CLLocationCoordinate2DMake([location.latitude doubleValue], [location.longitude doubleValue])];
[self.locationNameToAnnotation setObject:annotation forKey:location.name];
[self.mapView addAnnotation:annotation];
}
}
-(void)mapView:(MKMapView * )mapView didSelectAnnotationView:(MKAnnotationView * )view{
for(NSString *locationName in self.locationNameToAnnotation){
if([locationName isEqualToString:view.annotation.title]){
Location *location = [Location getLocationFromLocations:[(AppDelegate *)[[UIApplication sharedApplication] delegate] locations] byName:locationName];
self.locationName.text = location.name;
self.locationAddress.text = location.address;
}
}
self.locationInfoView.hidden = NO;
[self.mapView setCenterCoordinate:view.annotation.coordinate animated:YES];
}
-(void)mapView:(MKMapView *)mapView didDeselectAnnotationView:(MKAnnotationView *)view{
self.locationInfoView.hidden = YES;
}
-(void)loadOfflineMap{
self.mapView.delegate = self;
NSString *baseURL = [[[NSBundle mainBundle] bundleURL] absoluteString];
NSString *template = [baseURL stringByAppendingString:#"{x}-{y}.jpg"];
self.overlay = [[MKTileOverlay alloc] initWithURLTemplate:template];
self.overlay.canReplaceMapContent = YES;
self.overlay.minimumZ = 12;
self.overlay.maximumZ = 19;
[self.mapView addOverlay:self.overlay level:MKOverlayLevelAboveLabels];
}
- (MKOverlayRenderer *)mapView:(MKMapView *)mapView rendererForOverlay:(id<MKOverlay>)overlay {
return [[MKTileOverlayRenderer alloc] initWithTileOverlay:overlay];
}
- (IBAction)mapTypeChanged:(UISegmentedControl *)sender {
if(sender.selectedSegmentIndex == 1){
if([self checkIntetnetConnection] == YES){
[self.mapView removeOverlay:self.overlay];
}else{
sender.selectedSegmentIndex = 0;
}
}else if(sender.selectedSegmentIndex == 0){
[self.mapView addOverlay:self.overlay level:MKOverlayLevelAboveLabels];
}
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
-(BOOL)checkIntetnetConnection{
Reachability *networkReachability = [Reachability reachabilityForInternetConnection];
NetworkStatus networkStatus = [networkReachability currentReachabilityStatus];
if (networkStatus == NotReachable) {
//NSLog(#"There IS NO internet connection");
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"No Internet" message:#"Sorry, please turn on your internet to access the online map" delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil, nil];
[alert show];
return NO;
} else {
//NSLog(#"There IS internet connection");
return YES;
}
}
#end
MyAnnotation.m
//
// MyAnnotation.m
//
#import "MyAnnotation.h"
#implementation MyAnnotation
#synthesize coordinate=_coordinate;
#synthesize title=_title;
-(id) initWithTitle:(NSString *) title AndCoordinate:(CLLocationCoordinate2D)coordinate
{
self = [super init];
_title = title;
_coordinate = coordinate;
return self;
}
#end
Edit 1
Locations Array Parsing from JSON, which works fine:
-(void)createLocations:(NSDictionary *)jsonLocations{
self.locations = [[NSMutableArray alloc] init];
for(NSDictionary *jsonLocation in jsonLocations){
Location *location = [[Location alloc] init];
[location setName:jsonLocation[#"name"]];
[location setId:jsonLocation[#"id"]];
[location setLatitude:[self getNumberFromString:jsonLocation[#"latitude"]]];
[location setLongitude:[self getNumberFromString:jsonLocation[#"longitude"]]];
[location setZoomlevel:jsonLocation[#"zoomlevel"]];
[location setAddress:jsonLocation[#"address"]];
[self.locations addObject:location];
}
}
I'd really appreciate all ideas. Probably it's an easy question but since I'm new to iOS Development I'm quite frustrated right now.
Cheers Thomas!
I have a two view controllers (DatePickerViewController and RouteHistoryViewController). I also have the server response in DatePickerViewController. How can I pass that response to the RouteHitoryViewController. The RouteHistoryViewController has a map view.
Here is the code DatePicker.m :
#import "DatePickerViewController.h"
#import "MapAnnotation.h"
#interface DatePickerViewController ()
#end
#implementation DatePickerViewController
{
//#define URL #"http://140e3087.ngrok.com"
#define URL3 #"http://784effb4.ngrok.com/bustracking/json/student/route_history"
NSString *formatedDate;
NSString *lat;
NSString *longi;
NSString *server_created_date;
}
#synthesize appDelagate,datePicker;
- (void)viewDidLoad {
[super viewDidLoad];
AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
NSLog(#"%#", appDelegate);
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"yyyy-MM-dd HH:mm"];
formatedDate = [dateFormatter stringFromDate:self.datePicker.date];
// Do any additional setup after loading the view.
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (IBAction)sendPicker:(id)sender;
{
[self sendDataToServer : #"GET"];
// NSLog(#"%#", formatedDate);
//self.selectedDate.text =formatedDate;
}
-(void) sendDataToServer : (NSString *) method{
NSString *beaconiD = #"EC112729B51B";
NSString *trackerID = #"e61078a67e4233ad";//appDelagate.tracker_id;
NSString *date = formatedDate;
NSMutableURLRequest *request = nil;
NSString *getURL = [NSString stringWithFormat:#"%#?beacon_id=%#&tracker_id=%#&date=%#", URL3, beaconiD, trackerID, date];
getURL = [getURL stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSURL *url = [NSURL URLWithString: getURL];
request = [NSMutableURLRequest requestWithURL:url];
NSLog(#"link: %#", getURL);
[request setHTTPMethod:#"GET"];
[request addValue: #"application/x-www-form-urlencoded; charset=utf-8" forHTTPHeaderField:#"Content-Type"];
NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
NSLog(#"connection: %#", connection);
if( connection )
{
mutData = [NSMutableData new];
}
else
{
NSLog (#"NO_CONNECTION");
return;
}
}
#pragma mark NSURLConnection delegates
-(void) connection:(NSURLConnection *) connection didReceiveResponse:(NSURLResponse *)response
{
[mutData setLength:0];
}
-(void) connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
[mutData appendData:data];
}
-(void) connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
NSLog (#"NO_CONNECTION");
return;
}
-(void)connectionDidFinishLoading:(NSURLConnection *)connection
{
// NSString *jsonresultString =[jsonresultDict objectForKey:#"result"];
// NSLog(#"%#", jsonresultString);
// //serverResponse.text = jsonresultString;
NSError *error = nil;
NSDictionary *json = [NSJSONSerialization JSONObjectWithData:mutData options:kNilOptions error:&error];
NSArray *fetchedArr = [json objectForKey:#"result"];
for (NSDictionary *user in fetchedArr)
{
lat = [user objectForKey:#"latitude"];
longi = [user objectForKey:#"longitude"];
server_created_date = [user objectForKey:#"server_created_date"];
NSLog(#"Item date&time : %#", server_created_date);
NSLog(#"Item longitude : %#", longi);
NSLog(#"Item latitude : %#", lat);
}
}
Here is the code RouteHistory.m:
#import "RouteHistoryViewController.h"
#import "MapAnnotation.h"
#interface RouteHistoryViewController ()
#property (weak, nonatomic) IBOutlet MKMapView *mapView;
#end
#implementation RouteHistoryViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.mapView.delegate = self;
//[self.mapView removeAnnotations:self.mapView.annotations];
MapAnnotation *mapPoint = [[MapAnnotation alloc] init];
mapPoint.coordinate = CLLocationCoordinate2DMake([self.appDelagate.latitude doubleValue], [self.appDelagate.longitude doubleValue]);
mapPoint.title = self.appDelagate.name;
mapPoint.time = self.appDelagate.server_created_date;
mapPoint.mapimage = self.appDelagate.image;
// Add it to the map view
[self.mapView addAnnotation:mapPoint];
// Zoom to a region around the pin
MKCoordinateRegion region = MKCoordinateRegionMakeWithDistance(mapPoint.coordinate, 500, 500);
[self.mapView setRegion:region];
//testing
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(receiveTestNotification:)
name:#"MapUpdate"
object:nil];
// Do any additional setup after loading the view.
}
#pragma mark - MKMapViewDelegate
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation
{
MKPinAnnotationView *view = nil;
static NSString *reuseIdentifier = #"MapAnnotation";
// Return a MKPinAnnotationView with a simple accessory button
view = (MKPinAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:reuseIdentifier];
if(!view)
{
view = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:reuseIdentifier];
view.canShowCallout = YES;
view.animatesDrop = YES;
}
return view;
}
datepicker to route history using prepareforsegue
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier]isEqualToString:#"b"])
{
RouteHistoryViewController *rh = segue.destinationViewController;
NSLog(#"%#", rh);
}
}
In first view controller inside connectionDidFinishLoading after this line
NSArray *fetchedArr = [json objectForKey:#"result"];
add the following two lines
_responseFromServer = fetchedArr;
[self performSegueWithIdentifier:#"segueToRouteHistory" sender:self];
and then add this method in your first View Controller
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([[segue identifier] isEqualToString:#"segueToRouteHistory"])
{
RouteHistoryViewController *routeHistoryController = [segue segueToRouteHistory];
[routeHistoryController setFetchedArray:_responseFromServer];
}
}
In your First View Controller .h file add this
#property NSArray *responseFromServer;
Now We have assigned the Response array received from server to a object in your destination view controller.
Don't forget to add
#property NSArray *fetchedArray;
inside your Second ViewController's .h file
Now you can access this array in second view controller.
PS: Do not forget to give segue from storyboard from first view controller to second view controller and name the Segue Identifier as "segueToRouteHistory"
I tired to get indexpath of my custom annotation ,
I use this code for get my indexpath
NSUInteger index =[mapView.annotations indexOfObject:view.annotation];
its not really working because in my map, i got right lat and lang but not get the true data of pinview
pusingpalagw is my subclass
here is my code:
-(void)mapView:(MKMapView *)mapView didSelectAnnotationView:(MKAnnotationView *)view
{
// [(UIImageView *)view.leftCalloutAccessoryView setImageWithURL:[NSURL URLWithString:self.content.MERCHANT_IMAGE] usingActivityIndicatorStyle:UIActivityIndicatorViewStyleWhite];
//if ([view.annotation isKindOfClass:[pusingpalagw class]]) {
// pusingpalagw *annot = view.annotation;
//NSInteger index = [self.arrayOfAnnotations indexOfObject:annot];
NSUInteger index =[mapView.annotations indexOfObject:view.annotation];
if (!self.content) {
pusingpalagw *calloutView = [[pusingpalagw alloc] initWithFrame:CGRectMake(0.0, 0.0, 242.0, 57.0)];
self.content12 = [self.listContent objectAtIndex:index];
calloutView.titleLabel.text = self.content12.MERCHANT_NAME;
calloutView.subtitleLabel.text = self.content12.MERCHANT_NAME;
//UIView *rating2 = (UIView*)[cell2 viewWithTag:110];
_starRating = [[EDStarRating alloc]initWithFrame:CGRectMake(calloutView.viewRating.frame.origin.x-15, calloutView.viewRating.frame.origin.y,80,20)];
_starRating.backgroundColor = [UIColor clearColor];
self.starRating.starImage = [UIImage imageNamed:#"kuningstarkosong"];
self.starRating.starHighlightedImage = [UIImage imageNamed:#"kuningstarfull"] ;
_starRating.maxRating = 5.0;
_starRating.delegate = self;
_starRating.horizontalMargin = 15.0;
_starRating.editable=NO;
_starRating.rating= [self.content12.MERCHANT_RATTING floatValue];
_starRating.displayMode=EDStarRatingDisplayHalf;
[_starRating setNeedsDisplay];
[calloutView.viewRating addSubview:_starRating];
NSLog(#"keluarbintang%#",_starRating);
NSURL *url = [NSURL URLWithString:self.content12.MERCHANT_IMAGE];
NSData *imageData = [NSData dataWithContentsOfURL:url];
UIImage *abs = [UIImage imageWithData:imageData];
[calloutView.imageMap setImage:abs];
//[calloutView.buttonDetail setTitle: #"Post" forState: UIControlStateNormal];
UIButton *buttonAja = [[UIButton alloc]initWithFrame:CGRectMake(0, 0, calloutView.frame.size.width, calloutView.frame.size.height)];
[buttonAja setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
//[buttonAja setTitle: #"Post" forState: UIControlStateNormal];
buttonAja.titleLabel.font = [UIFont systemFontOfSize:13.0];
[buttonAja addTarget:self action:#selector(goDetail:) forControlEvents:UIControlEventTouchUpInside];
[calloutView addSubview:buttonAja];
calloutView.center = CGPointMake(CGRectGetWidth(view.bounds) / 2.0, 0.0);
[view addSubview:calloutView];
}
//To get permission
if([CLLocationManager locationServicesEnabled]){
NSLog(#"Location Services Enabled");
if([CLLocationManager authorizationStatus]==kCLAuthorizationStatusDenied){
alert = [[UIAlertView alloc] initWithTitle:#"App Permission Denied"
message:#"To re-enable, please go to Settings and turn on Location Service for this app."
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alert show];
}
}
//To set user Location
- (void)viewDidLoad
{
[super viewDidLoad];
self.mapView.showsUserLocation=YES;
self.mapView.delegate = self;
[self.mapView setUserTrackingMode:MKUserTrackingModeFollow animated:YES];
}
...
-(void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation
{
MKCoordinateRegion mapRegion;
mapRegion.center = mapView.userLocation.coordinate;
mapRegion.span.latitudeDelta = 0.2;
mapRegion.span.longitudeDelta = 0.2;
[mapView setRegion:mapRegion animated: YES];
}
Permission for IOS 8 Or Later :-
#define IS_OS_8_OR_LATER ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0)
if ([CLLocationManager locationServicesEnabled] )
{
if (self.locationManager == nil )
{
self.locationManager.delegate = (id)self;
self.locationManager = [[CLLocationManager alloc] init];
#ifdef __IPHONE_8_0
if(IS_OS_8_OR_LATER)
{
// Use one or the other, not both. Depending on what you put in info.plist
[self.locationManager requestWhenInUseAuthorization];
[self.locationManager requestAlwaysAuthorization];
}
#endif
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;
self.locationManager.distanceFilter = kDistanceFilter; //kCLDistanceFilterNone// kDistanceFilter;
}
[self.locationManager startUpdatingLocation];
self.mapViewForPlace.showsUserLocation = YES;
[self.locationManager setDelegate:self];
NSLog(#"Location Title Is: %#", self.mapViewForPlace.userLocation.title);
}
Add info.plist NSLocationWhenInUseUsageDescription type of string.
-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
{
#ifdef __IPHONE_8_0
if(IS_OS_8_OR_LATER) {
// Use one or the other, not both. Depending on what you put in info.plist
[self.locationManager requestWhenInUseAuthorization];
[self.locationManager requestAlwaysAuthorization];
}
#endif
self.mapViewForPlace.showsUserLocation = YES;
self.currentLocation = [locations lastObject];
// here we get the current location
NSLog(#"Current Locations : %#",self.currentLocation);
// CLLocation* location = (CLLocation*)locations.lastObject;
// Use Apple's Geocoder to figure the name of the place
CLGeocoder* geoCoder = [[CLGeocoder alloc] init];
[geoCoder reverseGeocodeLocation:self.currentLocation completionHandler: ^(NSArray* placemarks, NSError* error) {
if (error != nil) {
NSLog(#"Error in geo coder: %#", error);
}
else {
if (placemarks.count == 0) {
NSLog(#"The address couldn't be found");
}
else {
// Get nearby address
CLPlacemark* placemark = placemarks[0];
// Get the string address and store it
NSString* locatedAt = [[placemark.addressDictionary valueForKey:#"FormattedAddressLines"] componentsJoinedByString:#", "];
//location.name = locatedAt;
currentLocationNameIs=locatedAt;
NSLog(#"The address is: %#", locatedAt);
}
}
}];
}
- (void) locationManager:(CLLocationManager *) manager didUpdateToLocation:(CLLocation *) newLocation fromLocation:(CLLocation *) oldLocation
{
self.currentLocation = newLocation;
self.mapViewForPlace.showsUserLocation = YES;
NSLog(#"New location Cordinate : %f %f",self.mapViewForPlace.userLocation.coordinate.latitude,self.mapViewForPlace.userLocation.coordinate.longitude);
[self.locationManager stopUpdatingLocation];
}
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation
{
// If it's the user location, just return nil.
if ([annotation isKindOfClass:[MKUserLocation class]])
return nil;
// Handle any custom annotations.
if ([annotation isKindOfClass:[MKPointAnnotation class]])
{
// Try to dequeue an existing pin view first.
MKAnnotationView *pinView = (MKAnnotationView*)[mapView dequeueReusableAnnotationViewWithIdentifier:#"CustomPinAnnotationView"];
if (!pinView)
{
// If an existing pin view was not available, create one.
pinView = [[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:#"CustomPinAnnotationView"];
//pinView.animatesDrop = YES;
pinView.canShowCallout = YES;
pinView.image = [UIImage imageNamed:#"facebook30.png"];
pinView.calloutOffset = CGPointMake(0, 32);
// Add a detail disclosure button to the callout.
UIButton* rightButton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
pinView.rightCalloutAccessoryView = rightButton;
// Add an image to the left callout.
UIImageView *iconView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"facebook30.png"]];
pinView.leftCalloutAccessoryView = iconView;
} else {
pinView.annotation = annotation;
}
return pinView;
}
return nil;
}
#import "MyLocationViewController.h"
#define NSLog(FORMAT, ...) printf("%s\n", [[NSString stringWithFormat:FORMAT, ##__VA_ARGS__] UTF8String]);
#interface MyLocationViewController ()
#end
#implementation MyLocationViewController
{
CLLocationManager *locationManager;
}
- (void)requestAlwaysAuthorization
{
[locationManager requestAlwaysAuthorization];
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.mapView.showsUserLocation = YES;
self.mapView.delegate = self;
locationManager = [[CLLocationManager alloc] init];
}
- (IBAction)unwindToMap:(UIStoryboardSegue *)segue
{
}
- (IBAction)getCurrentLocation:(id)sender {
locationManager.delegate = self;
locationManager.desiredAccuracy = kCLLocationAccuracyBest;
[locationManager startUpdatingLocation];
}
- (void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation
{
MKCoordinateRegion mapRegion;
mapRegion.center = mapView.userLocation.coordinate;
mapRegion.span.latitudeDelta = 0.001;
mapRegion.span.longitudeDelta = 0.001;
CLLocationCoordinate2D location = userLocation.coordinate;
float lat = location.latitude;
float lng = location.longitude;
NSDictionary *locationDictionary = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithFloat:lat] , #"Latitude",
[NSNumber numberWithFloat:lng], #"Longitude", nil];
NSDictionary *dictionary = [NSDictionary dictionaryWithObjectsAndKeys:
locationDictionary, #"Location_A",
nil];
NSError *error;
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:dictionary options:NSJSONWritingPrettyPrinted error:&error];
NSString *str = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
NSLog(#"%#",str);
if (mapView.userLocation != nil)
{
_longitudeLabel.text = [NSString stringWithFormat:#"%.8f", mapView.userLocation.coordinate.longitude];
_latitudeLabel.text = [NSString stringWithFormat:#"%.8f", mapView.userLocation.coordinate.latitude];
}
[mapView setRegion:mapRegion animated: YES];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
This is my code.
Now, I understand that I needed to edit my info.plist file (which I did) with a NSLocationAlwaysUsageDescription key, and I added a string for the description.
However, I'm having issues implementing the authorization portion, as the error still reads as such:
Trying to start MapKit location updates without prompting for location authorization. Must call -[CLLocationManager requestWhenInUseAuthorization] or -[CLLocationManager requestAlwaysAuthorization] first.
I've read the Apple IOS 8 docs for the CLLocationManager, but somehow my code will not work.
Can someone help me so that the above error message goes away by looking at where in my code I need to modify so that it works?
Thanks!
You should not turn on MKMapView's showsUserLocation before the user has authorised your app to use Location services.
You can implement CLLocationManagerDelegate's locationManager:didChangeAuthorizationStatus: method and turn on showsUserLocation there like so:
- (void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status {
if (status == kCLAuthorizationStatusAuthorizedAlways || status == kCLAuthorizationStatusAuthorizedWhenInUse) {
self.mapView.showsUserLocation = YES;
}
}
now i find the my current location in simulator
when press button show my current location
but my app located other locations
.h
#import <MapKit/MapKit.h>
#import <UIKit/UIKit.h>
#import <CoreLocation/CoreLocation.h>
#interface ViewController : UIViewController<CLLocationManagerDelegate>
#property (nonatomic,retain)MKMapView *mapView;
- (IBAction)myview:(id)sender;
#property (strong, nonatomic) IBOutlet CLLocationManager *locationManger;
#end
.m
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (IBAction)myview:(id)sender {
_locationManger =[[CLLocationManager alloc]init];
_locationManger.distanceFilter=kCLDistanceFilterNone;
_locationManger.desiredAccuracy=kCLLocationAccuracyHundredMeters;
[_locationManger startUpdatingLocation];
[_mapView setMapType:MKMapTypeStandard];
[_mapView setZoomEnabled:YES];
[_mapView setScrollEnabled:YES];
MKCoordinateRegion region={ {0.0,0.0 },{0.0,0.0}};
region.center.latitude=_locationManger.location.coordinate.latitude;
region.center.longitude=_locationManger.location.coordinate.longitude;
region.span.longitudeDelta=0.007f;
region.span.latitudeDelta=0.007f;
[_mapView setRegion:region animated:YES];
[_mapView setDelegate:sender];
}
#end
i want when button press my current location show in map
use this following link it is very hopeful for you to find the current Location and etc, the link is http://www.appcoda.com/how-to-get-current-location-iphone-user/
Step 1: #import <MobileCoreServices/MobileCoreServices.h> in header file
Step 2: Add delegate CLLocationManagerDelegate
#interface yourViewController : UIViewController<CLLocationManagerDelegate>
{
CLLocationManager *locationManager;
CLLocation *currentLocation;
}
Step 3: Add this code in class file
- (void)viewDidLoad
{
[super viewDidLoad];
[self CurrentLocationIdentifier]; // call this method
}
Step 4: Method to get location
//------------ Current Location Address-----
-(void)CurrentLocationIdentifier
{
//---- For getting current gps location
locationManager = [CLLocationManager new];
locationManager.delegate = self;
locationManager.distanceFilter = kCLDistanceFilterNone;
locationManager.desiredAccuracy = kCLLocationAccuracyBest;
[locationManager startUpdatingLocation];
//------
}
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
{
currentLocation = [locations objectAtIndex:0];
[locationManager stopUpdatingLocation];
CLGeocoder *geocoder = [[CLGeocoder alloc] init] ;
[geocoder reverseGeocodeLocation:currentLocation completionHandler:^(NSArray *placemarks, NSError *error)
{
if (!(error))
{
CLPlacemark *placemark = [placemarks objectAtIndex:0];
NSLog(#"\nCurrent Location Detected\n");
NSLog(#"placemark %#",placemark);
NSString *locatedAt = [[placemark.addressDictionary valueForKey:#"FormattedAddressLines"] componentsJoinedByString:#", "];
NSString *Address = [[NSString alloc]initWithString:locatedAt];
NSString *Area = [[NSString alloc]initWithString:placemark.locality];
NSString *Country = [[NSString alloc]initWithString:placemark.country];
NSString *CountryArea = [NSString stringWithFormat:#"%#, %#", Area,Country];
NSLog(#"%#",CountryArea);
}
else
{
NSLog(#"Geocode failed with error %#", error);
NSLog(#"\nCurrent Location Not Detected\n");
//return;
CountryArea = NULL;
}
/*---- For more results
placemark.region);
placemark.country);
placemark.locality);
placemark.name);
placemark.ocean);
placemark.postalCode);
placemark.subLocality);
placemark.location);
------*/
}];
}
-(void)getLocationCurrentAddresslatitude:(NSString *)lat andlongitude:(NSString *)longitude
{
NSHTTPURLResponse *response = nil;
NSString *jsonUrlString = [NSString stringWithFormat:#"https://maps.googleapis.com/maps/api/geocode/json?latlng=%#,%#&key=gfhhfhfhfghfghfhghfghfghDyk&result_type=street_address",lat,longitude];
NSLog(#"%#",jsonUrlString);
NSURL *url = [NSURL URLWithString:[jsonUrlString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
//-- Get request and response though URL
NSURLRequest *request = [[NSURLRequest alloc]initWithURL:url];
NSData *responseData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:nil];
//-- JSON Parsing
NSDictionary * rootDictionary = [NSJSONSerialization JSONObjectWithData:responseData options:NSJSONReadingMutableContainers error:nil];
NSArray * result = [rootDictionary objectForKey:#"results"];
NSDictionary *dic=[result objectAtIndex:0];
NSString *address=[dic objectForKey:#"formatted_address"];
self.myAddress.text=address;
}