如何使用完成处理程序方法运行for循环?

时间:2018-05-05 00:11:24

标签: ios swift dji-sdk

我需要使用DJI SDK从无人机获取一些图像文件,但我完成它的方式似乎并不是最理想的。我想知道我怎么能做到这一点,但在一个for循环内部。这是代码:

func getImages(with file: DJIMediaFile?) {
    guard let file = file else { return }
    file.fetchPreview { (error) in
        if error != nil {
            print(String(describing: error?.localizedDescription))
            return
        }

        guard let image = file.preview else { print("No preview"); return }
        self.images.append(image)
        self.imageView.image = image
        self.index += 1

        if self.index < self.mediaList.count {
            self.getImages(with: self.mediaList[self.index])
        } else {
            // [...]
        }

       }
   }
}

熟悉DJI SDK和Swift的人(或许我应该使用其他一些API方法?)会感激任何帮助。谢谢!

1 个答案:

答案 0 :(得分:0)

这主要是一个快速的问题而不是DJI SDK问题,而且与代码审查有关。但它只是

func getNewImages() {
    for file in self.mediaList where file != nil { 
        self.getImages(with: file!) { image, error in //not ideal to force unwarp but i don't know if the where clause supports if let binding, or if file is really nil, you'll have to check yourself in code
            guard let newImage = image else { return }
            self.cachedImages.append(newImage)
        }
    }

    self.setImage(at: 0)
}

func getImages(with file: DJIMediaFile, completion: (UIImage?, Error?)->()) {
    file.fetchPreview { (error) in // is this async? If its' async you may want to use dispatch groups in the for in loop to run the setImage at the correct time
        if let newError = error {
            print(String(describing: newError.localizedDescription))
            completion(nil, error)
            return
        }

        guard let image = file.preview else { 
            print("No preview")
            completion(nil, nil)
            return
        }

        completion(image, nil)
   }
}

func setImage(at row: Int) {
     guard row < self.cachedImages.count - 1 else { return }
     self.imageView.image = self.cachedImages[row]
}

您的递归可能会导致您不想要的错误。这是你想要做的事情,但根据我在这里看到的内容,它应该很容易改变。

编辑:当人们从无人机本身加载图像时,您可能还打算替换该文件,在这种情况下代码更像是这样:

func getNewImages() {
    for file in self.mediaList where file != nil { 
        self.getImages(with: file!) { image, error in //not ideal to force unwarp but I don't know if the where clause supports if let binding, or if file is really nil, you'll have to check yourself in code
            guard let newImage = image else { return }
            self.imageView.image = newImage
        }
    }  
}

func getImages(with file: DJIMediaFile, completion: (UIImage?, Error?)->()) {
    file.fetchPreview { (error) in
        if let newError = error {
            print(String(describing: newError.localizedDescription))
            completion(nil, error)
            return
        }

        guard let image = file.preview else { 
            print("No preview")
            completion(nil, nil)
            return
        }

        completion(image, nil)
   }
}

edit2:另请注意,这不一定是执行此操作的最佳方式,但之前就是如何在for循环中执行此操作。我认为更好的方法是在mediaList数组本身上使用map或forEach。 (相同的getImages方法,没有任何变化)。这可以在协议,扩展和不知道你的程序之间进一步完善,但很难做出更好的建议。

func getNewImages() {
    self.mediaList.forEach { file in
        guard let newFile = file else { return }

        self.getImages(with: newFile) { image, error in
            guard let newImage = image else { return }
            self.imageView.image = newImage
        }
    }  
}