FBNativeAdsManagerDelegate in Facebook Native Ads working properly in UIViewController class but when used in custom NSObject class its not working i.e. its delegate methods nativeAdsLoaded and nativeAdsFailedToLoadWithError did not get called.
CustomFBAd.h file
#import FBAudienceNetwork;
#import <Foundation/Foundation.h>
#protocol OnFBNativeAdLoadedDelegate<NSObject>
- (void)onFBNativeAdLoaded:(UIView *)adView;
#end
#interface CustomFBAd : NSObject
#property (nonatomic,weak) id <OnFBNativeAdLoadedDelegate>delegate;
-(void)requestNativeAd:(NSString *)FaceBookPlacementID;
#end
CustomFBAd.m file
#import "CustomFBAd.h"
#interface CustomFBAd ()<FBNativeAdsManagerDelegate,FBNativeAdDelegate>
#property (nonatomic, strong) FBNativeAdsManager *manager;
#property (nonatomic, weak) FBNativeAdScrollView *scrollView;
#end
#implementation CustomFBAd
-(void)requestNativeAd:(NSString *)FaceBookPlacementID{
if(FaceBookPlacementID.length != 0){
FBNativeAdsManager *manager = [[FBNativeAdsManager alloc] initWithPlacementID:FaceBookPlacementID forNumAdsRequested:5];
manager.delegate = self;
[FBAdSettings addTestDevice:#"cf1bb93becbe6e31f26fdf7d80d19b4ae225afaa"];
[manager loadAds];
self.manager = manager;
}
}
#pragma mark - FBNativeAdDelegate implementation
- (void)nativeAdDidClick:(FBNativeAd *)nativeAd
{
// NSLog(#"Native ad was clicked.");
}
- (void)nativeAdDidFinishHandlingClick:(FBNativeAd *)nativeAd
{
// NSLog(#"Native ad did finish click handling.");
}
- (void)nativeAdWillLogImpression:(FBNativeAd *)nativeAd
{
// NSLog(#"Native ad impression is being captured.");
}
#pragma mark FBNativeAdsManagerDelegate
-(void)nativeAdDidLoad:(FBNativeAd *)nativeAd
{
}
- (void)nativeAdsLoaded
{
NSLog(#"Native ads loaded, constructing native UI...");
if (self.scrollView) {
[self.scrollView removeFromSuperview];
self.scrollView = nil;
}
FBNativeAdScrollView *scrollView = [[FBNativeAdScrollView alloc] initWithNativeAdsManager:self.manager withType:FBNativeAdViewTypeGenericHeight120];
scrollView.xInset = 0;
scrollView.delegate = self;
self.scrollView = scrollView;
[self.delegate onFBNativeAdLoaded:self.scrollView];
}
- (void)nativeAdsFailedToLoadWithError:(NSError *)error
{
NSLog(#"Native ads failed to load with error: %#", error);
}
#end
As stated in above code I did set FBNativeAdsManager's delegate in requestNativeAd method as
manager.delegate = self;
And also used as FBNativeAdsManagerDelegate,FBNativeAdDelegate
#interface CustomFBAd ()<FBNativeAdsManagerDelegate,FBNativeAdDelegate>
And call this code as
CustomFBAd *objFBAd = [[CustomFBAd alloc]init];
objFBAd.delegate = self;
[objFBAd requestNativeAd:#"my_FB_placement_Id"];
any clue (Note : same code works if I use it in UIViewController)? Thanks
Finally it works after making strong reference of CustomFBAd it works like a charm(Thanks to #MuhammadZohaibEhsan).So init CustomFBAd as
#property(nonatomic, strong) CustomFBAd * objFBAd;
And change
CustomFBAd *objFBAd = [[CustomFBAd alloc]init];
objFBAd.delegate = self;
[objFBAd requestNativeAd:#"my_FB_placement_Id"];
to
self.objFBAd = [[CustomFBAd alloc]init];
self.objFBAd.delegate = self;
[self.objFBAd requestNativeAd:#"my_FB_placement_Id"];
if your delegate methods are called in uiviewcontroller, than there is a problem with the code. I guess you have to have a strong reference of CustomFBAd in your controller. Because none of other references are taking hold of your CustomFBAd. hope it helps
Related
I am trying to get the gps information from the RTK in DJI M600 Pro by using an ios app, I have looked at DJI Mobile SDK API reference, and I have found some RTK API . When the drone is starting up, the property "isRTKBeingUsed" should be "YES" ,but I can't get the result.
Any help would be greatly appreciated! Here is my code:
#import "ViewController.h"
#import <DJISDK/DJISDK.h>
#import "DJIAppActivationManager_InternalTesting.h"
#import<DJISDK/DJIRTK.h>
#define WeakRef(__obj) __weak typeof(self) __obj = self
#define WeakReturn(__obj) if(__obj ==nil)return;
void ShowResult(NSString *format, ...)
{...
}
#interface ViewController ()<DJIAppActivationManagerDelegate, DJISDKManagerDelegate,DJIRTKDelegate>
...
...
#property (weak, nonatomic) IBOutlet UILabel *isusing;
#property(strong, nonatomic) DJIRTK * rtk1;
#property(strong, nonatomic) DJIRTKState * rtkstate1;
#end
#implementation ViewController
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
[self registerApp];
[self updateUI];
self.rtk1 = [[DJIRTK alloc] init];
self.rtkstate1 = [[DJIRTKState alloc] init];
[self rtk:_rtk1 didUpdateState:_rtkstate1];
}
- (void)viewDidLoad {
[super viewDidLoad];
}
-(void) rtk:(DJIRTK *)rtk didUpdateState:(DJIRTKState *)state
{
self.shifoushiyong.text = [NSString stringWithFormat:#"%d",state.isRTKBeingUsed];
}
- (void)registerApp
{
[DJISDKManager registerAppWithDelegate:self];
}
-(void)updateUI
{
...
}
...
#end
TLDR: You are using the RTK delegate method the wrong way.
didUpdateState: is a delegate method. You need to pass a delegate object to your RTK object. When data comes from the aircraft, didUpdateState will be called. You don't have to do it manually.
Furthermore, you shouldn't init your own RTK object:
1/ Once you have confirmation the SDK has registered (delegate method of DJISDKManager), get the product
- (void)appRegisteredWithError:(NSError *_Nullable)error {
DJISDKManager.product
// continue here
}
https://developer.dji.com/api-reference/ios-api/Components/SDKManager/DJISDKManager.html#djisdkmanager_product_inline
2/ Verify it's a DJIAircraft class
if ([[DJISDKManager.product class] isKindOf:[DJIAircraft class]) {
// Continue here
}
https://developer.dji.com/api-reference/ios-api/Products/Aircraft/DJIAircraft.html?search=djiaircraft&i=0&
3/ Get the RTK object from there:
DJIRTK *rtk = aircraft.flightController.RTK;
https://developer.dji.com/api-reference/ios-api/Components/FlightController/DJIFlightController.html#djiflightcontroller
4/ Set the delegate to RTK (a class that implemented DJIRTKDelegate - assuming self here)
rtk.delegate = self;
https://developer.dji.com/api-reference/ios-api/Components/RTK/DJIRTK.html#djirtk_protocol_inline
5/ Get the data in the delegate method like you did.
- (void)rtk:(DJIRTK *_Nonnull)rtk didUpdateState:(DJIRTKState *_Nonnull)state {
// Show me the data
}
https://developer.dji.com/api-reference/ios-api/Components/RTK/DJIRTK.html#djirtk_updatertkstate_inline
I'm having trouble figuring out why I'm getting a nil delegate for this call. It seems like I'm setting the delegate just fine.
LogoutViewController.h
#protocol SomeNewDelegate <NSObject>
#required
- (void)someMethod;
#end
#interface LogoutViewController : UIViewController
#property (nonatomic, weak) id<SomeNewDelegate> delegate;
LogoutViewController.m
- (IBAction)logoutButtonTapped:(id)sender {
NSLog(#"logout tapped");
[self.delegate someMethod];
[self dismissViewControllerAnimated:YES completion:nil];
}
MainViewController.m
#interface MainViewController () <UIScrollViewDelegate, SomeNewDelegate>
#property (nonatomic, strong) LogoutViewController *logoutVC;
#end
#implementation MainViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.logoutVC.delegate = self;
}
- (void)someMethod {
NSLog(#"someMethod");
}
someMethod never gets called and I don't see why the delegate is nil. Any help?
Use below code in viewDidload
LogoutViewController *logoutVC = [[LogoutViewController alloc]init];
logoutVC.delegate = self;
Remove LogoutViewController from property.
I have used this and its working fine.
Hope its working for you.
Edited code in .h file
#protocol syncDataDelegate <NSObject>
#required
- (void) offlineSyncProcess;
#end
#interface LoginViewController : UIViewController
{
id <syncDataDelegate> syncDelegate;
}
#property (retain) id syncDelegate;
in .m file
#implementation LoginViewController
{
// your code
}
#synthesize syncDelegate;
- (IBAction)logoutButtonTapped:(id)sender {
NSLog(#"logout tapped");
[syncDelegate offlineSyncProcess];
}
You can call delegate method from here in LoginViewController.m file from any method.
in My Delegate implementation
in .m file
#interface MainViewController ()<syncDataDelegate>
#end
#implementation MainViewController
- (void)viewDidLoad
{
[super viewDidLoad];
LoginViewController *LVC = [[LoginViewController alloc]init];
LVC.syncDelegate = self;
}
now use the delegate methode here
- (void) offlineSyncProcess
{
// your code here
}
this code is working in my project, check this in your project.
Make sure your logoutVC is not nil when you try to set the delegate property for it.
You can implement the setDelegate method in your LogoutViewController.m. Then use break point to make sure it is invoked.
Delegate is nil because your logoutVC is nil, you haven't allocated memory to the logoutvc property.
Just before self.logoutVC.delegate = self
Add following code
self.logoutVC = [[LogoutViewController alloc]init];
Everything will start working automatically.
I have been creating a cocoa static library in which I have a public nsobject file where I created a custom delegate. In the app I imported the nsobject file and implemented the delegate but the delegate is not getting called... the static library name is glamApi.
the SKUIDPasser.h file of the NSObject in the library
#import <Foundation/Foundation.h>
#protocol SubClassDelegate <NSObject>
#required
- (void)MethodNameToCallBack:(NSString *)s;
#end
#interface SKUIDPasser : NSObject
-(void)getSKUIDsFromCart:(NSString *)SKUIDs;
#property (nonatomic, weak) id <SubClassDelegate> delegatePasser;
#end
and the SKUIDPasser.m file
#import "SKUIDPasser.h"
#implementation SKUIDPasser
#synthesize delegatePasser;
-(void)getSKUIDsFromCart:(NSString *)SKUIDs{
NSLog(#"getSKUIDsFromCart %#",SKUIDs);
[delegatePasser MethodNameToCallBack:SKUIDs];
}
#end
And the method is called from a Viewcontroller in static library
- (IBAction)CartShowEvent:(id)sender {
if (![cartBadge isHidden]) {
buyClicked = TRUE;
[self loadCart];
[self showCartItemsAll];
self.cartView.frame = self.view.bounds;
[self.view addSubview:self.cartView];
SKUIDPasser *pass = [[SKUIDPasser alloc] init];
[pass getSKUIDsFromCart:#"sssss"];
} else {
[Utilities alert:#"No products to display !!!"];
}
}
The Viewcontroller which the custom delegate has to be implemented Viewcontroller.h
#import <glamAPI/SKUIDPasser.h>
#interface ViewController : UIViewController<SubClassDelegate>{
SKUIDPasser *sk;
}
Viewcontroller.m
- (void)viewDidLoad {
[super viewDidLoad];
sk = [[SKUIDPasser alloc] init];
sk.delegatePasser = self;
NSLog(#"sk.delegatePasser %#",sk.delegatePasser);
}
- (void)MethodNameToCallBack:(NSString *)s
{
NSLog(#"MethodNameToCallBack %#",s);
}
I didn't get any error but the method is not calling..Please help me to resolve this
The very first thing you need to understand is that each instance object of a class is entirely different entity and maintains it's state separately.
In you case your have created an object of your static library in viewDidLoad: and set the delegate accordingly, but when you are making the call to method getSKUIDsFromCart, you are using a different instance for which you never set the delegate property. That's why there was no callback.
To solve this, you can set the delegate in method CartShowEvent: before making the call, something like this
SKUIDPasser *pass = [[SKUIDPasser alloc] init];
pass.delegatePasser = self;
[pass getSKUIDsFromCart:#"sssss"];
However i would suggest that you should use the instance variable of library which you already created in viewDidLoad:
- (IBAction)CartShowEvent:(id)sender {
if (![cartBadge isHidden]) {
buyClicked = TRUE;
[self loadCart];
[self showCartItemsAll];
self.cartView.frame = self.view.bounds;
[self.view addSubview:self.cartView];
//No need to create another object.
//SKUIDPasser *pass = [[SKUIDPasser alloc] init];
//Use the previously created instance object
[sk getSKUIDsFromCart:#"sssss"];
}
else {
[Utilities alert:#"No products to display !!!"];
}
}
The SKUIDPasser object that you are calling within (IBAction)CartShowEvent:(id)sender and the SKUIDPasser object that you are setting the delegate are NOT the same.
Just for a test, try calling the method [sk getSKUIDsFromCart:#"sssss"]; just after you set the delegate and you will see that it will be called because this instance has the delegate set correctly:
ViewController.m
- (void)viewDidLoad {
[super viewDidLoad];
sk = [[SKUIDPasser alloc] init];
sk.delegatePasser = self;
[sk getSKUIDsFromCart:#"sssss"];
NSLog(#"sk.delegatePasser %#",sk.delegatePasser);
}
- (void)MethodNameToCallBack:(NSString *)s
{
NSLog(#"MethodNameToCallBack %#",s);
}
Update
I updated my answer to help you call the trigger from the static library
ViewController.m
- (void)viewDidLoad {
[super viewDidLoad];
sk = [[SKUIDPasser alloc] init];
sk.delegatePasser = self;
/*
You now can pass this variable to the static library to get called
from there ...
example:
viewControllerOnStaticLibrary.passer = sk;
*/
NSLog(#"sk.delegatePasser %#",sk.delegatePasser);
}
- (void)MethodNameToCallBack:(NSString *)s
{
NSLog(#"MethodNameToCallBack %#",s);
}
Viewcontroller_in_static_library.h
#property (nonatomic, strong) SKUIDPasser *passer;
Viewcontroller_in_static_library.m
- (IBAction)CartShowEvent:(id)sender {
if (![cartBadge isHidden]) {
buyClicked = TRUE;
[self loadCart];
[self showCartItemsAll];
self.cartView.frame = self.view.bounds;
[self.view addSubview:self.cartView];
//now you are calling the same instance
[self.passer getSKUIDsFromCart:#"sssss"];
} else {
[Utilities alert:#"No products to display !!!"];
}
}
I saw a lot of this kind of questions and answers here, but couldn't find solution to my problem. I'm trying to send data from one view controller to another and use delegate. But don't know why my postDelegate doesn't responds to selector. Is something wrong with this code or what is the problem?
PostViewController.h file
#protocol GetDataDelegate <NSObject>
-(void)getPassedInfo:(NSString*)info;
#end
#interface PostViewController : UIViewController
#property (nonatomic, weak) id <GetDataDelegate> postDelegate;
#end;
PostViewController.m file
#import "PostViewController.h"
- (IBAction)postData:(id)sender {
if ([_postDelegate respondsToSelector:#selector(getPassedInfo:)]) {
[self.postDelegate getPassedInfo:#"data"];
NSLog(#"responds");
}
[self dismissViewControllerAnimated:YES completion:nil];
}
in second view controllers .h file
#import "PostViewController.h"
#interface MainViewController : UITableViewController <GetDataDelegate>
and in .m file
#implementation MainWindowTableViewController
- (void)viewDidLoad
{
[super viewDidLoad];
PostViewController * postController = [[PostViewController alloc]init];
postController.postDelegate = self;
}
and here is delegate method:
-(void)getPassedInfo:(NSString *)info{
NSLog(#"info is %#", info);
}
You need to make postController a property or an ivar. Currently it is a local variable in the viewDidLoad method which will be deallocated after viewDidLoad completes as #CodaFi said above.
#import "PostViewController.h"
#interface MainViewController : UITableViewController <GetDataDelegate>
#property (nonatomic, strong) PostViewController *postController;
#end
Then:
- (void)viewDidLoad
{
[super viewDidLoad];
self.postController = [[PostViewController alloc]init];
self.postController.postDelegate = self;
}
I have a protocol in one class:
#protocol DataStorageManager
- (void) saveFile;
#end
#interface DataManager : NSObject
{
id <DataStorageManager> delegate;
}
#property (nonatomic, assign) id<DataStorageManager> delegate;
//methods
#end
and its implementation:
#implementation DataManager
#synthesize delegate;
#end
and I have another class which is the adapter between the first and the third one:
#import "DataManager.h"
#import "DataPlistManager.h"
#interface DataAdapter : NSObject <DataStorageManager>
#property (nonatomic,strong) DataPlistManager *plistManager;
- (void) saveFile;
#end
and its implementation
#import "DataAdapter.h"
#implementation DataAdapter
-(id) initWithDataPlistManager:(DataPlistManager *) manager
{
self = [super init];
self.plistManager = manager;
return self;
}
- (void) saveFile
{
[self.plistManager savePlist];
}
#end
So when I in first method try to call my delegate method like this
[delegate saveFile];
Nothing happened. I don't understand what's wrong with the realization - it's a simple adapter pattern realization. So I need to use the delegate which will call the methods from the third class. Any help?
You are not setting the delegate property. You need to do this,
-(id) initWithDataPlistManager:(DataPlistManager *) manager
{
self = [super init];
self.plistManager = manager;
self.plistManager.delegate = self;
return self;
}
Also, in DataManager class remove the ivar declaration, just declaring property is sufficient, the ivar gets automatically created. Call the delegate method as below,
if([self.delegate respondsToSelector:#selector(saveFile)] {
[self.delegate saveFile];
}
Hope that helps!
In your case you forget to set your protocol delegate and also need to call protocol method
by self.delegate....
I just Give Basic Idea for how to Create Protocol
Also Read This Question
#DetailViewController.h
#import <UIKit/UIKit.h>
#protocol MasterDelegate <NSObject>
-(void) getButtonTitile:(NSString *)btnTitle;
#end
#interface DetailViewController : MasterViewController
#property (nonatomic, assign) id<MasterDelegate> customDelegate;
#DetailViewController.m
if([self.customDelegate respondsToSelector:#selector(getButtonTitile:)])
{
[self.customDelegate getButtonTitile:button.currentTitle];
}
#MasterViewController.m
create obj of DetailViewController
DetailViewController *obj = [[DetailViewController alloc] init];
obj.customDelegate = self;
[self.navigationController pushViewController:reportTypeVC animated:YES];
and add delegate method in MasterViewController.m for get button title.
#pragma mark -
#pragma mark - Custom Delegate Method
-(void) getButtonTitile:(NSString *)btnTitle;
{
NSLog(#"%#", btnTitle);
}