DJI sdk get RTK information - ios

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

Related

How can i call same xib in multiple views but distinguish which i'm interacting?

I'm trying to use an xib file (which is just a simple view) on my viewcontroller more than once. I can add it on my viewcontroller more than once and interact with both of them. The question is, how can i distinguish between these views to know which one i'm clicking?
For example, when i tap on my firstview, i want to print "apples" and when i tap on second view i wan to print "oranges"
Below you can see my code and here is github repo for you to play with my code: https://github.com/TimurAykutYildirim/demoView/tree/multiple-instance
ViewController.h
#import <UIKit/UIKit.h>
#import "Mini.h"
#interface ViewController : UIViewController <SelectionProtocol>
#property (weak, nonatomic) IBOutlet Mini *miniView;
#property (weak, nonatomic) IBOutlet Mini *miniView2;
#end
ViewController.m
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.miniView.delegate = self;
self.miniView2.delegate = self;
}
-(void) isClicked {
NSLog(#"apples");
NSString * storyboardName = #"Main";
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:storyboardName bundle: nil];
UIViewController * vc = [storyboard instantiateViewControllerWithIdentifier:#"SecondViewController"];
[self presentViewController:vc animated:YES completion:nil];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
Mini.h
#import <UIKit/UIKit.h>
#protocol SelectionProtocol;
#interface Mini : UIView
#property (nonatomic, weak) id<SelectionProtocol> delegate;
- (IBAction)btnClick:(id)sender;
#end
#protocol SelectionProtocol <NSObject>
#required
-(void) isClicked;
#end
Mini.m
#import "Mini.h"
#implementation Mini
- (instancetype)initWithCoder:(NSCoder *)aDecoder {
if (self = [super initWithCoder:aDecoder]) {
[self load];
}
return self;
}
- (instancetype)initWithFrame:(CGRect)frame {
if (self = [super initWithFrame:frame]) {
[self load];
}
return self;
}
- (void)load {
UIView *view = [[[NSBundle bundleForClass:[self class]] loadNibNamed:#"Mini" owner:self options:nil] firstObject];
[self addSubview:view];
view.frame = self.bounds;
}
- (IBAction)btnClick:(id)sender {
if ([self.delegate conformsToProtocol:#protocol(SelectionProtocol)]) {
[self.delegate isClicked];
}
}
#end
There are lots of ways that you could do that. Here are two:
Add a sender parameter to your -[ViewController isClicked] method, and change Mini so that calls to -isClicked pass in a pointer to self. Then the code in -isClicked can compare that to each of the instances of Mini that it knows about, i.e. self.miniView and self.miniView2, to see if either of those is the one that sent the message.
Add a property to Mini that lets you distinguish between the two, e.g. name. You can configure that property in -viewDidLoad, like self.miniView.name = #"apples", or you can even do it in the .xib file using "user defined runtime attributes." Then you can have Mini pass it's name property as a parameter to methods that need to know which instance of Mini is the caller. (Or, combine 1 & 2 and pass a reference to self so that ViewController can examine the name parameter or anything else it wants.)
I'm assuming from your question that somewhere in the Mini xib there is an outlet with the text "apples" (or whichever fruit for that particular xib).
In that case, you can just change your protocol to:
- (void)isClickedFromView:(Mini *)mini
In the delegate (ViewController.m) change the btnClick action to:
- (IBAction)btnClick:(id)sender {
if ([self.delegate conformsToProtocol:#protocol(SelectionProtocol)]) {
[self.delegate isClickedFromView:self];
}
}
Add an outlet like fruitLabel to your Mini class.
#property (weak, nonatomic) IBOutlet UILabel *fruitLabel
Now when the delegate gets the call you can call:
NSLog(#"Fruit: %#", mini.fruitLabel.text);
===== Additional answer for if the data (in this case fruits) is available in code =====
If you have the data programmatically already (like an array of fruits), It might be easier to just put the Mini classes in an array ordered the same way.
So if miniViewArray contains an array of your Mini classes,
and fruitArray contains an array of NSStrings of fruits you can do:
At the time you set the miniView's delegate you can add them to the array..something like:
NSArray *fruitArray = #[ #"apples", #"oranges" ];
NSArray *miniViewArray = #[ miniView, miniView2 ];
Then in the delegate call you can do (Using the same protocol change as above):
- (void)isClickedFromView:(Mini *)mini {
NSInteger fruitIndex = [miniViewArray indexOfObject:mini];
NSString fruitName = fruitArray[fruitIndex];
NSLog(#"Fruit: %#", fruitName);
}
I use ENUM for distinguish between the view type.
typedef NS_ENUM(NSUInteger, <#MyViewType#>) {
<#MyViewTypeDefault#>,
<#MyViewTypeA#>,
<#MyViewTypeB#>,
};
#property (nonatomic, assign) MyEnum viewType;
Protocol:
-(void) isClickedForViewType:(MyEnum)viewType;
Common approach for calling delegate method is to include caller as a param. In your case it should be something like this:
- (IBAction)btnClick:(id)sender {
if ([self.delegate conformsToProtocol:#protocol(SelectionProtocol)]) {
[self.delegate isClickedOnMiniView:self];
}
}
Basically, this convention was created to cover such cases - one object is a delegate of many similar ones.
Check apple docs for examples of this convention:
https://developer.apple.com/documentation/uikit/uitableviewdelegate

Facebook Native Ads FBNativeAdsManagerDelegate implementation methods did not called

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

custom deleget not responding ToSelector

Following is my code, there is no error but selector is not responding.
Code in ExampleTableviewSubProductDetail.h
#protocol EnterAmountDelegate <NSObject>
-(void)titlechange:(NSInteger)amount;
#end
#class ASIFormDataRequest;
#interface ExampleTableviewSubProductDetail : UIViewController<UIScrollViewDelegate>
{
}
#property (nonatomic, strong) id <EnterAmountDelegate>delegate;
Code in ExampleTableviewSubProductDetail.m
#implementation ExampleTableviewSubProductDetail
#synthesize delegate;
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
if([delegate respondsToSelector:#selector(titlechange:)])
{
//send the delegate function with the amount entered by the user
[delegate titlechange:20];
}
code in HostProductdetailViewController.h
#import "ViewPagerController.h"
#import "ExampleTableviewSubProductDetail.h"
#interface HostProductdetailViewController : ViewPagerController <ViewPagerDataSource, ViewPagerDelegate, EnterAmountDelegate>
{
}
code in HostProductdetailViewController.m
- (void)viewDidLoad {
[super viewDidLoad];
self.dataSource = self;
self.delegate = self;
}
-(void)titlechange:(NSInteger)amount
{
NSLog(#"sdfsf");
}
In the viewwillapper following Line always return false
if([delegate respondsToSelector:#selector(titlechange:)])
Please let me know if i am missing anything.
Thanks
When pushing from HostProductdetailViewController to ExampleTableviewSubProductDetail you need to set the exampleTableviewSubProductDetail.delegate = self
As I see some other potentially dangerous things in your code try checking this example. It consists of 2 simple classes which are connected via delegate. Watch out for strong references on delegates as this code of yours will produce a retain cycle and cause a memory leak.
Protocol:
// defining a custom protocol
#protocol PingProtocol <NSObject>
- (void)didPing;
#end
Ping class:
//
// This class will be able to send notifications via delegate for the protocol PingProtocol
// Any object that implements PingProtocol will be able to assign itself to the delegate property and will be notified to all protocol methods
//
#interface PingClass : NSObject
// The listener object that implements PingProtocol
// Note this should be weak or there will a retain cycle
#property (nonatomic, weak) id<PingProtocol> delegate;
#end
#implementation PingClass
// Some event that happens will check if the delegate actually implements this method and call it.
// The respondsToSelector is not necessary in this case since the method is not optional though.
- (void)onEvent:(id)sender
{
if([self.delegate respondsToSelector:#selector(didPing)])
{
[self.delegate didPing];
}
}
// Will create a timer which will call onEvent: every second.
// Note there should be some way to invalidate the timer as this will cause a memory leak for the PingClass
- (void)startPing
{
[NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:#selector(onEvent:) userInfo:nil repeats:YES];
}
#end
Listener:
//
// This class will listen to PingProtocol methods.
// It will need to implement all non-optional methods defined by PingProtocol
//
#interface ListenerClass : NSObject<PingProtocol>
#property (nonatomic, strong) PingClass *someClass;
#end
#implementation ListenerClass
// will create a PingClass object and asign itself as a delegate to start listening to delegate methods
- (void)startListening
{
self.someClass = [[PingClass alloc] init];
self.someClass.delegate = self;
[self.someClass startPing];
}
// A protocol method
- (void)didPing
{
NSLog(#"Ping");
}
#end
Most likely you are missing self:
if([self.delegate respondsToSelector:#selector(titlechange:)])
You need to watch out for these things. The delegate in your case is closer to a function pointer then an actual object. You might also be able access it via _delegate as well.

Moving to and fro modal view inside TabBarController

hi i am working on an app and all was going good till now.... i am stuck at this point..
here is my storyboard snapshot..
in the DemoTableViewController when i clock on "filters" button .. Brands TableViewController is opened modally .
after user select multiple rows in Brands TableViewController ,, he then clicks on done button and view controller is dismissed by this code:
-(IBAction)DonePressed:(id)sender {
[self dismissViewControllerAnimated:YES completion:nil];
}
I am storing the user selections in NSMutableSet and it is to be Used in DemoTableViewController so that i can reload the table rows according to the selection but i dont know how to send NSMutableSet to DemoTableViewController and then reload the table according to selection..
what is the right way to dismiss modal view and reload the parent DemoTableViewController
i know i am not doing it correctly but can anyone help me in doing it...
here is some code ---
DemoTVC.h
#import <UIKit/UIKit.h>
#import "MyModelClass.h"
#import "brandsTableViewController.h"
#interface demoTableViewController : UITableViewController<UITableViewDataSource,UITableViewDelegate,MyModelProtocol,FilterProtocol>
#property (strong, nonatomic) IBOutlet UITableView *demoTable;
- (IBAction)FilterPressed:(id)sender;
#end
DemoTVC.m--
the method which performs segue--
- (IBAction)FilterPressed:(id)sender {
[self performSegueWithIdentifier:#"FilterPressed" sender:self];
}
the delegate method which is called to get the values from BrandsTVC--
-(void)GetTheSet:(NSMutableSet *)MySet{
[self dismissViewControllerAnimated:YES completion:nil];
}
viewdidLoad--
- (void)viewDidLoad
{
[super viewDidLoad];
productArray = [[NSMutableArray alloc] init];
homeModel = [[MyModelClass alloc] init];
// Set this view controller object as the delegate for the home model object
homeModel.delegate = self;
// Call the download items method of the home model object
[homeModel downloadItemswithurl:#"url is written here"];
}
BrandsTVC.h---
#import <UIKit/UIKit.h>
#import "MyModelClass.h"
#protocol FilterProtocol <NSObject>
-(void)GetTheSet:(NSMutableSet *) MySet;
#end
#interface brandsTableViewController : UITableViewController<UITableViewDataSource,UITableViewDelegate,MyModelProtocol>
#property (strong, nonatomic) IBOutlet UITableView *RetailerList;
#property (strong,nonatomic) NSMutableSet *selectStates;
#property (nonatomic, weak) id<FilterProtocol> delegate;
- (IBAction) DonePressed:(id)sender;
#end
BrandsTVC.m---
#interface brandsTableViewController ()
{
MyModelClass *myModelClass;
NSMutableArray *BrandsArray;
brandsTableViewController *Delegate;
}
#end
viewDidLoad----
- (void)viewDidLoad
{
[super viewDidLoad];
BrandsArray = [[NSMutableArray alloc] init];
self.selectStates=[NSMutableSet new];
myModelClass = [[MyModelClass alloc] init];
// Set this view controller object as the delegate for the home model object
myModelClass.delegate = self;
// Call the download items method of the home model object
[myModelClass downloadItemswithurl:#"url to get json"];
self.tableView.allowsMultipleSelection = YES;
}
Done Button is called ---
- (IBAction)DonePressed:(id)sender {
[self dismissViewControllerAnimated:YES completion:nil];
id<FilterProtocol> strongDelegate = self.delegate;
if ([strongDelegate respondsToSelector:#selector(GetTheSet:)]) {
[strongDelegate GetTheSet:self.selectStates];
}
}
#end
You can keep those elements in NSUserDefaults, and whenever DemoTableViewController appears, you send [tableView reloadData]. Do this in the viewDidAppear: method.
You can also use Core Data, but there are a lot of details to explain how to do that.
After a lot of trial and error i come to know that in BrandsTVC--
- (IBAction)DonePressed:(id)sender {
NSLog(#"done pressed %#",self.delegate);
[delegate GetTheSet:self.selectStates];
}
self.delegate is giving me NULL.
delegate is not setup and i cant figure out how to do that.. someone help me..
this answer solved my problem :D
custom viewcontroller delegate not working

delegate = nil, transfer information between VCs issue

I just started to learn obj-c and I have question about delegates. I know that on SOF is a lot of similar threads, but I was looking for and really didn't get my issue (maybe cause I'm beginner). Here's my problem: I want to use my own delegate and transfer an information from SlaveClass to MainClass. In SlaveClass in buttonDidClick: action, I declare delegate which is equal to NIL. Even I don't know where I should start to looking for mistake. Thanks in advance for any type of advice. Here's my code which refer to delegate:
SlaveClass.h
#protocol slaveDelegate <NSObject>
-(void)transferNameDidClick:(NSString *)text;
#end
// --------------------------------------------------------------------------------
#interface SlaveClass : UIViewController
#property (nonatomic, strong) id <slaveDelegate> myOwnDelegate;
#end
SlaveClass.m (here appears NIL)
-(void)buttonDidClick:(id)sender
{
if ([_myOwnDelegate respondsToSelector:#selector(transferNameDidClick:)])
{
[_myOwnDelegate transferNameDidClick:(_textField.text)];
}
}
MainClass.h
#interface MainClass : UIViewController <slaveDelegate>
#end
MainClass.m
-(void)transferNameDidClick:(NSString *)text
{
SlaveClass *delegate = [[SlaveClass alloc] init];
[delegate setMyOwnDelegate:self];
[_label setText:text];
NSLog(#"text: %#",text);
}
You are setting your delegate in wrong place. You have to set the delegate before going to slaveClass
mainClass.m
Present slave view controller like this
SlaveClass *slaveClass = [[SlaveClass alloc] init]
[slaveClass setMyOwnDelegate:self];
[self presentViewController:slaveClas animated:YES completion:nil];
-(void)transferNameDidClick:(NSString *)text
{
// This is the method getting called by the slaveClass. So it should know the delegate to call this.
[_label setText:text];
NSLog(#"text: %#",text);
}
Set you delegate out side the Custom delegate method. you are mistakenly setting inside the custom delegate method thats y delegate show nil. use like this.
Main Class .M
-(IBAction)nextView
{
nextView = [[ViewController2 alloc]init];
nextView.myOwnDelegate = self;
[self presentViewController:nextView animated:YES completion:nil];
}
-(void)transferNameDidClick:(NSString *)text;
{
NSLog(#"Value from Slave Delegate %#",text);
}
SlaveClass.h
#protocol slaveDelegate <NSObject>
-(void)transferNameDidClick:(NSString *)text;
#end
// --------------------------------------------------------------------------------
#interface SlaveClass : UIViewController
#property (nonatomic, strong) id <slaveDelegate> myOwnDelegate;
#end
SlaveClass.m
-(void)buttonDidClick:(id)sender
{
if ([_myOwnDelegate respondsToSelector:#selector(transferNameDidClick:)])
{
[_myOwnDelegate transferNameDidClick:(_textField.text)];
}
}

Resources