User Location-Mapview - ios

I would like to find out userlocation coordinate while my app is loading. I have implemented following code but it returns 0.000
mapView.showsUserLocation=YES;
CLLocationCoordinate2D annotationCoordinate;
annotationCoordinate.latitude=mapView.userLocation.location.coordinate.latitude;
NSLog(#"%f",annotationCoordinate.latitude);
I could not able to figure out. Any help?

First of all you should take into account that it takes time to retrieve the user location. Moreover the user can disable the location service for your application or even the location service can be unavailable during the connectivity conditions. So you'd better to rethink your application starting procedures.
When you make up you decision take a look at mapView:didUpdateUserLocation: method of MKMapViewDelegate protocol. After this method fires out the location can be available via the userLocation property of the MKMapView.
UPDATE
In case you want to open map view with the user location already checked, you may consider using CLLocationManager and CLLocationManagerDelegate. This way you can check if the location service is available and open map view after the method locationManager:didUpdateToLocation:fromLocation: fires up.
For the complete info take a look at Getting the User’s Location programing guide

You can not get users location coordinate in view did load what you need to do is using the delegate method below.
- (void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation
{
NSLog(#"coordinates = %f,%f", mapView.userLocation.coordinate.latitude,
mapView.userLocation.coordinate.longitude);
}
Make sure your map object is connected with the delegate
Just tested it should work

1) Add the FrameWork CoreLocation and Mapkit
2) In ViewController.h file
#import <UIKit/UIKit.h>
#import <MapKit/MapKit.h>
#interface MapViewController : UIViewController<MKMapViewDelegate,CLLocationManagerDelegate>
{
CLLocationManager *locationManager;
}
#property (nonatomic, strong) IBOutlet MKMapView *mapView;
3) In viewController.m file
- (void)viewDidLoad
{
[super viewDidLoad];
self.mapView.delegate = self;
locationManager = [[CLLocationManager alloc] init];
locationManager.delegate=self;
locationManager.distanceFilter = kCLDistanceFilterNone; // whenever we move
locationManager.desiredAccuracy = kCLLocationAccuracyHundredMeters; // 100 m
[locationManager startUpdatingLocation];
}
now in didUpdateUserLocation
- (void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation{
MKCoordinateRegion region = MKCoordinateRegionMakeWithDistance(userLocation.coordinate, 800, 800);
[self.mapView setRegion:[self.mapView regionThatFits:region] animated:YES];
// Add an annotation
MKPointAnnotation *point = [[MKPointAnnotation alloc] init];
point.coordinate = userLocation.coordinate;
point.title = #"Where am I?";
point.subtitle = #"I'm here!!!";
[self.mapView addAnnotation:point];}
4) Now add Mapview in your UI
NOTE: select MapView and goto Attribute Inspector and CKECK Mark the Shows user location Under BEHAVIOUR

