简体   繁体   English

DJI无人机未连接(未调用sdkManagerProductDidChange委托方法)

[英]DJI drone not connecting (sdkManagerProductDidChange delegate method not called)

I can't seem to get my own app to connect to a particular drone. 我似乎无法获得自己的应用程序以连接到特定的无人机。 I have downloaded the bridger app and am using it to debug. 我已经下载了bridger应用程序,并正在使用它进行调试。 I copied the "DJIBaseViewController" from the sample app and have made my own view controller a delegate of it. 我从示例应用程序复制了“ DJIBaseViewController”,并将自己的视图控制器作为它的委托。 After adding alot of breakpoints to the code I have found that the major difference between my app and the sample app is that the delegate method "sdkManagerProductDidChange." 在代码中添加了很多断点后,我发现我的应用程序与示例应用程序之间的主要区别在于委托方法“ sdkManagerProductDidChange”。

//  DJIBaseViewController.swift


import UIKit
import DJISDK

protocol DJIProductObjectProtocol {
    func fetchAircraft() -> DJIAircraft?
    func fetchCamera() -> DJICamera?
    func fetchGimbal() -> DJIGimbal?
    func fetchFlightController() -> DJIFlightController?
    func fetchRemoteController() -> DJIRemoteController?
    func fetchBattery() -> DJIBattery?
    func fetchAirLink() -> DJIAirLink?
    func fetchHandheldController() -> DJIHandheldController?
}

class ConnectedProductManager: DJIProductObjectProtocol {
    static let sharedInstance = ConnectedProductManager()

    var connectedProduct:DJIBaseProduct? = nil

    func fetchAircraft() -> DJIAircraft? {
        if (self.connectedProduct == nil) {
            return nil
        }
        if (self.connectedProduct is DJIAircraft) {
            return (self.connectedProduct as! DJIAircraft)
        }
        return nil
    }

    func fetchCamera() -> DJICamera? {
        if (self.connectedProduct == nil) {
            return nil
        }
        if (self.connectedProduct is DJIAircraft) {
            return (self.connectedProduct as! DJIAircraft).camera
        }
        else if (self.connectedProduct is DJIHandheld) {
            return (self.connectedProduct as! DJIHandheld).camera
        }

        return nil
    }

    func fetchGimbal() -> DJIGimbal? {
        if (self.connectedProduct == nil) {
            return nil
        }
        if (self.connectedProduct is DJIAircraft) {
            return (self.connectedProduct as! DJIAircraft).gimbal
        }
        else if (self.connectedProduct is DJIHandheld) {
            return (self.connectedProduct as! DJIHandheld).gimbal
        }

        return nil
    }

    func fetchFlightController() -> DJIFlightController? {
        if (self.connectedProduct == nil) {
            return nil
        }
        if (self.connectedProduct is DJIAircraft) {
            return (self.connectedProduct as! DJIAircraft).flightController
        }
        return nil
    }

    func fetchRemoteController() -> DJIRemoteController? {
        if (self.connectedProduct == nil) {
            return nil
        }
        if (self.connectedProduct is DJIAircraft) {
            return (self.connectedProduct as! DJIAircraft).remoteController
        }
        return nil
    }

    func fetchBattery() -> DJIBattery? {
        if (self.connectedProduct == nil) {
            return nil
        }
        if (self.connectedProduct is DJIAircraft) {
            return (self.connectedProduct as! DJIAircraft).battery
        }
        else if (self.connectedProduct is DJIHandheld) {
            return (self.connectedProduct as! DJIHandheld).battery
        }

        return nil
    }

    func fetchAirLink() -> DJIAirLink? {
        if (self.connectedProduct == nil) {
            return nil
        }
        if (self.connectedProduct is DJIAircraft) {
            return (self.connectedProduct as! DJIAircraft).airLink
        }
        else if (self.connectedProduct is DJIHandheld) {
            return (self.connectedProduct as! DJIHandheld).airLink
        }

        return nil
    }

    func fetchHandheldController() -> DJIHandheldController? {
        if (self.connectedProduct == nil) {
            return nil
        }
        if (self.connectedProduct is DJIHandheld) {
            return (self.connectedProduct as! DJIHandheld).handheldController
        }
        return nil
    }

    func setDelegate(delegate:DJIBaseProductDelegate?) {
        self.connectedProduct?.delegate = delegate
    }

}

class DJIBaseViewController: UIViewController, DJIBaseProductDelegate, DJIProductObjectProtocol {

    //var connectedProduct:DJIBaseProduct?=nil
    var moduleTitle:String?=nil

    override func viewDidLoad() {
        super.viewDidLoad()
        if (moduleTitle != nil) {
            self.title = moduleTitle
        }

        // Do any additional setup after loading the view.
    }


    override func viewWillAppear(animated: Bool) {
        super.viewWillAppear(animated)

        if (ConnectedProductManager.sharedInstance.connectedProduct != nil) {
            ConnectedProductManager.sharedInstance.setDelegate(self)
        }
    }

