Third part of the Custom Camera App series.
- Custom Camera App – Part 1: Custom Overlay
- Custom Camera App – Part 2: Taking Pictures
- Custom Camera App – Part 3: Assets Library
Welcome to the last installment of our Custom Camera App series! In the second part, we left the app almost finished, with everything ready except for the gallery button.
Today, I will show you how to use the Assets Library to access the iPhone resources and get the last picture taken.
Step 1
First of all, you need to add the Assets Library framework. Go to CustomCamera.xcodeproj in the Project navigator, and in the Summary tab scroll down until Linked Frameworks and Libraries. Click on the plus button and select AssetsLibary.framework.
Step 2
Before you start using this new framework, there is one little modification you need to do in the code from the previous tutorial. As we explained in the last tutorial, there is a method from UIImagePickerController that is called whenever the user takes a picture or selects an existing one from the library. Inside this method, if the user had taken a picture, we only saved the image in the photo library, and reenabled pictureButton.
However, there is one last thing that needs to be done in that method. Since our lastPicture button is a thumbnail of the last picture taken by the user, we need to update its image, so this is how it should look like:
- (void) imagePickerController:(UIImagePickerController *)aPicker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
UIImage *aImage = (UIImage *)[info objectForKey:UIImagePickerControllerOriginalImage];
if (aPicker.sourceType == UIImagePickerControllerSourceTypeCamera) {
UIImageWriteToSavedPhotosAlbum (aImage, nil, nil , nil);
overlay.pictureButton.enabled = YES;
[overlay.lastPicture setImage:aImage forState:UIControlStateNormal];
} else {
...
...
}
Step 3
Another thing you need to do to start using AssetsLibrary is to import it in the header file, so go to CameraViewController.h. Moreover, you are going to need to define one more attribute:
#import <UIKit/UIKit.h>
#import <AssetsLibrary/AssetsLibrary.h>
@interface CameraViewController : UIViewController <UIImagePickerControllerDelegate, UINavigationControllerDelegate, UIScrollViewDelegate> {
IBOutlet UIScrollView *scrollView;
UIImageView *imageView;
NSMutableArray *assets;
}
@property (nonatomic, strong) UIImagePickerController *picker;
- (IBAction) backButton:(id)sender;
- (IBAction) doneButton:(id)sender;
- (void) changeFlash:(id)sender;
- (void) changeCamera;
- (void) showLibrary;
- (void)showCamera;
- (void)takePicture;
@end
Step 4
Now you need to create an ALAssetsLibrary and enumerate through the ALAssetsGroups it has access to. Then, enumerate through the ALAssets inside each of the ALAssetsGroups, and add them to the NSMutableArray assets. Once it has stopped enumerating, you need to get the picture from the last ALAsset and assign it to the lastPicture button. You will also need to call the method showCamera once you have finished enumerating through the iPhone’s assets.
Unfortunately, to work with the AssetsLibrary framework you need to use blocks, so if you don’t know anything about blocks check out this tutorial. I declared two blocks to use as parameters when calling the methods to enumerate through the ALAssetsLibrary object and through each of the ALAssetsGroups.
This is how the viewDidLoad method looks like:
- (void)viewDidLoad
{
[super viewDidLoad];
overlay = [[CustomOverlayView alloc]
initWithFrame:CGRectMake(0, 0, SCREEN_WIDTH, SCREEN_HEIGTH)];
overlay.delegate = self;
self.picker = [[[UIImagePickerController alloc] init];
self.picker.delegate = self;
self.picker.navigationBarHidden = YES;
self.picker.toolbarHidden = YES;
self.picker.wantsFullScreenLayout = YES;
void (^assetEnumerator)(ALAsset *, NSUInteger, BOOL *) = ^(ALAsset *result, NSUInteger index, BOOL *stop) {
if(result) {
[assets addObject:result];
} else {
[self performSelectorOnMainThread:@selector(showCamera) withObject:nil waitUntilDone:NO];
ALAsset *lastPicture = (ALAsset *)[assets lastObject];
[[UIImage imageWithCGImage:[lastPicture thumbnail]] forState:UIControlStateNormal];
}
};
void (^assetGroupEnumerator)(ALAssetsGroup *, BOOL *) = ^(ALAssetsGroup *group, BOOL *stop) {
if(group) {
[group enumerateAssetsUsingBlock:assetEnumerator];
}
};
assets = [[NSMutableArray alloc] init];
ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
[library enumerateGroupsWithTypes:ALAssetsGroupSavedPhotos
usingBlock:assetGroupEnumerator
failureBlock: ^(NSError *error) {
NSLog(@"Failure");
}];
}
Conclusion
Building your own camera app with a custom UI is really easy, as you have just seen.