Camera+

← API Home

App integration API

Using the Camera+ app integration API, developers can integrate Camera+ functionality into their apps. Camera+ can be used to shoot a photo, to choose an existing photo from the Camera+ Lightbox, to edit a photo or to share photos.

Overview

The Camera+ app integration API is available in Camera+ 3. You use the API by adding a static library framework to your app.

We have created a sample app, which contains the integration framework, and demonstrates how to use it. You can read about and download the sample app below.

This documentation describes the process of preparing your app to integrate Camera+, the different functions available and how to use them.

If you have any questions or suggestions, please jump over to our Support forums.

Download

Download CameraPlusIntegration.zip, which contains the static library framework and the sample app, as described below.

Changes

Date Component Description
27 March 2012 Camera+ 3.0.1 Camera+ update fixes bug where the user could shoot photos when using the CameraPlusIntegrationModeLightboxOnly picker mode, and bug where the mode parameter is not correctly returned in delegate and block callbacks.
17 March 2012 Sample app Correct signature of example cameraPlusIntegrationManagerDidCancel:withMode: method in the app delegate.
6 June 2012 Sample app Correct use of UIImagePickerControllerMediaMetadata causing linker failure on iOS 4.
14 September 2013 Static library The static library now includes iOS 7 support and support for the iPhone 5s

Sample app

The sample app demonstrates how to use the API. It is included as an Xcode project in the zip archive linked above. Build and install it on your device to test it with Camera+.

When you first run the app you see an empty screen with an action button. Tap the action button to bring up an action sheet showing you three options for getting photos. The first two options are the standard options that use Apple’s UIImagePickerController. The third option is “Use Camera+”, which launches Camera+ to shoot or choose a photo from the Lightbox, and then returns the photo back to the sample app. These three options are our suggested UI, however you may find another UI that works best in your app.

After you’ve picked an image and it’s appeared back in the sample app, tap the action button again and you’ll see the options have changed to allow you to edit or share the current photo.

Choose Edit Photo and the current photo will be sent to Camera+ and put into the Edit mode. Edit the photo in Camera+ and then tap Done to return to the sample app with the edited image.

Then tap the action button again and choose Share Photo to open Camera+ and activate social sharing. You can either share the photo or tap Cancel at that point to return to the sample app.

If you like to dive straight into the code, let’s take a look at the sample app source code now. Otherwise skip to the next section.

Dive into the code!

Open the TesterViewController class and look at the choosePhoto: method. This code demonstrates testing for the availability of Camera+ and asking the user how they would like to use Camera+. See Checking for Camera+ below.

We have chosen to alert the user if Camera+ is too old or not installed; in your application you can decide how to present these situations to the user.

Now the action sheet delegate method. It demonstrates using the standard UIImagePickerController as well as how to use the CameraPlusIntegrationManager class to invoke Camera+.

Finally look in the TesterAppDelegate at the application:handleOpenURL: method. This is invoked when Camera+ returns a result to the sample app. The sample app calls the CameraPlusIntegrationManager class with itself as the delegate, and the delegate methods are then called with the result of the API operation.


Reference apps

We also suggest you check out some apps that have already integrated Camera+:

Tweetbot

Tweetbot enables you to use Camera+ to add a photo when you’re posting a tweet. When you’ve added a photo you can also use Camera+ to edit it before you post it.

WordPress

WordPress enables you to use Camera+ to take photos to post to your WordPress blog.

Foodspotting

Foodspotting enables you to use Camera+ to take a photo when you’re sharing your food or drink.

Prepare your app

To prepare your app to use the Camera+ app integration API first add the necessary files to your app, and then add a URL type in your Info.plist.

Required files

Copy and add the CameraPlusIntegrationAPI.framework folder from the downloaded zip archive into your project; then move it into the Frameworks group.

Then add the MobileCoreServices.framework to your project, by going to the Build Phases tab for your target, expand the Link Binary With Libraries section, click the + button and choose MobileCoreServices.framework from the list.

Info.plist configuration

