Call a function from a view - ios

I'm trying to create a method that I can call from different viewControllers.
I have a class called Info.h/Info.m and in this I have a method: -
-(void) testFunc {
... Do something here
}
I then want to call this function in my ViewController. I tried the following but I can't get the testFunc to run.
#import "ViewController.h"
#import "Info.h"
#interface ViewController ()
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
Info *targetsInstance = [[Info alloc] init];
[targetInstance testFunc];
}
#end
When I type [targetInstance testFunc] I get the error "No visible #interface for 'Info' declares the selector 'testFunc'"

In your Info.h file, you must declare -(void) testFunc as a method in the #interface section
#interface Info: UIViewController {
}
-(void) testFunc;
#end

assuming you declared the info class (I recommend using a capital letter for class names) correctly replace this:
[info testFunc];
with:
[targetsInstance testFunc];
Since the method is an instance method (due to the '-' character) you need an instance for invoking it.

Related

Need to develop Custom Delegate for API Calling

I want to develop Custom Connection Class by which I can make API calls using it. I do not want to use any third party apis like afhttprequest or asihttp.
I want to develop my self this type of delegate. I have searched much things but I do not have much idea in CustomDelegates.
I wrote one example of custom delegate.
From ViewController.m we call method with two number for addition of another class (Addition class)
Addition class will add these two number and call delegate method so we can get answer of that two number in ViewController using custom delegate.
Addition.h
#import <Foundation/Foundation.h>
// write protocal for this class
// you can give any name of that protocol
#protocol AdditionDelgate <NSObject>
// delegate method of this delegate
-(void)answerOfTwoNumberAddition:(int)ans;
#end
#interface Addition : NSObject
{
}
// set property of that protocol, so using that we can call that protocol methods (i.e. ansOfYourAns)
#property (nonatomic, weak) id <AdditionDelgate> delegate;
-(void) addThisNumber:(int) firstNumber withSecondNumber:(int)secondNumber;
#end
Addition.m
#import "Addition.h"
#implementation Addition
-(void)addThisNumber:(int)firstNumber withSecondNumber:(int)secondNumber
{
int ans = firstNumber + secondNumber;
// call delegate method of "AdditionDelgate" protocol
// we already set delegate of viewController to this protocol
// so it will call viewController class "answerOfTwoNumberAddition" method
[self.delegate answerOfTwoNumberAddition:ans];
}
#end
ViewController.h
#import <UIKit/UIKit.h>
// import addition class
#import "Addition.h"
// set AdditionDelgate to class
#interface ViewController : UIViewController <AdditionDelgate>
#end
ViewController.m
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// creat object of class
Addition * additionObj = [[Addition alloc] init];
// set delegate as self to that so that methods delegate methods will call
additionObj.delegate = self;
// call method
[additionObj addThisNumber:2 withSecondNumber:3];
}
#pragma mark ----- Delegate method of Addition view ----
// this is delegate method of Addition class, it will call from "addThisNumber" method line of code
// ([self.delegate answerOfTwoNumberAddition:ans];)
-(void)answerOfTwoNumberAddition:(int)ans
{
NSLog(#"addition of two number is %d",ans);
}
#end
I hope it will help you

iOS error: No visible #interface for 'xxxx' declares the selector 'alloc'

Here is my TextValidator class:
//TextValidator.h
#import <Foundation/Foundation.h>
#interface TextValidator : NSObject
- (BOOL) isValidPassword:(NSString *)checkPassword;
- (BOOL) isValidEmail:(NSString *)checkString;
- (BOOL) isEmpty:(NSString *)checkString;
#end
// TextValidator.m
#import "TextValidator.h"
#implementation TextValidator
- (BOOL) isEmpty:(NSString *)checkString
{
return YES;
}
- (BOOL) isValidPassword:(NSString *)checkPassword
{
return YES;
}
- (BOOL) isValidEmail:(NSString *)checkString
{
return YES;
}
#end
This is the way I try to initialise the TextValidator class in ViewController.m:
//ViewController.h
#import <Foundation/Foundation.h>
#interface SignUpViewController : UIViewController <UITextFieldDelegate>
#end
//ViewController.m
#import "SignUpViewController.h"
#import "TextValidator.h"
#interface SignUpViewController ()
#property TextValidator *myValidator;
#end
#implementation SignUpViewController
- (void)viewDidLoad
{
[[self.myValidator alloc] init]; //iOS error: No visible #interface for 'TextValidator' declares the selector 'alloc'*
[super viewDidLoad];
}
#end
When I try to compile the code I get the following error:
No visible #interface for 'TextValidator' declares the selector 'alloc'.
TextValidator class inherits from NSObject and as far as I know init and alloc functions are already defined at the base class. So why does the program gives such an error?
Note that, I already checked this topic and it doesn't work for me.
My psychic debugger, without reading your code, tells me you're calling alloc on an object instance, rather than a class. The alloc method is a static method defined by classes (typically inherited from NSObject) that returns a new instance of the underlying object. You can't ask an instance to allocate itself!
Now looking at the code, I see that you want:
self.myValidator = [[TextValidator alloc] init];
to construct a new instance, and assign it to the myValidator property.
Replace
[[self.myValidator alloc] init];
with
self.myValidator = [[TextValidator alloc] init];
The error signals that you have not implemented the alloc instance method for self.myValidator, which is true. But that's a class method that applies for all NSObject objects.
Your syntax of creating object is incorrect. Correct code:
self.myValidator = [[TextValidator alloc] init];
If you experience this randomly (like when you are changing branches), not because you forgot to declare selector.
Go to file inspector > Target Membership
uncheck the targets
then check it again
This will refresh your project.pbxproj
Then if you build, you'll see your real problem
For Others :
Check the varible name is not like the class name.
Well it happend to me.
XXXViewController * XXXViewController = [[XXXViewController alloc] init];
Don't tell anyone like I did right now.
For those who get the error of "no visible #interface for declares the selector ..."
such an error usually happens when you have mistyped the name of the method, or that method doesn't belong to that class at all and doesn't exist in your class
I had this problem today and solved it on my own. Basically you could also not be satisfying all the requirements of the function / procedure.
Go into the class itself and make sure your declaring all the requirements.
I took the class out of the header library and compared it word for word to verify it matches the function using it.

Objective C instance methods not found

I created a class called Datahandler with 2 methods. In my LoginViewController, I can use them, but in another ViewController they cannot be found.
This is my DataHandler.h file:
#import <Foundation/Foundation.h>
#interface DataHandler : NSObject
- (int) loginOnServer:(NSString *)username password:(NSString *)password;
- (NSString *) getJsonFromServer;
#end
In my LoginViewController, both methods are found.
LoginViewController.m:
#import "DataHandler.h"
...
#interface LoginViewController ()
...
#end
#implementation LoginViewController
- (void) checkLogin:(NSString *)email password:(NSString *) password
{
DataHandler *dataHandler = [[DataHandler alloc] init];
int result = [dataHandler loginOnServer:email password:password];
...
}
...
#end
FirstViewController.m:
#import "DataHandler.h"
...
#interface FirstViewController ()
#end
#implementation FirstViewController
- (void)viewDidLoad
{
...
DataHandler *dh = [[DataHandler alloc] init];
NSString *json = [dh getJsonFromServer];
...
}
What I get there is:
FirstViewController.m:32:23: No visible #interface for 'DataHandler' declares the selector 'getJsonFromServer'
What am I doing wrong?
Thank you.
Edit 1:
There was another old class called DataHandler in my project folder, which was used instead of the this one.
Please delete your or rename your another DataHandler file and give the reference in your buildPhases (Compile sources)
As you can see log is showing no visible interface that means definition of method is not available in your another DataHandler.h, therefore receiver isn't able to get the declaration of your method.

Why isn't my delegate object responding to method calls?

I ultimately want to write an iOS app incorporating ALAssetsLibrary, but as a first step toward understanding delegation, I'm trying to pass a simple message between two view controllers. For some reason, I can't seem to get the message to pass. In particular, the delegate object (derpy) doesn't appear to exist (if(self.derpy) returns NO)).
I asked the same question on the Apple forums and was told that I should be using segues and setting properties / calling methods using self.child instead, but that seems strange. If I were to pass messages using the parent / child properties, would I still be able to create my views in Interface Builder? Once I have my two views set up, say inside a UINavigationController, I'm not sure how to actually "wire them up" so I can pass messages between them. Sorry if the question is overly broad.
Here's the controller I'm declaring the protocol in (called PickerViewController):
Interface:
#import <UIKit/UIKit.h>
#import <AssetsLibrary/AssetsLibrary.h>
#protocol DerpDelegate <NSObject>
#required
- (void) test;
#end
#interface PickerViewController : UIViewController
#property (nonatomic, assign) id<DerpDelegate> derpy;
#end
Implementation:
#import "PickerViewController.h"
#interface PickerViewController ()
#end
#implementation PickerViewController
- (void)viewDidLoad
{
[super viewDidLoad];
if (self.derpy) { // If the delegate object exists
[self.derpy test]; // send it this message
} else {
NSLog(#"Still not working."); // This always returns (i.e., self.derpy doesn't exist)
}
}
Delegate controller (MainViewController) interface:
#import <UIKit/UIKit.h>
#import "PickerViewController.h"
#interface MainViewController : UIViewController <DerpDelegate> // public promise to implement delegate methods
#property (strong, nonatomic) PickerViewController *picker;
- (void) test;
#end
And lastly, the delegate controller (MainViewController) implementation:
#import "MainViewController.h"
#import "PickerViewController.h"
#interface MainViewController ()
#end
#implementation MainViewController
// Here's that method I promised I'd implement
- (void) test{
NSLog(#"Test worked."); // This never gets called
}
- (void)viewDidLoad {
[super viewDidLoad];
self.picker.derpy = self;
//lazy instantiation
- (PickerViewController *) picker{
if(!_picker) _picker = [[PickerViewController alloc]init];
return _picker;
}
EDIT: Many thanks to rydgaze for pointing me in the right direction with self.picker.derpy = self, but for some reason, things still aren't working properly. Importantly, once that property has been set, if(self.picker.derpy) returns YES from MainViewController. But if(self.derpy) is still returning NO when called from inside the PickerViewController's viewDidLoad. How can the property exist and not exist at the same time?
You need to be sure that you're setting the delegate on the instance of the view controller that you put on screen. If you're using a navigation controller and segues to go between MainViewController and PickerViewController, then you should set the delegate in prepareForSegue:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
self.picker = (PickerViewController *)segue.destinationViewController;
self.picker.derpy = self;
}
You need to populate the delegate first.
Basically, your MainViewController shoudl at somepoint do a
picker.derpy = self;
Then when the delegate fires in PickerViewController, the callback will happen.
Edit:
A good practice is to do something like in PickerViewController
#property (nonatomic, assign) id<DerpDelegate > derpy;
and in your MainViewController indicate that you will implement the delegate
#interface MainViewController : UIViewController<DerpDelegate>
Eventually in your implementation of MainViewController
You will have something like
picker = [[PickerViewController alloc]init];
picker.derpy = self;
[picker doYourThing];
Once picker is all done, it may want to return results using the delegate.

iOS method in data controller isn't being called

I am trying to call a method in my data controller object to load the data for my application, but for some reason it is not being called. Below is what I have done to initialize it. Any help would be greatly appreciated.
ViewController:
header file:
#import <UIKit/UIKit.h>
#class DetailViewController;
#class DataController;
#import <CoreData/CoreData.h>
#import "JointCAD.h"
#interface TableViewController : UITableViewController {
}
#property (nonatomic, assign) DataController *dataController;
#end
implementation file:
#import "TableViewController.h"
#import "DataController.h"
#implementation TableViewController
#synthesize dataController;
- (void)viewDidLoad {
[dataController refreshData];
}
#end
Data Controller:
header file:
#import <Foundation/Foundation.h>
#import "JointCAD.h"
#import "JointCADXMLParser.h"
#import "TFHpple.h"
#interface DataController : NSObject {
TFHpple *xpathParser;
}
- (void)refreshData;
- (void)initXMLParser;
- (void)noCallsMessage;
- (void)noInternetMessage;
#end
implementation file:
#import "DataController.h"
#implementation DataController
XMLParser *xmlParser;
- (void)refreshData {
NSLog("Some Method");
}
Is 'dataController' Object being set by some other class? - I believe that's why you have set it as a property? Right?
If No, then Remove the property,#synthesize of 'dataController' and try simple allocation of your 'dataController' object and then try calling your method.
Hope it helps.
You either need to initialize "DataController" prior to actually calling one of it's methods, or you need to make the method, "refreshData" a class by changing it's "-" to a "+".
If you need an instance callback instead. You need to rewrite "viewDidLoad" like this:
- (void)viewDidLoad {
DataController *dataController = [[DataController alloc] init];
[dataController refreshData];
}
And get rid of the property declaration of dataController because you haven't initialized it. If you would prefer a property declaration instead, simply allocate the viewcontroller prior to calling a function from it.
- (void)viewDidLoad {
dataController = [[DataController alloc] init];
[dataController refreshData];
}
One last thing to note is that I (and probably Ray) assume that you're using a storyboard configuration. If you are using a xib configuration, you need to add initWithNibName: to each initialization of the view controller.
I hope that's helpful!

Resources