    override func viewWillDisappear(
        animated: Bool) {
        super.viewWillDisappear(animated)
        if (ConnectedProductManager.sharedInstance.connectedProduct != nil &&
            ConnectedProductManager.sharedInstance.connectedProduct?.delegate === self) {
            ConnectedProductManager.sharedInstance.setDelegate(nil)
        }
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    func product(product: DJIBaseProduct, connectivityChanged isConnected: Bool) {
        if isConnected {
            NSLog("\(product.model) connected. ")
            ConnectedProductManager.sharedInstance.connectedProduct = product
            ConnectedProductManager.sharedInstance.setDelegate(self)

        }
        else {
            NSLog("Product disconnected. ")
            ConnectedProductManager.sharedInstance.connectedProduct = nil
        }
    }

    func componentWithKey(withKey key: String, changedFrom oldComponent: DJIBaseComponent?, to newComponent: DJIBaseComponent?) {
        //     (newComponent as? DJICamera)?.delegate = self
        if ((newComponent is DJICamera) == true && (self is DJICameraDelegate) == true) {
            (newComponent as! DJICamera).delegate = self as? DJICameraDelegate

        }
        if ((newComponent is DJICamera) == true && (self is DJIPlaybackDelegate) == true) {
            (newComponent as! DJICamera).playbackManager?.delegate = self as? DJIPlaybackDelegate
        }

        if ((newComponent is DJIFlightController) == true && (self is DJIFlightControllerDelegate) == true) {
            (newComponent as! DJIFlightController).delegate = self as? DJIFlightControllerDelegate
        }

        if ((newComponent is DJIBattery) == true && (self is DJIBatteryDelegate) == true) {
            (newComponent as! DJIBattery).delegate = self as? DJIBatteryDelegate
        }

        if ((newComponent is DJIGimbal) == true && (self is DJIGimbalDelegate) == true) {
            (newComponent as! DJIGimbal).delegate = self as? DJIGimbalDelegate
        }

        if ((newComponent is DJIRemoteController) == true && (self is DJIRemoteControllerDelegate) == true) {
            (newComponent as! DJIRemoteController).delegate = self as? DJIRemoteControllerDelegate
        }

    }


    func showAlertResult(info:String) {
        // create the alert
        var message:String? = info

        if info.hasSuffix(":nil") {
            message = info.stringByReplacingOccurrencesOfString(":nil", withString: " success")
        }

        let alert = UIAlertController(title: "Message", message: "\(message ?? "")", preferredStyle: .Alert)
        // add an action (button)
        alert.addAction(UIAlertAction(title: "OK", style: .Default, handler: nil))
        // show the alert
        self.presentViewController(alert, animated: true, completion: nil)
    }


    func fetchAircraft() -> DJIAircraft?{
        return ConnectedProductManager.sharedInstance.fetchAircraft()
    }

    func fetchCamera() -> DJICamera? {
        return ConnectedProductManager.sharedInstance.fetchCamera()
    }

    func fetchGimbal() -> DJIGimbal? {
        return ConnectedProductManager.sharedInstance.fetchGimbal()
    }

    func fetchFlightController() -> DJIFlightController? {
        return ConnectedProductManager.sharedInstance.fetchFlightController()
    }

    func fetchRemoteController() -> DJIRemoteController? {
        return ConnectedProductManager.sharedInstance.fetchRemoteController()
    }

    func fetchBattery() -> DJIBattery? {
        return ConnectedProductManager.sharedInstance.fetchBattery()
    }
    func fetchAirLink() -> DJIAirLink? {
        return ConnectedProductManager.sharedInstance.fetchAirLink()
    }
    func fetchHandheldController() -> DJIHandheldController?{
        return ConnectedProductManager.sharedInstance.fetchHandheldController()
    }
}

The first view that loads after the splashscreen loads is. 启动屏幕加载后加载的第一个视图是。

//  MenuViewController.swift
import UIKit
import DJISDK

let enterDebugMode=true

class MenuViewController: DJIBaseViewController {

    @IBOutlet weak var aircraft: UILabel!
    @IBOutlet weak var productID: UILabel!
              // Do any additional setup after loading the view.
    @IBOutlet weak var appConectivity: UILabel!


        var connectedProduct:DJIBaseProduct?=nil
        var componentDictionary = Dictionary<String, Array<DJIBaseComponent>>()

        let APP_KEY = "*******"//Please enter App Key Here
        override func viewDidLoad() {

            super.viewDidLoad()
            let air = self.fetchAircraft()

            if air == nil{
                aircraft.text?="no aircraft connected"
            }
            print(air?.model)
            initUI();

            guard !APP_KEY.isEmpty else {
                showAlert("Please enter your app key.")
                return
            }
            DJISDKManager.registerApp(APP_KEY, withDelegate: self)


            if DJISDKManager.product() == nil{
                productID.text?="Drone Not Connected"
            }
            else{
                productID.text? = "Drone Connected"
            }
        }

