Skip to content

Commit

Permalink
Optimise the demo #10 #12
Browse files Browse the repository at this point in the history
  • Loading branch information
Kjuly committed Sep 22, 2013
1 parent 5d267f5 commit 230725d
Show file tree
Hide file tree
Showing 2 changed files with 157 additions and 145 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,11 @@
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>1.0.5</string>
<string>1.1.3</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>105</string>
<string>113</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>UIRequiredDeviceCapabilities</key>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,7 @@
#import "PhotosTableViewController.h"

#import "PhotoViewController.h"

#import "ALAssetsLibrary+CustomPhotoAlbum.h"

#import <MobileCoreServices/MobileCoreServices.h>


Expand All @@ -21,25 +19,28 @@

@interface PhotosTableViewController () {
@private
ALAssetsLibrary * assetsLibrary_;
NSMutableArray * photos_;
ALAssetsLibrary * assetsLibrary_;
NSMutableArray * photos_;
UIImagePickerController * picker_;
PhotoViewController * photoViewController_;
}

@property (nonatomic, strong) ALAssetsLibrary * assetsLibrary;
@property (nonatomic, copy) NSMutableArray * photos;
@property (nonatomic, strong) ALAssetsLibrary * assetsLibrary;
@property (nonatomic, copy) NSMutableArray * photos;
@property (nonatomic, strong) UIImagePickerController * picker;
@property (nonatomic, strong) PhotoViewController * photoViewController;

- (void)_takePhoto:(id)sender;
- (BOOL)_startCameraControllerFromViewController:(UIViewController *)controller
usingDelegate:(id <UIImagePickerControllerDelegate,
UINavigationControllerDelegate>)delegate;

@end


@implementation PhotosTableViewController

@synthesize assetsLibrary = assetsLibrary_;
@synthesize photos = photos_;
@synthesize assetsLibrary = assetsLibrary_;
@synthesize photos = photos_;
@synthesize picker = picker_;
@synthesize parentViewController = photoViewController_;

- (id)initWithStyle:(UITableViewStyle)style
{
Expand Down Expand Up @@ -71,7 +72,6 @@ - (void)viewDidLoad
target:self
action:@selector(_takePhoto:)];
[takePhotoButton setStyle:UIBarButtonItemStyleBordered];
// [navigationController_.navigationItem setRightBarButtonItem:takePhotoButton];
[self.navigationItem setRightBarButtonItem:takePhotoButton];
}

Expand All @@ -83,7 +83,54 @@ - (void)viewDidUnload
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];

// Dispose of any resources that can be recreated.
assetsLibrary_ = nil;
picker_ = nil;
photoViewController_ = nil;
}

#pragma mark - Custom Getter

- (ALAssetsLibrary *)assetsLibrary
{
if (assetsLibrary_) {
return assetsLibrary_;
}
assetsLibrary_ = [[ALAssetsLibrary alloc] init];
return assetsLibrary_;
}

- (UIImagePickerController *)picker
{
if (picker_) {
return picker_;
}

picker_ = [[UIImagePickerController alloc] init];
picker_.sourceType = UIImagePickerControllerSourceTypeCamera;

// Displays a control that allows the user to choose picture or
// movie capture, if both are available:
//picker.mediaTypes =
// [UIImagePickerController availableMediaTypesForSourceType:UIImagePickerControllerSourceTypeCamera];
picker_.mediaTypes = [NSArray arrayWithObject:(NSString *)kUTTypeImage];

// Hides the controls for moving & scaling pictures, or for
// trimming movies. To instead show the controls, use YES.
picker_.allowsEditing = NO;
picker_.delegate = self;

return picker_;
}

- (PhotoViewController *)photoViewController
{
if (photoViewController_) {
return photoViewController_;
}
photoViewController_ = [[PhotoViewController alloc] init];
return photoViewController_;
}

#pragma mark - Table view data source
Expand Down Expand Up @@ -119,11 +166,10 @@ - (UITableViewCell *)tableView:(UITableView *)tableView
- (void) tableView:(UITableView *)tableView
didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
PhotoViewController * photoViewController = [[PhotoViewController alloc] init];
[self.navigationController pushViewController:photoViewController animated:NO];
[self.navigationController pushViewController:self.photoViewController animated:NO];

