Swift 2 Parse and KingFisher cache images - swift

I'm using KingFisher https://github.com/onevcat/Kingfisher
library so i can cache the images and if there is anyone familiar with it i want some hints.
So i have the following code
let myCache = ImageCache(name: recipesClass.objectId!)
let queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)
let optionInfo: KingfisherOptionsInfo = [
.DownloadPriority(0.5),
.CallbackDispatchQueue(queue),
.Transition(ImageTransition.Fade(1)),
.TargetCache(myCache)
]
if let imageFile = recipesClass[RECIPES_COVER] as? PFFile {
let URL = NSURL(string: imageFile.url!)!
cell.coverImage.kf_setImageWithURL(URL, placeholderImage: nil,
optionsInfo: optionInfo,
progressBlock: { receivedSize, totalSize in
print("\(indexPath.row + 1): \(receivedSize)/\(totalSize)")
},
completionHandler: { image, error, cacheType, imageURL in
print("\(indexPath.row + 1): Finished")
})
} else {
cell.coverImage.image = UIImage(named:"logo")
}
When i first enter the View it loads normally the images with this good anymation. But i also have a refresh button which makes a query to Parse and it checks if there is any new Recipe and then it reloads the data from the collection view and it prints "Finished"
Does this means that it downloads the images again? Or it loads them from Cache??
I'm asking because it appends the images in a different way inside the cells rather than the first time that it loads.
Any idea?
P.S. what i want to do is that in each cell i want to cache the image with the object ID of each recipe so when the cell loads and it has the image cached with this unique object id, to load it from cache and not to download it.

try this code:
var imageView:UIImageView!
let mCa = ImageCache(name: "my_cache")
let imagePath = getImagePath("image url")
imageView.kf_setImageWithURL(NSURL(string: imagePath)!,placeholderImage: UIImage(named: "DefaultImageName"),optionsInfo: [.TargetCache(mCa)])

Related

Download image from URL and save it to Core Data swift

There is I am trying to download image from URL and save it to variable of model. But it's not setting the image. Inside setImage I saw that it's downloading some data. URL's are checked and working. But when I check it for nil it's showing "empty input", "empty output".
let inputImage = UIImageView()
let outputImage = UIImageView()
DispatchQueue.main.async {
let inputURL = URL(string: "someURL")
let outputURL = URL(string: "someURL")
inputImage.kf.setImage(with: inputURL)
outputImage.kf.setImage(with: outputURL)
}
let coreDataModel = CoreDataModel()
if let inputImageData = inputImage.image?.pngData()
{ cloudAnalysisModel.input_image = inputImageData }
else
{ print("empty input") }
if let outputImageData = outputImage.image?.pngData()
{ coreDataModel.output_image = outputImageData }
else
{ print("empty output") }
I think you have not understood how asynchronous programming works. The block or completionHandler (the one that starts with { and ends with }) gets executed after url is called and response is obtained
What I mean to say here is , that block maybe executed at any time and the code after that is executed right away i.e the code from let coreDataModel onwards
So it is obvious that both the inputImageData and outputImageData are going to be null
Now coming to the solutions:
What you could do is:
Shift all the code inside the callback block instead of keeping it outside and show the user some progressbar or UI
Use DispatchGroup which keeps track of the DispatchQueue More info here

how to assign a URL to imageView in swift?

I have JSON response for image after a post request
"profile_picture": "uploads/profile_pictures/18/file.jpeg"
if I combine the base URL and "profile_picture" url I can have the image // browsing on the web page
http://ms.XXX.net/uploads/profile_pictures/18/file.jpeg
I want to store that image url to a UIImageView and show that image on ImageView.Please guide me how do I do that. Below is how im trying.
image = "http://ms.XXX.net/"+"\(LoginSingleton.shared.pathImage!)"
imageView.image = image as? UIImage
It would be ideal to use third party frameworks like SDWebImage, Kingfisher etc. for better user experience. But you can do it without them by getting the data from url asynchronously and then set the image.
guard let url = URL(string: "image-url") else { return }
DispatchQueue.global().async {
guard let data = try? Data(contentsOf: url) else { return }
DispatchQueue.main.async {
let image = UIImage(data: data)
// Set the image to your image view
}
}

