Background location service tracking not stopping when i "OFF" the UISwitch - iphone

Am using UISwitch to turn "ON" and "OFF" the the location services. When i Switch "ON" the UISwitch the location services start to to track teh location. I can come out the app and location services are running good. My problem is when i switch "OFF" the tracking and move to any View Controller the location tracking still in "ON" state and its not stopping the tracking. below is my code.
-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations{
CLLocation* location = [locations lastObject];
latDeg = location.coordinate.latitude;
longDeg = location.coordinate.longitude;
}
-(IBAction)startTracking:(id)sender{
if(startTrackingButton.on){
[locationManager startUpdatingLocation];
[[NSUserDefaults standardUserDefaults] setBool:startTrackingButton.on forKey:#"switchValue"];
[[NSUserDefaults standardUserDefaults] synchronize];
}
else{
[[NSUserDefaults standardUserDefaults] setBool:startTrackingButton.on forKey:#"switchValue"];
[[NSUserDefaults standardUserDefaults] synchronize];
[locationManager stopUpdatingLocation];
}
}
- (void)viewDidLoad{
[super viewDidLoad];
[startTrackingButton setOn:[[NSUserDefaults standardUserDefaults] boolForKey:#"switchValue"]];
locationManager = [[CLLocationManager alloc] init];
[locationManager setDelegate:self];
[locationManager setDesiredAccuracy:kCLLocationAccuracyBest];
[self.navigationItem setHidesBackButton:YES];
}
Any suggestions?

I'm going to assume that startTrackingButton is actually a UISwitch. If that is the case, you should be checking the isOn property.
if (startTrackingButton.isOn) {
[locationManager startUpdatingLocation];
[[NSUserDefaults standardUserDefaults] setBool:startTrackingButton.on forKey:#"switchValue"];
[[NSUserDefaults standardUserDefaults] synchronize];
} else {
[[NSUserDefaults standardUserDefaults] setBool:startTrackingButton.on forKey:#"switchValue"];
[[NSUserDefaults standardUserDefaults] synchronize];
[locationManager stopUpdatingLocation];
}

Related

CLLocationManager always locates London

I have the following lines of code to locate my position, but I always get the the same location regardless of where I am:
locationManager = [[CLLocationManager alloc] init];
locationManager.delegate = self;
locationManager.distanceFilter = kCLDistanceFilterNone;
locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters;
[locationManager startUpdatingLocation];
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations {
CLLocation *location = [locations lastObject];
self.lati = [NSString stringWithFormat:#"%f",location.coordinate.latitude];
self.longi = [NSString stringWithFormat:#"%f",location.coordinate.longitude];
[locationManager stopUpdatingLocation];
locationManager.delegate = nil;
}
in .h write
<CLLocationManagerDelegate>
then this also
CLGeocoder *geocoder;
CLLocationManager *locationManager;
then in .m
locationManager = [[CLLocationManager alloc] init] ;
locationManager.delegate = self;
[CLLocationManager locationServicesEnabled];
locationManager.desiredAccuracy = kCLLocationAccuracyBest;
locationManager.distanceFilter = kCLHeadingFilterNone;
[locationManager startUpdatingLocation];
and then implement its delegates
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation(CLLocation*)newLocation fromLocation:(CLLocation *)oldLocation
{
[manager stopUpdatingLocation];
userCoordinate=newLocation.coordinate;
[[NSUserDefaults standardUserDefaults] setFloat:userCoordinate.latitude
forKey:#"userLat"];
[[NSUserDefaults standardUserDefaults] setFloat:userCoordinate.longitude
forKey:#"userLong"];
CLGeocoder * geoCoder = [[CLGeocoder alloc] init];
[geoCoder reverseGeocodeLocation:newLocation completionHandler:^(NSArray *placemarks, NSError *error) {
for (CLPlacemark * placemark in placemarks)
{
NSString *cityName = #"";
NSString *countryName = #"";
cityName = [placemark.addressDictionary valueForKey:#"City"];
countryName = [placemark.addressDictionary valueForKey:#"Country"];
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
[prefs setObject:cityName forKey:#"CityName"];
[prefs setObject:countryName forKey:#"CountryName"];
}
}];
[manager stopUpdatingLocation];
}
-(void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error
{
[manager stopUpdatingLocation];
if(error.code == kCLErrorDenied)
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Warning" message:#"You have to select \"Allow\" for current location." delegate:self cancelButtonTitle:#"Ok"
otherButtonTitles: nil];
alert.tag = 888;
[alert show];
}
[[NSUserDefaults standardUserDefaults] setFloat:0.0
forKey:#"userLat"];
[[NSUserDefaults standardUserDefaults] setFloat:0.0
forKey:#"userLong"];
[manager stopUpdatingLocation];
}
Use this delegate method in place of your delegate method. It will work for you.
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
{
myLatitude = newLocation.coordinate.latitude;
myLongitude = newLocation.coordinate.longitude;
NSLog(#"LAT AND LON IS %f %f",myLatitude,myLongitude);
}

passing appdelegate data to viewcontroller

I have the following method in my AppDelegate.m. I want the value of deviceToken in my UIViewController
- (void)application:(UIApplication*)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData*)deviceToken
{
NSLog(#"My token is: %#", deviceToken);
ViewController *viewController = [[ViewController alloc]initWithNibName:#"ViewController" bundle:nil];
viewController.tokenStr = [NSString stringWithFormat:#"%#",deviceToken];
}
but when I display NSLog(#"%#",tokenStr); in UIViewController I'm getting (NULL).
how can I get the value in my UIViewController?
In AppDelegate, you can save the deviceToken value in NSUserDefaults like
[[NSUserDefaults standardUserDefaults] setObject:deviceToken forKey:#"DeviceToken"];
[[NSUserDefaults standardUserDefaults] synchronize];
and Retrieve that value from any View Controller using
[[NSUserDefaults standardUserDefaults] objectForKey:#"DeviceToken"];
You can have a reference to AppDelegate with [UIApplication sharedApplication].delegate.
It depends on your needs. Something like a token you really should save in NSUserDefaults, it was designed for saving user's credentials and tokens. But if you want to use all public properties and methods of AppDelegate in any viewController, you can use it's delegate.
AppDelegate *appDelegate = (AppDelegate *)[UIApplication sharedApplication].delegate;
NSString *token = appDelegate.token;
In AppDelegate.m class:
- (void)application:(UIApplication*)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData*)deviceToken
{
NSLog(#"My token is: %#", deviceToken);
NSString *device = [deviceToken description];
device = [device stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:#"<>"]];
device = [device stringByReplacingOccurrencesOfString:#" " withString:#""];
NSLog(#"My device is: %#", device);
[[NSUserDefaults standardUserDefaults] setObject:device forKey:#"MyAppDeviceToken"];
[[NSUserDefaults standardUserDefaults] synchronize];
}
In ViewController class, inside viewDidLoad method:
[super viewDidLoad];
NSString *deviceToken = [[NSUserDefaults standardUserDefaults] objectForKey:#"MyAppDeviceToken"];
NSLog(#"device token in controller: %# ", deviceToken);
This is working perfectly in my device. Happy Coding !! :)

NSUserDefaults remember view

My App contains a couple of views, I would like to display a small setup when the app launches and the user didn't complete the wizard yet.
I know I can achieve this with NSUserDefaults, But I'm unsure how I can make it to display a specific view depending on the input string of the NSUserDefaults storage.
My AppDelegate.m:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
NSString *controllerName = [[NSUserDefaults standardUserDefaults] objectForKey:#"WIZARD_VIEW"];
if ([controllerName length]) {
Class controllerClass = NSClassFromString(controllerName);
UIViewController *controller = [[controllerClass alloc] init];
// Override point for customization after application launch.
return YES;
}
Then in the viewcontroller files I added the following code as suggestion from jfaller:
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
NSUserDefaults* standard=[NSUserDefaults standardUserDefaults];
[standard registerDefaults: #{ #"WIZARD_VIEW" : [[self class]description]} ]; [[NSUserDefaults standardUserDefaults] synchronize];
}
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
NSUserDefaults* standard=[NSUserDefaults standardUserDefaults];
[standard registerDefaults: #{ #"WIZARD_VIEW" : [[self class]description]} ];
[[NSUserDefaults standardUserDefaults] synchronize];
}
But how can I make this so it will display the specific view that has been selected in the setup?
Personally, I would do the following:
Every time a user goes to a new view in your wizard, record the UIViewController in the user defaults:
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[[NSUserDefaults standardUserDefaults] setObject:[[self class] description] forKey:WIZARD_VIEW];
[[NSUserDefault standardUserDefaults] synchronize];
}
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
[[NSUserDefaults standardUserDefaults] removeObjectForKey:WIZARD_VIEW];
[[NSUserDefault standardUserDefaults] synchronize];
}
When the user restarts the app (hypothetically in the middle of the wizard), reload the view:
- (BOOL)application:(UIApplication *)application
willFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// etc.
NSString *controllerName = [[NSUserDefaults standardUserDefaults] objectForKey:WIZARD_VIEW];
if ([controllerName length]) {
Class controllerClass = NSClassFromString(controllerName);
NSViewController *controller = [[controllerClass alloc] init];
// push the controller, or whatever....
}
// etc.
}
Write the view you are on to NSUserDefaults as the view loads. Then check for the value in didFinishLaunchingWithOptions.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
if ([[[NSUserDefaults standardUserDefaults] valueForKey:#"current_setup"] isEqualToString:#"1"]) {
//on view 1!
}
}

Localization in iPhone not working on button click

I made an app for iPhone. In this user can change language on button click. but NSLoalizedString is not converting the value.
the code is
-(IBAction)btn1pressed:(id)sender {
SecViewController *sec = [[SecViewController alloc] initWithNibName:#"SecViewController" bundle:nil];
NSUserDefaults* userDefaults = [NSUserDefaults standardUserDefaults];
// NSLog(#"%#", [userDefaults objectForKey:#"AppleLanguages"]);
languages =#"en";
[[NSUserDefaults standardUserDefaults] setObject:languages forKey:#"AppleLanguages"];
[[NSUserDefaults standardUserDefaults] synchronize];
NSLog(#"%#", [userDefaults objectForKey:#"AppleLanguages"]);
// NSLog(#"%#", NSLocalizedString(#"Subhash", nil));
[self.navigationController pushViewController:sec animated:YES];
}
-(IBAction)btn2pressed:(id)sender {
SecViewController *sec = [[SecViewController alloc] initWithNibName:#"SecViewController" bundle:nil];
NSUserDefaults* userDefaults = [NSUserDefaults standardUserDefaults];
// NSLog(#"%#", [userDefaults objectForKey:#"AppleLanguages"]);
languages = #"es";
[[NSUserDefaults standardUserDefaults] setObject:languages forKey:#"AppleLanguages"];
[[NSUserDefaults standardUserDefaults] synchronize];
NSLog(#"%#", [userDefaults objectForKey:#"AppleLanguages"]);
// NSLog(#"%#", NSLocalizedString(#"Subhash", nil));
[self.navigationController pushViewController:sec animated:YES];
}
-(IBAction)btn3pressed:(id)sender {
SecViewController *sec = [[SecViewController alloc] initWithNibName:#"SecViewController" bundle:nil];
NSUserDefaults* userDefaults = [NSUserDefaults standardUserDefaults];
// NSLog(#"%#", [userDefaults objectForKey:#"AppleLanguages"]);
languages =#"ja";
[[NSUserDefaults standardUserDefaults] setObject:languages forKey:#"AppleLanguages"];
[[NSUserDefaults standardUserDefaults] synchronize];
NSLog(#"%#", [userDefaults objectForKey:#"AppleLanguages"]);
// NSLog(#"%#", NSLocalizedString(#"Subhash", nil));
[self.navigationController pushViewController:sec animated:YES];
}
Try
[[NSUserDefaults standardUserDefaults] setObject:[NSArray arrayWithObjects:languages,nil] forKey:#"AppleLanguages"];
Use NSLocalizedString(), for localization.
Also give corresponding localization string.

NSUserDefaults doubts in iphone SDK

I am integrating twitter in my app for sharing a text. My architecture of twitter integration is I have two Button _btnTwitter and _btntwitteLogout and when the user successfully login the twitter his name will display in _btntwitterLogout as title.
When the user tap the _btntwitterLogout it logs out the twitter and logout button hides and login button comes.every thing went ok.but when the user tap the login button(_btnTwitter) the Twitter login popup cmes for login purpose,here is the problem that am facing ,when the popup comes the user tap the cancel button of that popup the popup disappears and here the previous username of the user in the logout button.it didn't changes. I have put user defaults to check.
-(IBAction)_clickbtnTwitter:(id)sender
{
[[NSUserDefaults standardUserDefaults] setBool:YES forKey:#"Twitter_logged"];
[_btntwitterLogeout setTitle:nil forState:UIControlStateNormal];
_btntwitterLogeout.hidden = NO;
_btnTwitter.hidden=YES;
if (_engine) return;
_engine = [[SA_OAuthTwitterEngine alloc] initOAuthWithDelegate: self];
_engine.consumerKey = kOAuthConsumerKey;
_engine.consumerSecret = kOAuthConsumerSecret;
UIViewController *controller = [SA_OAuthTwitterController controllerToEnterCredentialsWithTwitterEngine: _engine delegate: self];
if (controller)
[self presentModalViewController: controller animated: YES];
else {
[_engine sendUpdate: [NSString stringWithFormat: #"Already Updated. %#", [NSDate date]]];
}
}
}
then logout code
-(IBAction)_clickbtntwitterlogeout:(id)sender
{
[[NSUserDefaults standardUserDefaults] setBool:NO forKey:#"Twitter_logged"];
crosstwitterimage.hidden = YES;
[_btntwitterLogeout setTitle:nil forState:UIControlStateNormal];
_btntwitterLogeout.hidden = YES;
_btnTwitter.hidden=NO;
_btnTwittermain.enabled = NO;
[_engine clearAccessToken];
[_engine clearsCookies];
[_engine setClearsCookies:YES];
[[NSUserDefaults standardUserDefaults] removeObjectForKey:#"authData"];
[[NSUserDefaults standardUserDefaults]removeObjectForKey:#"authName"];
NSLog(#"%#",[[NSUserDefaults standardUserDefaults]valueForKey:#"authName"]);
NSLog(#"%#",[[NSUserDefaults standardUserDefaults]valueForKey:#"authData"]);
[[NSUserDefaults standardUserDefaults] setBool:NO forKey:#"Twitter_logged"];
[_engine release];
_engine=nil;
NSHTTPCookie *cookie;
NSHTTPCookieStorage *storage = [NSHTTPCookieStorage sharedHTTPCookieStorage];
for (cookie in [storage cookies])
{
NSString* domainName = [cookie domain];
NSRange domainRange = [domainName rangeOfString:#"twitter"];
if(domainRange.length > 0)
{
[storage deleteCookie:cookie];
}
}
}
in viewwillappear
BOOL logged = [[NSUserDefaults standardUserDefaults] boolForKey:#"Twitter_logged"];
;
if (logged == YES) {
_btnTwitter. hidden = YES;
_btntwitterLogeout.hidden = NO;
crosstwitterimage.hidden = NO;
_btnTwittermain.enabled =YES;
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
//Checks if there is a saved User Name
if([defaults objectForKey:#"kTwitterUserName"])
{
NSString *username = [defaults objectForKey:#"kTwitterUserName"];
[_btntwitterLogeout setTitle:username forState:UIControlStateNormal];
crosstwitterimage.hidden = NO;
}
}
else
{
_btnTwitter. hidden = NO;
crosstwitterimage.hidden = YES;
[_btntwitterLogeout setTitle:nil forState:UIControlStateNormal];
_btnTwittermain.enabled =NO;
crosstwitterimage.hidden = YES;
}
but when i tap the cancel button in loginwindow of twitter,an comes back the username with the logout button shows ,if the user is already logedout from twitter.
is there any problem in my code.
thanks in advance.
EDIT
#pragma mark SA_OAuthTwitterEngineDelegate
- (void) storeCachedTwitterOAuthData: (NSString *) data forUsername: (NSString *) username {
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject: data forKey: #"authData"];
[defaults synchronize];
}
- (NSString *) cachedTwitterOAuthDataForUsername: (NSString *) username {
return [[NSUserDefaults standardUserDefaults] objectForKey: #"authData"];
}
#pragma mark SA_OAuthTwitterControllerDelegate
- (void) OAuthTwitterController: (SA_OAuthTwitterController *) controller authenticatedWithUsername: (NSString *) username {
NSLog(#"Authenicated for %#", username);
[_btntwitterLogeout setTitle:username forState:UIControlStateNormal];
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:username forKey:#"kTwitterUserName"];
[defaults synchronize];
}
- (void) OAuthTwitterControllerFailed: (SA_OAuthTwitterController *) controller {
NSLog(#"Authentication Failed!");
}
- (void) OAuthTwitterControllerCanceled: (SA_OAuthTwitterController *) controller {
NSLog(#"Authentication Canceled.");
}
#pragma mark TwitterEngineDelegate
- (void) requestSucceeded: (NSString *) requestIdentifier {
NSLog(#"Request %# succeeded", requestIdentifier);
}
- (void) requestFailed: (NSString *) requestIdentifier withError: (NSError *) error {
NSLog(#"Request %# failed with error: %#", requestIdentifier, error);
}
Yes there is a problem. Whenever you hit the _btnTwitter, you are setting the Twitter_logged to yes. That's not correct. You should only set it to yes when there is a successful login. That is when the user has NOT hit cancel on the twitter login window.
In other words, you need to set the Twitter_logged to YES once the user has actually logged in, not when the user clicked on the button _btnTwitter
Seems like SA_OAuthTwitterController has a delegate property pointing to self. You should handle code to set Twitter_logged YES in that delegate method.
Hope that helps.
Edit:
Given the latest code here is where you should add the NsUserDefaults data
- (void) OAuthTwitterController: (SA_OAuthTwitterController *) controller authenticatedWithUsername: (NSString *) username {
NSLog(#"Authenicated for %#", username);
[_btntwitterLogeout setTitle:username forState:UIControlStateNormal];
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:username forKey:#"kTwitterUserName"];
[defaults setBool:YES forKey:#"Twitter_logged"]; // Right here - mbh
[defaults synchronize];
}