How do I Call a method from other Class - objective-c

I'm having some trouble figuring out to call methods that I have in other classes
#import "myNewClass.h"
#import "MainViewController.h"
#implementation MainViewController
#synthesize txtUsername;
#synthesize txtPassword;
#synthesize lblUserMessage;
- (IBAction)calculateSecret {
NSString *usec = [self calculateSecretForUser:txtUsername.text
withPassword:txtPassword.text];
[lblUserMessage setText:usec];
[usec release];
}
...
myNewClass.h
#import <Foundation/Foundation.h>
#interface myNewClass : NSObject {
}
- (NSString*)CalculateSecretForUser:(NSString *)user withPassword:(NSString *)pwd;
#end
myNewClass.m
#import "myNewClass.h"
#implementation myNewClass
- (NSString*)CalculateSecretForUser:(NSString *)user withPassword:(NSString *)pwd
{
NSString *a = [[NSString alloc] initWithFormat:#"%# -> %#", user, pwd];
return a;
}
#end
the method CalculateSecretForUser always says
'MainViewController' may not respond to '-calculateSecretForUser:withPassword:'
what am I doing wrong here?

The keyword "self" means the instance of your current class. So you are sending the message calculateSecretForUser:withPassword to MainViewController which does not implements it. You should instantiate myNewClass and call it :
- (IBAction)calculateSecret {
myNewClass *calculator = [[myNewClass alloc] init];
NSString *usec = [calculator calculateSecretForUser:txtUsername.text
withPassword:txtPassword.text];
[lblUserMessage setText:usec];
[usec release];
[calculator release];
}

Related

No known class method for selector 'initWith...'

I found similar questions, but I couldn't solve my error. My error is:
No known class method for selector 'initWithUrl:sub:cont:cat:dat'
I've tried
#Synthesize,
self.variableName instead of _variableName,
adding [[MyClass init] alloc],
changing - to +
How can I fix it?
MyClass.h:
#import <Foundation/Foundation.h>
#interface MyClass : NSObject
-(id)init;
-(id)initWithURL:(NSURL *)url_ sub:(NSString *)subject_ cont:(NSString *)content_ cat:(NSString *)category_ dat:(NSString *)date_;
#property NSURL *bannerImageURL;
#property NSString *subject;
#property NSString *content;
#property NSString *category;
#property NSString *date;
#end
MyClass.m:
#import "MyClass.h"
#implementation MyClass
-(id)init {
self = [super init];
if (self) {
_bannerImageURL = [NSURL URLWithString:#"url0"];
_subject = #"sub0";
_content = #"cont0";
_category = #"cat0";
_date = #"dat0";
}
return self;
}
-(id)initWithURL:(NSURL *)url_ sub:(NSString *)subject_ cont:(NSString *)content_ cat:(NSString *)category_ dat:(NSString *)date_ {
self = [super init];
if (self) {
_bannerImageURL = url_;
_subject = subject_;
_content = content_;
_category = category_;
_date = date_;
}
return self;
}
#end
myViewController.m:
#import "myViewController.h"
#import "MyClass.h"
#implementation SimpleTableViewController
MyClass *news1;
- (void)viewDidLoad {
[super viewDidLoad];
NSURL *aUrl = [NSURL URLWithString:#"aUrl"];
// Error occurs here.
news1 = [MyClass initWithURL:aUrl sub:#"aSub" cont:#"aCont" cat:#"aCat" dat:#"aDat"];
}
I think you mean:
news1 = [[MyClass alloc] initWithURL:aUrl sub:#"aSub" cont:#"aCont" cat:#"aCat" dat:#"aDat"];
This is a standard pattern in Objective-C: call [SomeClass alloc] to create a new instance, then immediately call some initializer method on it. Initializers are instance methods which must be called on an instance of a class, whereas alloc is a class method that is called on the class itself (and which returns a newly allocated instance of that class).

"Missing Context for method declaration" with the constructor

Im getting only this failure after having built the project.
Im using the XCode 4.6.3
class.m
#import "Car.h"
//constructor
-(id)init //<----- ***MISSING CONTEXT FOR METHOD DECLARATION***
{
self = [super init];
if(self){
self.brand = #"";
self.model = #"";
self.vin = 0;
}
return self;
class.h contains no error.
#import <Foundation/Foundation.h>
#interface Car : NSObject
{
NSString *brand, *model;
NSNumber *vin;
}
//set
-(void) setBrand:(NSString *) newBrand;
-(void) setModel:(NSString *) newModel;
-(void) setVIN:(NSNumber *) newVIN;
//get
-(NSString *) getBrand;
-(NSString *) getModel;
-(NSNumber *) getVIN;
//methods
-(void) accelerateTo100;
-(void) fuelConsuming;
-(void) hardStop;
#end
Can you help me with this. Thanks alot.
Answer is what #CodaFi explained. Try this
#import "Car.h"
#implementation Car
-(id)init
{
self = [super init];
if(self){
[self setBrand : #""];
[self setMode1 : #""];
[self setVIN : #""];
}
return self;
}
#end
Implementations of methods related to the Car class are always wrapped in #implementation Car and terminated with an #end. You're declaring and implementing methods without telling the compiler which class they belong to.
Check that you don't have an #import "..." within the #implementation section.

Null variable in Objective C

I'm developing an iOS application and I'm having some problems when I try to save data.
My code is:
TuplaUsuario:
It is a class where I save user data. In that case, I use mensaje variable, so here is its code:
//TuplaUsuario.h:
#interface TuplaUsuario : NSObject
{
NSMutableString* mensaje;
}
#property NSMutableString* mensaje;
#end
//TuplaUsuario.m:
#import "TuplaUsuario.h"
#implementation TuplaUsuario
#synthesize mensaje;
- (id)initWithString:(NSString *)identifier {
if ( self = [super init] ) {
mensaje = [[NSMutableString alloc] initWithString:identifier];
}
return self;
}
#end
WebService:
It is a class where I communicate with a Web Service.
//WebService.h:
#import "TuplaUsuario.h"
#interface WebService : NSObject {
// Some other data
NSMutableString* message;
TuplaUsuario* usuario;
}
//Declaration of methods
#end
//WebService.m:
#import "WebService.h"
#import "AppDelegate.h"
#implementation WebService
- (id)init:(NSString *)identifier {
self = [super init];
usuario = [[TuplaUsuario alloc] initWithString:#""];
return self;
}
- (void) processComplete: (BOOL)success {
[[self delegate] processSuccessful:success];
AppDelegate* myAppDelegate = (AppDelegate*)[[UIApplication sharedApplication] delegate];
[myAppDelegate setUsuarioActual:usuario];
}
- (void)login:(NSString *)username password:(NSString *)password
{
//Connection with Web Service
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)theData {
NSDictionary* jsonArray=[NSJSONSerialization
JSONObjectWithData:theData
options:0
error:nil];
message = [jsonArray objectForKey:#"message"];
[usuario setMensaje:message];
}
AppDelegate:
//AppDelegate.h:
#import <UIKit/UIKit.h>
#import "TuplaUsuario.h"
#interface AppDelegate : UIResponder <UIApplicationDelegate>
{
Boolean rememberMe;
TuplaUsuario* usuarioActual;
}
#property (strong, nonatomic) UIWindow *window;
#property (retain) TuplaUsuario* usuarioActual;
#end
//AppDelegate.m:
#import "AppDelegate.h"
#implementation AppDelegate
#synthesize usuarioActual;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
usuarioActual = [[TuplaUsuario alloc] initWithString:#""];
return YES;
}
PROBLEM
In WebService, method connection didReceiveData, if I print message variable, it has the correct value, but if I print [usuario mensaje] it prints (null).
Where's my error?
SOLVED
The problem was in my ViewController and init method of WebService. I called init instead of initWithString:
ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
wSProtocol = [[WebService alloc] initWithString:#""]; //Variable of type WebService
}
WebService
- (id)initWithString:(NSString *)identifier {
self = [super init];
usuario = [[TuplaUsuario alloc] initWithString:#""];
return self;
}
Maybe because this method:
- (id)init:(NSString *)identifier {
if ( self = [super init] ) {
mensaje = [[NSMutableString alloc] init];
}
return self;
}
is never called, since you use:
usuario = [[TuplaUsuario alloc] init];
but is still wonder why you pass identifier into the method and never use it. I think you should make it like this:
mensaje = [[NSMutableString alloc] initWithString:identifier];

random generator to obtain data from array not displaying

I know theres a better solution using arc4random (it's on my to-try-out-function list), but I wanted to try out using the rand() and stand(time(NULL)) function first. I've created a NSMutableArray and chuck it with 5 data. Testing out how many number it has was fine. But when I tried to use the button function to load the object it return me with object <sampleData: 0x9a2f0e0>
- (IBAction)generateNumber:(id)sender {
srand(time(NULL));
NSInteger number =rand()% ds.count ;
label.text = [NSString stringWithFormat:#"object %#", [ds objectAtIndex:number] ];
NSLog(#"%#",label.text);
}
While I feel the main cause is the method itself, I've paste the rest of the code below just incase i made any error somewhere.
ViewController.h
#import <UIKit/UIKit.h>
#import "sampleData.h"
#import "sampleDataDAO.h"
#interface ViewController : UIViewController
#property (weak, nonatomic) IBOutlet UILabel *label;
#property (weak, nonatomic) IBOutlet UIButton *onHitMePressed;
- (IBAction)generateNumber:(id)sender;
#property(nonatomic, strong) sampleDataDAO *daoDS;
#property(nonatomic, strong) NSMutableArray *ds;
#end
ViewController.m
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
#synthesize label;
#synthesize onHitMePressed;
#synthesize daoDS,ds;
- (void)viewDidLoad
{
[super viewDidLoad];
daoDS = [[sampleDataDAO alloc] init];
self.ds = daoDS.PopulateDataSource;
// Do any additional setup after loading the view, typically from a nib.
}
- (void)viewDidUnload
{
[self setLabel:nil];
[self setOnHitMePressed:nil];
[super viewDidUnload];
// Release any retained subviews of the main view.
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}
- (IBAction)generateNumber:(id)sender {
srand(time(NULL));
NSInteger number =rand()% ds.count ;
label.text = [NSString stringWithFormat:#"object %#", [ds objectAtIndex:number] ];
NSLog(#"%#",label.text);
}
#end
sampleData.h
#import <Foundation/Foundation.h>
#interface sampleData : NSObject
#property (strong,nonatomic) NSString * object;
#end
sampleData.m
#import "sampleData.h"
#implementation sampleData
#synthesize object;
#end
sampleDataDAO.h
#import <Foundation/Foundation.h>
#import "sampleData.h"
#interface sampleDataDAO : NSObject
#property(strong,nonatomic)NSMutableArray*someDataArray;
-(NSMutableArray *)PopulateDataSource;
#end
sampleDataDAO.m
#import "sampleDataDAO.h"
#implementation sampleDataDAO
#synthesize someDataArray;
-(NSMutableArray *)PopulateDataSource
{
someDataArray = [[NSMutableArray alloc]init];
sampleData * myData = [[sampleData alloc]init];
myData.object= #"object 1";
[someDataArray addObject:myData];
myData=nil;
myData = [[sampleData alloc] init];
myData.object= #"object 2";
[someDataArray addObject:myData];
myData=nil;
myData = [[sampleData alloc] init];
myData.object= #"object 3";
[someDataArray addObject:myData];
myData=nil;
myData = [[sampleData alloc] init];
myData.object= #"object 4";
[someDataArray addObject:myData];
myData=nil;
myData = [[sampleData alloc] init];
myData.object= #"object 5";
[someDataArray addObject:myData];
myData=nil;
return someDataArray;
}
#end
what i guess is going on is that nslog function cant print the data inside your sample data class because its not a standard class. not standard classes must implement the "description" method. What you get when you print out your class is the pointer to it, because nslog has no way of knowing how to print out the data in your class.
if what you want to print on that label/nslog is the nsstring inside your class "sampledata" you should access the property.
this can be done in the following way:
SampleData *instanceOfSampleData = (SampleData*)[ds objectAtIndex:number];
label.text = [NSString stringWithFormat:#"object %#", instanceOfSampleData.object];

NSMutableArray KVC/KVO question

This is a sample from book "Cocoa Programming For Mac Os X 3rd(HD)" chapter 7 "Key-Value Coding. Key-Vaule Observing
Here is the code:
Person.h:
#import <Foundation/Foundation.h>
#interface Person : NSObject {
NSString *personName;
float expectedRaise;
}
#property (readwrite, copy) NSString *personName;
#property (readwrite) float expectedRaise;
#end
Person.mm:
#import "Person.h"
#implementation Person
#synthesize expectedRaise;
#synthesize personName;
- (id)init
{
[super init];
expectedRaise = 0.05;
personName = #"New Person";
return self;
}
- (void)dealloc
{
[personName release];
[super dealloc];
}
#end
MyDocument.h:
#import <Cocoa/Cocoa.h>
#interface MyDocument : NSDocument
{
NSMutableArray *employees;
}
#property (retain) NSMutableArray *employees;
#end
MyDocument.mm:
#import "MyDocument.h"
#import "Person.h"
#implementation MyDocument
#synthesize employees;
- (id)init
{
if (![super init])
return nil;
employees = [[NSMutableArray alloc] init];
return self;
}
- (void)dealloc
{
[employees release];
[super dealloc];
}
- (void)windowControllerDidLoadNib:(NSWindowController *) aController
#end
And the sample works fine.(A blank table at first and you can add or delete record).
Now I tried to add some records to the array so that the blank table would have
someting in it at first.
Here's what I'v tried(inside the init method):
[self willChangeValueForKey:#"employees"];
Person *p1 = [[Person alloc] init];
[employees addObject: [NSData dataWithBytes: &p1 length: sizeof(p1)]];
[self didChangeValueForKey:#"employees"];
But when I build and wrong I got the error msg:
[<NSConcreteData 0x422bf0> valueForUndefinedKey:]: this class is not key value coding-compliant for the key personName.
......
Can any one help me out of here? Thanks in advance ^_^
That seems like a very reasonable response... you added NSData to your array named employees; guessing from the names, and from the KVC, you probably meant to add p1 to your array instead. So, try:
[employees addObject:p1];