Retrieve images from a DJI Drone with EXIF data - ios

I'm using the DJISDK in iOS to download pictures from the aircraft.
I'm using the downloadSelectedFiles method from PlaybackManager class.
Here is my process callback:
process: { (data, error) in
if data != nil{
if self.downloadedImageData != nil{
self.downloadedImageData!.append(data!)
}else{
self.downloadedImageData = data!
}
}
}
And this is filecompletition callback:
fileCompletion: {
self.downloadedFilesCount += 1
let image = UIImage(data: self.downloadedImageData!)
if let img = image {
self.downloadedImagesArray?.append(img)
}
self.downloadedImageData = nil
}
I'm correctly retrieving the image but without the EXIF data. How can I get that info and add it to the image?
I already downloaded and tried the iOS-MediaManagerDemo and it's the same thing, downloads the image but without the exif data but the official DJI Go app retrieves all the info so thereĀ“s must be some way to do it.

There's also a similar issue in their forums regarding empty metadata and downloadSelectedFilesWithPreparation. The user that created the post
also found a solution:
I solved the problem by not converting the NSData into any format instead saved the NSData directly. Using PHAssets and temporary file to store the NSData as PHAssets only accepts data from URL.
Try using fetchFileDataWithOffset:updateQueue:updateBlock (it will be called fetchFileData(with:updateQueue:updateBlock) in Swift)
[...] fetching the media data will return all data for a video or image
Sample code (objc): here

Related

How do you get the attachment image from a local notification on the Apple Watch?

