I can't make delegate work from static library that i build. If I do in separate project it works correctly. Can you please check my code:
StaticSdk.h
#protocol SdkDelegate;
#interface Sdk : NSObject
#property (nonatomic, weak) id <SdkDelegate> delegate;
+(void)startAction
-(void)taskComplete;
#end
#protocol SdkDelegate <NSObject>
-(void)taskGetDataCompleted:(NSMutableData*)pushedData;
#end
StaticSdk.m
+(void)startAction{
SdkDelegate *sdk = [[SdkDelegate alloc] init];
[sdk.delegate taskGetDataCompleted:dataMy];
}
Than I am including this static library to my project and delegate which i specified is not executed.
Project code
ViewController.h
#interface ViewController : UIViewController <SdkDelegate>
-(IBAction) Connect: (id) sender;
#end
ViewController.m
- (void)taskGetDataCompleted:(NSMutableData*)pushedData
{
[imageView setImage:[[UIImage alloc] initWithData:pushedData]];
}
I'm guessing you're failing to compile on:
SdkDelegate *sdk = [[SdkDelegate alloc] init];
The issue here is that you cannot instantiate a protocol. Instead you have a class adopt that protocol, which it looks like you did correctly with ViewController. What you need to do now is assign your instance of ViewController to the delegate property of your Sdk instance, sometime before you call startAction.
Related
So I am calling delegate function but some how its not getting called, I tried everything from all the other similar threads but nothing works. It looks all good but the method is still not called. here is my code below -
So i created protocol like this -
AuthViewController.h
#class AuthViewController;
#protocol AuthViewControllerDelegate <NSObject>
- (void)updateNavigation:(NSString*)pageType
message:(NSString*)message;
#end
created a property -
#property (nonatomic, weak)id delegate;
And called the function in AuthViewController.m -
[self.delegate updateNavigation:#"xx" message:#"xx"];
Then in other class -
AssociateViewController.h
#interface AssociateViewController : UIViewController <AuthViewControllerDelegate>
#property (nonatomic, strong)AuthViewController *vc;
#End
AssociateViewController.m
First set the delegate in a button action or viewWillAppear(I tried both)-
self.vc = [[AuthViewController alloc] init];
self.vc.delegate = self;
And the here is the method which is somehow never called :( -
- (void)updateNavigation:(NSString*)pageType
message:(NSString*)message;
{
//method to do
}
Any help would be much appreciated. Thanks!
Starting point
I have a class, say A, used by an UI view.
A has a delegate that should notify UI view and this one should be write something on screen.
Question
What is the best approach to achieve this feature?
Seems something like observer-observable pattern
Code
---A.h
#interface A : NSObject
#end
---A.m
#implementation A
-(void)fooDelegate:(FooType *)sender {
/* Here I need to notify UI (that change notificationArea.text) */
}
---UIView.h
#interface UIView : UIViewController
#property(strong, nonatomic, retain) A* a;
#property(strong, nonatomic) IBOutlet UITextField *notificationArea;
#end
Based on the comments, I guess just code is what you're looking for...
Create your delegate protocol:
#protocol ADelegate;
#interface A : NSObject
#property (nonatomic, weak) id <ADelegate> delegate;
#end
#protocol ADelegate <NSObject>
#optional
-(void)fooDelegate:(A *)a;
#end
Notify your delegate:
#implementation A
-(void)fooDelegate:(FooType *)sender {
if ([[self delegate] respondsToSelector:#selector(fooDelegate:)]) {
[[self delegate] fooDelegate:self];
}
}
#end
Conform to the delegate protocol:
#import "A.h"
#import "MyView.h"
#interface MyView <ADelegate>
#end
#implementation MyView
-(void)fooDelegate:(A *)a {
// update text field here
}
#end
Finally, whenever you create an instance of A, set the delegate (where self in this example is an instance of MyView:
A *a = [[A alloc] init];
[a setDelegate:self];
I'm trying to implement delegate method between 2 classes in my app but the delegated method is not called.
Here is my code :
PBPartnersService.h
#protocol PBPartnersServicesDelegate <NSObject>
#required
-(void) didReceiveNewsDatasFromPartners:(NSDictionary *)Datas;
#end
Then I make my #property :
#interface PBPartnersServices : NSObject
#property (nonatomic, weak) id<PBPartnersServicesDelegate> delegate;
#end
In my PBPartnersService.m I call my delegate method (when I print self.delegate I get 'nil') :
if ([self.delegate respondsToSelector:#selector(didReceiveNewsDatasFromPartners:)]) {
[self.delegate didReceiveNewsDatasFromPartners:obj];
}
In my other class PBTicketsService.h I instantiate the first one :
#interface PBTicketsService : NSObject <PBPartnersServicesDelegate>
#property (nonatomic,strong) NSDictionary *ticketList;
#property (nonatomic, strong) PBPartnersServices *partnersServices;
- (void) prepareForDelegate;
#end
I made a method in PBTicketsService.m to set the partnersServices as a delegate :
- (void) prepareForDelegate{
self.partnersServices = [[PBPartnersServices alloc] init];
[self.partnersServices setDelegate:self];
}
and then I have my function who is never call :
-(void) didReceiveNewsDatasFromPartners:(NSDictionary *)Datas{
}
You should use Dependency injection: either add ticketsService as an argument of your partnerServices constructor, or do the opposite.
When you allocate the partnerServices property a second time your partnerServices will save in a new memory-adress. And for this object you didn't set the delegate property.
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.
Throughout my app, I'm getting semantic issue warnings when I set ViewController.delegate = self. I have searched and found similar posts but none were able to solve my problem.
ViewController.m:
GameAddViewController *gameAddViewContoller = [[navigationController viewControllers] objectAtIndex:0];
gameAddViewContoller.delegate=self;
I get the error message when setting .delegate=self.
GameAddViewController.h:
#protocol GameAddViewControllerDelegate <NSObject>
- (void)gameAddViewControllerDidCancel:(GameAddViewController *)controller;
- (void)gameAddViewController:(GameAddViewController *)controller didAddGame:(Game *) game;
#end
#interface GameAddViewController : UITableViewController <GameAddViewControllerDelegate>
{
sqlite3 *pitchcountDB;
NSString *dbPath;
}
#property (nonatomic, strong) id <GameAddViewControllerDelegate> delegate;
...
#end
ViewController.h:
#import "GameAddViewController.h"
#class ViewController;
#protocol ViewControllerDelegate <NSObject>
- (void)ViewControllerDidCancel:(ViewController *)controller;
#end
#interface ViewController : UIViewController <ViewControllerDelegate>
-(void) checkAndCreateFile;
#end
Can anyone point me in the right direction to resolve the warning messages?
At this line :
gameAddViewContoller.delegate=self;
Notice that self is of type ViewController which does NOT conform to the GameAddViewController protocol.
For me what ended up happening is that I wasn't adding the delegate to the #interface on my header file
For example
#interface TheNameOfYourClass : UIViewController <TheDelegatorClassDelegate>
#end
You are putting the < GameAddViewControllerDelegate > in the wrong place. It doesn't go on GameAddViewController, it goes on ViewController.
This might help other people who are adding Multipeer Connectivity straight to a ViewController. At the top of myViewControllerName.h add '<MCSessionDelegate>':
#interface myViewControllerName : UIViewController<MCSessionDelegate>
also, if you define your delegate on xx.m, but you use it in other class. you may get this problem. so, just put protocol define on xx.h, when it is needed.
If you have a hybrid project, the protocol in Swift and the assignment in Objective-C:
Swift declaration:
protocol BackgroundTasking {
func beginTask(withName: String, expirationHandler handler: (()->Void)?)
func endTask(withName: String)
}
Objective-C assignment:
#property (nonatomic) id<BackgroundTasking> backgroundTasker;
_backgroundTasker = [[BackgroundTasker alloc] init]; // WARNING
Assigning to '__strong id' from incompatible type 'BackgroundTasker *'
You need to declare the class (to remove this warning) and the functions (to make them accessible) as #objc for them to be correctly bridged.
Correct Swift declaration:
#objc protocol BackgroundTasking {
#objc func beginTask(withName: String, expirationHandler handler: (()->Void)?)
#objc func endTask(withName: String)
}
On hybrid projects you should add your delegates on .h file instead of .m file