Prerequisites

To develop your own clients, you need to be familiar with the architecture of SAP Mobile Documents, the CMIS open standard, and its SAP Mobile Documents extensions. For more information see the SAP Mobile Documents 1.0 – SAP Help Portal Page.

As this is an iOS app sample, experience with the development environment (Apple Xcode) is also necessary. Also, access to a running SAP Mobile Documents server instance is necessary to test the functionality of the compiled application.

Disclaimer

Please note that in addition to the SCN Terms of Use, the following terms and conditions govern your use of any sample code or sample applications.  Sample code and sample applications are provided only as examples and for illustrative purposes. SAP sample code and sample applications are NOT FOR PRODUCTION OR COMMERCIAL USE, unless otherwise specifically noted.

SAP grants you a nonexclusive copyright license to use any sample code or sample applications to generate the same or similarly functioning code/applications for internal testing and evaluation. You may not demonstrate, test, examine, evaluate or otherwise use them in a live operating environment, or with data that has not been sufficiently backed up. You may not rent, lease, lend, or resell SAP sample code or sample applications.  All sample code and sample applications are provided “AS IS” without any warranties of any kind. The implied warranties of non-infringement, merchantability and fitness for a particular purpose are expressly disclaimed.

Creating an iOS Client for SAP Mobile Documents

You can develop your own iOS client application for SAP Mobile Documents using the SAP Mobile Documents SDK. The example in this article demonstrates the following:

  • How to connect your client to the MyDocuments repository (the repository where users store their personal files).
  • How to execute operations on this repository.

The example implements an iOS note application. Users can use this application to create, edit, and delete notes. The Note List displays all existing notes. To display the content of a note, the user taps the note entry. The notes are stored as files in the personal folder of the currently logged-on user.

iOsNoteApplication.png

You can download the Notes sample application at http://scn.sap.com/servlet/JiveServlet/download/38-232478/NoteApplication.txt.zip. Please note that the unpacked file will have the name “NoteApplication.txt”… please rename the extension from *.txt to *.zip and unpack to view the content (we will soon have a version in which you only need to unpack once).

Introduction

SAP Mobile Documents uses the standard Content Management Interoperability Services (CMIS) protocol to connect to different content management systems (CMS) using a single API. CMIS servers provide capabilities, for example, for creating a folder or a document in a repository. CMIS clients can use the capabilities provided by CMIS servers.

The SAPMobile Documents server handles user authentication, authorization and connectivity to different CMIS repositories. It is both a CMIS server and a CMIS client. For the SAP Mobile Documents clients, it acts as a server providing functionality that the clients can use. At the same time, the server is a CMIS client since it delegates incoming CMIS calls to the correct repository in the backend and consumes the functionality the backend provides.

To create your own SAP Mobile Documents client application, connect to the SAP Mobile Documents server using the CMIS protocol. The Open Source project Apache Chemistry provides several CMIS client libraries, which simplify setting up a connection to a repository and using CMIS repository operations. For iOS, there is the ObjectiveCMIS library that the example application uses. You can download it at http://chemistry.apache.org.

Setting Up a Connection to the SAP Mobile Documents Server

To connect to the SAP Mobile Documents MyDocuments repository, perform the following steps:

  1. Create the connection parameters
  2. Find the MyDocuments repository
  3. Create a repository session

The next sections explain how to perform these steps with the ObjectiveCMIS library.

Note: The code snippets shown are contained in the example application and can be found in the RepositoryConnection.m class.

Creating the Connection Parameters

Setting up the session parameters is a prerequisite to opening a connection to the SAP Mobile Documents server. Using the parameters, you provide the SAP Mobile Documents server URL, authentication information (user name and password), and other information, for example, the binding that is used to communicate with the server. Currently, ObjectiveCMIS only allows you to communicate using the AtomPub binding. ObjectiveCMIS does not yet support Web services and browser binding.

To perform operations on the SAP Mobile Documents server, you must provide an authentication provider that protects the server against cross-site request forgery (XSRF) attacks using XSRF tokens. The example project contains the XSRFAuthenticationProvider class. This class adds the XSRF token as well as the user name and password to the HTTP header of each request.

The following code snippet shows a method that uses three parameters (user name, password, and server URL) to create a CMISSessionParameters object. In addition, the snippet showcases the use of the XSRFAuthenticationProvider class.