Camera+ uses a custom URL scheme to communicate with your app. You need to add a URL type to your Info.plist with a unique URL scheme. See Apple’s documentation for adding Custom URL Schemes to your app.

It is critical that this custom URL scheme is unique to your app, otherwise Camera+ may return the user to the wrong app! Therefore we suggest using your app identifier as your URL scheme. For example, the sample app uses com.taptaptap.CameraPlusIntegrationAPITester.

See the Info.plist file in the sample app for an example.

App delegate

When Camera+ communicates with your app it calls your custom URL scheme which calls the application:handleOpenURL: method in your app delegate. You then pass the URL to the CameraPlusIntegrationManager so it can handle the response, if appropriate.

If you already have a application:handleOpenURL: method you’ll need to integrate one of the code samples below with your existing code.

You can choose either a delegate or a blocks approach:

Delegate approach

If you want to use the delegate approach, copy and paste the following code block into your app delegate. The sample app uses the delegate approach so you can look at the sample app for an example implementation.

- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url {
   if ([[CameraPlusIntegrationManager sharedManager] handleCameraPlusIntegrationCallback:url 
                                                                                delegate:self]) {
       return YES;
   } else {
       /* Your own URL handling here, if any */
       return NO;
   }
}

- (void)cameraPlusIntegrationManager:(CameraPlusIntegrationManager*)manager
                    didReceiveImages:(CameraPlusImages*)images
                            withMode:(CameraPlusIntegrationMode)mode {

}

- (void)cameraPlusIntegrationManagerDidCancel:(CameraPlusIntegrationManager*)manager
                                     withMode:(CameraPlusIntegrationMode)mode {

}

- (void)cameraPlusIntegrationManagerDidShare:(CameraPlusIntegrationManager*)manager {

}

- (void)cameraPlusIntegrationManager:(CameraPlusIntegrationManager*)manager 
                    didCreateWebLink:(NSURL*)link {

}

The integration manager will call your supplied delegate according to the result of the requested operation. The delegate callbacks are explained along with the corresponding API calls below.

In the above code example, the delegate is self and therefore it is the app delegate in this case. The delegate could be any class; the app delegate often makes sense as your app may have been terminated and other objects may not yet exist.

When images are returned to your app they are returned in a CameraPlusImages object. See the CameraPlusImages API documentation below.

Blocks approach

If you want to use the blocks approach, copy and paste the following code block into your app delegate.

- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url {
   if ([[CameraPlusIntegrationManager sharedManager] handleCameraPlusIntegrationCallback:url 
       usingBlock:^(CameraPlusIntegrationResult *result) {
           /* Handle result from Camera+ */
       } cancelBlock:^(CameraPlusIntegrationMode mode) {
           /* User cancelled in Camera+ */
       }]) {
       return YES;
   } else {
       /* Your own URL handling here, if any */
       return NO;
   }
}

The first block is called when the operation succeeds. You must inspect the mode property of the CameraPlusIntegrationResult to determine how to handle the result. See the CameraPlusIntegrationResult API documentation below.

CameraPlusImages API

When photos are returned to your app they are returned in a CameraPlusImages object. You can access photos as JPEG data in an NSData object or as a UIImage object. You can also get the original camera metadata.

Note that although the CameraPlusImages API supports multiple images being returned, the current version of Camera+ only allows choosing a single image. This will change in a future update to Camera+.

Property Description
NSInteger numberOfImages Returns the number of images available.
Method Description
-(UIImage*)image Returns the first UIImage, or nil if there are no images.
-(NSArray*)images Returns an array of UIImage objects.
-(UIImage*)imageAtIndex:(NSUInteger)index Returns a UIImage for the image at the given index, or nil if there is no image at the given index.
-(NSData*)imageDataAtIndex:(NSUInteger)index Returns an NSData containing JPEG image data for the image at the given index, or nil if there is no image at the given index.
-(NSDictionary*)metadataAtIndex:(NSUInteger)index Returns a NSDictionary containing the camera metadata dictionary for the image at the given index, possibly nil. See the attachments parameter in the AVCaptureStillImageOutput documentation for a description of the contents of this dictionary.

