Add Annotation to map from another View - ios

I'm trying to call plotParkingLots from my AppDelegate as I want it to be called first when the app starts (and then every x seconds which I will implement later).
plotParkingLots works fine if I call it through my MapViewController's viewDidLoad, but when I call it from AppDelegate, it doesn't work.
I know that it is called but when I switch to my map view, no annotation is shown!
MapViewController.h
#import <UIKit/UIKit.h>
#import <MapKit/MapKit.h>
#define METERS_PER_MILE 1609.344
#interface MapViewController : UIViewController <MKMapViewDelegate>
#property (strong, nonatomic) IBOutlet MKMapView *mapView;
- (void)plotParkingLots;
#end
MapViewController.m
- (void)plotParkingLots {
NSString *url = [NSString stringWithFormat:#"http:/localhost/testes/parking.json"];
NSData *jsonData = [NSData dataWithContentsOfURL: [NSURL URLWithString:url]];
if (jsonData == nil) {
UIAlertView *alertBox = [[UIAlertView alloc] initWithTitle: #"Erro de conexão" message: #"Não foi possível retornar os dados dos estacionamentos" delegate: self cancelButtonTitle: #"Ok" otherButtonTitles: nil];
[alertBox show];
}
else {
NSError *error;
NSDictionary *json = [NSJSONSerialization JSONObjectWithData:jsonData options:NSJSONReadingMutableContainers error:&error];
NSArray *parkings = [json objectForKey:#"parkings"];
for (NSDictionary * p in parkings) {
Parking *annotation = [[Parking alloc] initWithDictionary:p];
[_mapView addAnnotation:annotation];
}
}
}
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation {
static NSString *identifier = #"Parking";
if ([annotation isKindOfClass:[Parking class]]) {
MKPinAnnotationView *annotationView = (MKPinAnnotationView *) [_mapView dequeueReusableAnnotationViewWithIdentifier:identifier];
if (annotationView == nil) {
annotationView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:identifier];
} else {
annotationView.annotation = annotation;
}
annotationView.enabled = YES;
annotationView.canShowCallout = YES;
annotationView.image=[UIImage imageNamed:#"car.png"];
return annotationView;
}
return nil;
}
AppDelegate.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Override point for customization after application launch.
[[MapViewController alloc] plotParkingLots];
return YES;
}

You're not talking to the MapViewController that is displayed to the user. In your AppDelegate you momentarily allocation a MapViewController, plot the parking lots, then abandon that MapViewController and never use it again.
You'll need to keep a handle to that controller so that when the user presses something to make that viewcontroller get displayed it is the same one that has just plotted the parking lots.

Related

Annotations on Map at lat/long (0,0) on device but located right in simulator

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!

Pass Data to another view controller

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"

mapview annotation not working in iphone 4s

I don't know what's wrong with my code. This code work fine in iphone5 to higher version. In the first load of controller the map will show the country first then zoom in where the user point and the annotation show. Unfortunately, the iphone4s work different. It shows only the country then no more point or annotation show.
here is my code:
#import "ViewController.h"
#define IS_OS_8_OR_LATER ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0)
#interface ViewController ()
#property (weak, nonatomic) IBOutlet MKMapView *mapView;
#property (nonatomic,strong) CLLocationManager * locationManager;
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.mapView.delegate = self;
self.locationManager = [[CLLocationManager alloc] init];
self.locationManager.delegate = self;
#ifdef __IPHONE_8_0
if(IS_OS_8_OR_LATER) {
[self.locationManager requestWhenInUseAuthorization];
[self.locationManager requestAlwaysAuthorization];
}
#endif
[self.locationManager startUpdatingLocation];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status {
if (status == kCLAuthorizationStatusAuthorizedAlways || status == kCLAuthorizationStatusAuthorizedWhenInUse) {
self.mapView.showsUserLocation = YES;
}
}
#pragma mark Map View
-(MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation{
static NSString *identifier = #"getLocation";
MKAnnotationView *annotationView = (MKPinAnnotationView *) [self.mapView dequeueReusableAnnotationViewWithIdentifier:identifier];
if (annotationView == nil) {
annotationView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:identifier];
annotationView.enabled = YES;
annotationView.canShowCallout = YES;
} else {
annotationView.annotation = annotation;
}
return annotationView;
}
-(void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation{
[self.mapView setShowsUserLocation:NO];
[self.mapView removeAnnotations:self.mapView.annotations];
CLLocation *currentLocation = [[CLLocation alloc] initWithLatitude:userLocation.coordinate.latitude longitude:userLocation.coordinate.longitude];
CLGeocoder * geocoder = [[CLGeocoder alloc] init];
[geocoder reverseGeocodeLocation:currentLocation completionHandler:^(NSArray *placemark, NSError *error) {
NSString *annTitle = #"Address unknown";
if (placemark.count > 0)
{
CLPlacemark *topResult = [placemark objectAtIndex:0];
annTitle = [NSString stringWithFormat:#"%#", topResult.locality];
}
MKPointAnnotation *toAdd = [[MKPointAnnotation alloc]init];
toAdd.coordinate = userLocation.coordinate;
toAdd.title =annTitle;
[self.mapView addAnnotation:toAdd];
}];
}
-(void)mapView:(MKMapView *)mapView didAddAnnotationViews:(NSArray *)views{
MKAnnotationView *annotationView = [views objectAtIndex:0];
id<MKAnnotation> mp = [annotationView annotation];
[UIView animateWithDuration:3.0 animations:^{
MKCoordinateRegion region = MKCoordinateRegionMakeWithDistance([mp coordinate] ,500,500);
[self.mapView setRegion:region animated:YES];
} completion:^(BOOL finished) {
[self.mapView selectAnnotation:mp animated:YES];
}];
}
and my viewcontroller.m
#import <UIKit/UIKit.h>
#import <MapKit/MapKit.h>
#import <CoreLocation/CoreLocation.h>
#interface ViewController : UIViewController <MKMapViewDelegate, MKAnnotation,CLLocationManagerDelegate>
#property (nonatomic, readonly) CLLocationCoordinate2D coordinate;
#end
but I get this error
Trying to start MapKit location updates without prompting for location authorization. Must call -[CLLocationManager requestWhenInUseAuthorization] or -[CLLocationManager requestAlwaysAuthorization] first.
The errors shows only for iphone4s. The version of my iphone4s is ios8.
This is happening because you have not made entry in plist as shown below.
If still not working, update code to below.
myMapView.delegate = self;
locationManager.delegate = 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 startUpdatingLocation];
myMapView.showsUserLocation = YES;
[myMapView setMapType:MKMapTypeStandard];
[myMapView setZoomEnabled:YES];
[myMapView setScrollEnabled:YES];
Edit 1
As per your comment, you don't find info.plist.
You can find that in Supporting files.

connect to server then plot coordinates on mkmapview

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];
}

Overlaying a transparent PNG on top of the current location blue dot

i'm just playing around with Apple's CurrentAddress sample code and I was trying to use the trueHeading property to determine the direction the user is facing. While that proved simple enough, I wanted to display a transparent PNG on top of the current location dot and I wanted to rotate it in order to simulate a compass.
Here's the very basic code I've currently got:
#implementation MapViewController
#synthesize mapView, reverseGeocoder, getAddressButton;
- (void)viewDidLoad
{
[super viewDidLoad];
mapView.showsUserLocation = YES;
}
- (IBAction)reverseGeocodeCurrentLocation
{
self.reverseGeocoder =
[[[MKReverseGeocoder alloc] initWithCoordinate:mapView.userLocation.location.coordinate] autorelease];
reverseGeocoder.delegate = self;
[reverseGeocoder start];
}
- (void)reverseGeocoder:(MKReverseGeocoder *)geocoder didFailWithError:(NSError *)error
{
NSString *errorMessage = [error localizedDescription];
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:#"Cannot obtain address."
message:errorMessage
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alertView show];
[alertView release];
}
- (void)reverseGeocoder:(MKReverseGeocoder *)geocoder didFindPlacemark:(MKPlacemark *)placemark
{
PlacemarkViewController *placemarkViewController =
[[PlacemarkViewController alloc] initWithNibName:#"PlacemarkViewController" bundle:nil];
placemarkViewController.placemark = placemark;
[self presentModalViewController:placemarkViewController animated:YES];
}
- (void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation
{
// we have received our current location, so enable the "Get Current Address" button
[getAddressButton setEnabled:YES];
NSString *north = [NSString stringWithFormat:#"%f", self.mapView.userLocation.heading.trueHeading];
NSLog(#"here: %#", north);
}
#end
How can I overlay the PNG to the exact position of the blue dot and keep it there (following the dot if the user moves, that is)?
The point is that you need to implement mapView:viewForAnnotation: delegate method and look inside it for annotation objects which are not yours. Take a look at the code snipped:
- (MKAnnotationView *)mapView:(MKMapView *)map viewForAnnotation:(id <MKAnnotation>)annotation {
NSString static *defaultID = #"defaultID";
NSString static *userLocationID = #"userLocationID";
if ([annotation isKindOfClass:[MyAnnotation class]]) {
// your code here
} else {
MKAnnotationView *annotationView = [map dequeueReusableAnnotationViewWithIdentifier:userLocationID];
if (!annotationView) {
annotationView = [[[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:userLocationID] autorelease];
annotationView.image = [UIImage imageNamed:#"UserLocationIcon.png"];
}
return annotationView;
}
}

Resources