// Get image from Custom Photo Album for the selected photo url.
__weak PhotoViewController * weakPhotoViewController = photoViewController;
__weak PhotoViewController * weakPhotoViewController = self.photoViewController;
[self.assetsLibrary assetForURL:[NSURL URLWithString:[self.photos objectAtIndex:indexPath.row]]
resultBlock:^(ALAsset *asset) {
//
Expand All @@ -145,155 +191,121 @@ - (void) tableView:(UITableView *)tableView
// Take photo
- (void)_takePhoto:(id)sender
{
if (! [self _startCameraControllerFromViewController:self
usingDelegate:self]) {
UIAlertView * alertView = [UIAlertView alloc];
(void)[alertView initWithTitle:@"Camera Unavailable"
message:@"Sorry, camera unavailable for the current device."
delegate:self
cancelButtonTitle:@"Cancel"
otherButtonTitles:nil, nil];
[alertView show];
if (! [UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) {
[[[UIAlertView alloc] initWithTitle:@"Camera Unavailable"
message:@"Sorry, camera unavailable for the current device."
delegate:self
cancelButtonTitle:@"Cancel"
otherButtonTitles:nil, nil] show];
return;
}
return;
}

// verifies the prerequisites are satisfied by way of its method signature
// and a conditional test, and goes on to instantiate, configure,
// and asynchronously present the camera user interface full screen
- (BOOL)_startCameraControllerFromViewController:(UIViewController *)controller
usingDelegate:(id <UIImagePickerControllerDelegate,
UINavigationControllerDelegate>)delegate
{
if (([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera] == NO)
|| delegate == nil
|| controller == nil) return NO;

UIImagePickerController * picker = [[UIImagePickerController alloc] init];
picker.sourceType = UIImagePickerControllerSourceTypeCamera;

// Displays a control that allows the user to choose picture or
// movie capture, if both are available:
//picker.mediaTypes =
// [UIImagePickerController availableMediaTypesForSourceType:UIImagePickerControllerSourceTypeCamera];
picker.mediaTypes = [NSArray arrayWithObject:(NSString *)kUTTypeImage];

// Hides the controls for moving & scaling pictures, or for
// trimming movies. To instead show the controls, use YES.
picker.allowsEditing = NO;
picker.delegate = delegate;

[controller presentModalViewController:picker animated:YES];

// No need to release here, as it'll be released after camera action done
// in |imagePickerControllerDidCancel:| method
// [picker release];
return YES;
if ([self.navigationController respondsToSelector:
@selector(presentViewController:animated:completion:)])
{
[self.navigationController presentViewController:self.picker animated:YES completion:nil];
} else {
[self.navigationController presentModalViewController:self.picker animated:YES];
}
}

#pragma mark - UIImagePickerController Delegate

// For responding to the user tapping Cancel.
- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker
{
// Prior to iOS 5.0, if a view did not have a parent view controller
// and was being presented modally, the view controller that was presenting
// it would be returned.
// This is no longer the case. You can get the presenting view controller
// using the presentingViewController property.
//
// Guess |parentViewController| is nil on iOS 5 and that is why the controller
// will not dismiss.
// Replacing |parentViewController| with |presentingViewController| will fix
// this issue.
//
// However, you'll have to check for the existence of presentingViewController
// on UIViewController to provide behavior for iOS versions < 5.0
if ([picker respondsToSelector:@selector(presentingViewController)])
[[picker presentingViewController] dismissModalViewControllerAnimated:YES];
else
[[picker parentViewController] dismissModalViewControllerAnimated:YES];
if ([self.navigationController respondsToSelector:
@selector(presentViewController:animated:completion:)])
{
[picker dismissViewControllerAnimated:YES completion:nil];
} else {
// Prior to iOS 5.0, if a view did not have a parent view controller
// and was being presented modally, the view controller that was presenting
// it would be returned.
// This is no longer the case. You can get the presenting view controller
// using the presentingViewController property.
//
// Guess |parentViewController| is nil on iOS 5 and that is why the controller
// will not dismiss.
// Replacing |parentViewController| with |presentingViewController| will fix
// this issue.
//
// However, you'll have to check for the existence of presentingViewController
// on UIViewController to provide behavior for iOS versions < 5.0
if ([picker respondsToSelector:@selector(presentingViewController)]) {
[[picker presentingViewController] dismissModalViewControllerAnimated:YES];
} else {
[[picker parentViewController] dismissModalViewControllerAnimated:YES];
}
}
}

// For responding to the user accepting a newly-captured picture or movie
- (void)imagePickerController:(UIImagePickerController *)picker
didFinishPickingMediaWithInfo:(NSDictionary *)info
{
// dismiss image picker view
// Dismiss image picker view
[self dismissModalViewControllerAnimated:YES];

// manage the media (photo)
// Manage the media (photo)
NSString * mediaType = [info objectForKey:UIImagePickerControllerMediaType];

// Handle a still image capture
if (CFStringCompare((CFStringRef)mediaType, kUTTypeImage, 0) == kCFCompareEqualTo) {
// manage tasks in background thread
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
UIImage * imageToSave = nil;
UIImage * editedImage = (UIImage *)[info objectForKey:UIImagePickerControllerEditedImage];
if (editedImage) imageToSave = editedImage;
else imageToSave = (UIImage *)[info objectForKey:UIImagePickerControllerOriginalImage];

UIImage * finalImageToSave = nil;
/* Modify image's size before save it to photos album
*
* CGSize sizeToSave = CGSizeMake(imageToSave.size.width, imageToSave.size.height);
* UIGraphicsBeginImageContextWithOptions(sizeToSave, NO, 0.f);
* [imageToSave drawInRect:CGRectMake(0.f, 0.f, sizeToSave.width, sizeToSave.height)];
* finalImageToSave = UIGraphicsGetImageFromCurrentImageContext();
* UIGraphicsEndImageContext();
*/
finalImageToSave = imageToSave;

/*/ Get the image metadata
UIImagePickerControllerSourceType pickerType = picker.sourceType;
if (pickerType == UIImagePickerControllerSourceTypeCamera) {
NSDictionary * imageMetadata = [info objectForKey:UIImagePickerControllerMediaMetadata];
NSLog(@"%@", imageMetadata);
// Get the assets library
ALAssetsLibrary * library = [[ALAssetsLibrary alloc] init];
ALAssetsLibraryWriteImageCompletionBlock imageWriteCompletionBlock =
^(NSURL *newURL, NSError *error) {
if (error) {
NSLog( @"Error writing image with metadata to Photo Library: %@", error );
} else {
NSLog( @"Wrote image with metadata to Photo Library");
}
};
// Save the new image (original or edited) to the Camera Roll
[library writeImageToSavedPhotosAlbum:[finalImageToSave CGImage]
metadata:imageMetadata
completionBlock:imageWriteCompletionBlock];
}*/

// The completion block to be executed after image taking action process done
void (^completion)(NSURL *, NSError *) = ^(NSURL *assetURL, NSError *error) {
if (error) NSLog(@"!!!ERROR, write the image data to the assets library (camera roll): %@",
[error description]);
NSLog(@"*** URL %@ | %@ || type: %@ ***", assetURL, [assetURL absoluteString], [assetURL class]);
// Add new item to |photos_| & table view appropriately
NSIndexPath * indexPath = [NSIndexPath indexPathForRow:self.photos.count
inSection:0];
[self.photos addObject:[assetURL absoluteString]];
CFStringRef mediaTypeRef = (__bridge CFStringRef)mediaType;
if (CFStringCompare(mediaTypeRef,
kUTTypeImage,
kCFCompareCaseInsensitive) != kCFCompareEqualTo)
{
CFRelease(mediaTypeRef);
return;
}
CFRelease(mediaTypeRef);

// Manage tasks in background thread
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
UIImage * imageToSave = nil;
UIImage * editedImage = (UIImage *)[info objectForKey:UIImagePickerControllerEditedImage];
if (editedImage) imageToSave = editedImage;
else imageToSave = (UIImage *)[info objectForKey:UIImagePickerControllerOriginalImage];

UIImage * finalImageToSave = nil;
/* Modify image's size before save it to photos album
*
* CGSize sizeToSave = CGSizeMake(imageToSave.size.width, imageToSave.size.height);
* UIGraphicsBeginImageContextWithOptions(sizeToSave, NO, 0.f);
* [imageToSave drawInRect:CGRectMake(0.f, 0.f, sizeToSave.width, sizeToSave.height)];
* finalImageToSave = UIGraphicsGetImageFromCurrentImageContext();
* UIGraphicsEndImageContext();
*/
finalImageToSave = imageToSave;

// The completion block to be executed after image taking action process done
void (^completion)(NSURL *, NSError *) = ^(NSURL *assetURL, NSError *error) {
if (error) NSLog(@"!!!ERROR, write the image data to the assets library (camera roll): %@",
[error description]);
NSLog(@"*** URL %@ | %@ || type: %@ ***", assetURL, [assetURL absoluteString], [assetURL class]);
// Add new item to |photos_| & table view appropriately
NSIndexPath * indexPath = [NSIndexPath indexPathForRow:self.photos.count
inSection:0];
[self.photos addObject:[assetURL absoluteString]];
dispatch_async(dispatch_get_main_queue(), ^{
[self.tableView insertRowsAtIndexPaths:@[indexPath]
withRowAnimation:UITableViewRowAnimationFade];
};

void (^failure)(NSError *) = ^(NSError *error) {
if (error == nil) return;
NSLog(@"!!!ERROR, failed to add the asset to the custom photo album: %@", [error description]);
};

// save image to custom photo album
if (! self.assetsLibrary) assetsLibrary_ = [[ALAssetsLibrary alloc] init];
[self.assetsLibrary saveImage:finalImageToSave
toAlbum:kKYCustomPhotoAlbumName_
completion:completion
failure:failure];
});
}
});
};

void (^failure)(NSError *) = ^(NSError *error) {
if (error == nil) return;
NSLog(@"!!!ERROR, failed to add the asset to the custom photo album: %@", [error description]);
};

// Save image to custom photo album
// The lifetimes of objects you get back from a library instance are tied to
// the lifetime of the library instance.
[self.assetsLibrary saveImage:finalImageToSave
toAlbum:kKYCustomPhotoAlbumName_
completion:completion
failure:failure];
});
}

@end

0 comments on commit 230725d

Please sign in to comment.