CameraPlusIntegrationResult API

Successful block callbacks have a CameraPlusIntegrationResult parameter that describes the successful result.

Property Description
CameraPlusIntegrationMode mode Returns the mode that was used to invoke Camera+. Use the mode property to determine how to handle the result.
CameraPlusImages *images Returns a CameraPlusImages object containing the images returned, if any.
NSURL *link Returns the link that photos were shared to when using the Create Web Link API call.

Important note

When Camera+ is launched, your application goes into the background state. Your application may be terminated by the OS while the user is in Camera+ so you need to ensure that you can restore your state sufficiently when relaunched. It is possible to test this by running your application in debug mode from Xcode and stopping it after it has launched Camera+.

Setup and configuration

To use the Camera+ app integration API in your class file, first include the CameraPlusIntegrationManager header:

#import <CameraPlusIntegrationAPI/CameraPlusIntegrationManager.h>

Configuring the CameraPlusIntegrationManager

You must configure the CameraPlusIntegrationManager by setting the callbackURLScheme to the custom URL scheme you added to your app in the Prepare your app section above.

CameraPlusIntegrationManager *integrationManager = [CameraPlusIntegrationManager sharedManager];
integrationManager.callbackURLScheme = @"com.taptaptap.CameraPlusIntegrationAPITester";

There are properties on the CameraPlusIntegrationManager that control how Camera+ behaves. Some properties are only applicable in certain modes, and will be described with the mode below.

Property Description
NSInteger imageSize the maximum image size to return from Camera+, as the maximum length of the longest side, eg. 1000. Defaults to 0 for no maximum.
CGFloat compressionQuality the JPEG compression quality to use to create JPEGs from UIImages to send to Camera+. Defaults to 0.9.
BOOL autoCloseShareSuccess When a sharing operation succeeds, instantly return back to your app rather than showing the confirmation in Camera+.

Checking if Camera+ is installed

Your app needs to check if Camera+ is installed on the user’s device before attempting to use it. The CameraPlusIntegrationManager provides two properties for this purpose:

Property Description
cameraPlusAvailable Check if Camera+ is installed.
cameraPlusIntegrationAvailable Check if the required minimum version of Camera+ is installed

If Camera+ isn’t installed then it probably makes sense to simply hide your Camera+ integration. It is up to you whether you want to notify users that they could use Camera+ with your app; please don’t make it spammy.

If Camera+ is installed then you then need to check if the installed version is able to support the integration API. If it isn’t then we suggest you ask the user to update Camera+ to the latest version, however you could also simply hide your integration.

This suggested workflow means that you should check [CameraPlusIntegrationManager sharedManager].cameraPlusAvailable before displaying your Camera+ integration. Therefore you might call that before displaying a UIActionSheet with the option to use Camera+. If the user has Camera+ and chooses a Camera+ integration option then you should check [CameraPlusIntegrationManager sharedManager].cameraPlusIntegrationAvailable and if it returns NO then show an alert requesting they update Camera+.

This example shows how you might check if Camera+ is installed:

if ([CameraPlusIntegrationManager sharedManager].cameraPlusAvailable) {
   /* Show you Camera+ integration options */
}

Then when the user requests a Camera+ integration option:

if ([CameraPlusIntegrationManager sharedManager].cameraPlusIntegrationAvailable) {
   /* Use CameraPlusIntegrationManager to invoke Camera+ */
} else {
   UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Camera+ update required" 
                                                   message:@"The version of Camera+ installed must "
                                                            "be updated to use with this app. "
                                                            "Please go to the App Store app and "
                                                            "update Camera+." 
                                                  delegate:self
                                         cancelButtonTitle:@"OK"
                                         otherButtonTitles:nil];
   [alert show];
   [alert release];
}

Shooting or choosing a photo with Camera+

You can launch Camera+ and let the user either shoot a photo or choose an existing photo from the Lightbox. We expect that you would combine this feature with an existing UIImagePickerController workflow, ideally as pictured on the left below. The first two options are your existing functionality, and the “Use Camera+” option should be shown if you’ve detected that the user has Camera+ installed (see above).