My Objective-C iOS app schedules a local notification that has a userInfo dictionary and one small JPEG image attachment.
The image is attached like this:
content.attachments = #[[UNNotificationAttachment attachmentWithIdentifier:myIdentifier
URL:[imageURL filePathURL]
options:#{UNNotificationAttachmentOptionsTypeHintKey : UTTypeJPEG}
error:&error]];
This works fine. The notification is correctly scheduled.
If I ignore the Watch and let the notification appear on my phone's Lock Screen, the image is there.
Going back to the Watch. The Watch app receives the notification, and the didReceive method is called in the NotificationController.
No matter what I try, I can't get the image from the notification.
I've tried converting the image to NSData and adding it to the userInfo dictionary, but the data is too large despite the image actually being only a few Kb.
NotificationController.swift: (image is an Image type, and is sent to the NotificationView to use as the background.)
guard let attachment = notification.request.content.attachments.first
else {
print("Couldn't get the first attachment, using default image")
image = Image.init(kDefaultImage)
return
}
// We get here, so we know there's an attachment
if attachment.url.startAccessingSecurityScopedResource() {
let imageData = try? Data.init(contentsOf: attachment.url)
if let imageData = imageData {
image = Image(uiImage: UIImage(data: imageData) ??
UIImage.init(imageLiteralResourceName: kDefaultImageMasked))
}
attachment.url.stopAccessingSecurityScopedResource()
} else {
print("Couldn't access the file, using default")
image = Image.init(kDefaultImageMasked)
}
I always get told I can't access the file in the security scoped bit.
If I take out that check I get Fatal error: Unexpectedly found nil while implicitly unwrapping an Optional value because the code doesn't put anything into image.
Obviously I would put the default image in there instead of crashing, but once the Watch app crashes the notification that's shown on the Watch shows the correct image, but it's obviously not using my NotificationView because that crashed. It's using the standard mirror feature to show the notification, so it's completely bypassing my code at that point.
I've also tried this:
if(attachment.url.isFileURL) {
print("attachment image is a file url")
}
It does print out that it's a file url, and it's: file:///var/mobile/Library/BulletinDistributor/Attachments/com.mycompany.myapp/<UUID>.jpeg.
But this fails, so the file doesn't exist at that path, or I'm not allowed to load files from there (?):
if(FileManager.default.fileExists(atPath: attachment.url.path)) {
...
How do I get the image from the attachment? I've tried getting the image as Data, as an Image, as a UIImage. Nothing works.
This was simple to do in the old Objective-C WatchKit extension stuff:
NSArray *attachments = notification.request.content.attachments;
if(attachments.count == 1) {
[_backgroundGroup setBackgroundImage:attachments[0]];
}
No problems there; it always worked.
Any ideas?

URL of an image that can seen in browser from firebase in Swift

I am creating a iOS swift application that uses an SDK that requires a link to image that can be seen in browser for example http://i.imgur.com/HALb2yN.jpg is acceptable as it does not automatically download.
However for firebase the download URL I get using the code:
let imageRef = String(format: "images/%#", file.identifier)
let testRef = storageRef.child(imageRef)
let uploadTask = testRef.putData(imageData, metadata: nil) { metadata, error in
if (error != nil) {
// Uh-oh, an error occurred!
print(error?.localizedDescription)
} else {
// Metadata contains file metadata such as size, content-type, and download URL.
let downloadURL = metadata!.downloadURL()!.absoluteString
print(downloadURL)
}
}
from downloadURL automatically downloads... I would like to be able to get a link that can be viewed in the from a browser. Is that possible with firebase?
I suspect the issue is that you haven't set any metadata with the image. Therefore Firebase (and your browser) doesn't know that your mystery binary object is an image that can be displayed in-browser instead of some other file that needs to be downloaded.
Try creating a metadata object with the appropriate content-type and use that in your putData call, and I betcha that'll work.

Downloading image from Amazon S3 (using AWS mobile hub helper)

I'm trying to download an image called "aaa.jpeg" in my s3 bucket using AWSMobileHubHelper. I found this function on their documentation site.
func downloadContent(content: AWSContent, pinOnCompletion: Bool) {
content.downloadWithDownloadType( .Always, pinOnCompletion: pinOnCompletion, progressBlock: {(content: AWSContent?, progress: NSProgress?) -> Void in
// Handle progress feedback
}, completionHandler: {(content: AWSContent?, data: NSData?, error: NSError?) -> Void in
if let error = error {
print("Failed to download a content from a server.)")
// Handle error here
return
}
// Handle successful download here
if let image = UIImage(data: data!){
self.imageView = image
}
})
}
Once the download is successful (it Did, There is no error message), I'm trying to assign the image to an imageView.
I can tell that the data has been downloaded successfully. I can print the data and see a familiar binary structure of an image. But for some reasons I can't assign the UIImage to the imageView. Because I can't convert the data to a UIImage.
I just want to know if this is the proper way to download image from s3 or am I missing something. Does "data" in the completion block carry the downloaded image? I can't seem to find any documentations on this.
Is this the correct function to use to download from S3?
Yes, the data contains the actual image data. You can put the downloaded data in an UIImageViewController and it should open up fine. Also, this is demonstrated in a Sample App which can be downloaded from the Mobile Hub Console.

Parse Cloud Code: Retrieve Image Data For iOS App

I'm writing an iOS app with a Parse backend, and amongst other things it will list blog entries.
Each blog entry has an associated image, but I don't want to fetch the image object for each entry and then have to fetch the image file for each of those. So I wrote a cloud function that would combine the two steps and return the raw image data with a single request.
Here's the cloud code:
var imageFile = image.get("photoFile");
Parse.Cloud.httpRequest({ url: imageFile.url()
}).then(function(dataResponse){
response.success(dataResponse.buffer);
});
When I do this, I get back an array of integers, and I don't know where to go from here to get a UIImage. Here's the iOS code I have so far:
PFCloud.callFunctionInBackground(latestImageCloudFunctionName, withParameters: parameters) { (imageData, error) -> Void in
if let data = imageData {
//imageData is of the type [Int]
}
}
Is the image base64 encoded here? How do I get an NSData object from this that will create a UIImage?

How to delete PFFile's cache

I'm using Parse and PFFile and developing iOS app that provide audio contents.
And when I download new mp3 file from cloud, the data look to be saved locally as cache.
Caching itself is good.
But my problem is since each audio content is around 3mb and storage usage of my app keep increasing.
I want to delete old local cache manually.
It is possible? and how can I delete cached files?
[UPDATED]
Heres my code.
Basically I download mp3 data from parse cloud by using getDataInBackgroundWithBlock.
// lessonObj is PFObject
let lessonFile = lessonObj["mp3"] as PFFile
lessonFile.getDataInBackgroundWithBlock {
(mp3Data: NSData!, error: NSError!) -> Void in
if ( error == nil ) {
// next step
} else {
// println("error")
}
}
Thank you!
[PFFile clearAllCachedDataInBackground];
In order to clear the cache you would need to use the following function.
[PFQuery clearAllCachedResults];

Resources