- (CMISSessionParameters *)sessionParametersForUsername:(NSString *)username
  password:(NSString *)password serverUrl:(NSString *)serverUrl
{
    NSURL *url = [NSURL URLWithString:serverUrl];
    if ((username.length == 0 || password.length == 0) || url == nil) {
        return nil;
    }
    CMISSessionParameters *parameters = [[CMISSessionParameters alloc]
                                                              initWithBindingType:CMISBindingTypeAtomPub];
    if (url.lastPathComponent.length == 0 || [url.lastPathComponent isEqualToString:@"/"]) {
        url = [url URLByAppendingPathComponent:@"mcm/b/atom"];
    } else if ([url.lastPathComponent isEqualToString:@"mcm"]) {
        url = [url URLByAppendingPathComponent:@"b/atom"];
    }
    parameters.atomPubUrl = url;
    XSRFAuthenticationProvider *xsrfAuthenticationProvider;
    xsrfAuthenticationProvider = [[XSRFAuthenticationProvider alloc]
                                              initWithUsername:username password:password];
    parameters.authenticationProvider = xsrfAuthenticationProvider;
    return parameters;
}














To access a repository, put its unique identifier into the session parameters. For information about how to get the unique ID of the MyDocuments repository, see the next step.

Finding the MyDocuments Repository

To determine the unique ID of the MyDocuments repository, read the list of available repositories from the SAP Mobile Documents server.

  1. To get this list, use the arrayOfRepositories method that is contained in the CMISSession class. The method expects the session parameters defined in step Creating the Connection Parameters and returns a list of available repositories.
  2. Determine which repository in the list is the MyDocuments repository. The MyDocuments repository has the myDocuments extension, which is used to identify the MyDocuments repository. Loop over the repository list and check whether there is a repository with the myDocuments extension. The value of the extension is the folder ID of the user’s MyDocuments root folder.

The following listing shows how to find the MyDocuments repository. To check for the extension, the code in the listing uses a helper method (extensionElementForName:fromRepositoryInfo:), which looks for an extension with a specified name for a given repository. Another helper method (isMyDocumentsRepository) uses this method to check whether the MyDocuments extension exists in a repository. If this method returns YES, extract the unique ID of the repository and put it into the CMISSessionParameters object.


// constants
NSString * const SAPNamespace = @"http://www.sap.com/mcm"; 
NSString * const MyDocumentsRepositoryExtension = @"myDocuments";
...
- (void)connectWithUsername:(NSString *)username password:(NSString *)password
  serverUrl:(NSString *)serverUrl
{
    // create session parameters
    CMISSessionParameters *parameters = [self sessionParametersForUsername:username
                                                                    password:password serverUrl:serverUrl];
    if(parameters) {
            // get a list of available repositories
            [CMISSession arrayOfRepositories:parameters completionBlock:^(NSArray *repositories,
            NSError *error) {
            if(error == nil) {
                for (CMISRepositoryInfo *cmisRepository in repositories) {
                    // find MyDocuments repository
                    if([self isMyDocumentsRepository:cmisRepository]) {
                        // add my documents repository id to session parameters and open the session
                        parameters.repositoryId = cmisRepository.identifier;
                        NSLog(@"MyDocuments repository found! Opening session...");
                        [self openSession:parameters];
                        [self setMyDocumentsFolderId:cmisRepository];
                        break;
                    }
                }
                NSLog(@"MyDocuments repository not found.");
            } else {
                NSLog(@"Could not get repository list.");
                [[NSNotificationCenter defaultCenter] postNotificationName:SessionNotCreatedNotification
                object:self];
            }
        }];
    } else {
        NSLog(@"Something is wrong with the session parameters.");
        [[NSNotificationCenter defaultCenter] postNotificationName:SessionNotCreatedNotification object:self];
    }
}
// helper method to determine MyDocuments repository
- (BOOL)isMyDocumentsRepository:(CMISRepositoryInfo *)repositoryInfo
{
    CMISExtensionElement *extension = [self extensionElementForName:MyDocumentsRepositoryExtension
                                                          fromRepositoryInfo:repositoryInfo];
    if(extension) {
        return YES;
    }
    return NO;
}
// helper method to find an extension in a repository info
- (CMISExtensionElement *)extensionElementForName:(NSString*)extensionName fromRepositoryInfo:
  (CMISRepositoryInfo *)repositoryInfo
{
    for(CMISExtensionElement *extensionElement in repositoryInfo.extensions) {
        if(extensionElement.namespaceUri == nil || [extensionElement.namespaceUri
        isEqualToString:SAPNamespace]) {
            if([extensionElement.name isEqualToString:extensionName]) {
                return extensionElement;
            }
        }
    }
    return nil;
}

