“Use Camera+” is the suggested nomenclature when you launch Camera+ to shoot a photo or to choose from the Lightbox. Alternatively you may wish to restrict the user to either shooting or choosing. The second screenshot below illustrates how those options could be presented. You control what options are available to the user in Camera+ using modes, as illustrated in the table below.

Note that in a future update to Camera+ it will be possible to let the user choose multiple photos from the Lightbox.

	CameraPlusIntegrationManager *integrationManager = [CameraPlusIntegrationManager sharedManager];
	[integrationManager openCameraPlusPickerWithMode:CameraPlusIntegrationModeShootAndLightbox];
	

Example

Below is some example code for how you might present a UIActionSheet like the first one above:

UIActionSheet *sheet = [[UIActionSheet alloc] initWithTitle:nil
				                                   delegate:self
				                          cancelButtonTitle:nil
				                     destructiveButtonTitle:nil
				                          otherButtonTitles:nil];
if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) {
    [sheet addButtonWithTitle:@"Take Photo"];
}
if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypePhotoLibrary]) {
    [sheet addButtonWithTitle:@"Choose Existing"];
}
[sheet addButtonWithTitle:@"Use Camera+"];
sheet.cancelButtonIndex = [sheet addButtonWithTitle:@"Cancel"];
[sheet showInView:self.view];

And then the UIActionSheetDelegate method:

- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex {
    if (buttonIndex == actionSheet.cancelButtonIndex)
        return;
    
    NSString *buttonTitle = [actionSheet buttonTitleAtIndex:buttonIndex];
    if ([@"Take Photo" isEqual:buttonTitle]) {
        UIImagePickerController *imagePicker = [[UIImagePickerController alloc] init];
        imagePicker.sourceType = UIImagePickerControllerSourceTypeCamera;
        imagePicker.delegate = self;
        [self presentModalViewController:imagePicker animated:YES];
        [imagePicker release];
    } else if ([@"Choose Existing" isEqual:buttonTitle]) {
        UIImagePickerController *imagePicker = [[UIImagePickerController alloc] init];
        imagePicker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
        imagePicker.delegate = self;
        [self presentModalViewController:imagePicker animated:YES];
        [imagePicker release];
    } else if ([@"Use Camera+" isEqual:buttonTitle]) {
        if ([CameraPlusIntegrationManager sharedManager].cameraPlusIntegrationAvailable) {
            CameraPlusIntegrationManager *integrationManager = 
                [CameraPlusIntegrationManager sharedManager];
            integrationManager.callbackURLScheme = @"com.taptaptap.CameraPlusIntegrationAPITester";
            [integrationManager openCameraPlusPickerWithMode:
                CameraPlusIntegrationModeShootAndLightbox];
        } else {
            /* Alert the user that they should upgrade Camera+ */
        }
    }
}

CameraPlusIntegrationManager picker methods

Method Description
-(BOOL)openCameraPlusPickerWithMode:(CameraPlusIntegrationMode)mode Open Camera+ to pick an image, constrained by the given mode (see below).

Modes

Using different picker modes you can choose to allow the user to shoot photos or choose from the Lightbox, or limit them to one or other of those options.

Mode Description
CameraPlusIntegrationModeShootAndLightbox The user can shoot and edit a photo or choose a photo from their Lightbox.
CameraPlusIntegrationModeShootOnly The user can shoot and edit a photo. They cannot choose a photo from their Lightbox.
CameraPlusIntegrationModeLightboxOnly The user can choose a photo from their Lightbox. They cannot shoot a new photo. (Note there was a bug in the first Camera+ 3 release that allowed the user to switch to the camera in this mode; this was fixed in 3.0.1)

Callbacks

Delegate callbacks

Method Description
-(void)cameraPlusIntegrationManager:(CameraPlusIntegrationManager*)manager didReceiveImages:(CameraPlusImages*)images withMode:(CameraPlusIntegrationMode)mode The photo or photos shot or chosen in Camera+ are returned by this delegate callback. See above for documentation of the CameraPlusImages object that contains the images. The mode is set to the mode Camera+ was opened with above. Note that this delegate callback is also used to receive the results of editing a photo with Camera (see below).
-(void)cameraPlusIntegrationManagerDidCancel:(CameraPlusIntegrationManager*)manager withMode:(CameraPlusIntegrationMode)mode Called if the user cancels the operation, with the mode set to the mode Camera+ was opened with above. (Note there was a bug in the first Camera+ 3 release that caused the mode to not be set correctly; this was fixed in 3.0.1)

The example below shows the delegate callback receiving one or more images from Camera+ and showing them in a UIImageView. Note that the current version of Camera+ will not return more than one image. This will change in a future release.

- (void)cameraPlusIntegrationManager:(CameraPlusIntegrationManager *)manager 
                    didReceiveImages:(CameraPlusImages *)images
                            withMode:(CameraPlusIntegrationMode)mode {
   if (images.numberOfImages == 1) {
       [imageView stopAnimating];
       imageView.image = [images imageAtIndex:0];
   } else if (images.numberOfImages > 1) {
       imageView.animationImages = [images images];
       imageView.animationDuration = 1;
       [imageView startAnimating];
   }
}

Block callbacks

Block Description
usingBlock:^(CameraPlusIntegrationResult *result) This block is invoked if the photo was successfully edited. The CameraPlusIntegrationResult’s mode property will be set to the mode Camera+ was opened with above, and its images property will contain the CameraPlusImages object that contains the returned images.
cancelBlock:^(CameraPlusIntegrationMode mode) Called if the user cancels the operation, with the mode set to the mode Camera+ was opened with above. (Note there was a bug in the first Camera+ 3 release that caused the mode to not be set correctly; this was fixed in 3.0.1)

Editing a photo with Camera+

You can launch Camera+ to edit any image. Simply pass an existing UIImage, or NSData containing JPEG data, to the integration manager. Camera+ will launch and put your image into the editing mode. The user can complete their edits and then return the image to your app, or cancel the process.

	CameraPlusIntegrationManager *integrationManager = [CameraPlusIntegrationManager sharedManager];
	[integrationManager openCameraPlusEditorWithImage:image];
	

CameraPlusIntegrationManager editing methods

Method Description
-(BOOL)openCameraPlusEditorWithImage:(UIImage*)image Edit the given UIImage.
-(BOOL)openCameraPlusEditorWithImageData:(NSData*)imageData Edit the given NSData containing JPEG data.

Callbacks

Delegate callbacks

Method Description
-(void)cameraPlusIntegrationManager:(CameraPlusIntegrationManager*)manager didReceiveImages:(CameraPlusImages*)images withMode:(CameraPlusIntegrationMode)mode This is the same delegate callback as for shooting or choosing photos, except in this case the mode will be set to CameraPlusIntegrationModeEdit. See above for documentation on retrieving the image.
-(void)cameraPlusIntegrationManagerDidCancel:(CameraPlusIntegrationManager*)manager withMode:(CameraPlusIntegrationMode)mode Called if the user cancels the operation, with the mode set to CameraPlusIntegrationModeEdit. (Note there was a bug in the first Camera+ 3 release that caused the mode to not be set correctly; this was fixed in 3.0.1)

Block callbacks

Block Description
usingBlock:^(CameraPlusIntegrationResult *result) This block is invoked if the photo was successfully edited. The CameraPlusIntegrationResult’s mode property will be set to CameraPlusIntegrationModeEdit, and its images property will contain the CameraPlusImages object that contains the edited image.
cancelBlock:^(CameraPlusIntegrationMode mode) Called if the user cancels the operation, with the mode set to CameraPlusIntegrationModeEdit. (Note there was a bug in the first Camera+ 3 release that caused the mode to not be set correctly; this was fixed in 3.0.1)

Sharing photos with Camera+

