J'ai eu quelques problèmes téléchargés images de mon drone directement à mon application. Je reçois toujours un "Le système est occupé, veuillez réessayer plus tard." (Code: -1004) "Message d'erreur lorsque vous essayez de télécharger l'image, j'ai vérifié le forum DJI et d'autres questions ici sur stackoverflow toute solution à ce problème.Comment télécharger par programme des images à partir du drone à l'aide de l'IOS DJI-SDK
J'ai déjà jeté un oeil à this question, mais j'utilise déjà la technique suggérée par cette réponse.
Voici la fonction que j'ai écrit pour télécharger les images:
func downloadFilesFromDrone(){
// get current product
guard let drone = DJISDKManager.product() else {
Logger.logError("Product is connected but DJISDKManager.product is nil when attempting to download media")
return
}
// Get camera on drone
guard let camera: DJICamera = drone.camera else {
Logger.logError("Unable to detect Camera in downloadFilesFromDrone()")
// make recursive call until we are able to detect the camera
DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
Logger.logH1("Trying to detect Camera again")
self.downloadFilesFromDrone()
}
return
}
Logger.logH1("Successfully detected the camera")
// check if we can download images with the product
if !camera.isMediaDownloadModeSupported() {
Logger.logError("Product does not support media download mode")
return
}
// switch camera mode to allow for media downloads
camera.setMode(.mediaDownload, withCompletion: {(error) in
if error != nil {
print("\(error!.localizedDescription)")
}
else {
// get the media manager from the drone to gain access to the files
let manager = camera.mediaManager!
manager.refreshFileList(completion: { (error) in
if error != nil {
print("State: \(manager.fileListState.rawValue)")
print("Error refreshing list: \(error!.localizedDescription)")
}
else {
Logger.logH1("Refreshed file list")
print("State: \(manager.fileListState.rawValue)")
guard let files = manager.fileListSnapshot() else {
Logger.logError("No files to download")
return
}
Logger.logH1("There are files to download")
var images: [UIImage] = []
for file in files {
if file.mediaType == .JPEG {
print("Time created: \(file.timeCreated)")
DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
file.fetchData(withOffset: 0, update: DispatchQueue.main, update: {(_ data: Data?, _ isComplete: Bool, _ error: Error?) -> Void in
if error != nil {
print("State: \(manager.fileListState.rawValue)")
print("Error downloading photo: \(error!)")
}
else {
// unwrap downloaded data and create image
if let data = data, let downloadedImage = UIImage(data: data) {
print("Image was downloaded!")
images.append(downloadedImage)
}
}
}) // end of filedata fetch
}
}
} // end of loop
}
}) // end of file-refresh block
}
})// end of camera setMode block
}
Et voici la sortie de cette fonction lors du test avec mon drone:
*** Product Connected ***
*** Unable to detect Camera in downloadFilesFromDrone() ***
*** Firmware package version is: Unknown ***
--> Trying to detect Camera again
--> Successfully detected the camera
--> Refreshed file list
State: 0
--> There are files to download
Time created: 2017-09-01 15:17:04
Time created: 2017-09-01 15:17:16
Time created: 2017-09-01 15:17:26
Time created: 2017-09-01 15:17:36
Time created: 2017-09-01 15:19:06
State: 0
Error downloading photo: System is busy, please retry later.(code:-1004)
State: 0
Error downloading photo: System is busy, please retry later.(code:-1004)
State: 0
Error downloading photo: System is busy, please retry later.(code:-1004)
State: 0
Error downloading photo: System is busy, please retry later.(code:-1004)
Edit:
Voici le code que j'ai utilisé pour télécharger des images du drone.
/**
* This function downloads the N latest images from the drone and passes them to the completionhandler once all images have completed downloading
*/
func downloadImages(files: [DJIMediaFile], howMany: Int, maxErrors: Int, completion: @escaping ([UIImage]) -> Void){
Logger.logH1("Queueing \(howMany) image(s) to be downloaded")
func downloadNextImage(files: [DJIMediaFile], fileCount: Int, index: Int = 0, downloadedFiles: [UIImage] = [], errorCount: Int = 0) {
// stop when we reach the end of the list
if index == fileCount {
completion(downloadedFiles)
return
}
else {
var imageData: Data?
let file = files[index]
file.fetchData(withOffset: 0, update: DispatchQueue.main, update: {(_ data: Data?, _ isComplete: Bool, _ error: Error?) -> Void in
if let error = error {
Logger.logError("\(error)")
if errorCount < maxErrors {
DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
Logger.logH1("Attempting to download: \(file.fileName) again")
downloadNextImage(files: files, fileCount: fileCount, index: index, downloadedFiles: downloadedFiles, errorCount: errorCount + 1)
}
}
else {
Logger.logError("Too many errors downloading the images, try downloading again")
}
}
else {
// if image is done downloading
if isComplete {
// get full image data
if let imageData = imageData, let image = UIImage(data: imageData) {
Logger.logH1("Downloaded: \(file.fileName)")
// now that the image is done downloading, move onto the next image
downloadNextImage(files: files, fileCount: fileCount, index: (index + 1), downloadedFiles: downloadedFiles + [image], errorCount: 0)
}
}
// else, download the file
else {
// If image exists, append the data
if let _ = imageData, let data = data {
imageData?.append(data)
}
// initialize the image data
else {
imageData = data
}
}
}
}) // end of filedata fetch
} // end of else statement
}
// bounds checking
let available = files.count
let n = howMany > available ? available : howMany
// grab the N latest images taken by the drone
let filesToDownload : [DJIMediaFile] = Array (files.suffix(n))
// start the recursive function
downloadNextImage(files: filesToDownload, fileCount: filesToDownload.count)
}
Et voici comment l'appeler:
// get current product
guard let drone = DJISDKManager.product() else {
Logger.logError("Product is connected but DJISDKManager.product is nil when attempting to download media")
return
}
// Get camera on drone
guard let camera: DJICamera = drone.camera else {
Logger.logError("Unable to detect Camera in initDownload()")
return
}
Logger.logH1("Successfully detected the camera")
// check if we can download images with the product
if !camera.isMediaDownloadModeSupported() {
Logger.logError("Product does not support media download mode")
return
}
// switch camera mode to allow for media downloads
camera.setMode(.mediaDownload, withCompletion: {(error) in
if error != nil {
print("\(error!.localizedDescription)")
}
else {
// get the media manager from the drone to gain access to the files
let manager = camera.mediaManager!
manager.refreshFileList(completion: { (error) in
if error != nil {
print("State: \(manager.fileListState.rawValue)")
print("Error refreshing list: \(error!.localizedDescription)")
}
else {
Logger.logH1("Refreshed file list")
print("State: \(manager.fileListState.rawValue)")
// get list of files
guard let files = manager.fileListSnapshot() else {
Logger.logError("No files to download")
return
}
Logger.logH1("There are files to download.. Beginning Download")
self.downloadImages(files: files, howMany: waypoints, maxErrors: 4, completion: { images in
Logger.logH1("Finished downloading: \(images.count) image(s)")
// do something with the images here
})
}
}) // end of file-refresh block
}
})// end of camera setMode block
Avez-vous téléchargé la version de travail de la fonction pour l'exhaustivité? – IanTimmis
@IanTimmis J'ai mis à jour ma question avec la solution que j'ai utilisée. En passant, la fonction peut ne pas détecter la caméra sur le premier appel, vous devez essayer plusieurs appels avant que la caméra est détectée. –