Swift load images asynchronously for SearchTextField

I use the SearchTextField library for having an AutoComplete text edit. It works like a charm but I have an issue. I have more than 200 records to list. I have to fetch all images from an URL. Thus, my code below works very slowly.
What I want to do is fetching images from the web asynchronously and run this library quickly. I found some solutions to load images asynchronously like SDWebImage and Kingfisher but they need UIImageView, not UIImage, therefore I cannot use them.
Any idea will be appreciated.
This is my code scrap for creating SearchTextField
var item = [SearchTextFieldItem]()
//I have more than 100 records in my UserList
for key in UsersList {
var imgUser : UIImage? = nil
let url = URL(string: key.ProfilePicture)
let data = try? Data(contentsOf: url!)
if ( data == nil) {
imgUser = UIImage(named: "UserIcon")
} else {
imgUser = UIImage(data:data!)
}
item.append(SearchTextFieldItem(title: key.Name!, subtitle: key.EMail,image: imgUser))
}
mySearchTextField.filterItems(item)

how to get image from Json in Swift

i'm a baby of xcode developer, and i really need a help. Below is one of my json data, that i have print in output, for the text i already got display into my screen, but now i'm trying to get the image from the server, and i don't know how to do it.
JSON :
"MoviePhotoL" : "\/Data\/UploadFile\/cnymv-01_1.jpg",
"MoviePhotoP" : "\/Data\/UploadFile\/cnymv-02_1.jpg"
XCODE:
let userImage = iP["MoviePhotoP"] as? String
cell.imageView.image = userImage (??????)
i know that String cannot be converted into UIImage, and i already try to convert it to NSData and convert the NSData to UIImage(data), but still not get the picture :'(.... can somebody please help me?? i really need some help
Those paths seem relative to another source.
You need to generate or get an absolute URL that will let you access the image.
Right now you have a simple string and that's all, you can't convert this to data or image.
You need a string that you can put in a browser and load an image.
Once you're able to do that, you can load the image in your app.
Example:
func getImage(from string: String) -> UIImage? {
//2. Get valid URL
guard let url = URL(string: string)
else {
print("Unable to create URL")
return nil
}
var image: UIImage? = nil
do {
//3. Get valid data
let data = try Data(contentsOf: url, options: [])
//4. Make image
image = UIImage(data: data)
}
catch {
print(error.localizedDescription)
}
return image
}
//1. Get valid string
let string = "https://images.freeimages.com/images/large-previews/f2c/effi-1-1366221.jpg"
if let image = getImage(from: string) {
//5. Apply image
cell.imageView.image = image
}
NOTE: Data(contentsOf:options:) is synchronous and can reduce performance. The larger the image, the longer it will lock it's thread.
Generally you would do such intensive tasks in a background thread and update UI on the main thread, but... to keep this answer simple, I chose not to show that.

Swift: image cache not working as expected

I am trying to use image cache in swift but nothing works as expected. I have tried NSCache and AlamofireImage but both didn't work for me. I did not get any error with code but when I tried to fetch image from cache it always returns nil.
I guess the image is not saved in cache. Can someone here share some links with example on how to use image caching in swift or ios?
What you can do is download images in background thread. When image is downloaded save it an Object and update you'r main thread too. For displaying image next time you can directly load image from the cache.
Below I'm sharing my code
var imageCache = NSMutableDictionary()
if let img = imageCache.valueForKey("key") as? UIImage{
imageView.image = img
}
else{
let session = NSURLSession.sharedSession()
let task = session.dataTaskWithURL(NSURL(string: imgURL!)!, completionHandler: { (data, response, error) -> Void in
if(error == nil){
let img = UIImage(data: data!)
imageCache.setValue(img, forKey: "key") // Image saved for cache
dispatch_async(dispatch_get_main_queue(), { () -> Void in
//Update your image view
})
}
})
task.resume()
}
Hope so this may help you
You can use this as a disk and memory cache, if you implemented downloading image mechanism. You can specify cache size, expire time
https://github.com/huynguyencong/DataCache
Or you can use Kingfisher as a image caching library