Picup Design Patterns & Best Practices

Replace File-Input Form Fields

The Picup JavaScript helper has a few functions that convert file-input fields with buttons to the Picup app. Use this tool to conditionally replace form elements if your visitor is using iOS. The script can also help generate Picup URLs to request and view local files.

Suggested Callback Cycle

Picup's callback functionality can greatly improve the integration with your app. It allows you to define how Picup returns information back to your app. Making this handoff as seamless as possible will improve the user experience. For this example, let's assume you have a web form at the URL http://myapp.com/form.

  1. When http://myapp.com/form loads, give the browser window a name (e.g. window.name = "my_form") and replace any file-input fields with an "upload photo" button using the Picup JavaScript helper.

  2. Define the Picup2.callbackHandler function to accept a JavaScript object with key/value callback parameters. For example:

    Picup2.callbackHandler = function(params){
      for(var key in params){
        alert(key+' == '+params[key]);

  3. Launch Picup with a callback URL for a "transaction complete" page, that's hosted in the same domain as the current page.

  4. Your user selects and uploads a file with Picup.

  5. When the upload is complete, Picup opens the "transaction complete" callback URL in a new Safari window. This page should give the user some feedback regarding the status of the upload.

  6. Optional

    Return control to the original window with new hash parameters. This can be done using window.open if your callback URL is in the same domain as the original window. The window name should be the same name that you assigned in step 1.

    If the original window is still open and in-memory, Safari will return focus to it. If the page is no-longer in memory, Safari will open a new window.

    NOTE: If the user is on an iPhone, the callback window cannot reliably be closed when control returns to the initial page. If you know of a workaround for this, please contact me.

  7. Once control has returned to the original window, Picup2.callbackHandler() will be called with the callback parameters. These parameters are parsed from the query-string formatted hash. Use these parameters to update your page as necessary. If there is more than one file-upload fields in the form, the field that requested the upload can be referenced by the Picup2.activeFileInput variable.

The above callback cycle can be seen in-use on the Scratchpad Demo.

Smooth User Experience

Give your visitors visual feedback that the upload is complete by adding a thumbnail of the photo to your form. This can be done by requesting a thumbnail data:URL from Picup or inserting the uploaded photo into the page using the remote URL.

Offline Usage and Incomplete Uploads

Picup will store files locally and return control to your application even if the upload was not complete. This might happen if the user doesn't have an internet connection, or there was an error from the remote server. If you provide a callback URL, Picup will return a "status" parameter which will either be "Complete" or "Incomplete."

If the upload was not complete, the images can still be viewed locally by launching Picup with a "view" URL. This URL takes the picID as a parameter, which is returned by Picup. View the Scratchpad Demo for an example of a "view" URL. Your app might also store the thumbnail data to use as a visual representation of the image when the user is not online.

App Not Installed

If the user doesn't have Picup installed, they will be prompted to download it when they try to upload a file. This behavior can be overridden by assigning a new function to Picup2.appNotInstalledHandler(). For example, you might want to simply update your UI.

Multiple File Uploads

As of version 2, Picup allows the user to select multiple files unless the API configuration forbids it. Each file is uploaded individually (like version 1) but the return information is sent back as collection. If you're using the fileupload2:// scheme, the callback format has been changed to accommodate this feature. Please read the Discussion under the returnStatus parameter in the Scratchpad Demo for specifics on the new callback format.