I am using MKMapView on my application. i need to show current location on simulator.
is it possible. to show current location on simulator.
In the simulator, the user's current location is always in Cupertino, California.
If you're using Interface Builder to add your map view, simply check the "Shows User Location" check box in the Attributes Inspector for the map view. (Select the map view and type command-1 to display the attributes inspector.)
If you're adding or manipulating the map view programmatically, set the showsUserLocation property of the map view to YES.
Update: It turns out that this is possible, just not using the built in map view functionality, and it doesn't always work.
Recent versions of the SDK (which have to run on Snow Leopard) can get the location of the machine the simulator is running on using CLLocationManager. You can then use this location to create an annotation to display on the map view. It won't behave like the built in "user's location indicator" (at least not without some work), but it will show the user's current location.
See this post for details of when this technique won't work.
See the "Related sample code" section of the CLLocationManager documentation for sample code that uses CLLocationManager and CLLocationManagerDelegate and then displays the user's location on a map view.
self.mapView.delegate = self;
self.mapView.showsUserLocation = YES;
This will show the current location in MkMapview.
If you are using Interface Builder,In the Attributes Inspector , we have an option Behaviour which has an option Show User Location, on checking that option will also do the same.
If you are not able to see in simulator,
Open the application in the simulator.
From the Menu Bar select Debug - > Location - > (If "None" option is selected ,change it to "Custom Location") and set location .
With CLLocationManager also we can get the current location,
Import Corelocation FrameWork to the project
In .h file
#import <CoreLocation/CoreLocation.h>
#property (nonatomic, strong) CLLocationManager *locationManager;
#property (nonatomic, strong) CLLocation* currentLocation;
In .m file
if ([CLLocationManager locationServicesEnabled] )
{
if (self.locationManager == nil )
{
self.locationManager = [[CLLocationManager alloc] init];
self.locationManager.delegate = self;
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;
self.locationManager.distanceFilter = kDistanceFilter; //kCLDistanceFilterNone// kDistanceFilter;
}
[self.locationManager startUpdatingLocation];
}
The delegate function :
-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
{
self.currentLocation = [locations lastObject];
// here we get the current location
}
Hope this answer may help you.
Simulator will not show user current location no matter whether it is iOS 6, 6.1 or iOS 7. To simulate location you can see here. If you want to show user current location then run your app in device or change simulator setting -
from the simulator's menu choose Debug > Location > Custom Location....
Related
Is it possible to make use of geo-based push notifications on iOS when the application is killed (not in the background)?
I am interested in building an app, where the user will choose a position on a map, and then if he/she for example is close to that area a local geo-based push notification would be triggered.
However is this "idea" even possible? Can the GPS run and compare coordinates when the app is killed and run and notify the user when is in place? Is there a tutorial/article/more information of any kind on the subject that i could read?
Most of the information I read online were more like general ideas of implementing without anything specific though on the matter.
For tracking a user's location while the app is not running (ie. has previously been terminated), there are two options:
From the iOS app programming guide under "Tracking the User's Location":
The significant-change location service is highly recommended for apps that do not need high-precision location data. With this service, location updates are generated only when the user’s location changes significantly; thus, it is ideal for social apps or apps that provide the user with noncritical, location-relevant information. If the app is suspended when an update occurs, the system wakes it up in the background to handle the update. If the app starts this service and is then terminated, the system relaunches the app automatically when a new location becomes available. This service is available in iOS 4 and later, and it is available only on devices that contain a cellular radio.
However, according to the CLLocationManager class reference, it's not too accurate and updates are infrequent:
Note: Apps can expect a notification as soon as the device moves 500 meters or more from its previous notification. It should not expect notifications more frequently than once every five minutes. If the device is able to retrieve data from the network, the location manager is much more likely to deliver notifications in a timely manner.
Region Monitoring works in a similar way - including restarting the app after being terminated - but with higher accuracy (depending on availability of Wifi networks and cell towers):
The specific threshold distances are determined by the hardware and the location technologies that are currently available. For example, if Wi-Fi is disabled, region monitoring is significantly less accurate. However, for testing purposes, you can assume that the minimum distance is approximately 200 meters.
Another region monitoring consideration is that (according to the CLLocationManager class reference) region entry and exit notifications might only be received 3-5 minutes or so after crossing the region's boundaries.
Depending on the actual requirements, region monitoring could be used for obtaining a "rough" location and then when the user is within a specific region, start up the more accurate GPS based service on the location manager. When the user leaves the region of interest, turn off the GPS service to preserve battery and revert to the rough location monitoring service (ie. region monitoring) once again. Here's a basic implementation:
SomeViewController.m:
...
#interface SomeViewController () <CLLocationManagerDelegate>
#property (nonatomic, strong) CLLocationManager *locationManager;
#property (nonatomic, strong) CLRegion *someRegion;
#end
#implementation SomeViewController
- (void)viewDidLoad
{
[super viewDidLoad];
self.locationManager = [[CLLocationManager alloc] init];
CLLocationDistance radius = 10; // 10 metre sensitivity
self.someRegion = [[CLRegion alloc] initCircularRegionWithCenter:someCoordinates radius:radius identifier:#"Smithtown Dry Cleaners"];
self.locationManager.delegate = self;
[self.locationManager startMonitoringForRegion:self.someRegion];
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;
self.locationManager.distanceFilter = 10;
[self.locationManager startUpdatingLocation];
}
- (void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region
{
[self.locationManager startUpdatingLocation];
}
- (void)locationManager:(CLLocationManager *)manager didExitRegion:(CLRegion *)region
{
[self.locationManager stopUpdatingLocation];
}
// Delegate method from the CLLocationManagerDelegate protocol.
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
{
CLLocation* location = [locations lastObject];
// If the user's current location is not within the region anymore, stop updating
if ([self.someRegion containsCoordinate:location.coordinate] == NO) {
[self.locationManager stopUpdatingLocation];
}
NSString *locationData = [NSString stringWithFormat:#"latitude %+.6f, longitude %+.6f\n",
location.coordinate.latitude,
location.coordinate.longitude];
NSLog(#"%#", locationData);
UILocalNotification *localNotification = [[UILocalNotification alloc] init];
localNotification.alertBody = locationData;
localNotification.alertAction = #"Location data received";
localNotification.hasAction = YES;
[[UIApplication sharedApplication] presentLocalNotificationNow:localNotification];
}
Remember to add the appropriate entries to the application's plist file so the app will run in the background with access to the appropriate resources:
MyApp-Info.plist:
<key>UIBackgroundModes</key>
<array>
...
<string>location</string>
</array>
<key>UIRequiredDeviceCapabilities</key>
<array>
...
<string>location-services</string>
<string>gps</string>
</array>
The above code assumes the use of iOS6 and ARC
I have tried the launch the settings of iPhone in my application using the call
CLLocationManager *locationManager = [[CLLocationManager alloc] init];
locationManager.delegate = self;
[locationManager startUpdatingLocation];
[locationManager release];
but I was able to launch only once,now I am not able to launch the settings in my application.
I am using iPhone 3GS with iOS 4.2
Is there any other way to launch settings any no of time if the location services are off.
but I was able to launch only once,now I am not
If you saw an alert kind of msg on your app asking for your permission for using yous gps location. Then this is the default behavior of iPhone OS. if you try to get gps location in any app the OS ask for user's permission. You can not launch this alert again!
but if you wants to change the setting (means wants to enable or disable the location tracking) then you can open the "Settings" application and look for location services setting. You can find your app there and disable the location tracking. But remember you can not open the "Settings" app using your app.
Now this issue is not in iOS5.
If you are calling startUpdatingLoaction method as below code and if location service is off,the system alert will popup and if you tap setting button,it will navigate to phone settings screen. And in phone setting screen you can switch on the location service.
CLLocationManager *locationManager = [[CLLocationManager alloc] init];
locationManager.delegate = self;
[locationManager startUpdatingLocation];
I have a core location app that I'm writing leveraging the startMonitoringSignificantLocationChanges method to generate updates when appropriate but this does not work on older devices such as iPhone 3g.
I would like for the core location functionality to still work while the device is open, so I thought I could use a selector test to see if the device supports the method, and if it doesnt just use the standard core location updating method. Although this selector doesnt work on my iphone 3g, it still uses startMonitoringSignificantLocationChanges even though it doesnt work on the phone.
Any ideas? I would rather not use the device identifier tests because then it will have to be updated for every future release of the phone.
#interface RootViewController : UITableViewController <CLLocationManagerDelegate> {
CLLocationManager *locationManager;
}
#property (nonatomic, retain) CLLocationManager *locationManager;
#implementation RootViewController
#synthesize locationManager;
if([locationManager respondsToSelector:#selector(startMonitoringSignificantLocationChanges)]) {
[locationManager startMonitoringSignificantLocationChanges];
NSLog(#"Using bg updates");
}
else {
[locationManager startUpdatingLocation];
NSLog(#"Using reg updates");
}
if ([CLLocationManager significantLocationChangeMonitoringAvailable]) {
…
}
I am new to iphone development.I am creating a map application. I have created tool bar with a button below the mapview.When i click the button it should display a alert view showing the current location and asking to update. on clicking OK in alert view should open my map with the current location and CANCEL to close the alert view.The button action is defined in the method
-(IBAction) gosearch : (id) sender{
NSLog(#"inside go search");
}
What should i do to achieve my task.I have added core location framework.But i dont know how to proceed.I saw some inbuilt methods to be used from this link http://iappdevs.blog.co.in/2008/12/06/get-current-location-sample-example-iphone-programming/ but i am not able to implement it.Please guide me.Thanks.
the MapKit component MKMapView display the current position on its own, you don't have to do anything.
Actually, internally, it instantiates a CLLocationManager and starts updating location on it to get live position events. when it gets those positions, it displays them as a blue dot, with circles with various radius to indicate the accuracy, but this is done automatically.
To trigger the display of the current position on the MKMapView, just set the showsUserLocation to YES on your MKMapView instance and you'll get this this blue dot being displayed and updated in real time.
Where does your problem start - have you got a core location delegate that gets location updates? You need to start core location using these methods:
In applicationdidfinishingLauncing()
{
self.locationManager = [[[CLLocationManager alloc] init] autorelease];
self.locationManager.delegate = self; // Tells the location manager to send updates to this object
[locationManager startUpdatingLocation];
This will get core location to call you back as it gets updates on the location, starting with a rough location but further updates should get you a more accurate focus.
My app knows the current user position (CoreLocation.framework).
As soon as the user opens a new MapView his iPhone starts searching for the current position again.
Is it possible to skip that or to change the first user position for mkMapView?
Edit:
Is it possible to overwrite MKMapView and use an other LocationManager?
Yes, it is possible to have a separate location manager object and assign its value to the mapview (BTW, I'm using '=' below as list prefix to prevent the SO code-formatter from borking).
= In your UIViewController maintain two separate properties: one to a MKMapView and one to a CLLocationManager.
= Create a XIB file with the MKMapView and any other window chrome you want. Connect the outlets to the controller propeties. Make sure MKMapView does NOT follow user location.
= Have the UIViewController implement the CLLocationManagerDelegate protocol--especially the locationManager:didUpdateToLocation:fromLocation: method which will be called whenever a new location value is available. We'll be setting the controller as the delegate for the location manager.
= In the viewController's loadView method, load the NIB with the MKMapView in it. To give user feedback you may want to put up a UIActivityIndicatorView spinner and set it to startAnimating. Then you start with:
self.locationManager = [[CLLocationManager alloc] init];
self.locationManager.delegate = self;
self.locationManager.desiredAccuracy = kCLLocationAccuracyKilometer;
self.locationManager.distanceFilter = 10; // or whatever
[self.locationManager startUpdatingLocation];
= In locationManager:didUpdateToLocation:fromLocation: check to see if the event was updated since the last N seconds. Then tell the location manager to stop updating, the spinner to stop animating, and get the lat/long data and assign it to the map view along with a view span and region so it zooms and centers to the right place.
= Now here's the tricky part: the blue marble 'throbber' is a feature of the mapview tracking user location. You'll have to momentarily 'fake it' until the real one kicks in (or just use a separate marker for the current location and maintain its position yourself). Personally I'd go with the blue marble that the user is familiar with.
= To make it so it shows right at startup you will need to create a custom MKAnnotationView with just the blue marble graphic added at the location returned by the location manager. This means taking a snapshot of a Mapview with the location showing, then photoshopping just the blue marble out and using it as the image for a custom annotation view.
= If you want it to actively follow the map, you can enable the userlocation tracking of the mapview and when it gets the actual data, you hide your previously set marker and let the mapview do the updating. The other option is to allow the existing location manager to continue receiving updates every second or so and update the position of the blue marble annotation yourself.
= To let the mapview's own userLocation do the updating add to viewDidLoad:
[self.map.userLocation addObserver:self
forKeyPath:#"location"
options:(NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld)
context:NULL];
self.map.showsUserLocation = YES; // starts updating user location
= Implement observeValueForKeyPath. It gets called when the location attribute of the mapview's userlocation has a value:
-(void)observeValueForKeyPath:(NSString *)keyPath
ofObject:(id)object
change:(NSDictionary *)change
context:(void *)context
{
if ([self.map isUserLocationVisible]) {
[self.locationManager stopUpdatingLocation];
self.ownBlueMarble.hidden = YES;
}
// The current location is in self.map.userLocation.coordinate
}
= To avoid the warm-up delay in showing current location, keep a reference to the viewController containing the map and the location manager so it doesn't go away (it's a bit of a memory hog but if you release it you'll have to wait again until MapView loads the tiles and is ready to go).
= In viewWillLoad you can stuff the last known location into the custom bluemarble annotation and show it. Toggle on/off the userLocation tracking and when you get the notification the same hide-the-annotation-show-the-real-marble trick will work. The mapview's own location manager kicks in and when it has the data, you can make your annotation marker disappear.
= You might want to implement the viewController's viewWillDisappear method and manually turn off userLocation tracking on the mapview so it's off by default the next time the view is brought up. You'll also want to get the last known userLocation and save it for the next get-go. That way, you can do all the positioning marker-juggling in the viewWillAppear method and not have to worry about userLocation interfering until you're ready for it.
Good luck.
In your controller:
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
CLLocationCoordinate2D coord = {latitude: 37.423617, longitude: -122.220154};
MKCoordinateSpan span = {latitudeDelta: 1, longitudeDelta: 1};
MKCoordinateRegion region = {coord, span};
[mapView setRegion:region];
}
When map appears it's going to be centered close to Palo Alto
Try setting the showUserLocation property to false on initialisation and then restore the region the map view previously had (you will obviously have to store this before the previous map is destroyed).
Is this what you wanted?
You don't need to use another Location Manager, you can add whatever points you want to the map and update them via whatever other logic you want.
Let's say you had a socket connection to a remote control car, and that car send back socket data containing geo-location information in the payload. You could parse that out, and update the location of the thumbnail on your map in real time. The "userLocation" property is not needed for that, but you could show it if you wanted to.
The location of the user is read-only, you can use it or not. That doesn't mean you need another location manager to do anything you might need to do. It sounds like your app doesn't really need that feature, but I could be misunderstanding your question.