I think you should use this:
#import <CoreLocation/CoreLocation.h>
Then in viewDidLoad method:
CLLocationManager *locationManager = [[CLLocationManager alloc] init];
[locationManager startUpdatingLocation];
[mapView setRegion:MKCoordinateRegionMake(locationManager.location.coordinate, MKCoordinateSpanMake(0.2, 0.2))];
mapView.showsUserLocation = YES;
NSLog(#"%f",mapView.region.center.latitude);

Okay, so I just managed to fix it myself too. What no one is telling you is that you need to set a key/value pair in the info.plist.
Depending on what method (requestAlwaysAuthorization or requestWhenInUseAuthorization) you need to add a key under the 'Information Property List' dictionary. For the first method use: NSLocationAlwaysUsageDescription and for the second method use: NSLocationWhenInUseUsageDescription .
The value fields of both keys can be set to whatever string you would like to display to the user.
Both keys at the top are what we are looking for.
Now you should see a dialogue that prompts you for confirmation.
PS: No tutorial on the internet listed this step of the process, but when you read the documentation for each of those methods (requestWhenInUse on CLLocationManager) it does mention that nothing gets displayed without those two keys.

Related

Issue with sending data from one view to another.

I am trying to transfer a users location from a screen where I allow the user to take a picture to another view where I have a map. The purpose of this is to tag the image location on the map and have that be related with the image. The current code I have for launching the ability to take an image is as follows:
- (IBAction)takePhoto:(UIButton *)sender {
UIImagePickerController *picker = [[UIImagePickerController alloc] init];
picker.delegate = self;
picker.sourceType = UIImagePickerControllerSourceTypeCamera;
[self presentViewController:picker animated:YES completion: NULL];
}
-(void) imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
// Pin location as annotation on map
NSString *dateString = [NSDateFormatter localizedStringFromDate:[NSDate date]
dateStyle:NSDateFormatterShortStyle
timeStyle:NSDateFormatterFullStyle];
MKPointAnnotation *point = [[MKPointAnnotation alloc] init];
MKUserLocation *userLocation = [[MKUserLocation alloc] init];
MKMapView *mapView = [[MKMapView alloc] init];
point.coordinate = userLocation.coordinate;
point.title = #"Picture Entry";
point.subtitle = dateString;
[mapView addAnnotation:point];
// Close camera and go back to home screen
[self dismissModalViewControllerAnimated:YES];
}
I'm new to iOS programming and I'm not sure how to pass the location back to my mapView, and I believe in this code I'm just initializing a new map to save the annotation to, and thats not what I want obviously.
MapViewController.h
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#import <MapKit/MapKit.h>
#interface MapViewController : UIViewController <MKMapViewDelegate>
#property (strong, nonatomic) IBOutlet MKMapView *mapView;
#end
MapViewController.m
#import "MapViewController.h"
#interface MapViewController ()
#end
#implementation MapViewController
#synthesize mapView;
- (void)viewDidLoad
{
// Get user location
mapView.showsUserLocation = YES;
self.mapView.delegate = self;
}
// Update map based on user location and zoom to area
- (void)mapView:(MKMapView *)mapView didUpdateUserLocation:
(MKUserLocation *)userLocation
{
mapView.centerCoordinate = userLocation.location.coordinate;
MKCoordinateRegion region = MKCoordinateRegionMakeWithDistance(userLocation.coordinate, 800, 800);
[self.mapView setRegion:[self.mapView regionThatFits:region] animated:YES];
}
#end
This is what I have for now, and I'm at a loss for how to handle this.
I believe in this code I'm just initializing a new map to save the annotation to, and thats not what I want obviously.
You're right -- you're creating a new map and adding the annotation to that object. (Also, you're not creating the map view correctly -- you should use -initWithFrame: because that's a designated initializer for views.)
You should rethink your approach. What you seem to be trying to do is to modify the map view of one view controller (your MapViewController) from a different view controller (assuming that the image picker delegate is some view controller other than MapViewController). A view controller should be in charge of its own views but shouldn't mess with the views of another view controller. Also, adding the annotation that way means that you're effectively storing the location in the map view, and you should avoid using views to store data.
Instead, think about where you should really be saving your data. The M in MVC is for model, i.e. that part of your app that manages the data. As you can see in the acronym, it should be separate from your view(s) and from your controller(s). The model is something that your various view controllers can all use to get the information they need, and having one makes your app simpler because you don't have to worry as much about sending data back and forth between view controllers. The model doesn't have to be anything terribly complicated -- for very simple apps that mainly manage a list of items, even an plain old NSArray or NSSet could serve as a data model. Give each view controller that needs it a reference to the model, or to part of the model.
With that in mind, the right way to fix your app is to have some sort of data model. The image picker delegate should update the map by adding information to the model. The map view controller should be in charge of adding annotations to the map view, and it can do that based on the information in the model.

MKMapView location won't update