You can launch Camera+ to share any image. Simply pass an existing UIImage, or NSData containing JPEG data, to the integration manager. Camera+ will launch and present the social sharing screen for your image or images. When the share is complete, or cancelled, the user is returned to your app. You can also share multiple photos at once, see the table of sharing methods below.

	CameraPlusIntegrationManager *integrationManager = [CameraPlusIntegrationManager sharedManager];
	[integrationManager openCameraPlusSharingWithImage:image];
	

You can configure whether Camera+ shows the user the result of a successful sharing operation, and gives them the opportunity to copy the URL it was shared to, or whether the sharing is automatically closed and the user returned to your app. The default is not to automatically close the sharing success message.

integrationManager.autoCloseShareSuccess = NO;

CameraPlusIntegrationManager sharing methods

Method Description
-(BOOL)openCameraPlusSharingWithImage:(UIImage*)image Share a single UIImage.
-(BOOL)openCameraPlusSharingWithImageData:(NSData*)imageData Share a single NSData containing JPEG data.
-(BOOL)openCameraPlusSharingWithImages:(NSArray*)images Share an array of images as either UIImages or NSDatas containing JPEG data.

Callbacks

Delegate callbacks

Method Description
-(void)cameraPlusIntegrationManagerDidShare:(CameraPlusIntegrationManager*)manager This delegate callback is called if the share succeeded.
-(void)cameraPlusIntegrationManagerDidCancel:(CameraPlusIntegrationManager*)manager withMode:(CameraPlusIntegrationMode)mode Called if the user cancels the operation, with the mode set to CameraPlusIntegrationModeShare. (Note there was a bug in the first Camera+ 3 release that caused the mode to not be set correctly; this was fixed in 3.0.1)

Block callbacks

Block Description
usingBlock:^(CameraPlusIntegrationResult *result) This block is invoked if the photos were successfully shared. The CameraPlusIntegrationResult’s mode property will be set to CameraPlusIntegrationModeShare.
cancelBlock:^(CameraPlusIntegrationMode mode) Called if the user cancels the operation, with the mode set to CameraPlusIntegrationModeShare. (Note there was a bug in the first Camera+ 3 release that caused the mode to not be set correctly; this was fixed in 3.0.1)

As an extension to sharing, Camera+ can upload a photo to Camera+’s own sharing service and return the secret link to that photo to your app. This enables you to share the link to those photos however you wish, such as in an email or SMS, or by posting the link to your own service.

CameraPlusIntegrationManager *integrationManager = [CameraPlusIntegrationManager sharedManager];
[integrationManager createWebLinkWithImage:image];

CameraPlusIntegrationManager create web link methods

Method Description
-(BOOL)createWebLinkWithImage:(UIImage*)image Create a web link with a single UIImage.
-(BOOL)createWebLinkWithImageData:(NSData*)imageData Create a web link with a single NSData containing JPEG data.
-(BOOL)createWebLinkWithImages:(NSArray*)images Create a web link with an array of images as either UIImages or NSDatas containing JPEG data.

Callbacks

Delegate callbacks

Method Description
-(void)cameraPlusIntegrationManager:(CameraPlusIntegrationManager*)manager didCreateWebLink:(NSURL*)link This delegate callback is called if the photos were successfully uploaded and the web link created. The web link is returned in the link parameter which contains an NSURL.
-(void)cameraPlusIntegrationManagerDidCancel:(CameraPlusIntegrationManager*)manager withMode:(CameraPlusIntegrationMode)mode Called if the user cancels the operation, with the mode set to CameraPlusIntegrationModeCreateWebLink. (Note there was a bug in the first Camera+ 3 release that caused the mode to not be set correctly; this was fixed in 3.0.1)

Block callbacks

Block Description
usingBlock:^(CameraPlusIntegrationResult *result) This block is invoked if the photos were successfully uploaded and the web link created. The CameraPlusIntegrationResult’s mode property will be set to CameraPlusIntegrationModeCreateWebLink, and the web link is in its link property.
cancelBlock:^(CameraPlusIntegrationMode mode) Called if the user cancels the operation, with the mode set to CameraPlusIntegrationModeCreateWebLink. (Note there was a bug in the first Camera+ 3 release that caused the mode to not be set correctly; this was fixed in 3.0.1)

tap tap tap