Technology Blogs by SAP
Learn how to extend and personalize SAP applications. Follow the SAP technology blog for insights into SAP BTP, ABAP, SAP Analytics Cloud, SAP HANA, and more.
Showing results for 
Search instead for 
Did you mean: 
0 Kudos

Sample code Fridays?  Sounds good.

The last several posts have been about the HttpConversationManager and SODataStore components.  This ties in nicely with one of the other components which got a major facelift in the SDK 3.0 SP05 release:  Supportability.  Also, I'll touch on the Usage library, which isn't part of Supportability, but has a similar behavior for the purpose of this discussion.

Supportability Components

Our Supportability component refers to a set of libraries for:

  1. Client logging
  2. E2E Trace (SAP Passport/BTX XML)

When using these libraries, you typically use the SupportabilityFacade singleton, to get the respective manager, which holds the context of the respective log content throughout the application session.

Client Logging:

id<SAPClientLogManager>logManager = [[SAPSupportabilityFacade sharedManager] getClientLogManager];

E2E Trace:

id<SAPE2ETraceManager> e2eTraceManager = [[SAPSupportabilityFacade sharedManager] getE2ETraceManager];

Uploading Logs

When you're ready to upload the contents of the logs or BTX document to the Mobile Platform server, you call an upload method on the manager, which takes a SupportabilityUploader as the parameter.  As you can see, the SupportabilityUploader takes both a HttpConversationManager and NSURLRequest as parameters.  We've already discussed how to construct a HttpConversationManager, so it's easy to reuse the regular manager that's used for all other data requests.  But, you need to know the URL of the endpoint where the log (or trace) should be POSTed.

SupportabilityUploader *uploader = [[SupportabilityUploader alloc] initWithHttpConversationManager:self.httpConvManager urlRequest:request];

[e2eTraceManager uploadBTX:uploader completion:^(NSError* error) {

    if (error == nil) {

        NSLog(@"upload succeeded");


    else {

        NSLog(@"upload failed: %@", [error description]);



For the Usage library, the developer does not need to construct an uploader, since the Usage library uses Reachability settings (wifi vs. cellular data) to determine when to upload the Usage records.  But, it also requires a URL and HttpConversationManager--passed in its initialization method:

[Usage initUsageWithURL:[self.baseURL clientUsageURL] httpConversationManager:self.httpConvManager];

URL Schemes Reference

For reference, here are the main URL's required for Supportability, and also Usage, and Data requests:

  • Data:            <protocol>://<host>:<port>/<appId>/
  • Client Logs: <protocol>://<host>:<port>/clientlogs
  • E2E Trace:    <protocol>://<host>:<port>/btx
  • Usage:          <protocol>://<host>:<port>/clientusage

These URL schemes are as documented as of SDK 3.0 SP05/06.  Please consult the documents for your particular version, if you encounter any issues.

Note that only the Data requests include the applicationId as a URL path component.  The other URL endpoints are constant for all applications on a Mobile Platform server.  The server uses the X-SMP-APPCID or X-HM-APPCID cookies passed with the request to map the uploaded documents to the correct application.

Sample Code

I've mocked up a helper category on NSURL, that generates these url schemes.  It is posted (along with the code snippets shared above) in the open-source STSOData project here:  NSURL+MobilePlatform.

@interface NSURL (MobilePlatform)

@property (nonatomic, copy) NSString *appId;


helper constructor for handling the output of MAFLogonRegistrationContext


-(NSURL *)initWithHost:(NSString *)host port:(int)port protocol:(BOOL)isSecure appId:(NSString *)appId;


base constructor... could be changed slightly, depending on the interface of how configurations are acquired

BaseURL string should be:  <protocol>://<host>:<port>


-(NSURL *)initWithBaseURLString:(NSString *)urlString appId:(NSString *)appId;




-(NSURL *)applicationURL;




-(NSURL *)clientLogsURL;




-(NSURL *)btxURL;




-(NSURL *)clientUsageURL;


The concept is simple:  when you know the application connection settings (either from MAFLogon, in the -logonFinishedWithError: callback, or from your own code), construct a NSURL containing host, port, protocol, and applicationId.  Then, store it somewhere easily accessible:  on the AppDelegate, or a LogonHandler or DataController singleton class.

When you're setting up the SupportabilityUploader, Usage library, or SODataStore's, you can just access the getter on this base URL to construct the correct scheme.

Here is an example configuration of the SupportabilityUploader, implemented on a category of the class containing my shared base URL:

@implementation LogonHandler (E2ETrace)

-(SupportabilityUploader *)configuredUploader {


    BTX upload endpoint is constant for all applications on a host:port


    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[self.baseURL btxURL]];


    Set the HttpConversationManager and request to the SupportabilityUploader


SupportabilityUploader *uploader = [[SupportabilityUploader alloc] initWithHttpConversationManager:self.httpConvManager


    return uploader;


//Happy Weekend!