        func initUI() {
            self.title = "DJI iOS SDK Sample"
            //sdkVersionLabel.text = "DJI SDK Version: \(DJISDKManager.getSDKVersion())"
            //openComponents.isEnabled = false;
            //bluetoothConnectorButton.isEnabled = true;
            //productModel.isHidden = true
            //productFirmwarePackageVersion.isHidden = true
            //debugModeLabel.isHidden = !enterDebugMode
        }
    func showAlert(msg: String?) {
        // create the alert
        let alert = UIAlertController(title: "", message: msg, preferredStyle: .Alert)
        // add the actions (buttons)
        alert.addAction(UIAlertAction(title: "OK", style: .Default, handler: nil))
        // show the alert
        self.presentViewController(alert, animated: true, completion: nil)
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }



    /*
    // MARK: - Navigation

    // In a storyboard-based application, you will often want to do a little preparation before navigation
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        // Get the new view controller using segue.destinationViewController.
        // Pass the selected object to the new view controller.
    }
    */
}
extension MenuViewController: DJISDKManagerDelegate{

        func sdkManagerDidRegisterAppWithError(error: NSError?) {

            guard error == nil  else {
                self.showAlertResult("Error:\(error!.localizedDescription)")
                appConectivity.text?="app isn't registering properly"
                return
            }

            //Debug("Registered!")

            if enterDebugMode {

                DJISDKManager.enterDebugModeWithDebugId("10.202.38.238")
                print("WTF")
            }else{
                //DJISDKManager.enterDebugModeWithDebugId("10.202.38.238")
                DJISDKManager.startConnectionToProduct()
            }

        }

        func sdkManagerProductDidChange(From oldProduct: DJIBaseProduct?, To newProduct: DJIBaseProduct?) {

            print("entered changed product")
            if oldProduct==nil{
                print("old product is nill")
            }
            if newProduct==nil{
                print("new product is nill")
            }

            guard let newProduct = newProduct else
            {
                appConectivity.text? = "Status: No Product Connected"

                ConnectedProductManager.sharedInstance.connectedProduct = nil
                //logDebug("Product Disconnected")
                return
            }

            //Updates the product's model
            productID.text = "Model: \((newProduct.model)!)"
            productID.hidden = false

            if let oldProduct = oldProduct {
                print("Product changed from: \(oldProduct.model) to \((newProduct.model)!)")
            }
            //Updates the product's firmware version - COMING SOON

            //Updates the product's connection status
            //appConectivity.text = "Status: Product Connected"

            ConnectedProductManager.sharedInstance.connectedProduct = newProduct
            productID.text?="product connected"
            //openComponents.isEnabled = true;
            //openComponents.alpha = 1.0;
            //logDebug("Product Connected")

        }
    override func product(product: DJIBaseProduct, connectivityChanged isConnected: Bool) {

            if isConnected {
                print("Status: Product Connected")
                //appConectivity.text?="Drone Recognized"
            } else {
                print("Status: No Product Connected")
                //appConectivity.text="Atleast Its trying"
            }
        }


    }

The sdkManager is registering properly with the given app key and bundler identifier. sdkManager正在使用给定的应用程序密钥和捆绑程序标识符正确注册。 I have also added "Supported external accessory protocols" to my info.plist file with three elements com.dji.video, com.dji.protocol, and com.dji.common. 我还在我的info.plist文件中添加了“受支持的外部附件协议”,其中包含三个元素com.dji.video,com.dji.protocol和com.dji.common。

Been stuck here for quite some time and it's been damn frustrating. 被困在这里已经有一段时间了,真是令人沮丧。 Hope someone call help. 希望有人打电话帮助。

Thanks in advance. 提前致谢。

I figured it out. 我想到了。 The issue here is that the sample app has named its delegate 这里的问题是示例应用程序已为其委托命名

func sdkManagerProductDidChange(from oldProduct: DJIBaseProduct?, to newProduct: DJIBaseProduct?)

whereas for whatever reason in my sample app the DJISDK knows my delegates function as 而无论出于何种原因,DJISDK都知道我的委托函数是

func sdkManagerProductDidChangeFrom(oldProduct: DJIBaseProduct?, to newProduct: DJIBaseProduct?)

a bit annoying that that made such a big difference but that's what I get for copying code I guess. 有点烦人,这带来了很大的不同,但这就是我猜到的复制代码所得到的。 Hope this is helpful to someone else down the road... 希望这对以后的人有帮助...

Cheers 干杯

PS they may change it again the way I found it is when I typed func into my extension section Xcode spit out a list of functions I could use and the sdkManagerDidChange was one of them with different input variables. PS,当我在扩展部分的Xcode中键入func时,他们可能会再次更改它,方法是吐出我可以使用的功能列表,而sdkManagerDidChange是其中一个具有不同输入变量的函数。

edit: if anyone can explain why it worked on the sample app and not mine that would be sweet too. 编辑:如果有人可以解释为什么它可以在示例应用程序上运行,而不是我认为那也很好。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM