Pass Data between two view controllers using 'Delegation' : Objective-C - ios

I am implementing an library(.a), and I want to send notification count from library to app so they can show in their UI, notification count. I want them to implement the only method like,
-(void)updateCount:(int)count{
NSLog(#"count *d", count);
}
How can I send the count from my library continuously so they can use it in updateCount method to show.
I searched and come to know about call back functions. I have no idea how to implement them. Is there any other way to do this.

You have 3 options
Delegate
Notification
Block,also known callback
I think what you want is Delegate
Assume you have this file as lib
TestLib.h
#import <Foundation/Foundation.h>
#protocol TestLibDelegate<NSObject>
-(void)updateCount:(int)count;
#end
#interface TestLib : NSObject
#property(weak,nonatomic)id<TestLibDelegate> delegate;
-(void)startUpdatingCount;
#end
TestLib.m
#import "TestLib.h"
#implementation TestLib
-(void)startUpdatingCount{
int count = 0;//Create count
if ([self.delegate respondsToSelector:#selector(updateCount:)]) {
[self.delegate updateCount:count];
}
}
#end
Then in the class you want to use
#import "ViewController.h"
#import "TestLib.h"
#interface ViewController ()<TestLibDelegate>
#property (strong,nonatomic)TestLib * lib;
#end
#implementation ViewController
-(void)viewDidLoad{
self.lib = [[TestLib alloc] init];
self.lib.delegate = self;
[self.lib startUpdatingCount];
}
-(void)updateCount:(int)count{
NSLog(#"%d",count);
}
#end

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 - delegate not working

i have two view controllers, AbcViewController and XyzViewController. Both controllers behave similarly. Each has a "add" button which opens up a AddNewAbcViewController and AddNewXyzViewController respectively.
On AddNewAbcViewController, when the button "submit" is taped, it does it necessary stuff and close, bringing it back to AbcViewController. I am using delegate here where AbcViewController does the closing of AddNewAbcViewController. This works.
Now I want to do the same for XyzViewController and AddNewXyzViewController, but it is not working. When the btnSubmit is called in AddNewXyzViewController, it didn't enter into XyzViewController dimiss method. I have scanned through my codes many times but don't find anything extra not added. I even gave a different dismiss method name in XyzViewController and AddNewXyzViewController but that didn't work either. What did I miss?
here are my snippets for AbcViewController and AddAbcViewController. The codes for Xyz are identical:
class AddNewAbcViewController.h is
#import <Foundation/Foundation.h>
// protocol
#protocol AddNewAbcProtocol <NSObject>
-(void)dismiss;
#end
#interface AddNewAbcViewController : UIViewController<UITextViewDelegate>
#property(nonatomic, weak)id<AddNewAbcProtocol> delegate;
#end
class AddNewAbcViewController.m is
#interface AddNewAbcViewController() <UINavigationControllerDelegate, UIImagePickerControllerDelegate>
...
#end
#implementation AddNewAbcViewController
...
- (IBAction)btnSubmit:(id)sender
{
[self.delegate dismiss];
}
#end
class AbcViewController.h is
#import <Foundation/Foundation.h>
#import "AddNewAbcViewController.h"
#interface AbcViewController : UIViewController<AddNewAbcProtocol, UISplitViewControllerDelegate>
...
#end
class AbcViewController.m is
#implementation AbcViewController
-(void)dismiss
{
NSLog(#"delegated to dismiss()");
[self dismissViewControllerAnimated:YES completion:nil];
}
#end
As everyone explained, basically you forgot a line of code like ".delegate = self".
Here's a handy beginner's intro to delegates.
https://stackoverflow.com/a/4213005/294884
Use if statement to see if delegate works:
if ([self.delegate respondsToSelector:#selector(dismiss)])
{
[self.delegate dismiss];
}
Create AddNewXyzViewController as an instance variable, but not a local variable.

trouble implementing method from inherited class -ios

I have looked through the other topics on this matter and I have not been able to determine my error.
I am very new to IOS programming. I am trying to create a program that looks at the selected state of 2 buttons and determines whether the buttons selected state are the same.
I am currently trying to use a model to determine the buttons selected state and then pass the state to a label. I have an error which says:
No visible #interface for 'MatchTest' declares the selector 'doesItMatch'
I'd appreciate any help that may be offered.
Thanks!
this is the MatchTest.h file
// MatchTest.h
#import <Foundation/Foundation.h>
#interface MatchTest : NSObject
#end
this is the MatchTest.m file
// MatchTest.m
#import "MatchTest.h"
#implementation MatchTest
-(NSString*)doesItMatch:(UIButton *)sender
{
NSString* tempString;
if(sender.isSelected)
{
tempString = #"selected";
}
else
{
tempString = #"not selected";
}
return tempString;
}
#end
this is the MatchViewController.h file
// MatchViewController.h
#import <UIKit/UIKit.h>
#import "MatchTest.h"
#interface MatchViewController : UIViewController
#end
this is the MatchViewController.m file
// MatchViewController.m
#import "MatchViewController.h"
#interface MatchViewController ()
#property (weak, nonatomic) IBOutlet UILabel *matchLabel;
#property (strong, nonatomic) MatchTest *match;
#end
#implementation MatchViewController
-(MatchTest *)match
{
if(!_match) _match = [[MatchTest alloc] init];
return _match;
}
- (IBAction)button:(UIButton *)sender
{
sender.selected = !sender.isSelected;
self.matchLabel.text = [self.match doesItMatch:sender];
}
#end
declare doesItMatch method in MatchTest.h file
like
in MatchTest.h
-(NSString*)doesItMatch:(UIButton *)sender;
compiler is not able to file doesItMatch method's declaration in .h file that's why that error is there.
You have not defined your method -(NSString*)doesItMatch:(UIButton *)sender in MatchTest.h file.
You are importing MatchTest.h file in MatchViewController.h file so you need to define your methods or variables or property to make available this method.
Therefore according to your error log viewController wasn't able to find the interface where this method is declared.

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