i am facing problem when i call method within method of another class like this i have method for button when someone click on button
//within ViewController.m button method
-(IBAction)login:(id)sender
{
DBHelper *objdb = [[DBHelper alloc] init];
[objdb loginnow:textname.text andpassword:textpassword.text];
}
and this button method calling this method in DBhelper.m file and it succesfully calling this method
-(void) loginnow:(NSString *) username andpassword:(NSString *) password
{
[self createEditableCopyOfDatabaseIfNeeded];
[self initializeDatabase];
const char *sql;
NSString *querySQL = [NSString stringWithFormat: #"SELECT username, password FROM CONTACT WHERE username='%#' AND password='%#'",username,password];
sql = [querySQL UTF8String];
if (sqlite3_prepare_v2(database, sql, -1, &init_statement, NULL) != SQLITE_OK) {
NSAssert1(0, #"Error: failed to prepare statement with message '%s'.", sqlite3_errmsg(database));
}
while (sqlite3_step(init_statement) == SQLITE_ROW)
{
NSLog(#"char sql = %s" ,sql);
dbusername = [NSString stringWithUTF8String:(char *)sqlite3_column_text(init_statement,0)];
dbpassword = [NSString stringWithUTF8String:(char *)sqlite3_column_text(init_statement,1)];
}
if ([dbusername isEqualToString:username] && [dbpassword isEqualToString:password])
{
//DBHelper.callingViewController = self;
[self.callingViewController addview];
}
else if (dbusername != username || dbpassword != password)
{
NSLog(#"dbusername is = %#" ,dbusername);
NSLog(#"dbpassword is = %#" ,dbpassword);
UIAlertView *alert = [[UIAlertView alloc]
initWithTitle:#"Login Failed"
message:#"Username Or Password is not Correct"
delegate:nil
cancelButtonTitle:nil
otherButtonTitles:#"OK ", nil];
[alert show];
[alert release];
}
sqlite3_reset(init_statement);
[self closeDatabase];
}
and also in DBhelper.h i define property for this
#property (strong) ViewController * callingViewController;
and within if condidtion in lognow method if password and username is succesully match i am calling this mathod in Viewcontroller.com file but am fail to call that
//ViewController.m
-(void) addview
{
DBHelper *f = [[DBHelper alloc] init];
f.callingViewController = self;
newview.center = CGPointMake(1000, 1000);
}
Though it's not wise to hold the viewController in the DBhelper(it breaks MVC), you could call your ViewController's method as your code but remember to set to pass your ViewController to the DBhelper. Maybe like this:
//ViewController.m
-(IBAction)login:(id)sender
{
DBHelper *objdb = [[DBHelper alloc] init];
[objdb loginnow:textname.text andpassword:textpassword.text viewController:self];
}
//DBHelper.m
-(void) loginnow:(NSString *) username andpassword:(NSString *)password viewController:(ViewController *)vc
{ ...
if ([dbusername isEqualToString:username] && [dbpassword isEqualToString:password])
{
[vc addview];
}
...
}
But in fact you should use a delegate (or block or notification, but delegate is the most case) here. Like this:
In DBHelper.h, before #interface, add
#class DBHelper;
#protocol DBHelperDelegate <NSObject>
-(void) DBHelp:(DBHelper *)helper didFinishedLoginSuc:(BOOL)suc;
#end
and between the #interface and #end tag, add(suppose you are not using ARC)
#property (nonatomic, assign) id delegate;
in the DBHelper.m, in the #implementation, add(suppose you are not using auto synthesize)
#synthesize delegate = _delegate;
Now, you can change the [self.callingViewController addview]; to
if (self.delegate && [self.delegate responseToSelector:#selector(DBHelp:didFinishedLoginSuc:)]) {
[self.delegate DBHelp:self didFinishedLoginSuc:YES];
}
Now you get a delegate prepared for every view controller which obey the DBHelperDelegate.
In your ViewController.h, tell the compiler that it obey the DBHelperDelegate by add behind the class declare:
#interface ViewController:UIViewController<DBHelperDelegate>
and change the addView method name to
-(void) DBHelp:(DBHelper *)helper didFinishedLoginSuc:(BOOL)suc
At last, when you click the button, set self as the objdb's delegate
-(IBAction)login:(id)sender
{
DBHelper *objdb = [[DBHelper alloc] init];
objdb.delegate = self;
[objdb loginnow:textname.text andpassword:textpassword.text];
}
Now, when you login successfully, -(void) DBHelp:(DBHelper *)helper didFinishedLoginSuc:(BOOL)suc in ViewController.m will be called and you can deal with your view.
Remember to set the delegate to nil when your viewController gets dealloc, or you will expect an memory error. Be careful.
Related
I have a picker where its values are populated from the database(using NSMutableArray), the problem is that I'm trying to add a NSString value to index 0 of my picker(or of the NSMutableArray) but nothing is showing just a blank space in that position(position 0) and below it the other values from the database are shown like this(assuming its my picker):
------------------------
------------------------
Mouse
------------------------
Keyboard
------------------------
Motherboard
------------------------
this is my code that I use to retrieve the data from the database:
-(NSMutableArray *)getProducts
{
NSMutableArray *products = [[NSMutableArray alloc] init];
Products *all = [[Products alloc]init];
NSString allstring= #"All";
all.all= allstring; // the "all" is a NSString type variable declared in Products class
[products addObject:all];
NSMutableArray *newadditions = [[NSMutableArray alloc]init];
NSMutableIndexSet *indexes =[NSMutableIndexSet indexSetWithIndex:1];
[indexes addIndex:2];
[indexes addIndex:3];
const char* sql = "SELECT ID,Name \
FROM Products";
sqlite3_stmt *statement;
int sqlResult = sqlite3_prepare_v2(database, sql, -1, &statement, NULL);
if(sqlResult == SQLITE_OK)
{
while(sqlite3_step(statement)==SQLITE_ROW)
{
int i=0;
Products *product =[[Products alloc]init];
char*name = (char*)sqlite3_column_text(statement, 1);
product.name = (name)?[NSString stringWithUTF8String:name]: #"";
[newadditions insertObject:product atIndex:i];
i++;
}
[products insertObjects:newadditions atIndexes:indexes];
sqlite3_finalize(statement);
}
else
{
NSLog(#"Problem with the database");
NSLog(#"%d",sqlResult);
}
return products;
}
Any help would be appreciated :)
EDIT:
This is my Products.h
#interface Products : NSObject
{
NSString *name;
NSString *all;
}
#property (strong,nonatomic) NSString *name;
#property (strong,nonatomic) NSString *all;
#end
Products.m:
#import "Products.h"
#implementation Products
#synthesize name;
#synthesize all;
#end
and where I call the picker:
#interface ViewController () <UIPickerViewDataSource, UIPickerViewDelegate>
#property (strong, nonatomic) IBOutlet PRLabel *namesLabel;
#property (strong, nonatomic) UIPickerView* namesPicker;
#property (strong, nonatomic) NSMutableArray *namesAll;
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.namesPicker = [[UIPickerView alloc] init];
self.namesPicker.dataSource = self;
self.namesPicker.delegate = self;
self.namesPicker.showsSelectionIndicator = YES;
self.namesLabel.inputView = [self namesPicker];
self.namesLabel.inputAccessoryView = [self accessoryToolbar];
DBAccess *dbAccess = [[DBAccess alloc]init];
self.namesAll = [dbAccess getProducts];
[dbAccess closeDatabase];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}
#pragma mark - UIPickerViewDataSource
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView {
return 1;
}
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component {
return [self.namesAll count];
}
#pragma mark - UIPickerViewDelegate
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component {
Products * prod = [self.namesAll objectAtIndex:row];
return prod.type;
}
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component {
self.namesLabel.text = [self.namesPicker.delegate pickerView:pickerView titleForRow:row forComponent:component];
}
#end
EDIT AGAIN:
the getProducts before I try to add "All" string to first position of array:
-(NSMutableArray *)getProducts
{
NSMutableArray *products = [[NSMutableArray alloc] init];
const char* sql = "SELECT ID,Name \
FROM Products ";
sqlite3_stmt *statement;
int sqlResult = sqlite3_prepare_v2(database, sql, -1, &statement, NULL);
if(sqlResult == SQLITE_OK)
{
while(sqlite3_step(statement)==SQLITE_ROW)
{
Product *product =[[Product alloc]init];
char*name = (char*)sqlite3_column_text(statement, 1);
product.name = (name)?[NSString stringWithUTF8String:name]: #"";
[products addObject:product];
}
NSLog(#"%#",products);
sqlite3_finalize(statement);
}
else
{
NSLog(#"Problem with the database");
NSLog(#"%d",sqlResult);
}
return products;
}
LOG:
2013-07-24 13:49:56.425 just[1401:c07] Opening Database
2013-07-24 13:49:56.433 just[1401:c07] (
All,
"<Product: 0x719f350>",
"<Product: 0x719fcb0>",
"<Product: 0x719ff30>"
)
2013-07-24 13:49:58.053 just[1401:c07] -[__NSCFConstantString name]: unrecognized selector sent to instance 0xd938
2013-07-24 13:49:58.054 just[1401:c07] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFConstantString name]: unrecognized selector sent to instance 0xd938'
*** First throw call stack:
(0x20a1012 0x11aee7e 0x212c4bd 0x2090bbc 0x209094e 0x6a06 0xeb6fc 0xee886 0x1ad8fb 0x1ad9cf 0x1961bb 0x194872 0x19f5d4 0x52e299 0xed27a 0xed10c 0x1432dd 0x11c26b0 0x269dfc0 0x269233c 0x269deaf 0x4a23fe 0x49b798 0x49ca34 0x49e8a2 0x49e931 0x49e97b 0x498117 0x201386 0x200e29 0x2935 0x125cef 0x125f02 0x103d4a 0xf5698 0x1ffcdf9 0x1ffcad0 0x2016bf5 0x2016962 0x2047bb6 0x2046f44 0x2046e1b 0x1ffb7e3 0x1ffb668 0xf2ffc 0x250d 0x2435)
libc++abi.dylib: terminate called throwing an exception
(lldb)
Change all.all to all.name, and t should work.
As a comment, your code is not very readable. The naming of variables is confusing and the use of indexes is scary. There's no need for a newadditions collection if you can do addObject: for each record you read.
The picker cannot show a random object, but a only a string (in its base configuration). Make sure you add the name or some other string attribute of your Products class to the array, (or instruct your picker's datasource to use the right field).
You should really change some names of your classes and variables. If one instance of your class represents a product, the class name should be Product not Products. Also, to use a property name like all is really not intuitive - try to think of something more generic and descriptive.
Also, in your for loop you set i to 0, use it once and then increase it at the end of the loop. Why? Your index set code can also be eliminated.
So I'm trying to access the variable 'username' from another class and append it to a URL as a string. I'm getting the error "No known class method for selector 'myStaticUsername'" and don't really know how to solve it. Any help would be appreciated.
FirstViewController.h
+(NSString *) username;
FirstViewController.m
static NSString *myStaticUsername = nil;
#implementation FirstViewController
+(NSString *) username{
return myStaticUsername;
}
- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex {
if (buttonIndex == 0) {
NSLog(#"Cancel Tapped.");
}
else if (buttonIndex == 1) {
myStaticUsername= Textbox.text;
NSLog(myStaticUsername);
}
My ViewController.m class where I'm trying to access it:
- (void)viewDidLoad
{
NSString *email = [FirstViewController myStaticUsername];
NSString *website =[NSString stringWithFormat:#"http://www.nameofwebsite?un=:%#", email]; //append the username right here
Thanks.
In your viewDidLoad you need to change this:
NSString *email = [FirstViewController myStaticUsername];
to this:
NSString *email = [FirstViewController username];
myStaticUsername is the name of your static NSString, but the name of the class method you wrote to access it is username.
I am doing an alarm app for iOS, but I am a bit confused in taking data from different classes and save them to db in controller class.
for taking name, I have Name class, for taking time I have Time Class, for taking ringtone type, I have Ringtone class, so I am taking different values for one alarmTable(sqlite table) and saving them to db on save button which is in Controller.
I thought to take from every class and save them to delegate variables, and then fetch in controller class, is it almost successful, but having trouble in saving again default values,
Can anyone guide me that what is logic behind this?
These are variables in appDelegate
NSString *name;
NSString *time;
NSString *repeat;
NSString *sound;
NSString *snooz;
NSString *soundFade;
NSString *volume;
NSString *vibrate;
NSString *soundName;
This is way of getting values from appDelegates
-(NSString *) getName {
return name;
}
-(NSString *) getTime {
return time;
}
-(NSString *) getRepeat {
return repeat;
}
-(NSString *) getSound {
return sound;
}
-(NSString *) getSnooz {
return snooz;
}
-(NSString *) getSoundFade {
return soundFade;
}
-(NSString *) getVolume {
return volume;
}
-(NSString *) getVibrate {
return vibrate;
}
and when I do assign values to these delegate variables, I do write in different classes are below
AlarmProjectAppDelegate *delegate = (AlarmProjectAppDelegate *)[[UIApplication sharedApplication] delegate];
[delegate setName:name_textField.text];//name_textField contain alarmname
and I do like this before adding to Database
AlarmProjectAppDelegate *delegate = (AlarmProjectAppDelegate *)[[UIApplication sharedApplication] delegate];
//data for databas for new alarm start
NSString *name=[delegate getName];
NSString *time=[delegate getTime];
NSString *repeat=[delegate getRepeat];
NSString *sound=[delegate getSound];
NSString *snooz=[delegate getSnooz];
NSString *soundFade=delegate.soundFade;
NSString *volume=[delegate getVolume];
NSString *vibrate= [delegate getVibrate];
To make it simpler, you have to do is...
1. Create a separate class for individual table and declare all columns of table as variable in it.
2. Whenever you want to insert into any table, just create an instance of that table class and set all the variables.
3.Finally, pass that instance to your insert query as a parameter and get values from that.
For example...Create a class for Alarm table as below.
For master class, I'm modifying partial code. Assume it with name, time and repeat class.
In Alarm.h
#import <Foundation/Foundation.h>
#interface Alarm : NSObject {
name *objName;
time *objTime;
repeat *objRepeat;
}
// sample code for master class.
#property (nonatomic, retain) NSString *objName;
#property (nonatomic, retain) NSString *objTme;
#property (nonatomic, retain) NSString *objRepeat;
#end
In Alarm.m
#import "Alarm.h"
#implementation Alarm
#synthesize objName;
#synthesize objTime;
#synthesize objRepeat;
#end
Now, call your insert query as given below...
- (void) InsertAlarmData : (Alarm*)objAlarm
{
name *objName = objAlarm.objName;
time *objTime = objAlarm.objTime;
repeat *objRepeat = objAlarm.objRepeat;
NSString *query = [NSString stringWithFormat:#"INSERT into Alarm(name, time, repeat) values ('%#','%#','%#')", objAlarm.objName, objAlarm.objTime, objAlarm.objRepeat];
const char *sql = [query cStringUsingEncoding:NSUTF8StringEncoding];
if (sqlite3_open([databasePath UTF8String], &dbaseConnection) == SQLITE_OK)
{
if (sqlite3_prepare_v2(masterDBase, sql, -1, &hydrate_statement, NULL) == SQLITE_OK)
{
int success = sqlite3_step(hydrate_statement);
sqlite3_reset(hydrate_statement);
if (success != SQLITE_DONE)
{
UIAlertView *alert=[[UIAlertView alloc]initWithTitle:#"Database operation is not successful.." message:#" " delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil,nil];
[alert show];
[alert release];
NSLog(#"Error: failed to excecute query domain with message '%s'.", sqlite3_errmsg(masterDB));
}
}
else
{
NSAssert1(0, #"Error while creating add statement. '%s'", sqlite3_errmsg (masterDB));
}
sqlite3_reset(hydrate_statement);
sqlite3_finalize(hydrate_statement);
}
}
To set values in Alarm class...
name *objName = [[name alloc] init];
objName.name = #"ABC";
time *objTime = [[time alloc] init];
objTime.time = #"5 AM";
repeat *objRepeat = [[repeat alloc] init];
objRepeat.repeat = #"After 5 mins";
Alarm *objAlarm = [[Alarm alloc] init];
objAlarm.objName = objName;
objAlarm.objTime = objTime;
objAlarm.objRepeat = objRepeat;
[self InsertAlarmData:objAlarm];
Hope, you are getting my point exactly now.
I am trying to create a singleton User class in my app, here's the code:
#import "User.h"
#import "Login.h"
#import "SFHFKeychainUtils.h"
// Constants
static NSString* const kDBUserCurrentUserIDDefaultsKey = #"kDBUserCurrentUserIDDefaultsKey";
// Current User singleton
static User* currentUser = nil;
#implementation User
#synthesize username = _username;
#synthesize password = _password;
#synthesize delegate = _delegate;
- (id)init
{
self = [super init];
if (self) {
// Initialization code here.
}
return self;
}
+ (NSString*)primaryKeyProperty {
return #"username";
}
+ (User*)currentUser {
if (nil == currentUser) {
id username = [[NSUserDefaults standardUserDefaults] objectForKey:#"kApplicationUserNameKey"];
if (!username) {
currentUser = [self new];
} else{
NSLog(#"CURRENT USER");
return self;
}
[currentUser retain];
}
return currentUser;
}
+ (void)setCurrentUser:(User*)user {
[user retain];
[currentUser release];
currentUser = user;
}
/**
* Implementation of a RESTful login pattern. We construct an object loader addressed to
* the /login resource path and POST the credentials. The target of the object loader is
* set so that the login response gets mapped back into this object, populating the
* properties according to the mappings declared in elementToPropertyMappings.
*/
- (void)loginWithUsername:(NSString*)username andPassword:(NSString*)password delegate:(NSObject<DBUserAuthenticationDelegate>*)delegate {
_delegate = delegate;
//[RKObjectManager sharedManager].client.username = username;
//[RKObjectManager sharedManager].client.password = password;
self.username = username;
self.password = password;
RKObjectMapping * userMapping = [[RKObjectManager sharedManager].mappingProvider objectMappingForKeyPath:#"LoginViewController"];
[[RKObjectManager sharedManager] loadObjectsAtResourcePath:#"/account/verify.json" objectMapping:userMapping delegate:self];
}
/**
* Implementation of a RESTful logout pattern. We POST an object loader to
* the /logout resource path. This destroys the remote session
*/
- (void)logout/*:(NSObject<DBUserAuthenticationDelegate>*)delegate */{
NSError * error = nil;
[[NSUserDefaults standardUserDefaults] setValue:nil forKey:#"kApplicationUserNameKey"];
[[NSUserDefaults standardUserDefaults] synchronize];
[SFHFKeychainUtils deleteItemForUsername:self.username andServiceName:#"convore" error:&error];
NSLog(#"LOGGING OUT");
if ([self.delegate respondsToSelector:#selector(userDidLogout:)]) {
[self.delegate userDidLogout:self];
}
[[NSNotificationCenter defaultCenter] postNotificationName:#"DBUserDidLogoutNotification" object:nil];
}
- (void)loginWasSuccessful {
// Upon login, we become the current user
[User setCurrentUser:self];
NSError * error = nil;
// Persist the username for recovery later
[[NSUserDefaults standardUserDefaults] setValue:self.username forKey:#"kApplicationUserNameKey"];
[[NSUserDefaults standardUserDefaults] synchronize];
[SFHFKeychainUtils storeUsername:self.username andPassword:self.password forServiceName:#"convore" updateExisting:TRUE error:&error];
// Inform the delegate
if ([self.delegate respondsToSelector:#selector(userDidLogin:)]) {
[self.delegate userDidLogin:self];
}
[[NSNotificationCenter defaultCenter] postNotificationName:#"DBUserDidLoginNotification" object:self];
}
- (void)request:(RKRequest*)request didLoadResponse:(RKResponse*)response
{
NSLog(#"Loaded payload: %#", [response bodyAsString]);
}
- (void)objectLoader:(RKObjectLoader*)objectLoader didLoadObject:(id)object
{
if ([objectLoader wasSentToResourcePath:#"/account/verify.json"]) {
Login * login = (Login *) object;
if ([login.username length] > 0)
[self loginWasSuccessful];
}
}
- (void)objectLoader:(RKObjectLoader *)objectLoader didFailWithError:(NSError*)error {
if ([objectLoader wasSentToResourcePath:#"/account/verify.json"]) {
NSLog(#"Encountered an error: %#", error);
// Login failed
if ([self.delegate respondsToSelector:#selector(user:didFailLoginWithError:)]) {
[self.delegate user:self didFailLoginWithError:error];
}
}
}
- (BOOL)isLoggedIn {
return self.username != nil;
//return self.singleAccessToken != nil;
}
- (void)dealloc {
_delegate = nil;
[_password release];
[_passwordConfirmation release];
[super dealloc];
}
#end
The issue is that whenever I tried to access currentUser it always breaks down. I first called the loginWithUsernameandPassword and then tried calling the currentUser, but when I call the currentUser on logout, it gives me an error:
calling this:
if ([[User currentUser] isLoggedIn])
gives me:
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '+[User isLoggedIn]: unrecognized selector sent to class 0x1a671c'
seems that currentUser is nil, why is this?
Quick Singleton 101 (I wish I had this when I started, lol. Everyone just pointed me to the docs which didn't help much). The name of the singleton is going to be "Singleton"
//Singleton.h
#import <Foundation/Foundation.h>
#interface SingletonManager : NSObject
{
NSDictionary* randomDictionary; //just using a dictionary for demonstrative purposes. You can make this a string or whatever you want.
}
+ (Singleton*)sharedSingleton;
#property (nonatomic, retain) NSDictionary *randomDictionary;
#end
And now the .m
//Singleton.m
#import "Singleton.h"
static Singleton *sharedSingleton = nil;
#implementation Singleton
#synthesize randomDictionary;
#pragma mark Singleton Method
+ (Singleton*)sharedSingleton
{
#synchronized(self)
{
if(sharedSingleton == nil)
{
sharedSingleton = [[super allocWithZone:NULL] init];
}
}
return sharedSingleton;
}
#end
And to set/get, first import the singleton in whatever class you need: #import "Singleton.h", then grab the singleton with Singleton *singletonManager = [Singleton sharedSingleton]; and then you can do whatever you need to as necessary. i.e. to get the description of the NSDictionary you would call [[singletonManager randomDictionary] description];
Now this is using ARC, so if you are not you'd just have to make sure you manage your memory correctly. Enjoy.
You need to get the singleton object before you can call a method on it.
if ( [[User currentUser] isLoggedIn] ) {
// Magic happens here
}
You aren't coding your singleton properly.
+ (User *) currentUser {
#synchronized (self) {
if (currentUser == nil) {
currentUser = [[self alloc] init];
}
return currentUser;
}
}
The answer is really a combo of the two answers from XCodeDev and Matthieu Cormier. You need to "protect" your init the way the code sample says so new versions of the object are not created. Otherwise, its not a real singleton. More info on Singleton pattern.
Also, just because its a singleton doesn't mean you can access it with just class methods after you initialize it. You still need to get the instance you initialized, otherwise you cannot do operations that require certain values only in the instance.
I have a problem with this code. I have been looking for the solution and get the following warning:
warning: (Messages without a matching method signature will be assumed to return 'id' and accept '...' as arguments.).
I know that there probably is a problem with the .h file but i cannot find where.
#import <UIKit/UIKit.h>
#class NewGameViewController;
#class AccessCurrentGameData;
#class QandA_ViewController;
enum {
kTagNewGame = 1,
kTagContinueGame = 2,
};
#interface MainViewController : UIViewController <UIAlertViewDelegate> {
IBOutlet NewGameViewController *newGameViewController;
IBOutlet QandA_ViewController *qanda_ViewController;
UIAlertView *continueExistingGame_alert;
UIAlertView *zeroGameFile_alert;
NSString *title_txt;
NSString *message_txt;
NSString *cancelButton_txt;
NSString *otherButton_txt;
UIAlertView *myAlert;
}
#property (nonatomic, retain) IBOutlet NewGameViewController *newGameViewController;
#property (nonatomic, retain) IBOutlet QandA_ViewController *qanda_ViewController;
#property (nonatomic, retain) UIAlertView *myAlert;
-(IBAction)continueGame_button:(id)sender;
-(IBAction)newGame_button:(id)sender;
#end
The .m file:
-(IBAction)continueGame_button:(id)sender {
//=====CHECK IF THERE IS AN ON-GOING GAME, IF SO CONTINUE=====//
AccessCurrentGameData *isThereAnOngoingGameFunction = [AccessCurrentGameData new];
BOOL ongoingGame = [isThereAnOngoingGameFunction checkIfGameOngoing];
[isThereAnOngoingGameFunction release];
NSLog(#"+ + +continueGame_button+ + +");
NSLog(#"ongoingGame = %#\n", (ongoingGame ? #"YES" : #"NO"));
//
if (ongoingGame == YES) {
NSLog(#"+++++++++ ONGOING GAME +++++++++");
myAlert = [[UIAlertView alloc]
initWithTitle:#"Fortsätta spel"
message:#"Det finns ett aktivt spel, klicka Spela eller Tillbaka"
delegate:self
cancelButtonTitle:#"Tillbaka"
otherButtonTitles:#"Spela", nil];
myAlert.tag=kTagContinueGame;
[myAlert show];
[myAlert release];
}
}
// Load new game screen
-(IBAction)newGame_button:(id)sender {
myAlert = [[UIAlertView alloc]
initWithTitle:#"Varning"
message:#"Om du går vidare kommer pågående spel stoppas och nollställas!"
delegate:self
cancelButtonTitle:#"Tillbaka"
otherButtonTitles:#"Fortsätt", nil];
myAlert.tag=kTagNewGame;
[myAlert show];
[myAlert release];
}
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
switch(myAlert.tag ) {
case kTagContinueGame:
NSLog(#"kTagContinueGame");
NSMutableArray *continueGameArray = [[NSMutableArray alloc] initWithCapacity:0];
AccessCurrentGameData *getCurrentGameInfo = [AccessCurrentGameData new];
continueGameArray = [getCurrentGameInfo continueTheCurrentGame];
[getCurrentGameInfo release];
NSLog(#"continueGameArray %#", continueGameArray);
[continueGameArray release];
QandA_ViewController * temp = [[QandA_ViewController alloc] init];
[self setQandA_ViewController:temp]; //>>>>>HERE IS THE PROBLEM
[temp release];
[[self navigationController] pushViewController:qanda_ViewController animated:YES];
break;
case kTagNewGame:
NSLog(#"kTagNewGame");
AccessCurrentGameData *zeroCurrentGameFileFunction = [AccessCurrentGameData new];
[zeroCurrentGameFileFunction firstCreationOrRestoreOfGameDataFile];
[zeroCurrentGameFileFunction release];
NewGameViewController * temp2 = [[NewGameViewController alloc] init];
[self setNewGameViewController:temp2];
[temp2 release];
[[self navigationController] pushViewController:newGameViewController animated:YES];
break;
default:
break;
}
}
I get the following output:
2011-02-12 22:20:40.943 FamQuiz_R0_1[6346:207] -[MainViewController setQandA_ViewController:]: unrecognized selector sent to instance 0xa120980
2011-02-12 22:20:40.945 FamQuiz_R0_1[6346:207] * Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[MainViewController setQandA_ViewController:]: unrecognized selector sent to instance 0xa120980'
There's a simple typo. You declared a property for QandA_ViewController *qanda_ViewController, so the setter's name will be setQanda_ViewController with a capital Q, but a lowercase a (only the first letter is capitalized).
Try [self setQanda_ViewController:temp]; or renaming your property.