After posting on Apple's iOS Devs forums with no answer, I'm trying to see if anyone's got any experience with such issue.
I'm using xcode for iOS 7.
MapView won't update. I'm quite sure the problem's within the simulator, though I'm not sure how to check it. I'd love to take this project on a real device but my iOS 7 device's still in store.
I created a MKMapView nested under a View (nested under a ViewController) -> Added CoreLocation and MapKit into Frameworks -> Connected the MKMapView to the right property mapView.
My files look like this:
MapScanViewController.h:
#import <UIKit/UIKit.h>
#import <MapKit/MapKit.h>
#interface MapScanViewController : UIViewController<MKMapViewDelegate>
// I was trying to create a label and print the
// userLocation description into the label - but none worked
#property (nonatomic,retain) IBOutlet UILabel *myLabel;
#property (nonatomic,strong) IBOutlet MKMapView *mapView;
#end
And MapScanViewController.m :
#import "MapScanViewController.h"
#implementation MapScanViewController
- (void)viewDidLoad
{
[super viewDidLoad];
_mapView.delegate = self;
}
- (void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation
{
MKCoordinateRegion region = MKCoordinateRegionMakeWithDistance(userLocation.coordinate, 800, 800);
[_mapView setRegion:[_mapView regionThatFits:region] animated:YES];
// Label idea did not work eiter
[_myLabel setText:[userLocation description]];
}
#end
When I try to change location to Apple's Infinite loop, the map stays still like nothing's changing at all. Also tried to use bicycle ride and running but nothing happened.
I tried to reset the iOS Simulator few times which did not help at all and of course tried to manually set the location from within xcode it-self.
Tried to add/force this (which did not help either):
if (_mapView.showsUserLocation)
{
_mapView.showsUserLocation = NO;
_mapView.showsUserLocation = YES;
}
None worked for me. MapView just wont respond.
I verified the map view
// Meters-Miles convertion
#define METERS_PER_MILE 1609.344
// Just wanted to check if MapView's dead or not - worked- it took me to see (39.28..., -76.58...)
- (void)viewWillAppear:(BOOL)animated {
// 1
CLLocationCoordinate2D zoomLocation;
zoomLocation.latitude = 39.281516;
zoomLocation.longitude= -76.580806;
// 2
MKCoordinateRegion viewRegion = MKCoordinateRegionMakeWithDistance(zoomLocation, 0.5*METERS_PER_MILE, 0.5*METERS_PER_MILE);
// 3
[_mapView setRegion:viewRegion animated:YES];
}
you have to call _mapView.showsUserLocation = YES; before you get anything from the map.
That call will for prompt the user for access to location services.
As Daij-Djan said Try like this
- (void)viewDidLoad
{
_mapView.showsUserLocation = YES;
}

MapKit, Dropping pin on one location with button

Trying to learn how to have a pin drop at a users location when they push a button on screen. Do I need to use Mkannotation, also I want this pin to disappear when they drop a new pin in the future. This is the code I have in controller.h. Also the longitude and latitude are just for example.
thanks
#implementation ViewController
- (void)viewWillAppear:(BOOL)animated {
CLLocationCoordinate2D zoomLocation;
zoomLocation.latitude = 39.281516;
zoomLocation.longitude = -76.580806;
MKCoordinateRegion viewRegion = MKCoordinateRegionMakeWithDistance(zoomLocation,
0.1*METERS_PER_MILE, 0.1*METERS_PER_MILE);
[_mapView setRegion:viewRegion animated:YES];
}
While I think this is discussed in some detail in the Adding Annotations to a Map section of the Location Awareness Programming Guide, I have a few observations:
You ask "do I need to use MKAnnotation?" Yes and no.
Yes, all annotations should conform to the MKAnnotation protocol. As that guide describes, if you can create your own annotation subclass, you'd want it explicitly declare it to conform to the MKAnnotation protocol.
But, no, you don't have to always create your own annotation class that conforms to the MKAnnotation protocol. You can also use a predefined annotation class, MKPointAnnotation (which, itself, already conforms to the MKAnnotation protocol), such as:
MKPointAnnotation *annotation = [[MKPointAnnotation alloc] init];
annotation.coordinate = CLLocationCoordinate2DMake(39.281516, -76.580806);
annotation.title = #"Lens Crafters";
annotation.subtitle = #"2400 Boston St.";
[self.mapView addAnnotation:annotation];
If you want the old annotation to disappear when you drop a new one on your map, you just (a) keep a reference to the old annotation; (b) when adding a new annotation, remove the old one (if you have an old one); and then (c) add your new annotation.
Thus you might have defined some class property for your annotation:
#property (weak, nonatomic) id<MKAnnotation> annotation;
(Two side observations: First, whether you use weak or strong is up to you and your app design. By saying weak, I'm saying that when the annotation is removed from the map, I'm happy to have the annotation released. Maybe you want it retained until you explicitly nil this property, in which case you'd make this property strong. That's entirely up to you and the goals of your app. Second, I use the type id<MKAnnotation> (i.e. "an object that conforms to MKAnnotation") which makes this more flexible. If you later replace MKPointAnnotation with your own custom annotation class, this property will still work. But if you want to explicitly define this annotation property to be a MKPointAnnotation to match your annotation adding routine, that's fine, too.)
Anyway, now that you have this property, you can now write a method to add an annotation to your map (which removes the old one):
- (void)addAnnotationAtCoordinate:(CLLocationCoordinate2D)coordinate
title:(NSString *)title
subtitle:(NSString *)subtitle
{
if (self.annotation)
[self.mapView removeAnnotation:self.annotation];
MKPointAnnotation *annotation = [[MKPointAnnotation alloc] init];
annotation.coordinate = coordinate;
annotation.title = title;
annotation.subtitle = subtitle;
[self.mapView addAnnotation:annotation];
self.annotation = annotation;
}

Google Maps SDK drop marker

I am using Google Maps SDK in my Iphone app.
Now I want to drop marker when user touch and hold on map more than 2 sec on touched place, but I can't find any solution.
Thank you...
I have found solution.
You should implement GMSMapViewDelegate protocol on the view controller that displays the map and listen to didLongPressAtCoordinate event.
#interface MapViewController : UIViewController<GMSMapViewDelegate>
and
-(void) mapView:(GMSMapView *)mapView didLongPressAtCoordinate:(CLLocationCoordinate2D)coordinate{
GMSMarker *marker3 = [[GMSMarker alloc] init];
marker3.position = coordinate;
marker3.title = #"170 Asbury Anderson Rd";
marker3.snippet = #"US";
marker3.map = mapView_;
}
Protocol GMS Map View Delegate

iOS MKMapView starts zoomed out default map but zooms in only on refresh

Everytime I start the app, the first time seeing the map results in a default map that is always zoomed out with no annotations. When I go back on the navigation controller and go back into the map, it now shows the correct region with the appropriate pins. The code I use to add the
- (void) zoomIn {
mapView.showsUserLocation = YES;
CLLocationCoordinate2D annotation;
annotation.latitude = 47.640071;
annotation.longitude = -122.129598;
MKPointAnnotation *annoPoint = [[MKPointAnnotation alloc] init];
annoPoint.coordinate = annotation;
annoPoint.title = #"name";
[mapView addAnnotation:annoPoint];
MKCoordinateRegion region = MKCoordinateRegionMakeWithDistance(annotation, 500, 500);
[mapView setRegion:region animated:YES];
}
I call this block of code from the viewDidLoad, but it only works after I go back to the main page from the navigation controller and enter this UIViewController again.
Does anyone know what the problem is or have seen it before?
- (void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation
{
// this delegate fonction is called when the userlocation is updated
// try to move your code here
}
you have also
- (void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated
{
}
hope this helps
Show us your viewDidLoad function, you're probably calling zoomIn too early, maybe before your MKMapView has been initialized.

Resources