Your session parameters are complete and you are ready to open a session with the MyDocuments repository.

Creating a Repository Session

  1. To open a session to a repository on the SAP Mobile Documents server, use the connectWithSessionParameters class method that is defined in the CMISSession class.
  2. Provide the CMISSessionParameters object that you created in step Create the Connection Parameters enriched with the repository ID determined in step Finding the MyDocuments Repository.
  3. In the completion block, check if the session is authenticated. If so, you have opened a session to the MyDocuments repository.
  4. Extract the XSRF token value and put it in the authentication provider.

See the example below.


- (void)openSession:(CMISSessionParameters*) parameters
{
    if(parameters) {
        // create the session
        NSLog(@"Connecting to repository '%@' ", parameters.repositoryId);
        [CMISSession connectWithSessionParameters:parameters completionBlock:^(CMISSession *session,
        NSError *error) {
            if(session.isAuthenticated) {
                // get xsrf token
                NSLog(@"Session to repository '%@' established", parameters.repositoryId);
                NSString *token = [self getXsrfToken:session.repositoryInfo];
                if(token) {
                    // get XSRFAuthenticationProvider and set token
                    XSRFAuthenticationProvider *xsrfAuthenticationProvider = (XSRFAuthenticationProvider*)
                                                                                                                  parameters.authenticationProvider;
                    xsrfAuthenticationProvider.token = token;
                } else {
                    NSLog(@"Could not to fetch xsrf token.");
                }
                // the session is ready to use
                self.session = session;
                [[NSNotificationCenter defaultCenter] postNotificationName:SessionCreatedNotification object:self];
            } else {
                NSLog(@"Could not establish session to myDocuments repository.");
                [[NSNotificationCenter defaultCenter] postNotificationName:SessionNotCreatedNotification
                object:self];
            }
        }];
    } else {
        NSLog(@"Something is wrong with the session parameters.");
        [[NSNotificationCenter defaultCenter] postNotificationName:SessionNotCreatedNotification object:self];
    }
}
// helper method to determine the token
- (NSString *)getXsrfToken:(CMISRepositoryInfo *)repositoryInfo
{
    CMISExtensionElement *extension = [self extensionElementForName:@"token"
                                                                fromRepositoryInfo:repositoryInfo];
    if(extension) {
        return extension.value;
    }
    return nil;
}




























Executing CMIS Operations

Having set up the session, you can now execute any CMIS operation supported by the SAP Mobile Documents server, as long as the logged-on user has the necessary permissions. For a list of supported operations, see the SAP Mobile Documents Master Guide, Section 10.1 on the Help Portal at http://help.sap.com/mdocs10.

The following sample code snippet shows how to create a document inside a folder using ObjectiveCMIS.


- (void)createDocumentInFolder:(NSString*)folderId title:(NSString *)title content:(NSData*)content
{
    NSInputStream *inputStream = [NSInputStream inputStreamWithData:content];
    NSMutableDictionary *properties = [NSMutableDictionary dictionary];
    [properties setObject:name forKey:@"cmis:name"];
    [properties setObject:@"cmis:document" forKey:@"cmis:objectTypeId"];
    [self.session createDocumentFromInputStream:inputStream
                                      mimeType:@"application/vnd.sap.note"
                                    properties:properties
                                      inFolder:folderId
                                bytesExpected:[content length]
                              completionBlock:^(NSString *objectId,
                                                NSError *error) {
      if(error == nil) {
          // document successfully created
      } else {
        // document couldn't created
      }
  } progressBlock:^(unsigned long long bytesUploaded, unsigned long long bytesTotal) {
      // use this e.g. to display the upload state
      NSLog(@"uploading...(%llu/%llu)", bytesUploaded, bytesTotal);
  }];
}
























To report this post you need to login first.

7 Comments

You must be Logged on to comment or reply to a post.

    1. Jonathan Cooper

      Hi Larry,

      Under the assumption that you are either a customer or partner, you can apply for a Mobile Documents trial account – just contact your SAP representative.

      Best regards,

      Jon

      (0) 

Leave a Reply