0

Alright I'm making a iOS app.. I am INCREDIBLY new at programming apps for iOS... (I do have experience programming, but this is completely new to me)

I am trying to display the user's city & state on the screen.. I don't know what I'm doing wrong. I have this: (There's a warning that says unused variables city and state [I don't know how to fix this]).. By the way this is the single view and I'm also using storyboard (I wish I didn't have to.. work so much better just with code)

#import "VOIViewController.h"
#import <CoreLocation/CoreLocation.h>
#import <AddressBook/AddressBook.h>

@interface VOIViewController ()  <CLLocationManagerDelegate>

@property (nonatomic, strong) CLLocationManager *locationManager;
@property (weak, nonatomic) IBOutlet UILabel *city;
@property (weak, nonatomic) IBOutlet UILabel *state;

@end

@implementation VOIViewController

- (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.
}

- (void)startSignificantChangeUpdates
{
    if ([CLLocationManager locationServicesEnabled])
    {
        if (!self.locationManager)
            self.locationManager = [[CLLocationManager alloc] init];

    self.locationManager.delegate = self;
    [self.locationManager startMonitoringSignificantLocationChanges];
}
}

- (void)stopSignificantChangesUpdates
{
    [self.locationManager stopUpdatingLocation];
    self.locationManager = nil;
}

- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
{
    CLLocation *location = [locations lastObject];

    CLGeocoder *geocoder = [[CLGeocoder alloc] init];

    [geocoder reverseGeocodeLocation:location completionHandler:^(NSArray *placemarks, NSError *error) {

    CLPlacemark *placemark = placemarks[0];
    NSDictionary *addressDictionary = [placemark addressDictionary];
    NSString *city = addressDictionary[(NSString *)kABPersonAddressCityKey];
    NSString *state = addressDictionary[(NSString *)kABPersonAddressStateKey];




}];

[self stopSignificantChangesUpdates];
}

@end

UPDATED: (But still nothing on screen... I only see City and State but they aren't actually displaying the city and state. Something here isn't connected.)

#import "VOIViewController.h"
#import <CoreLocation/CoreLocation.h>
#import <AddressBook/AddressBook.h>

@interface VOIViewController ()  <CLLocationManagerDelegate>

@property (nonatomic, strong) CLLocationManager *locationManager;
@property (weak, nonatomic) IBOutlet UILabel *city;
@property (weak, nonatomic) IBOutlet UILabel *state;

@end

@implementation VOIViewController

- (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.
}

- (void)startSignificantChangeUpdates
{
    if ([CLLocationManager locationServicesEnabled])
    {
        if (!self.locationManager)
            self.locationManager = [[CLLocationManager alloc] init];

        self.locationManager.delegate = self;
        [self.locationManager startMonitoringSignificantLocationChanges];
    }
}

- (void)stopSignificantChangesUpdates
{
    [self.locationManager stopUpdatingLocation];
    self.locationManager = nil;
}

- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
{
    CLLocation *location = [locations lastObject];

    CLGeocoder *geocoder = [[CLGeocoder alloc] init];

    [geocoder reverseGeocodeLocation:location completionHandler:^(NSArray *placemarks, NSError *error) {

        CLPlacemark *placemark = placemarks[0];
        NSDictionary *addressDictionary = [placemark addressDictionary];
        self.city.text = addressDictionary[(NSString *)kABPersonAddressCityKey];
        self.state.text = addressDictionary[(NSString *)kABPersonAddressStateKey];

    }];

    [self stopSignificantChangesUpdates];
}

@end
user3159537
  • 61
  • 1
  • 12

6 Answers6

0

You are storing city & state name in NSString, not using them thus it shows you warning. Create a label & assign values to them as label_name.text = city;

demonofthemist
  • 4,081
  • 4
  • 26
  • 45
0

You're not setting text in the labels.

Remove the NSString *city/state from your locationManager, as this only creates a local NSString variable with the same name as your UILabel properties.

Then, instead:

self.city.text = addressDictionary[(NSString *)kABPersonAddressCityKey];
self.state.text = addressDictionary[(NSString *)kABPersonAddressStateKey];

By the way, a common convention in property labeling is to include the type of view you are using. UILabels are commonly named cityLabel, UITextViews are commonly labeled bodyTextView etc.

Also, be sure you have connected the properties to the actual labels in Interface Builder (in the storyboard).

Marius Waldal
  • 9,537
  • 4
  • 30
  • 44
0

Yes you are getting city and state as NSString's object , but not using them any where.

NSString *city = addressDictionary[(NSString *)kABPersonAddressCityKey];
NSString *state = addressDictionary[(NSString *)kABPersonAddressStateKey];

you assign as

city.text= city/// city.text is label .......
state.text = state///// state.text is label.......... 

Also differentiate label object as cityLAbel and sateLabel

Macrosoft-Dev
  • 2,195
  • 1
  • 12
  • 15
0

You can do this in

[geocoder reverseGeocodeLocation:location completionHandler:^(NSArray *placemarks, NSError *error) {

CLPlacemark *placemark = placemarks[0];
NSDictionary *addressDictionary = [placemark addressDictionary];

dispatch_async(dispatch_get_main_queue(), ^{
        self.city.text = addressDictionary[(NSString *)kABPersonAddressCityKey];
        self.state.text = addressDictionary[(NSString *)kABPersonAddressStateKey];
    });


}];
Akhilrajtr
  • 5,170
  • 3
  • 19
  • 30
  • I understand what you did to an extent - but nothing shows up on the screen. – user3159537 Mar 24 '14 at 11:33
  • This won't work, as you cannot set at string on city or state directly. You need to set it on the .text property of the label. – Marius Waldal Mar 24 '14 at 11:33
  • @Handsomeguy that was a mistake, now i've edited it. – Akhilrajtr Mar 24 '14 at 11:34
  • I see it. It was missing the .text. There is no warning showing up now, but still nothing shows up on the simulator? I made a city and a state label on my storyboard. – user3159537 Mar 24 '14 at 11:39
  • In fact, to clarify that is the only thing showing. I put a 'city' and 'state' on my storyboard and those are the only words showing - but not the city and state. – user3159537 Mar 24 '14 at 11:40
  • @user3159537 did you connected `IBOutlet` of `UILabel`? – Akhilrajtr Mar 24 '14 at 11:41
  • I am pretty sure I did. In my original code, near the top you see @property for city and state. I did this by dragging the label from the storyboard to the code using the control button on my keyboard. – user3159537 Mar 24 '14 at 11:43
  • @user3159537 does the `addressDictionary ` have values? Put `NSLog` and check. – Akhilrajtr Mar 24 '14 at 11:48
  • @user3159537 are you testing the app in iOS simulator? – Sujith Thankachan Mar 24 '14 at 11:52
  • Yes I am testing it in iOS simulator.. and i took a screenshot of what i believe to be the NSLog http://i.imgur.com/2zQuHeg.png... is this it? I also don't see why it won't work on my laptop... this is a bit different but a couple days ago when I experimenting with other people's code (http://www.appcoda.com/how-to-get-current-location-iphone-user/) It gave me my long/lat and I tested it on my laptop. (Mac Air 2013) – user3159537 Mar 24 '14 at 11:55
  • @user3159537 Try simulating a location, if you are not doing. Check [here](http://code.tutsplus.com/tutorials/ios-simulator-tips-tricks--mobile-12844) – Akhilrajtr Mar 24 '14 at 12:00
  • Just did that and received nothing. I put Apple as my location then switched it to the other options.. and still nothing. – user3159537 Mar 24 '14 at 12:04
0

Set your UILabels with the address got from the CLGeocoder response.

For that update - (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations as follows:

- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
{
    CLLocation *location = [locations lastObject];

    CLGeocoder *geocoder = [[CLGeocoder alloc] init];

    [geocoder reverseGeocodeLocation:location completionHandler:^(NSArray *placemarks, NSError *error) {

    CLPlacemark *placemark = placemarks[0];
        NSDictionary *addressDictionary = [placemark addressDictionary];
        NSString *cityText = addressDictionary[(NSString *)kABPersonAddressCityKey];
        NSString *stateText = addressDictionary[(NSString *)kABPersonAddressStateKey];

        self.city.text = [NSString stringWithFormat:@"%@", cityText]; 
        self. state.text = [NSString stringWithFormat:@"%@", stateText];
    }];

    [self stopSignificantChangesUpdates];
}

EDIT

You haven't called startSignificantChangeUpdates method anywhere. Thats the problem. Call it in your viewDidLoad using the code: [self startSignificantChangeUpdates];

Sujith Thankachan
  • 3,508
  • 2
  • 20
  • 25
  • Bro thank you! There is only a small problem left now. The city changes to CA while the state doesn't do anything. It just stays as 'state' .. why is the city CA? – user3159537 Mar 24 '14 at 12:33
0

You are not using the NSString variables city and state whose name you given same as the label name.

So, to correct it you have to directly assign the city and state to the city and state label text:

[geocoder reverseGeocodeLocation:location completionHandler:^(NSArray *placemarks, NSError *error) {
   CLPlacemark *placemark = placemarks[0];
   NSDictionary *addressDictionary = [placemark addressDictionary];

   /* Delete the code I commented
   NSString *city = addressDictionary[(NSString *)kABPersonAddressCityKey];
   NSString *state = addressDictionary[(NSString *)kABPersonAddressStateKey];
    */

   _city.text = addressDictionary[(NSString *)kABPersonAddressCityKey];
   _state.text = addressDictionary[(NSString *)kABPersonAddressStateKey];
}];

or you can assign the variables city and state to the city and state label text:

[geocoder reverseGeocodeLocation:location completionHandler:^(NSArray *placemarks, NSError *error) {
   CLPlacemark *placemark = placemarks[0];
   NSDictionary *addressDictionary = [placemark addressDictionary];
   NSString *city = addressDictionary[(NSString *)kABPersonAddressCityKey];
   NSString *state = addressDictionary[(NSString *)kABPersonAddressStateKey];

   NSLog(@"City => %@", city);
   NSLog(@"State => %@", state);

   _city.text = city;
   _state.text = state;
}];

in your code's

- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations{}

and if you didn't connected the IBOutlets of the labels then connect them first to do it you have to

Ctrl + Click on ViewController in Storyboad and then drag the connecting line to city and state label.

It will show you the name city and state in the opened list select the corresponding IBOutlet name from that.

Yash Vyas
  • 558
  • 4
  • 24
  • Yeah man I did control + click on ViewController and still nothing on the screen except for the text 'city' and 'state' – user3159537 Mar 24 '14 at 12:12
  • Add a break point to the _city.text assignment then run the project to debug. It will come in it after some time then check it line by line. – Yash Vyas Mar 24 '14 at 12:19
  • You can log city and state using NSLog() function to check the reverseGeocoding. Check my code edition in second block. – Yash Vyas Mar 24 '14 at 12:25