ObjectiveC: How to stop a music player from another view in Xcode? - ios

I would like to stop my music playing from another view by using delegates. I already have that setup and i know there is this option...
- (void)viewWillDisappear:(BOOL)animated{
[player stop]; ///(my players name here and command to stop the player)
}
However i do not want to use that function because i have the music playing throughout. I have already added code to ensure my player does not overlap. But when i do want to stop my music i want to do so in a different view. I have tried the '[player stop];' function when the delegate is called but it does not work.
Can anyone help?
Thanks in advanced...
EDIT
HERE IS THE CODE FOR MY OPTIONS PAGE.H FILE:
#protocol onHandlerDelegate <NSObject>
- (void)off:(BOOL)success;
- (void)on:(BOOL)success;
-(void)volumeValueChange:(UISlider *)sender;
#end
#import <UIKit/UIKit.h>
#interface OptionsPage : UIViewController{
IBOutlet UISlider *VolumeSlider;
NSTimer *VolumeTimer;
IBOutlet UISwitch *onoroffmusic;
}
-(IBAction) UIBarButtonItem:(id)sender;
-(IBAction) SwitchMusic:(id)sender;
-(IBAction)changevolume:(id)sender;
#property (nonatomic, retain) UISwitch *onoroffmusic;
#property (nonatomic, strong) id<onHandlerDelegate> delegatePpty1;
#end
HERE IS MY OPTIONS PAGE .M FILE:
#import "OptionsPage.h"
#import "ViewController.h"
#interface OptionsPage ()
#end
#implementation OptionsPage
#synthesize onoroffmusic;
#synthesize delegatePpty1;
- (IBAction)changevolume:(id)sender{
int volume = VolumeSlider.value;
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:[NSNumber numberWithInt:volume] forKey:#"volume"];
[defaults synchronize];
[[self delegatePpty1]volumeValueChange:(VolumeSlider)];
}
-(IBAction) SwitchMusic:(id)sender{
if (onoroffmusic.on) {
[[self delegatePpty1] on:YES];
printf("done");
onoroffmusic.on = YES;
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults removeObjectForKey:#"off"];
[defaults setObject:[NSNumber numberWithBool:YES] forKey:#"on"];
[defaults synchronize];
}
else {
/// do nothing
[[self delegatePpty1] off:YES];
printf("off");
onoroffmusic.on = NO;
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults removeObjectForKey:#"on"];
[defaults setObject:[NSNumber numberWithBool:YES] forKey:#"off"];
[defaults synchronize];
ViewController *home = [[ViewController alloc] initWithNibName:nil bundle:nil];
[home.player stop];
}
}
-(IBAction) UIBarButtonItem:(id)sender{
ViewController *Backbutton = [[ViewController alloc] initWithNibName:nil bundle:nil];
[self presentViewController:Backbutton animated:YES completion:nil];
}
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad{
VolumeSlider.value = 0.3;
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
NSObject * object = [prefs valueForKey:#"volume"];
if(object == nil){
VolumeSlider.value = 0.3;
}
else{
VolumeSlider.value = [[[NSUserDefaults standardUserDefaults] objectForKey:#"volume"] intValue];
}
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
NSUserDefaults *defaults2 = [NSUserDefaults standardUserDefaults];
BOOL restoredBoolValue2 = [[defaults2 objectForKey:#"off"] boolValue];
BOOL restoredBoolValue1 = [[defaults2 objectForKey:#"on"] boolValue];
if (restoredBoolValue2) {
////donothing
onoroffmusic.on = FALSE;
}
if (restoredBoolValue1) {
////donothing
onoroffmusic.on = TRUE;
}
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
Within the two files i declare a delegate and my switches. Now just to receive that delegate in my view controller:
MY VIEWCONNTROLLER .H FILE:
#import "OptionsPage.h"
#interface ViewController : UIViewController <onHandlerDelegate>{
AVAudioPlayer *player;
}
#property (nonatomic, retain) AVAudioPlayer *player;
#end
HERE IS MY .M FILE:
Firstly I
#synthesize player;
Then check if my delegates have been called by using:
-(void)volumeValueChange:(UISlider *)sender
{
if (sender.value > 0.3) {
player.volume = sender.value;
}
else{
player.volume = 0.3;
}
}
-(void)on:(BOOL)success{
NSLog(#"Delegate Method Called");
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:[NSNumber numberWithBool:YES] forKey:#"mykey1"];
[self play];
[player play];
}
-(void)off:(BOOL)success{
NSLog(#"Delegate Method Called");
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults removeObjectForKey:#"mykey1"];
[defaults setObject:[NSNumber numberWithBool:YES] forKey:#"mykey"];
[player stop];
player = nil;
[defaults removeObjectForKey:#"music"];
}
I then load the bool value of my nsuserdefults by using this:
- (void)viewDidLoad
{
if ([[NSUserDefaults standardUserDefaults] stringForKey:#"mykey"] == nil ) {
if ([[NSUserDefaults standardUserDefaults] stringForKey:#"music"] == nil) {
[self play];
}
}
}
NSUserDefaults *defaults2 = [NSUserDefaults standardUserDefaults];
BOOL restoredBoolValue2 = [[defaults2 objectForKey:#"mykey"] boolValue];
if (restoredBoolValue2) {
////donothing
[player stop];
}
BOOL restoredBoolValue1 = [[defaults2 objectForKey:#"mykey1"] boolValue];
if (restoredBoolValue1){
[self play];
}
And i have my play void function
-(void)play{
if ([[NSUserDefaults standardUserDefaults] stringForKey:#"music"] == nil) {
NSURL *url = [NSURL fileURLWithPath:[NSString stringWithFormat:#"%#/Music.mp3", [[NSBundle mainBundle] resourcePath]]];
NSError *error;
player = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:&error];
player.numberOfLoops = -1;
[player play];
player.volume = 0.3;
player.currentTime = 0.0;
[[NSUserDefaults standardUserDefaults] setObject:#"-" forKey:#"music"];
}
else {
[player stop];
}
}
and lastly in my app delegate.m file i :
- (void)applicationDidEnterBackground:(UIApplication *)application
{
// Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
// If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
[[NSUserDefaults standardUserDefaults] setObject:nil forKey:#"music"];
}

Make player a property and stop it like this:
[anotherView.player stop];

First you need to change onHandlerDelegate from strong to weak because it is a delegate.
Secondly you need an instance of OptionsPage on the second view controller and you need to implement the delegate and do optionPage.delegate = self after it this will work.

Related

How can I keep background music playing when switching ViewControllers?

I currently have a SettingsViewController which handles starting/stopping music and adjusting the musics volume.
Is it possible to make the music stay on after unwinding the SettingsViewController? And after turning on the music and switching ViewControllers, can I re-open the SettingsViewController and turn off the music as well? Please let me know the limitations.
Here is the code for my SettingsViewController.h
#import <UIKit/UIKit.h>
#import <AVFoundation/AVFoundation.h>
#interface SettingsViewController : UIViewController <AVAudioPlayerDelegate>
{
AVAudioPlayer *audioPlayer;
IBOutlet UISwitch *Switch;
IBOutlet UISlider *Slider;
}
-(IBAction)Switch:(UISwitch *)sender;
-(IBAction)Slider:(UISlider *)sender;
#end
And here is the code for my SettingsViewController.m
#import "SettingsViewController.h"
#interface SettingsViewController ()
#end
#implementation SettingsViewController
-(IBAction)Switch:(UISwitch *)sender{
NSUserDefaults *standardDefaults = [NSUserDefaults standardUserDefaults];
if(sender.tag == 0){
if(sender.on){
[standardDefaults setObject:#"On" forKey:#"keyName"];
//choosing and setting the music file
NSString *music = [[NSBundle mainBundle]pathForResource:#"bgmusic1" ofType:#"mp3"];
audioPlayer = [[AVAudioPlayer alloc]initWithContentsOfURL:[NSURL fileURLWithPath:music] error:NULL];
audioPlayer.delegate = self;
audioPlayer.numberOfLoops= -1; //sets the music to loop infinitely
[audioPlayer play]; //plays the music
} else if (sender.on == 0){
[standardDefaults setObject:#"Off" forKey:#"keyName"];
[audioPlayer stop]; //stops the music
}
}
[standardDefaults synchronize];
}
-(IBAction)Slider:(UISlider *)sender{
audioPlayer.volume = sender.value / 100.0; //will adjust the volume of the music according the slider value
}
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
Let me know what needs to be modified!
Do that in your AppDelegate.
To access it from anywhere, import it's .h file in your ViewControllers .m file and access it with
MyAppDelegate *appDelegate = (MyAppDelegate *)[[UIApplication sharedApplication] delegate];
Make the audioplayer to a property in your AppDelegate.h to allow public access (for e.g. your other viewControllers)
#interface AppDelegate: NSAppDelegate
{
IBOutlet UISwitch *Switch;
IBOutlet UISlider *Slider;
}
#property AVAudioPlayer *audioPlayer; // <------
-(IBAction)Switch:(UISwitch *)sender;
-(IBAction)Slider:(UISlider *)sender;
#end
Then adjust each call of your audioplayer in the m file to adopt the change in your h file.
//Instead of [audioplayer doSomething] write...
[self.audioplayer doSomething];
// in modern objective-c you can use also
[_audioplayer doSomething];
To call your audioplayer from other ViewControllers then implement the first mentioned code and call your player like so
[appDelegate.audioplayer doSomething]
Because your audioPlayer will be release when its parent SettingsViewController released.
So you should add it to global and you can make it with Singleton Pattern.
Create BackgroundPlayer.h
#interface BackgroundPlayer: NSObject {
AVAudioPlayer *audioPlayer;
}
+ (id)sharedManager;
#end
and BackgroundPlayer.m
#implementation BackgroundPlayer
static BackgroundPlayer* sharedInstance = nil;
+ (BackgroundPlayer*) sharedInstance {
if (sharedInstance == nil) {
sharedInstance = [[super allocWithZone:NULL] init];
}
return sharedInstance;
}
- (id)init
{
self = [super init];
return self;
}
-(void)playAudio:(NSString *) audioPath
{
audioPlayer = [[AVAudioPlayer alloc]initWithContentsOfURL:[NSURL fileURLWithPath:audioPath] error:NULL];
audioPlayer.delegate = self;
audioPlayer.numberOfLoops= -1; //sets the music to loop infinitely
[audioPlayer play]; //plays the music
}
-(void)setVolum:(float) volum {
if (audioPlayer) {
audioPlayer.volume = sender.value / 100.0;
}
}
Then you just call
NSString *music = [[NSBundle mainBundle]pathForResource:#"bgmusic1" ofType:#"mp3"];
[[BackgroundPlayersharedInstance] playAudio:music];

Use of undeclared identifier 'startClient' ERROR

I am writing an application in Objective C and I keep getting a Use of Undeclared Identifier 'startClient' error. I have attached a link to my project file and the tutorial link is here: https://www.sinch.com/tutorials/building-one-button-app-conference-calling/
https://drive.google.com/file/d/0B5loU41SFmzDZ2RNbWJsR0xoSk0/view?usp=sharing
The relevant portion of my code is here...
#import <QuartzCore/QuartzCore.h>
#import "ConferenceViewController.h"
#import "LoginViewController.h"
#import <SinchCallingUIKit/SinchCallingUIKit.h>
#class ConferenceViewController;
#interface UIView ()
#end
#implementation ConferenceViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
}
- (void)viewDidAppear:(BOOL)animated
{
- (void)startClient {}{
NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults];
[[CallingManager sharedManager] startClientWithKey:8b6893bf-41c6-4527-bc68-9d3703c13be3 secret:Ox18uwq7gkiAdeQYzntN6A== userName:[defaults stringForKey:#"userName"] sandbox:NO launchOptions:nil];
NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults];
if ([defaults stringForKey:#"userName"] == nil)
{
[self performSegueWithIdentifier:#"login" sender:nil];
}
else
{
[self startClient];
}
}
You can't stick a function inside another function. You have the implementation of startClient inside of viewDidAppear.
I don't know what your viewDidAppear is supposed to do, but this will compile:
- (void)viewDidAppear:(BOOL)animated
{
if ([defaults stringForKey:#"userName"] == nil)
{
[self performSegueWithIdentifier:#"login" sender:nil];
}
else
{
[self startClient];
}
}
- (void)startClient
{
NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults];
[[CallingManager sharedManager] startClientWithKey:8b6893bf-41c6-4527-bc68-9d3703c13be3 secret:Ox18uwq7gkiAdeQYzntN6A== userName:[defaults stringForKey:#"userName"] sandbox:NO launchOptions:nil];
}

Register Login Logout App(NSUserDefaults) in iOS using Xcode

There should be a registration page with Full Name, User Name, Password, Email and Register Button.
When we Click on Register Button we then go to Login Page where it validate the username and password that we created in registration page using NSUserDefaults.
Now if we give right credentials then it should redirect to logout page and when we next time open the app it should directly redirect to logout page.
Data Should be stored locally using NSUserDefaults(value should be stored in string format).
Login view controller .h
#import <UIKit/UIKit.h>
#interface ViewController2 : UIViewController
#property(strong, nonatomic)NSString *dataString;
#property(strong, nonatomic)NSString *dataString2;
#property (strong, nonatomic) IBOutlet UILabel *lblOutput;
#property (strong, nonatomic) IBOutlet UITextField *inputTxt1;
#property (strong, nonatomic) IBOutlet UITextField *inputTxt2;
- (IBAction)btnAction:(id)sender;
#end
Login view controller .m
#import "ViewController2.h"
#interface ViewController2 ()
#end
#implementation ViewController2
- (void)viewDidLoad {
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSString *firstName = [defaults objectForKey:#"firstName"];
NSString *lastName = [defaults objectForKey:#"lastname"];
firstName = _inputTxt1.text;
lastName = _inputTxt2.text;
[super viewDidLoad];
NSLog(#"%#",self.dataString);
NSLog(#"%#",self.dataString2);
self.navigationItem.title = #"Login Page";
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (IBAction)btnAction:(id)sender {
NSString *firstName = [_inputTxt1 text];
NSString *lastName = [_inputTxt2 text];
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:firstName forKey:#"firstName"];
[defaults setObject:lastName forKey:#"lastname"];
[defaults synchronize];
// [Defaults setObject:#"Eezy"forKey:#"iOS"];
NSLog(#"%#",[defaults stringForKey:#"firstName"]);
NSLog(#"%#",[defaults stringForKey:#"lastName"]);
if ([self.dataString isEqualToString:[defaults objectForKey:#"firstName"]] && [self.dataString2 isEqualToString:[defaults objectForKey:#"lastName"]])
{
NSLog(#"goog");
[self performSegueWithIdentifier:#"segueToNextPage2" sender:self];
}
else
{
UIAlertView *alert = [[UIAlertView alloc]initWithTitle:#"Hey Listen" message:#"Wrong User Name or Password" delegate:nil cancelButtonTitle:#"Ok" otherButtonTitles:nil, nil];
[alert show];
}
}
#end
The problem is that I have passed the value from registration page but when I am storing it in NSUserDefault then it is storing the value of username but in case of password it is showing null value.
FOR Saving login values you can use
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
// saving an NSString
[prefs setObject:txtUsername.text forKey:#"userName"];
[prefs setObject:txtPassword.text forKey:#"password"];
[prefs synchronize];
FOR RETRIEVING Values
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
// getting an NSString
NSString *savedUsername = [prefs stringForKey:#"userName"];
NSString *savedPassword = [prefs stringForKey:#"password"];
For logout:
[[NSUserDefaults standardUserDefaults] removeObjectForKey:#"Your Key"];
Here is the Solution i got :-
Step 1: In login page define a bool variable and set its value as true on clicking the login button
- (IBAction)btnAction:(id)sender {
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
[prefs setBool:YES forKey:#"registered"];
[prefs synchronize];
}
Step 2. Create a storyBoard in identity inspector as "UITabBarController". Keep in mind this will be the page where you want to go.
Step 3. In AppDelegate.h file just below #implemention write following code :-
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
if ([[NSUserDefaults standardUserDefaults] boolForKey:#"registered"]) {
UITabBarController *controller = [self.window.rootViewController.storyboard instantiateViewControllerWithIdentifier:#"UITabBarController"];
self.window.rootViewController = controller;
}
return YES;
}
That's it very simple.
Save the details in NSUserDefaults from registration page. Also make entry in NSUserDefaults to check whether user logged in or not.
[[NSUserDefaults standardUserDefaults]setValue:#"YES" forKey:#"isLoggedIn"];
In your AppDelegate's didFinishLaunching method, change the initialViewController based on isLoggedIn key value e.g.
if ([[[NSUserDefaults standardUserDefaults]valueForKey:#"isLoggedIn"] isEqualToString:#"YES"])
{
// redirect to logout screen
}
else
{
//show login or register screen
}

NSUserDefault Update Formula

Have a question on how can I update my formula by NSUserDefault. So I have two text field which needs to keep my Formula uptodate. So the user types in there number (value) then that numbers needs to go to my formula but the formula only showing me the distance value :).
I think the problem may lie here:
int gas = [[NSUserDefaults standardUserDefaults] objectForKey:#"Gas"];
int money = [[NSUserDefaults standardUserDefaults] objectForKey:#"Money"];
You are writing out to your NSUserDefaults directly from your textField.text, often with 0.00 formatting, but you are reading it in as an int. It is stored as a NSString likely. You should store and read it as a NSNumber.
Going In:
NSNumber *foo = [NSNumber numberWithInteger:TextGas.text.integerValue];
NSNumber *bar = [NSNumber numberWithDouble:TextMoney.text.doubleValue];
[defaults setObject:foo forKey:#"Gas"];
[defaults setObject:bar forKey:#"Money"];
Coming out:
NSNumber *gas = [[NSUserDefaults standardUserDefaults] objectForKey:#"Gas"];
NSNumber *money = [[NSUserDefaults standardUserDefaults] objectForKey:#"Money"];
gas.integerValue;
money.doubleValue;
I tried your code with some changes. Here are my .h file and .m files. Try this. Now also I didn't understand what your trying to find out, but this code gives me the values not a nan. While you writing code, don't forget to start your variable name in small letter that is a standard way. And also use self if you set a variable as property.
ViewController.h
#import <UIKit/UIKit.h>
#import <MapKit/MapKit.h>
#import <CoreLocation/CoreLocation.h>
#interface ViewController : UIViewController
<UITextFieldDelegate,CLLocationManagerDelegate>{
IBOutlet MKMapView *mapView;
IBOutlet UITextField *textGas;
IBOutlet UITextField *textMoney;
IBOutlet UITextField *textTotal;
IBOutlet UITextField *textDistance;
}
#property (nonatomic, retain) CLLocationManager *locationManager;
#end
ViewController.m
#import "ViewController.h"
#interface ViewController ()
{
double totalDistance;
float gas,money;
}
#end
#implementation ViewController
#synthesize locationManager;
- (void)viewDidLoad
{
[super viewDidLoad];
self.locationManager = [[CLLocationManager alloc] init];
self.locationManager.delegate = self;
self.locationManager.desiredAccuracy = kCLLocationAccuracyHundredMeters;
[self.locationManager startUpdatingLocation];
//set default value for Gas
if (![[NSUserDefaults standardUserDefaults] objectForKey:#"Gas"]) {
[[NSUserDefaults standardUserDefaults] setObject:#"1.0" forKey:#"Gas"];
[[NSUserDefaults standardUserDefaults] synchronize];
}
//set default value for Money
if (![[NSUserDefaults standardUserDefaults] objectForKey:#"Money"]) {
[[NSUserDefaults standardUserDefaults] setObject:#"1.0" forKey:#"Money"];
[[NSUserDefaults standardUserDefaults] synchronize];
}
gas = [[[NSUserDefaults standardUserDefaults] objectForKey:#"Gas"] floatValue];
money = [[[NSUserDefaults standardUserDefaults] objectForKey:#"Money"] floatValue];
textGas.text = [NSString stringWithFormat:#"%.1f",gas];
textMoney.text = [NSString stringWithFormat:#"%.1f",money];
// Do any additional setup after loading the view, typically from a nib.
}
-(void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
if ([[NSUserDefaults standardUserDefaults] objectForKey:#"Gas"])
textGas.text = [[NSUserDefaults standardUserDefaults] objectForKey:#"Gas"];
else
textGas.text = #"0";//set default value
if ([[NSUserDefaults standardUserDefaults] objectForKey:#"Money"])
textMoney.text = [[NSUserDefaults standardUserDefaults] objectForKey:#"Money"];
else
textMoney.text = #"0.01";//set default value
}
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
[textMoney resignFirstResponder];
[textGas resignFirstResponder];
}
- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex
{
if (buttonIndex == 1)
{
exit(0);
}
if (buttonIndex == 0) {
[self.locationManager stopUpdatingLocation];
mapView.showsUserLocation = NO;
}
}
#pragma mark - UITextFieldDelegate
-(void)textFieldDidEndEditing:(UITextField *)textField
{
if ([textField.text intValue] == 0) {
textGas.text = [NSString stringWithFormat:#"%.1f",gas];
textMoney.text = [NSString stringWithFormat:#"%.1f",money];
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#""
message:#"Value cann't be zero."
delegate:self
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alert show];
alert = nil;
return;
}
if (![textField.text length]) {
textGas.text = [NSString stringWithFormat:#"%.1f",gas];
textMoney.text = [NSString stringWithFormat:#"%.1f",money];
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#""
message:#"Value cann't be empty."
delegate:self
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alert show];
alert = nil;
return;
}
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
if (textField == textGas) {
[defaults setObject:textGas.text forKey:#"Gas"];
gas = [textGas.text floatValue];
}
else if (textField == textMoney)
{
[defaults setObject:textMoney.text forKey:#"Money"];
money = [textMoney.text floatValue];
}
[defaults synchronize];
}
- (BOOL) textFieldShouldReturn:(UITextField *)textField
{
[textField resignFirstResponder];
return YES;
}
#pragma mark -
#pragma mark CLLocationManagerDelegate Methods
- (void)locationManager:(CLLocationManager *)manager
didUpdateToLocation:(CLLocation *)newLocation
fromLocation:(CLLocation *)oldLocation {
{
// Zoom to the current user location.
MKCoordinateRegion userLocation = MKCoordinateRegionMakeWithDistance(newLocation.coordinate, 1200.0, 1200.0);
[mapView setRegion:userLocation animated:NO];
mapView.showsUserLocation = YES;
}
if (!oldLocation)
totalDistance = 0.0;
else
totalDistance += [newLocation distanceFromLocation:oldLocation];
double distance = totalDistance*0.00062137119;
textTotal.text = [[ NSString alloc] initWithFormat:#"$%.2f", distance/gas*money];
textDistance.text = [NSString stringWithFormat:#"%.2f Miles", distance];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
And the result in Simulator is
Don’t forget to connect delegates and IBOutlet from interface builder.

Unknown errors for "undeclared"

this was working earlier but now it is not because it does not recognize the settings in the first .m file below. I did #import Setting.h but it still does not work. Please help!
Here is the .h file:
#import <UIKit/UIKit.h>
#import "EditNameViewController.h"
#interface SettingsViewController : UIViewController <EditNameDelegate>{
IBOutlet UIButton *froshsched;
IBOutlet UIButton *uppersched;
}
.m file. it says settings and 'settings are undeclared
#import "SettingsViewController.h"
#import "Settings.h"
#interface SettingsViewController ()
#end
#implementation SettingsViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
self.title = NSLocalizedString(#"Settings", #"Settings");
self.tabBarItem.image = [UIImage imageNamed:#"spanner"];
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
}
- (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (BOOL)shouldAutorotateToInterfaceOrientation: (UIInterfaceOrientation)interfaceOrientation
{
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
} else {
return YES;
}
}
-(IBAction)froshsched{
Settings *settings = [Settings sharedInstance];
settings.timelabelfirst = #"12:35";
settings.timelabelsecond = #"1:25";
[[Settings sharedInstance] save];
}
-(IBAction)uppersched{
Settings *settings = [Settings sharedInstance];
settings.timelabelfirst = #"12:10";
settings.timelabelsecond = #"1:00";
[[Settings sharedInstance] save];
}
-(IBAction)editclass{
EditNameViewController*vc2 = [[EditNameViewController alloc] init];
vc2.delegate = self;
[self presentModalViewController:vc2 animated:YES];
}
-(void)dismiss{
[self dismissModalViewControllerAnimated:YES];
}
#end
-(IBAction)editclass;
-(IBAction)froshsched;
-(IBAction)uppersched;
here is the Settings.h
#import <Foundation/Foundation.h>
#interface Settings : NSObject
#property (nonatomic) NSString *redClassName, *orangeClassName, *yellowClassName, *greenClassName, *ltblueClassName, *dkblueClassName, *purpleClassName, *pinkClassName, *timelabelfirst, *timelabelsecond;
+(Settings*)sharedInstance;
-(void)save;
#end
and lastly here is the Settings.m file, I feel like I am missing something simple, thanks
#import "Settings.h"
#implementation Settings
#synthesize redClassName, orangeClassName, yellowClassName, greenClassName, ltblueClassName, dkblueClassName, purpleClassName, pinkClassName, timelabelfirst, timelabelsecond;
-(id)init{
self = [super init];
if(self){
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
redClassName = [defaults objectForKey:#"kredClass"];
orangeClassName = [defaults objectForKey:#"korangeClass"];
yellowClassName = [defaults objectForKey:#"kyellowClass"];
greenClassName = [defaults objectForKey:#"kgreenClass"];
ltblueClassName = [defaults objectForKey:#"kltblueClass"];
dkblueClassName = [defaults objectForKey:#"kdkblueClass"];
purpleClassName = [defaults objectForKey:#"kpurpleClass"];
pinkClassName = [defaults objectForKey:#"kpinkClass"];
timelabelfirst = [defaults objectForKey:#"ktime1"];
timelabelsecond = [defaults objectForKey:#"ktime2"];
}
return self;
}
+(Settings*)sharedInstance{
static Settings *sharedSettings;
if(!sharedSettings) sharedSettings = [[Settings alloc] init];
return sharedSettings;
}
-(void)save{
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:redClassName forKey:#"kredClass"];
[defaults setObject:orangeClassName forKey:#"korangeClass"];
[defaults setObject:yellowClassName forKey:#"kyellowClass"];
[defaults setObject:greenClassName forKey:#"kgreenClass"];
[defaults setObject:ltblueClassName forKey:#"kltblueClass"];
[defaults setObject:dkblueClassName forKey:#"kdkblueClass"];
[defaults setObject:purpleClassName forKey:#"kpurpleClass"];
[defaults setObject:pinkClassName forKey:#"kpinkClass"];
[defaults setObject:timelabelfirst forKey:#"ktime1"];
[defaults setObject:timelabelsecond forKey:#"ktime2"];
[defaults synchronize];
}
#end
You didn't give us EditNameController (with its delegate). In any case I copied and pasted all of your code above and by commenting out EditNameController related items it all compiled fine (except of course these lines floating at the bottom of your file:
-(IBAction)editclass;
-(IBAction)froshsched;
-(IBAction)uppersched;
You also didnt show a "#end" at the bottom of SettingsViewController.h (which I added before compiling).

Resources