Use of undeclared identifier 'startClient' ERROR - ios

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

Related

Change NSString value for ever : NSUserDefaults?

I have two views :
View1 (Shop) : URL stocked in NSString for displaying image.
View2 (ModifyShop) : Text field with URL from view1.
I can pass data from view1 to view2 : The URL stocked in NSString appears in Text field and pass data from view2 to view1. (URL for example)
Now I would like to modify this URL with Text field from view2 and that modify the NSString in view1 for ever. How can I make that ? Using NSUserDefaults ?
Here is my code :
Shop:
- (void)viewDidLoad {
[super viewDidLoad];
[self.modifyButton setHidden:YES];
}
-(void) viewWillAppear:(BOOL)animated{
[super viewWillAppear:animated];
if(![[NSUserDefaults standardUserDefaults] boolForKey:#"admin"]) {
NSLog(#"pas admin");
} else {
[self.modifyButton setHidden:NO];
}
dispatch_async(dispatch_get_global_queue(0,0), ^{
self.imageButtonURL = #"http://bundoransurfshop.com/wp-content/uploads/2015/02/72-torq-pink.jpg";
imageButtonData = [[NSData alloc] initWithContentsOfURL: [NSURL URLWithString:self.imageButtonURL]];
if ( imageButtonData == nil )
return;
dispatch_async(dispatch_get_main_queue(), ^{
self.imageButton.imageView.image = [UIImage imageWithData: imageButtonData];
});
});
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:#"modifyShop"]) {
ShopModify *viewcontroller = (ShopModify *)segue.destinationViewController;
viewcontroller.imageButtonURL = self.imageButtonURL; }
}
-(IBAction)prepareForUnwindShopModify:(UIStoryboardSegue *)segue {
NSLog(#"%#", self.imageButtonURL);
}
Shopmodify:
- (void)viewDidLoad {
[super viewDidLoad];
}
-(void)viewWillAppear:(BOOL)animated{
[super viewWillAppear:animated];
self.photoURL.text = [NSString stringWithFormat:#"%#", self.imageButtonURL];
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
Shop *viewcontroller = (Shop *)segue.destinationViewController;
viewcontroller.imageButtonURL = self.photoURL.text;
}
You can store a URL string in NSUserDefaults by following this post:
Save string to the NSUserDefaults?
Simply have your view1 always get it from NSUserDefaults in viewWillAppear and have view2 change the NSUserDefaults key for the URL string and that should do it
If with foverer you mean even after you close and open again your app, replacing the default http://bundoransurfshop.com/wp-content/uploads/2015/02/72-torq-pink.jpg, yes, for example you could use NSUserDefaults (or any other persistent way to store your data/configuration).
Save on edit in view2:
[[NSUserDefaults standardUserDefaults] setObject:valueToSave
forKey:#"imageUrl"];
[[NSUserDefaults standardUserDefaults] synchronize]; //Important
Load/Reload in view1:
NSString *savedUrl = [[NSUserDefaults standardUserDefaults] stringForKey:#"imageUrl"];
if(!savedValue){
savedUrl = #"http://bundoransurfshop.com/wp-content/uploads/2015/02/72-torq-pink.jpg";
}
Official documentation for NSUserDefaults.

Clean array by using delegate

I made an AR app that recognize image and show the object recognized in an AlertView. In the AlertView I have 2 buttons: Add and Cancel, I'm using the UIAlertViewDelegate to understand which button the user pressed. If the user press the Add button, the object recognized will be stored in an array. I pass this array to another ViewController, in which I set up a TableView. On the bottom of this TableView there's a button "Pay" to go to another ViewController in which I display the total price of the object recognized. From the last ViewController I can press a button to pay the objects I selected by using the AR. Now when I press this button the app close this ViewController and go back to the first ViewController, but the array in which I stored the object that the AR recognized it's full. To delete the content of this array I thought that the best way is to use the delegation methods, so I made this:
PaymentViewController.h
#import <UIKit/UIKit.h>
#protocol PaymentViewControllerDelegate;
#interface PaymentViewController : UIViewController
#property (strong, nonatomic) IBOutlet UILabel *labelTotal;
- (IBAction)buttonClosePaymentVC:(id)sender;
- (IBAction)buttonPay:(id)sender;
#property(nonatomic,strong)NSString *total;
#property(assign) id<PaymentViewControllerDelegate> delegate;
#end
#protocol PaymentViewControllerDelegate <NSObject>
- (void)cleanReportArray;
#end
PaymentViewController.m
#import "PaymentViewController.h"
#interface PaymentViewController () <UIAlertViewDelegate>
#end
#implementation PaymentViewController
#synthesize delegate = _delegate;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
self.labelTotal.text = self.total;
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (IBAction)buttonClosePaymentVC:(id)sender {
[self dismissViewControllerAnimated:YES completion:nil];
}
- (IBAction)buttonPay:(id)sender {
NSString *pay = [NSString stringWithFormat:#"Stai per pagare %#, procedi?", self.total];
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"HelloMS" message:pay delegate:self cancelButtonTitle:#"Si" otherButtonTitles:#"No", nil];
[alert show];
}
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
if (buttonIndex == 0) {
// Procedura per il pagamento e cancellazione del file plist
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *path = [documentsDirectory stringByAppendingPathComponent:#"objects.plist"];
NSError *error;
if (![[NSFileManager defaultManager]removeItemAtPath:path error:&error]) {
NSLog(#"Errore: %#", error);
}
__weak UIViewController *vcThatPresentedCurrent = self.presentingViewController;
[self dismissViewControllerAnimated:YES completion:^{
[vcThatPresentedCurrent dismissViewControllerAnimated:YES completion:nil];
}];
[self.delegate cleanReportArray];
}
if (buttonIndex == 1) {
// Non deve far nulla: fa scomparire l'UIAlertView
}
}
Here I post to you the method of the class that will use the delegate:
Interface of the ScannerViewController.m
#interface ScannerViewController () <MSScannerSessionDelegate, PaymentViewControllerDelegate, UIActionSheetDelegate, UIAlertViewDelegate>
#property (weak) IBOutlet UIView *videoPreview;
- (IBAction)stopScanner:(id)sender;
#end
In ViewDidLoad I inserted this rows:
PaymentViewController *pay = [[PaymentViewController alloc]init];
[pay setDelegate:self];
And in the ScannerViewController.m I implemented the method I declared in PaymentViewController.h:
- (void)cleanReportArray {
[arrayObjectAdded removeAllObjects];
}
I tested my app on my iPhone, the app works fine until I try to pay the objects I scanned by camera, indeed, I tried to pay the object, but it doesn't clean the array in which I stored the objects scanned.
What's wrong in my code? I used an tutorial on the web to understand better how the delegation method works. I hope you can help me to fix this issue, thank you
UPDATE:
here i will post my ScannerViewController code:
ScannerViewController.h
#import <UIKit/UIKit.h>
#interface ScannerViewController : UIViewController
#end
ScannerViewController.m
#import "ScannerViewController.h"
#import "PaymentViewController.h"
#import "ReportViewController.h"
#import "MSScannerSession.h"
#import "MSResult.h"
#import "XmlReader.h"
static int kMSScanOptions = MS_RESULT_TYPE_IMAGE |
MS_RESULT_TYPE_EAN8 |
MS_RESULT_TYPE_EAN13;
#interface ScannerViewController () <MSScannerSessionDelegate, PaymentViewControllerDelegate, UIActionSheetDelegate, UIAlertViewDelegate>
#property (weak) IBOutlet UIView *videoPreview;
- (IBAction)stopScanner:(id)sender;
#end
#implementation ScannerViewController {
MSScannerSession *_scannerSession;
NSString *nameOfObjectScanned;
XmlReader *reader;
NSMutableArray *arrayObjectAdded;
}
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
_scannerSession = [[MSScannerSession alloc] initWithScanner:[MSScanner sharedInstance]];
[_scannerSession setScanOptions:kMSScanOptions];
[_scannerSession setDelegate:self];
}
return self;
}
- (void)session:(MSScannerSession *)scanner didScan:(MSResult *)result {
if (!result) {
return;
}
[_scannerSession pause];
NSString *resultStr = nil;
if (result) {
switch ([result getType]) {
case MS_RESULT_TYPE_IMAGE:
resultStr = [NSString stringWithFormat:#"Immagine trovata: %#", [result getValue]];
break;
case MS_RESULT_TYPE_EAN8:
case MS_RESULT_TYPE_EAN13:
resultStr = [NSString stringWithFormat:#"EAN trovato: %#", [result getValue]];
break;
default:
break;
}
}
dispatch_async(dispatch_get_main_queue(), ^{
UIActionSheet *asView = [[UIActionSheet alloc]initWithTitle:resultStr delegate:self cancelButtonTitle:#"OK" destructiveButtonTitle:nil otherButtonTitles:nil, nil];
asView.actionSheetStyle = UIActionSheetStyleBlackTranslucent;
[asView showInView:self.view];
[self addObjectToList:resultStr];
});
}
- (void)addObjectToList:(NSString *)objectName {
// Ricerca dell'oggetto
NSString *object = [objectName substringFromIndex:18];
if ([object isEqualToString:#"Binario_con_coppia"]) {
[self showAlert:object];
}
if ([object isEqualToString:#"Dadi_colorati"]) {
[self showAlert:object];
}
if ([object isEqualToString:#"Dadi_rossi"]) {
[self showAlert:object];
}
if ([object isEqualToString:#"Bici_da_corsa"]) {
[self showAlert:object];
}
}
- (void)showAlert:(NSString*)name {
name = [name stringByReplacingOccurrencesOfString:#"_" withString:#" "];
nameOfObjectScanned = name;
NSString *message = [NSString stringWithFormat:#"Ho riconosciuto questo oggetto: %#, vuoi aggiungerlo al carrello?", name];
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"HelloMS" message:message delegate:self cancelButtonTitle:#"Aggiungi" otherButtonTitles:#"Annulla", nil];
[alert show];
}
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
if (buttonIndex == 0) {
NSLog(#"Aggiungi");
for (int i = 0; i < [reader.objArray count]; i++) {
if ([[reader.objArray[i]objectForKey:#"name"] isEqualToString:nameOfObjectScanned]) {
// Salvo il nome dell'oggetto trovato, il prezzo e la descrizione
NSString *name = [reader.objArray[i]objectForKey:#"name"];
NSString *desc = [reader.objArray[i]objectForKey:#"desc"];
NSString *price = [reader.objArray[i]objectForKey:#"price"];
NSDictionary *newObjectAdded = [[NSDictionary alloc]init];
newObjectAdded = #{#"name": name,
#"desc": desc,
#"price": price};
[arrayObjectAdded addObject:newObjectAdded];
}
}
} else {
NSLog(#"Annulla");
}
}
- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex {
[_scannerSession resume];
}
- (void)viewDidLoad
{
[super viewDidLoad];
arrayObjectAdded = [[NSMutableArray alloc]init];
CALayer *videoPreviewLayer = [self.videoPreview layer];
[videoPreviewLayer setMasksToBounds:YES];
CALayer *captureLayer = [_scannerSession previewLayer];
[captureLayer setFrame:[self.videoPreview bounds]];
[videoPreviewLayer insertSublayer:captureLayer below:[[videoPreviewLayer sublayers] objectAtIndex:0]];
reader = [[XmlReader alloc]init];
[reader parseXml];
[_scannerSession startCapture];
PaymentViewController *pay = [[PaymentViewController alloc]init];
[pay setDelegate:self];
}
- (void)cleanReportArray {
[arrayObjectAdded removeAllObjects];
}
- (void)dealloc {
[_scannerSession stopCapture];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (IBAction)stopScanner:(id)sender {
ReportViewController *reportVC = [[ReportViewController alloc]initWithNibName:#"ReportViewController" bundle:nil];
reportVC.reportArray = arrayObjectAdded;
[reportVC setModalTransitionStyle:UIModalTransitionStyleFlipHorizontal];
[self presentViewController:reportVC animated:YES completion:nil];
}
#end
To recognize picture I'm using this AR SDK. I hope you can help me to understand where's my issue
Your problem is that in viewDidLoad you have the code:
PaymentViewController *pay = [[PaymentViewController alloc]init];
[pay setDelegate:self];
this is the last thing you do in that method. So the instance of PaymentViewController that you create and set the delegate on is immediately destroyed (by ARC).
You need to modify your code so that you call setDelegate: on the actual instance of PaymentViewController that is presented on screen as this is the instance that needs to use the delegate (it receives the callback from the alert view).

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

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.

save login session credentials and loading throughout the app

I am new to iOS development. I am developing photo sharing app. In this , First i need to use Web service for Login page. Web service is in PHP and return response in JSON. I want to save login session throughout the app . When user launches the app then it always check whether the user is logged in or not. Please give me suitable solution for this very soon as there is deadline of my job if i don`t do this in early time. Here is my Code.
**<HomeKiddoAppDelegate.h file>**
#import <UIKit/UIKit.h>
#class HomeKiddoViewController;
#interface HomeKiddoAppDelegate : UIResponder <UIApplicationDelegate>
#property (strong, nonatomic) UIWindow *window;
#property (strong, nonatomic) HomeKiddoViewController *viewController;
#end
**<HomeKiddoAppDelegate.m file>**
#import "HomeKiddoAppDelegate.h"
#import "HomeKiddoViewController.h"
#implementation HomeKiddoAppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions: (NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// Override point for customization after application launch.
self.viewController = [[HomeKiddoViewController alloc] initWithNibName:#"HomeKiddoViewController" bundle:nil];
self.window.rootViewController = self.viewController;
[self.window makeKeyAndVisible];
//Register defaults
NSMutableDictionary *defaultsDictionary = [[NSMutableDictionary alloc] init];
[[NSUserDefaults standardUserDefaults] registerDefaults: defaultsDictionary];
return YES;
}
- (void)applicationWillResignActive:(UIApplication *)application
{
}
- (void)applicationDidEnterBackground:(UIApplication *)application
{
}
- (void)applicationWillEnterForeground:(UIApplication *)application
{
}
- (void)applicationDidBecomeActive:(UIApplication *)application
{
}
- (void)applicationWillTerminate:(UIApplication *)application
{
}
#end
> #import <UIKit/UIKit.h>
> #import "SignInViewController.h"
>
> #interface HomeKiddoViewController : UIViewController{
> SignInViewController *signInViewController;
> }
>
> -(IBAction)signInClicked:(id)sender;
>
> #end
**<HomekiddoViewController.m>**
> #import "HomeKiddoViewController.h"
>
> #interface HomeKiddoViewController ()
>
> #end
>
> #implementation HomeKiddoViewController
>
> - (void)viewDidLoad
> {
> [super viewDidLoad];
> }
>
> - (void)viewDidUnload {
> [super viewDidUnload]; }
>
> - (BOOL)shouldAutorotateToInterfaceOrientation: (UIInterfaceOrientation)interfaceOrientation {
> return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown); }
>
> -(IBAction)signInClicked:(id)sender{
> if(signInViewController==nil){
> signInViewController=[[SignInViewController alloc]initWithNibName:#"SignInViewController" bundle:nil];
> }
> [self.view addSubview:signInViewController.view];
> } #end
>
>
**<SignInFormViewController.h>**
> #import <UIKit/UIKit.h>
> #import "SBJson.h"
>
> #interface SignInFormViewController : UIViewController
> <NSURLConnectionDelegate>
{
> IBOutlet UITextField *email1;
> IBOutlet UITextField *password1;
> NSURLConnection *conn;
> NSMutableData *webData;
> IBOutlet UITextView *textView;
> }
#
property (nonatomic, retain) IBOutlet UITextField *email1; #property
> (nonatomic, retain) IBOutlet UITextField *password1;
>
>
-(IBAction)btnSignInClicked:(id)sender;
> -(IBAction)backClicked:(id)sender;
>
> #end
>
import "SignInFormViewController.h"
#interface SignInFormViewController ()
#end
#implementation SignInFormViewController
#synthesize email1;
#synthesize password1;
- (void)viewDidLoad
{
[super viewDidLoad];
}
- (void)viewDidUnload
{
[super viewDidUnload];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}
-(IBAction)btnSignInClicked:(id)sender{
NSString *queryUrl=[NSString stringWithFormat:#"Url of the web service with parameters",email1.text,password1.text];
NSURL *url=[NSURL URLWithString:queryUrl];
NSMutableURLRequest *request=[NSMutableURLRequest requestWithURL:url];
conn=[[NSURLConnection alloc] initWithRequest:request delegate:self];
if(conn)
{
webData=[NSMutableData data];
NSLog(#"in Connection if statement");
}
}
-(void) connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *) response{
[webData setLength: 0];
NSLog(#" inside didReceiveZResponse");
}
-(void) connection:(NSURLConnection *)connection didReceiveData:(NSData *) data {
[webData appendData:data];
NSLog(#"inside did receive data");
}
-(void) connection:(NSURLConnection *)connection didFailWithError:(NSError *) error {
NSLog(#"in fail with error");
}
-(void) connectionDidFinishLoading:(NSURLConnection *)connection{
[email1 resignFirstResponder];
[password1 resignFirstResponder];
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:email1.text forKey:#"email"];
[defaults setObject:password1.text forKey:#"password"];
[defaults synchronize];
}
-(IBAction)backClicked:(id)sender{
[self.view removeFromSuperview];
}
#end
I'm gonna give you a comprehensive answer.
Don't use NSUserDefaults and don't store password it's a bad solution
Let's create a structured user class instead
When the user logged in, you will need to make sure you have access to user data throughout the app so you can get the data on any screen when you need it.
To achieve this, we need to make a great structure to organize this properly. Remember that current user and another users are both "users" so we will use the same class.
Create a class and name it "EDUser" (you can choose other name if you want).
This class will contain a user information (either current user or other user).
More than that, this class will have capability to log the user in.
Here's a picture of what the class might look like:
class EDUser {
var firstName: String
var lastName: String?
var birthDate: NSDate?
init(firstName: String, lastName: String?, birthDate: NSDate?) {
self.firstName = firstName
self.lastName = lastName
self.birthDate = birthDate
}
}
// MARK: - Accessor
extension EDUser {
class var currentUser: EDUser? {
get {
return loadCurrentUserFromDisk()
}
set {
saveCurrentUserToDiskWithUser(newValue)
}
}
}
// MARK: - Log in and out
extension EDUser {
class func loginWithUsername(username: String,
andPassword password: String,
callback: (EDUser?, NSError) -> Void) {
// Access the web API
var parameters = [
"username": username,
"password": password
]
YourNetworkingLibrary.request(.POST,
"https://api.yourwebsite.com/login",
parameters: parameters).responseJSON {
response in
if response.statusCode == .Success {
let user = EDUser(firstName: response["firstName"],
lastName: response["lastName"],
birthDate: NSDate.dateFromString(response["birthDate"]))
currentUser = user
callback(currentUser, nil)
} else {
callback(nil, yourError)
}
}
}
class func logout() {
deleteCurrentUserFromDisk()
}
}
// MARK: - Data
extension EDUser {
class private func saveCurrentUserToDiskWithUser(user: EDUser) {
// In this process, you encode the user to file and store it
}
class private func loadCurrentUserFromDisk() -> EDUser? {
// In this process, you get the file and decode that to EDUser object
// This function will return nil if the file is not exist
}
class private func deleteCurrentUserFromDisk() {
// This will delete the current user file from disk
}
}
// MARK: - Helper
extension NSDate {
class func dateFromString(string: String) -> NSDate {
// convert string into NSDate
}
}
Use Case
Now with everything in place, we can use it like this
Non-blocking logging in process
EDUser.loginWithUsername(username: "edward#domain.com",
password: "1234") {
user, error in
if error == nil {
// Login succeeded
} else {
// Login failed
}
}
Logging out
EDUser.logout()
Check whether the user is logged in
if EDUser.currentUser != nil {
// The user is logged in
} else {
// No user logged in
// Show the login screen here
}
Get current user data on any screen
if let currentUser = EDUser.currentUser {
// do something with current user data
}
Store other user as object
let user = EDUser(firstName: "Edward",
lastName: "Anthony",
birthDate: NSDate())
You can save the login data in the NSUserDefaults like this.
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
[userDefaults setObject:cookieString forKey:#"Cookie"];
[userDefaults setObject:pwString forKey:#"Password"];
[userDefaults synchronize];
Then you can load the user default from anywhere you like in the app with
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSString *myString = [defaults objectForKey:#"Cookie"];
the simplest solution is to use keychain.
Another simple method is to save the login credentials in a locale file (txt, xml or even an sqldb).

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