| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220 |
- //
- // MWPhoto.m
- // MWPhotoBrowser
- //
- // Created by Michael Waterfall on 17/10/2010.
- // Copyright 2010 d3i. All rights reserved.
- //
- #import "MWPhoto.h"
- #import "MWPhotoBrowser.h"
- #import "EMSDWebImageDecoder.h"
- #import "EMSDWebImageManager.h"
- #import "EMSDWebImageOperation.h"
- #import <AssetsLibrary/AssetsLibrary.h>
- @interface MWPhoto () {
- BOOL _loadingInProgress;
- id <EMSDWebImageOperation> _webImageOperation;
-
- }
- - (void)imageLoadingComplete;
- @end
- @implementation MWPhoto
- @synthesize underlyingImage = _underlyingImage; // synth property from protocol
- #pragma mark - Class Methods
- + (MWPhoto *)photoWithImage:(UIImage *)image {
- return [[MWPhoto alloc] initWithImage:image];
- }
- // Deprecated
- + (MWPhoto *)photoWithFilePath:(NSString *)path {
- return [MWPhoto photoWithURL:[NSURL fileURLWithPath:path]];
- }
- + (MWPhoto *)photoWithURL:(NSURL *)url {
- return [[MWPhoto alloc] initWithURL:url];
- }
- #pragma mark - Init
- - (id)initWithImage:(UIImage *)image {
- if ((self = [super init])) {
- _image = image;
- }
- return self;
- }
- // Deprecated
- - (id)initWithFilePath:(NSString *)path {
- if ((self = [super init])) {
- _photoURL = [NSURL fileURLWithPath:path];
- }
- return self;
- }
- - (id)initWithURL:(NSURL *)url {
- if ((self = [super init])) {
- _photoURL = [url copy];
- }
- return self;
- }
- #pragma mark - MWPhoto Protocol Methods
- - (UIImage *)underlyingImage {
- return _underlyingImage;
- }
- - (void)loadUnderlyingImageAndNotify {
- // NSAssert([[NSThread currentThread] isMainThread], @"This method must be called on the main thread.");
- if (_loadingInProgress) return;
- _loadingInProgress = YES;
- @try {
- if (self.underlyingImage) {
- [self imageLoadingComplete];
- } else {
- [self performLoadUnderlyingImageAndNotify];
- }
- }
- @catch (NSException *exception) {
- self.underlyingImage = nil;
- _loadingInProgress = NO;
- [self imageLoadingComplete];
- }
- @finally {
- }
- }
- // Set the underlyingImage
- - (void)performLoadUnderlyingImageAndNotify {
-
- // Get underlying image
- if (_image) {
-
- // We have UIImage!
- self.underlyingImage = _image;
- [self imageLoadingComplete];
-
- } else if (_photoURL) {
-
- // Check what type of url it is
- if ([[[_photoURL scheme] lowercaseString] isEqualToString:@"assets-library"]) {
-
- // Load from asset library async
- dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
- @autoreleasepool {
- @try {
- ALAssetsLibrary *assetslibrary = [[ALAssetsLibrary alloc] init];
- [assetslibrary assetForURL:self->_photoURL
- resultBlock:^(ALAsset *asset){
- ALAssetRepresentation *rep = [asset defaultRepresentation];
- CGImageRef iref = [rep fullScreenImage];
- if (iref) {
- self.underlyingImage = [UIImage imageWithCGImage:iref];
- }
- [self performSelectorOnMainThread:@selector(imageLoadingComplete) withObject:nil waitUntilDone:NO];
- }
- failureBlock:^(NSError *error) {
- self.underlyingImage = nil;
- MWLog(@"Photo from asset library error: %@",error);
- [self performSelectorOnMainThread:@selector(imageLoadingComplete) withObject:nil waitUntilDone:NO];
- }];
- } @catch (NSException *e) {
- MWLog(@"Photo from asset library error: %@", e);
- [self performSelectorOnMainThread:@selector(imageLoadingComplete) withObject:nil waitUntilDone:NO];
- }
- }
- });
-
- } else if ([_photoURL isFileReferenceURL]) {
-
- // Load from local file async
- dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
- @autoreleasepool {
- @try {
- self.underlyingImage = [UIImage imageWithContentsOfFile:self->_photoURL.path];
- if (!self->_underlyingImage) {
- MWLog(@"Error loading photo from path: %@", _photoURL.path);
- }
- } @finally {
- [self performSelectorOnMainThread:@selector(imageLoadingComplete) withObject:nil waitUntilDone:NO];
- }
- }
- });
-
- } else {
-
- // Load async from web (using SDWebImage)
- @try {
- EMSDWebImageManager *manager = [EMSDWebImageManager sharedManager];
- _webImageOperation = [manager downloadImageWithURL:_photoURL
- options:0
- progress:^(NSInteger receivedSize, NSInteger expectedSize) {
- if (expectedSize > 0) {
- float progress = receivedSize / (float)expectedSize;
- NSDictionary* dict = [NSDictionary dictionaryWithObjectsAndKeys:
- [NSNumber numberWithFloat:progress], @"progress",
- self, @"photo", nil];
- [[NSNotificationCenter defaultCenter] postNotificationName:MWPHOTO_PROGRESS_NOTIFICATION object:dict];
- }
- }
- completed:^(UIImage *image, NSError *error, EMSDImageCacheType cacheType, BOOL finished, NSURL *imageURL) {
- if (error) {
- MWLog(@"SDWebImage failed to download image: %@", error);
- }
- self->_webImageOperation = nil;
- self.underlyingImage = image;
- [self imageLoadingComplete];
- }];
- } @catch (NSException *e) {
- MWLog(@"Photo from web: %@", e);
- _webImageOperation = nil;
- [self imageLoadingComplete];
- }
-
- }
-
- } else {
-
- // Failed - no source
- @throw [NSException exceptionWithName:@"" reason:nil userInfo:nil];
-
- }
- }
- // Release if we can get it again from path or url
- - (void)unloadUnderlyingImage {
- _loadingInProgress = NO;
- self.underlyingImage = nil;
- }
- - (void)imageLoadingComplete {
- // NSAssert([[NSThread currentThread] isMainThread], @"This method must be called on the main thread.");
- // Complete so notify
- _loadingInProgress = NO;
- // Notify on next run loop
- [self performSelector:@selector(postCompleteNotification) withObject:nil afterDelay:0];
- }
- - (void)postCompleteNotification {
- [[NSNotificationCenter defaultCenter] postNotificationName:MWPHOTO_LOADING_DID_END_NOTIFICATION
- object:self];
- }
- - (void)cancelAnyLoading {
- if (_webImageOperation) {
- [_webImageOperation cancel];
- _loadingInProgress = NO;
- }
- }
- @end
|