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];
Related
I'm working on an app that has to load some images and data from server on every launch (to make sure it's using up-to-date info). I'm using Firestore as a DB and currently storing images in it as an URL to Firebase storage.
Is it somehow possible to store an actual image in Firestore? And how can I cache loaded image? Either from
UIImage(contentsOf: URL)
or from Firestore?
Try this Asynchronous image downloader with cache support as a UIImageView category - http://cocoadocs.org/docsets/SDWebImage
It is called sdwebimage really easy to use
I don't know if that's the most efficient way of solving my problem but I did it the following way:
In my Firestore DB I stored references to images in Cloud Storage. Then when app starts for the first time, it loads those files from Firestore DB using default methods AND saves those images in app's container (Documents folder) using Swift's FileManager().
Next time the app starts, it goes through references array and skips the files which are already in app's container.
You could use the bytes type in Firestore (see a list of types) to save whatever binary data you want (use NSData on iOS), but this is almost certainly not what you actually want to do. The limit for the size of an entire document is 1 MB, and images can easily exceed that. Also, you'll be paying the cost of downloading that image to the client any time that document is read, which could be wasteful.
You'll be far better off storing the actual file data in Cloud Storage (using the Firebase SDK on the client), then storing a reference or URL to that in the document, and fetch it from there only when needed.
You could use https://github.com/pinterest/PINRemoteImage, this framework use https://github.com/pinterest/PINCache
import PINRemoteImage
extension UIImageView {
public func setImageFrom(urlString: String!, animated: Bool = false) {
guard let urlString = urlString else {
return
}
guard let url = URL(string: urlString) else {
return
}
layer.removeAllAnimations()
pin_cancelImageDownload()
image = nil
if !animated {
pin_setImage(from: url)
} else {
pin_setImage(from: url, completion: { [weak self] result in
guard let _self = self else { return }
_self.alpha = 0
UIView.transition(with: _self, duration: 0.5, options: [], animations: { () -> Void in
_self.image = result.image
_self.alpha = 1
}, completion: nil)
})
}
}
}
....
UIImageView(). setImageFrom(urlString: "https://ssssss")
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
I'm working on local parse with swift 3.0
I'm doing querys to get results from server. but if there's no connection it wont show last results we got because losing connection.
so what i want to do is to save query results to view it if there is no connection
this is the query:
var query = PFUser.query()
query = PFQuery(className: "_User")
// query?.fromLocalDatastore()
query!.whereKey("objectId", equalTo: PFUser.current()!.objectId!)
query!.findObjectsInBackground {
(objects , error) -> Void in
if error == nil {
for object in objects! {
self.usernamelbl.text = object["username"] as! String
if let userp = PFUser.current()?["photo"] as? PFFile {
userp.getDataInBackground {
(imageData, error) -> Void in
if error == nil {
self.profilepic.image = UIImage(data: imageData!)!
}
}
}
}
Now how can i save the results and view them offline also if app closed?
Any help will be appreciated
It's possible to set the caching policy of specific PFQuery calls. To save a copy to disk, and rely on that before making another network hit, you set the kPFCachePolicyCacheElseNetwork policy.
However according to this Parse question, there is apparently a pretty strict limit on the size these caches are allowed to be. I'm not sure if those still apply in the open source version of Parse, but if you want to save more information to disk, it might be appropriate to use a more dedicated data persistence framework, like Core Data, SQLite, or Realm (Full disclosure: I work for Realm. :) )
For the purposes of image files, I'd recommend you manually manage the caching of those on disk, instead of storing it in Parse's cache (Due to the size constraints). There are some great image caching libraries out there (Like PINCache) that make it very easy.
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.
I want to save and then later retrieve the images I'm saving to my tmp folder, this is my first time using the file-system so please bear with me if I'm hopeless.
Right now, I'm saving the images that are being retrieved like this:
let userImageFile = object["Image"] as PFFile
userImageFile.getDataInBackgroundWithBlock { (imageData: NSData!, error: NSError!) -> Void in
if error == nil {
image = UIImage(data:imageData)
let imageToSave:NSData = UIImagePNGRepresentation(image)
let path = NSTemporaryDirectory() + "MyFile"
imageToSave.writeToFile(path, atomically: true)
}
}
Assuming this is the correct way to save it I also want to retrieve the images. How do I create a reference to the file I want to retrieve. I've only used the userDefaults before, and there you add a name to the file you're saving, I can't see how you would do it when saving to the tmp-folder.
Any suggestions on how to solve this would be appreciated.
Use the path you've created already to retrieve the image later, you can save this path in the userDefaults for instance, or in an array or whatever you like if you don't need it to be stored.
let tempImage = UIImage(contentsOfFile: path)
Make sure you save the image with a suffix though, .png for instance, so the method understands that the what type of image the file is.
Remember to check if there is still an image at the location, as there is no guarantee that the image is there still, since it's in the NSTemporaryDirectory(). I'd recommend reading this article on the subject of temporary directories.