I have released AFImageDownloader to the open source community. It, asynchronously, downloads JPEGs from the Internet and decompresses them on a background queue.
[AFImageDownloader imageDownloaderWithURLString:@"http://static.ashfurrow.com./github/worked.jpg" autoStart:YES completion:^(UIImage *decompressedImage) {
self.imageView.image = decompressedImage;
}];
Network calls obviously take a long time and must not be performed on the main thread. JPEG decompression can actually take a long time if it’s performed on a large image or on small images very frequently. It can be a common cause of performance problems.
What I’m really excited about is that it is the first Objective-C project I’ve developed using strict TDD/BDD using Kiwi. Until I was completely finished writing the code, I had only tested it using unit tests — never letting it touch the Internet at all. The first time I ran it, it worked perfectly.
(While I think that blindly adhering to TDD may not be a wise choice for iOS development, I wanted to see if I were up to the challenge.)
Kiwi encourages Behaviour-Driven Development. While the setup is a little arduous, it was a joy to work with.
describe(@"Image downloader", ^{
NSString *urlString = @"http://example.com/image.jpeg";
__block AFImageDownloader *imageDownloader;
context(@"has been newly created", ^{
beforeEach(^{
imageDownloader = [[AFImageDownloader alloc] initWithURLString:urlString autoStart:NO completion:nil];
});
it (@"should create a new URL connection when started", ^{
[[imageDownloader should]
receive:@selector(urlRequestForURLString)];
[[imageDownloader should]
receive:@selector(urlConnectionForURLRequest:)];
[imageDownloader start];
});
it (@"should return a URL request with the proper URL string", ^{
NSURLRequest *request = [imageDownloader urlRequestForURLString];
[[request.URL.absoluteString should] equal:urlString];
});
it (@"should start the new URL connection", ^{
[imageDownloader start];
});
it (@"should be set it state to started when started", ^{
NSURLConnection *urlConnectionMock = [NSURLConnection mock];
[[urlConnectionMock should] receive:@selector(start)];
[imageDownloader stub:@selector(urlConnectionForURLRequest:)
andReturn:urlConnectionMock];
[[imageDownloader should]
receive:@selector(setState:) withArguments:theValue(AFImageDownloaderStateStarted), nil];
[imageDownloader start];
});
});
});
I’m looking for any feedback you have about the code, the structure of the project, or the testing I’ve performed.