Saturday, 18 June 2016

UIDocumentPickerViewController and UIDocumentMenuViewController in iOS


A document picker view controller is used to access the files from variety of the sources like iCloud, dropbox, google drive etc. It provides the below following main operation.

  1. Open
  2. Import
  3. Export
  4. Move

Today we will learn how to achieve (mainly used Import and Export) this functionality in our iOS apps for providing more option to user to perform operation with the files.

Importing a file using document picker

/** Create the array of UTI Type that you want to support
     * Pass the array of UTI Type that application wants to support. Add more UTI Type if you want to support more other than listed
     */
    NSArray *types = @[(NSString*)kUTTypeImage,(NSString*)kUTTypeSpreadsheet,(NSString*)kUTTypePresentation,(NSString*)kUTTypeDatabase,(NSString*)kUTTypeFolder,(NSString*)kUTTypeZipArchive,(NSString*)kUTTypeVideo];

    //Create a object of document picker view and set the mode to Import
    UIDocumentPickerViewController *docPicker = [[UIDocumentPickerViewController alloc] initWithDocumentTypes:types inMode:UIDocumentPickerModeImport];

    //Set the delegate
    docPicker.delegate = self;
    //present the document picker
    [self presentViewController:docPicker animated:YES completion:nil];


It will open the document picker to import the file that match the given UTI Type. You can restrict the specific file type according to your use.





Exporting a file using document picker –

//Create the file path of the document to upload
        NSURL *filePathToUpload = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"testing" ofType:@"doc"]]  ;
    //Create a object of document picker view and set the mode to Export
    UIDocumentPickerViewController *docPicker = [[UIDocumentPickerViewController alloc] initWithURL:filePathToUpload inMode:UIDocumentPickerModeExportToService];
    //Set the delegate
    docPicker.delegate = self;
    //present the document picker
    [self presentViewController:docPicker animated:YES completion:nil];
   
Create the url with the document that you want to upload and then initiate the document picker with that url.



When the above import or export methods are called we will get the status in the delegate methods of UIDocumentPickerDelegate.

/**
 *  This delegate method is called when user will either upload or download the file.
 *
 *  @param controller UIDocumentPickerViewController object
 *  @param url        url of the file
 */

- (void)documentPicker:(UIDocumentPickerViewController *)controller didPickDocumentAtURL:(NSURL *)url
{
    if (controller.documentPickerMode == UIDocumentPickerModeImport)
    {
     
        // Condition called when user download the file
        NSData *fileData = [NSData dataWithContentsOfURL:url];
        // NSData of the content that was downloaded - Use this to upload on the server or save locally in directory
       
        //Showing alert for success
        dispatch_async(dispatch_get_main_queue(), ^{
           
            NSString *alertMessage = [NSString stringWithFormat:@"Successfully downloaded file %@", [url lastPathComponent]];
            UIAlertController *alertController = [UIAlertController
                                                  alertControllerWithTitle:@"UIDocumentView"
                                                  message:alertMessage
                                                  preferredStyle:UIAlertControllerStyleAlert];
            [alertController addAction:[UIAlertAction actionWithTitle:@"Ok" style:UIAlertActionStyleDefault handler:nil]];
            [self presentViewController:alertController animated:YES completion:nil];
           
        });
    }else  if (controller.documentPickerMode == UIDocumentPickerModeExportToService)
    {
        // Called when user uploaded the file - Display success alert
        dispatch_async(dispatch_get_main_queue(), ^{
           
            NSString *alertMessage = [NSString stringWithFormat:@"Successfully uploaded file %@", [url lastPathComponent]];
            UIAlertController *alertController = [UIAlertController
                                                  alertControllerWithTitle:@"UIDocumentView"
                                                  message:alertMessage
                                                  preferredStyle:UIAlertControllerStyleAlert];
            [alertController addAction:[UIAlertAction actionWithTitle:@"Ok" style:UIAlertActionStyleDefault handler:nil]];
            [self presentViewController:alertController animated:YES completion:nil];
           
        });
    }
   
}

/**
 *  Delegate called when user cancel the document picker
 *
 *  @param controller - document picker object
 */
- (void)documentPickerWasCancelled:(UIDocumentPickerViewController *)controller {
   
}


UIDocumentMenuView

Instead of directly presenting the document picker view we can also present menu view that contains all the document providers. Use can control which extensions they want to display and which they don’t want.

We can also add our own option in the list either in top or bottom of the list.

/** Create the array of UTI Type that you want to support
     * Pass the array of UTI Type that application wants to support. Add more UTI
        Type if you want to support more other than listed

     */
     NSArray *types = @[(NSString*)kUTTypeImage,(NSString*)kUTTypeSpreadsheet,(NSString*)kUTTypePresentation,(NSString*)kUTTypeDatabase,(NSString*)kUTTypeFolder,(NSString*)kUTTypeZipArchive,(NSString*)kUTTypeVideo];
    //Create a object of document menu view and set the mode to Import
    UIDocumentMenuViewController *objMenuView = [[UIDocumentMenuViewController alloc]initWithDocumentTypes:types inMode:UIDocumentPickerModeImport];
  
    //Create Custom option to display
    [objMenuView addOptionWithTitle:@"My Custom option" image:nil order:UIDocumentMenuOrderFirst handler:^{
        //Call when user select the option
       
    }];
    //Set the delegate
    objMenuView.delegate = self;
    //present the document menu view
    [self presentViewController:objMenuView animated:YES completion:nil];


When user select any option other than custom we have to display the document view controller to select the file.To get the notification we have to implement UIDocumentMenuDelegate.

- (void)documentMenu:(UIDocumentMenuViewController *)documentMenu didPickDocumentPicker:(UIDocumentPickerViewController *)documentPicker {
    documentPicker.delegate = self;
    [self presentViewController:documentPicker animated:YES completion:nil];
}



 Note- To use document picker and iCloud you must enable iCloud in project settings and create the entitlement.



That’s all we have successfully integrated the document menu view and document picker view controller.
Here is sample project with all the code of the above tutorial.

If you face any issue or have any suggestions, please leave your comment.