I am working on an iPhone app. In this app I have used many images and I need to store those images in cache memory. For this I have found SDWebImage is the right framework but I can not include this framework in my iPhone project. Can anyone please suggest how to include this framework in my project and how to save and retrieve images using this framework?
Go to
SDWebImage frame work download Site.
-Click on Zip tag and download the archive.
-Unarchive the file.
-You will find the "SDWebImage" folder.
-see that path and add this folder in your project. (don't forget to take copy of folder in your project instead of jusk linking).
So far GOOD.
Goto your view controller and add
#import <SDWebImage/UIImageView+WebCache.h>
#import "UIImageView+WebCache.h"
and use imageview method like below.
UIImageView *imageView = [[UIImageView alloc] init];
[imageView setImageWithURL:[NSURL URLWithString:#"ImageURL here"]];
[imageView release];
You can view image even after you close and reopen the application because of caching.
Even you can delete cache when you wish by,
clearCache and clearDisk method in Manager
And you can trace each image by tracing NSdictionary in sourcecode(Check if you interested).
And best thing is you can easily add progressbar on image view while image is under downloading.
For more Info - SDWebImage Doc
Keep Enjoy Coding. By the way great question(Even useful for beginners)
And thanks for rs for great framework.
Last compiled framework is 3.6.0 and you can find it in:
https://github.com/rs/SDWebImage/releases
For easier access, the direct link to the framework is below:
https://github.com/rs/SDWebImage/releases/download/3.6/SDWebImage-3.6.framework.zip
Related
I'm using a photo viewer and i wan't to implement a trash button.
I already have the button ready and everything is good to go but the following:
How do I actually delete the ALAsset??
I tried searching in many places but couldn't find an answer...
Thanks,
For some reason i'm not allowed to post this question so i'm adding an irrelevant code of my trash button:
UIBarButtonItem *trash = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemTrash target:self action:#selector(trashButtonHit:)];
You can't delete an ALAsset, there is no API for this.
An ALAsset is link to a file in the Photo library, which is outside of the sandbox of your app. The assets library allows you the acces the file in the photo library but they are read only.
ALAssets are not read only:
editable
Indicates whether the asset is editable. (read-only)
#property(nonatomic, readonly, getter=isEditable) BOOL editable
And the documentation goes on to describe how to edit an ALAsset (your app must have created it). But the documentation offers no 'delete'. This is kind of silly, as your app could edit the photo down to a 1x1 px image, or a 'skull and crossbones', etc.
I think what happens is that Apple saves the original, so you can't delete the image, only edit it.
I can see what Apple is driving at - they don't want Applications to delete photos and 'surpise' the user. But some applications might want to have their own editing facilities, including a trash can.
The answer, then is to recreate the entire camera roll interface in your own app, and store images in your own storage.
I use the SDWebImage image downloading/caching library pretty much any time I display an image in a table view.
I would usually implement it like so (in a table view cellForRowAtIndexPath method).
[cell.imageView setImageWithURL:
[NSURL URLWithString:#"http://asite.com/animage.jpg"]
placeholderImage:[UIImage imageNamed:#"placeholder.png"]];
And that would load a cached version if it had one.
What about if I wanted to use the simplicity of SDWebImage (with the placeholder / robust downloading code) - but without the cache in just one place.
I know how to disable caching throughout SDWebImage, but I don't know how you would call setImageWithUrl: placeholderImage: making sure that SDWebImage doesn't use any cache?
The reason I want to do this is I'm using it to display webcams in a table view (obviously, you want this updated every time).
I recommend moving away from the Category on UIImageView and creating your own version of SDWebImageManager. You'd get more control if you use the class SDImageCache yourself.
Heres and example right from SDWebImageManager itself:
[[SDImageCache sharedImageCache] storeImage:image
imageData:downloader.imageData
forKey:[downloader.url absoluteString]
toDisk:NO];
toDisk is probably where I changed the BOOL to NO, the default manager uses disk caching. You may also want to clear the memory every so often to support your streaming images:
[[SDImageCache sharedImageCache] clearMemory];
The SDWebImageManager code is easy to follow and I imagine you won't need to reinvent most of it, just a few important portions to suit your needs.
Here you go. Make sure you get the latest version of SDWebImage:
[anImageView setImageWithURL:[NSURL URLWithString:#"http://asite.com/animage.jpg"]
placeholderImage:[UIImage imageNamed:#"placeholder.png"]
options:SDWebImageCacheMemoryOnly];
From SDWebImageManager.h:
/**
* This flag disables on-disk caching
*/
SDWebImageCacheMemoryOnly = 1 << 2,
Swift 4.2
Xcode: 10.0
SDWebImage: ~>4.0
SDImageCache.shared().config.shouldCacheImagesInMemory = false
You just need to use the shouldCacheImagesInMemory property from SDImageCache and set it to NO.
This feature available in 3.7.4+.
You can use SDWebImageDownloader. It doesn't cache data.
You should use SDWebImageManager.shared.loadImage with fromLoaderOnly option
I am building a photo album app and find a few image caching libraries, namely:
JMImageCache
HJCache
SDWebImage
What one you'd recommend (or other libs not on the list)? I am looking for:
Efficiency
Minimum effort in terms of garbage collection
Support for Blocks preferred
Thanks
Personally, I think SDWebImage is the best because it is an absolute no-effort solution, and provides the simplest mechanism for cache handling as it is simply an extension of the UIImageView class.
Image async downloading and caching is not a simple task. It needs to be done well otherwise it will defeat its purpose. Therefore I strongly suggest that eventually you build your own. Having said that, I needed a quick and simple solution in order to move forward with the development of my application.
I found these solutions:
HJCache
SDWebImage
Apple's LazyTableImages
An adaption from Apple's LazyTableImages,MHLazyTableImages
I tried HJCache, but it didn't offer great scrolling performance when handling large images (1.5M+). For small images it worked great though. Tried both LazyTableImages as well but the integration wasn't simple.
Ultimately, I chose SDWebImage. The integration couldn't be simpler. Once you have linked the library to your project all you need to do is:
[cell.imageView setImageWithURL:[NSURL URLWithString:#"http://www.domain.com/path/to/image.jpg"]
placeholderImage:[UIImage imageNamed:#"placeholder.png"]];
in your tableView:cellForRowAtIndexPath:.
Additionally:
Works with custom cells as well
Doesn't block the UI
Offers great scrolling performance
Image downloading and caching is seamless.
There are multiple frameworks that solve this problem. Just to name a few:
Swift:
Nuke (mine)
Kingfisher
AlamofireImage
HanekeSwift
Objective-C:
AFNetworking
PINRemoteImage
YYWebImage
SDWebImage
Try also APSmartStorage. It automatically caches UIImage/NSData on disk or in memory.
It has cute Blocks–style API;
// setup data parsing block
APSmartStorage.sharedInstance.parsingBlock = ^(NSData *data, NSURL *url)
{
return [UIImage imageWithData:data scale:UIScreen.mainScreen.scale];
};
...
// show some progress/activity
...
// load object with URL
[APSmartStorage.sharedInstance loadObjectWithURL:imageURL callback:(id object, NSError *error)
{
// hide progress/activity
if (error)
{
// show error
}
else
{
// do something with object
}
}];
It's quite smart and still simple:
I tried using SDWebImage.
Agreed that it is very easy to integrate.
However the big issue with this library is that it does not honour "max-age" cache control.
The library is still under development but they are not picking this limitation.
I strongly recommend you to try Kingfisher and SDWebImage. Both works perfectly for downloading and caching images from the web.
Moa
Moa is an image download library written in Swift. It allows to download and show an image in an image view by setting its moa.url property.
Installation
Use CocoaPods to add Moa to your project. Just add the following line to your Podfile.
pod 'moa', '~> 8.0'
Does anyone know of a good tutorial that shows how to lazy load images in a UITableView? I've searched online but the only one I found that looked like it did what I wanted was hard to follow because only parts of the code were shown and I'm new at this so I didn't understand how to hook everything up.
I suggest you check out the SDWebImage project on github, I use it for my table views when I need to load a remote image into the cells.
https://github.com/rs/SDWebImage
As Daniel suggested SDWebImage https://github.com/rs/SDWebImage, I don't know of any tutorial, but in amongst the KTPhotoBrowser samples there is one that uses SDWebImage that can show you how to do it https://github.com/kirbyt/KTPhotoBrowser/tree/master/src/Sample/Classes/SDWebImageSample
If I remember correctly you need to import and use the SDWebImage UIImageView category and then pass the url to the cell and call
setImageWithURL:[NSURL URLWithString:#"yoururl"] placeholderImage:[UIImage imageNamed:#"placeholder.png"]
when setting the cell image.
I haven't actually followed it, but this one has plenty of positive commentary: http://www.markj.net/iphone-asynchronous-table-image/
In Xcode I use targets to release several apps versions which share some base code and tend to have different graphics.
i.e. Pretending I have target JOHN and target DOE. I could add different images named exactly example.png to the bundle, and have each one targeted respectively. The code does not need any changes this way.
UIImageView *image = [UIImageView alloc] initWithImage:[UIImage imageNamed:#"example.png"]];
If instead I named each image per different version I would end up with something similar to this:
NSString *imageName;
#ifdef JOHN
imageName = #"johnExample.png";
#else
imageName = #"doeExample.png";
#endif
UIImageView *image = [UIImageView alloc] initWithImage:[UIImage imageNamed:imageName]];
Having several versions and many images this quickly becomes messy and having a huge file with constants looks to me like an overkill, so I end up with the first option.
The problem is:
While working on nibs files, Interface Builder just appears to load example.png randomly. So if I'm working on target JOHN it's an annoyance that IB just decided to load example.png from the DOE target.
There's any way for Interface Builder to load media based on a target?
Just to close this question, the answer is: no.
As of Jan '11, you can't load media based on a target on Interface Builder, but you could use some workarounds, as Digital Robot and my own description in the question pointed out.
why not have this define at the beginning of the code
#ifdef JOHN
#define APP #"john"
#elseif DOE
#define APP #"doe"
#endif
and then, every time you want to use this, you may have...
imagename = [NSString stringWithFormat:#"%#Example.png", APP];
That should work. This may be new because some time has passed and I just learned that recently. Don't know wether this was possible ages ago when you acutally asked this question :) But it may be useful for others searching for a solution.
When adding a target to a project within xcode then it creates a subfolder in the file system. There is one subfolder for each of the taragts. The basic idea is, as far as I understand it, that all commonly used files are on the upper level in the project main directory and those that are individual to each target are in their respective directory.
(A bit like localized versions of files.)
So you may put the image of John as example.png in /project/john and the image of Doe as example.png in /project/doe.
You should double check that the correct versions of each image are included in the build settings for each of the targets respectively. (Copy Boundle Resources)
Doing so "example.png" is included only once in the boundle. Randomly loading of one image or the other should not longer happen, although you refer to it as "example.jpg" within your code.