MicroStrategy ONE

Apply Custom Logic to Link Drilling and URL API Event Processing in iOS

MicroStrategy Mobile relies on link drilling and the URL API to trigger navigation and perform mobile-specific actions, such as displaying the settings screen or viewing the home screen, inside the app. The Link Drill Handler sample illustrates how to use custom events and custom link drilling. In this sample, every third time that link drilling takes place, a screenshot is taken and shared with the view controller. Every other time that link drilling takes place, the URL API is processed as usual.

The MicroStrategy Mobile SDK provides an API that allows developers to add custom logic when a user performs a link drill or generates a URL API event.

  • The MSILinkDrillHandler class exposes the functionality used to perform link drilling and URL API event processing, as well as the ability to designate an MSILinkDrillCustomEventDelegate delegate object, which is notified when link drilling or URL API events occur in the application.

The diagram below illustrates the workflow of the application when link drilling and URL API events are processed:

To perform custom actions on user input, developers create a custom event delegate, implement the shouldHandleLinkDrillNavigation method of the delegate, and add the logic for manually handling the link drilling navigation in the executeURL method of the delegate. The executeURL method can include logic for processing both out-of-the box events and custom events created by the developer.

  • Creating a custom event delegate
    You use a custom event delegate object (MSILinkDrillCustomEventDelegate) to manually intervene in the processing of link drilling and URL API events, for both custom and out-of-the-box events.
  • Handling link drilling navigation manually
    You implement the shouldHandleLinkDrillNavigation method of your custom event delegate and add your custom logic for processing link drilling and URL API events to the executeURL method.
  • Creating a custom event
    If you want to perform specific actions for an event that is not provided out-of-the-box, you can create a custom event and add custom logic for processing that event to the executeURL method of your custom event delegate.

The MSILinkDrillHandler class is used for processing edit links, as well as hyperlinks and URL APIs. The URL that is passed to the event can either be a standard URL API or it can be an URL that conforms to the syntax of edit links. To help you understand the information that is passed in the URL for edit links, refer to:

Creating a custom event delegate

To create custom code that is responsible for handling link drilling and URL API event processing for MicroStrategy Mobile, developers must define the object that is responsible for handling the navigation and make its class conform to the MSILinkDrillCustomEventDelegate protocol.

The MSILinkDrillCustomEventDelegate protocol has two main methods:

  • -(BOOL)shouldHandleLinkDrillNavigation;
    The custom delegate implements this method to tell MicroStrategy Mobile whether the custom delegate is responsible for handling the link drilling and URL API event processing for the application.
  • -(void)executeURL:(NSString *)url withCommander:(id<MSICommanderDelegate>)commander sourceView:(UIView *)view;
    The custom delegate implements this method to define the logic for processing link drilling and URL API events. In a typical implementation of this method, the logic would determine if and how the URL API should be processed, and then call the method to process the URL API.

The code below provides an example for how to set up the custom delegate. The code assumes that the developer has created a custom event delegate object called CustomEventDelegate that implements the two methods described above.

#import "CustomAppDelegate_CustomLinkDrillHandler.h"

#import <MicroStrategyMobileSDK/MSILinkDrillHandler.h>

@interface CustomAppDelegate_CustomLinkDrillHandler()

@property (strong,nonatomic) CustomEventDelegate *delegate;

@end

@implementation CustomAppDelegate_CustomLinkDrillHandler

-(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

  NSLog(@"app didFinishLaunchingWithOptions");

  BOOL res = [super application:application didFinishLaunchingWithOptions:launchOptions];

  self.delegate = [[CustomEventDelegate alloc]init];

  [MSILinkDrillHandler linkDrillHandler].customEventDelegate = delegate;

  return res;

}

-(BOOL)shouldHandleLinkDrillNavigation{

  return YES;

}

-(void)executeURL:(NSString *)url withCommander:(id<MSICommanderDelegate>)commander sourceView:(UIView *)view{

  [MSILinkDrillHandler handleURLLink:url withCommander:commander];

}

@end

Handling link drilling navigation manually

To handle the application's link drilling and URL API event processing manually, developers return YES for out-of-the-box events and NO for custom events, in the implementation of the shouldHandleLinkDrillNavigation method in the MSILinkDrillCustomEventDelegate delegate object.

Once this is done, all the URL API event and link drilling processing is passed to the executeURL:withCommander:sourceView method of the customEventDelegate object of the MSILinkDrillHandler. Developers can add custom logic on this implementation and perform the navigation programmatically as needed using the static method handleURLLink:withCommander: of the MSILinkDrillHandler class.

Creating a custom event

In addition to adding custom link-handling logic for out-of-the-box events, developers can create custom events and add the logic to handle those events. Custom events are events with identifiers that are equal to or larger than 10000000. For example, a developer could assign mstr://?evt=10000001 to the hyperlink property of a label on the Properties and Formatting dialog, as shown below.

The handling of custom events is always directed to the executeURL:withCommander:sourceView method of the customEventDelegate object of the MSILinkDrillHandler singleton.

A simple example of how this functionality could be used would be to add the ability to take a device screenshot and then display sharing options using a UIActivityViewController for a user to send via SMS.

The following is a snippet of an implementation of this method. In this example, if the URL API matches a custom event with the identifier 10000001, the app should take a screenshot of the screen; otherwise, the code should handle the URL API as normal.

-(void)executeURL:(NSString *)url withCommander:(id<MSICommanderDelegate>)commander sourceView:(UIView *)view{

  if([url isEqualToString:@"mstr://?evt=10000001"]){

    //Take a screenshot and share it with UIActivityViewController

    MSIAppDelegateImpl *_appDelegate = (MSIAppDelegateImpl *)[UIApplication sharedApplication].delegate;

    if ([[UIScreen mainScreen] respondsToSelector:@selector(scale)]) {

      // for retina-display

      UIGraphicsBeginImageContextWithOptions(_appDelegate.window.bounds.size, NO, [UIScreen mainScreen].scale);

      [_appDelegate.window drawViewHierarchyInRect:_appDelegate.window.bounds afterScreenUpdates:NO];

      // non-retina-display

      UIGraphicsBeginImageContext(_appDelegate.window.bounds.size);

      [_appDelegate.window drawViewHierarchyInRect:_appDelegate.window.bounds afterScreenUpdates:NO];

    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();

    UIGraphicsEndImageContext();

    UIActivityViewController *activityViewController = [[UIActivityViewController alloc]initWithActivityItems:@[image] applicationActivities:nil];

    UIPopoverPresentationController *popoverPresentationController = activityViewController.popoverPresentationController;

    popoverPresentationController.sourceView = view;

    [self.window.rootViewController presentViewController:activityViewController animated:YES completion:^{

  }];

  }else{

    //Process the URL API as usual

    [MSILinkDrillHandler handleURLLink:url withCommander:commander];

  }

}

URL format for edit links

An example of the format of the URL that is passed for edit links is shown below.

<ud>

  <hls>

    <hl

      idf="1"

      aopam="2"

      dtxt="Hyperlink1"

      lt="1"

      tid="CDC1F6994357D120F7EBED93D9A6B77A"

      ttp="3"

      tstp="768"

      so="0">

      <prms>

        <prm

          id="DE6BCCFC46932717E07E06A4075E2059"

          pt="2"

          am="4"

          orid="8D679D3711D3E4981000E787EC6DE8A4"

          ortp="12"/>

      </prms>

    </hl>

  </hls>

</ud>

URL parameters for edit links

A description of the parameters in the URL for edit links is provided in the table below:

Element Attribute Description Possible values

hl

 

hyperlink

 

 

aopam

default answer mode

LinkAnswerSamePrompt = 1,

LinkAnswerDoNotAnswer = 2,

LinkAnswerClose = 3,

LinkAnswerDynamic = 4,

LinkAnswerStatic = 5,

LinkAnswerCurrentUnit = 6,

LinkAnswerAllValidUnits=7,

LinkAnswerUseDefaultAnswer = 8

  tid

target GUID

String

For example, CDC1F6994357D120F7EBED93D9A6B77A

 

ttp

target type

ObjectTypeUnknown = -1, ObjectTypeReportDefinition = 3,

ObjectTypeDocumentDefinition = 55,

ObjectTypeAttribute = 12, ObjectTypeMetric = 4,

ObjectTypeAttributeForm = 21,

ObjectTypePrompt=10, ObjectTypeFolder = 8, ObjectTypeConsolidation = 47, ObjectTypeCustomGroup = 1,

ObjectTypeFilter = 1, ObjectTypeDimension=14, ObjectTypeSearch = 39, ObjectTypeExternalLink=67, ObjectTypeExternalObject=68, ObjectTypeFact=13, ObjectTypeTemplate=2, ObjectPromptFilter = 10

 

tstp

target sub-type

ObjectSubTypeUnknown = -1, ObjectSubTypeReportGraph = 0x301, ObjectSubTypeReportGrid = 0x300, ObjectSubTypeReportGridAndGraph = 0x306,

ObjectSubTypeFilter = 0x100, ObjectSubTypeMetric = 0x400, ObjectSubTypeFolder = 0x800, ObjectSubTypeAttribute = 0xC00,

ObjectSubTypeAttributeForm = 0x1500, ObjectSubTypeReportWritingDocument = 0x3701,

ObjectSubTypeReportCube = 776, ObjectSubTypeSegment = 0x103,

ObjectSubTypeExternalLink=17153, ObjectSubTypeExternalObject=17408, ObjectSubTypeCustomGroup = 257

 

idf

is default

0 = NO

1 = YES

 

lt

link type

 
 

url

URL

DssRWLinkReserved = 0,

DssRWLinkHyperLink = 1,

DssRWLinkImage = 2,

DssRWLinkToolTip = 3,

DssRWLinkURL = 4,

DssRWLinkHTML = 5,

DssRWLinkResolvedHyperLinks = 6,

DssRWLinkLastOne = 7

  so

carryover selected mode

CarryOverReserved = 0,

CarryOverMatchbyID = 1,

CarryOverMatchbyName = 2,

prm

 

prompt

 

  id

prompt GUID

String representing the ID of the prompt

For example, DE6BCCFC46932717E07E06A4075E2059

  pt

prompt type

EnumPromptTypeUnsupported = 0,

EnumPromptTypeConstant = 1,

EnumPromptTypeElements = 2,

EnumPromptTypeExpression = 3,

EnumPromptTypeObjects = 4,

EnumPromptTypeDimty = 5

  orid

origin GUID

String representing the ID of the origin object of the prompt (for example, an element prompt's origin property is the attribute where the elements come from)

 

For example, 8D679D3711D3E4981000E787EC6DE8A4

  ortp

origin type

DssTypeAttribute (for an element prompt)

  am

answer mode

LinkAnswerSamePrompt = 1,

LinkAnswerDoNotAnswer = 2,

LinkAnswerClose = 3,

LinkAnswerDynamic = 4,

LinkAnswerStatic = 5,

LinkAnswerCurrentUnit = 6,

LinkAnswerAllValidUnits=7,

LinkAnswerUseDefaultAnswer = 8

  bfi

base form GUID

 

String

e

 

element

 
  ei

element GUID

String representing the ID of the element

  disp_n

element display name

String

  emt

element type

Value from EnumDSSElementType:

DssElementReserved = 0,

DssElementConcrete = 1,

DssElementMetric = 2,

DssElementSubtotal = 3,

DssElementFirst = 4,

DssElementLast = 5,

DssElementDimension = 6,

DssElementConsolidation = 7,

DssElementFilter = 8,

DssElementCustomGroup = 9,

DssElementJoint =10,

DssElementBand =11,

DssElementResidue =12,

DssElementSubexpression =13,

DssElementAll = 14,

DssElementNode = 15,

DssElementNULL = 16,

DssElementAny = 17,

DssElementAttribute = 18