Version 2021

Manage Caches in iOS

Because you cannot extend the storage capacity on an iPhone or iPad, cache management is very important. The MSICacheManager APIs give you more granular control of the caches that MicroStrategy Mobile has on the device. You can use these APIs to do the following:

Delete Caches

The MSICacheManager is a singleton that can be obtained by calling:

Copy
MSICacheManager *manager = [MSICacheManager manager];

Once you have a pointer to the manager, you can delete caches at different levels: 

  •  All caches on the device

    MSICacheManager *manager = [MSICacheManager manager];

    [manager deleteAllCaches];

  • All caches for a given report/document by providing its object Id

    MSICacheManager *manager = [MSICacheManager 
    		manager]; 
    [manager deleteCachesForObjectWithId:@” 
    				BAFCD2A948F1A8D49D2FEC879FB834AD”]; //Deletes all caches for document 
    				BAFCD2A948F1A8D49D2FEC879FB834AD, multiple caches can exist for a given 
    				document since there is one cache per set of prompt answers provided for 
    			a given execution
    
  • All caches that were retrieved before a certain date

    MSICacheManager *manager = [MSICacheManager 
    		manager]; 
    NSDate *now = [NSDate date];
    NSDate *sevenDaysAgo = [now dateByAddingTimeInterval:-7*24*60*60];
    [manager deleteAllCachesBeforeDate:sevenDaysAgo];
    
  • Caches for a given report/document Id with a given set of prompt answers by providing the key of the cache

    MSICacheManager *manager = [MSICacheManager 
    			manager];
    ProjectInfo *project = [ProjectInfo 
    			defaultProjectInfo];
    MSIDocumentCache *cache = [manager 
    				cacheForKey:[NSString stringWithFormat: @"%@%@%@",[project projectIdentifier],@” 
    			BAFCD2A948F1A8D49D2FEC879FB834AD”,nil];
    [manager deleteCache:cache];
    

Retrieve Caches 

The MSICacheManager also provides an API to retrieve caches programmatically for a given report or document. This can be done by using the following API in MSICacheManager:

/**
* This method will retrieve cache at report/document and prompt answer level.
* @param objectId is the id of the object you want to retrieve cache for.
* @param withPriority is used to define the priority of current request.
* @prarm projectInfo is used to specify project, if not provided, we will use default projectInfo
* @param block is used when the MSMCache is retrieved.
*/
-(void)retrieveCacheForObjectId:(NSString*)objectId withPriority:(MSMCachePriorities)priority withElementsPromptAnswers:(NSString*)elementsPromptAnswers andValuePromptAnswers:(NSString*)valuePromptAnswers andProjectInfo:(MSIProjectInfo*)projectInfo completionHandler:(void(^)(MSIDocumentCache* documentCache, NSError* error))handlerBloc

This API is asynchronous and only works if the application is in the foreground (as of update 3, this API doesn’t support background cache downloads). When the cache retrieval completes, the cache will be available for MicroStrategy to use when the user executes the retrieved document.

Add Custom Logic to Manage Caches

You can use the MSICacheManager APIs to customize the way caches are managed by MicroStrategy Mobile.

For example, suppose that you want the application to delete all existing caches and reload a given set of caches each time a specific document is opened between 10 am and 4 pm. You could accomplish this by creating a custom AppDelegate class that overrides one method and defines another method:

  • Override the didFinishLaunchingWithOptions method and add code to force the application to reload a given set of caches every minute between 10 am and 4 pm.
  • -(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{
      BOOL res = [super application:application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions ];
      NSDate* now = [NSDate date];
      NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
      NSDateComponents *dateComponents = [gregorian components:(NSCalendarUnitHour  | NSCalendarUnitMinute | 
      NSCalendarUnitSecond) fromDate:now];
      NSInteger hour = [dateComponents hour];
      if(hour >= 10 && hour <= 16){
        [[MSICacheManager manager]: deleteAllCaches
        [NSTimer scheduledTimerWithTimeInterval:60.0
        target:self
        selector:@selector(reloadSpecifiedCaches)
        userInfo:nil
        repeats:YES];
      }
      return res;
    }

    The code checks to see if the time is between 10 am and 4 pm. If it is, it sets a timer with an interval of 60 seconds and calls the reloadSpecifiedCaches method, which deletes a specified set of existing caches and fetches it again.

  • Define the reloadSpecifiedCaches method as follows and add code to delete the document cache and fetch it again each time a specified document is opened.

    -(void)reloadSpecifiedCaches{
      NSString *displayID = @"define document ID";  [[MSICacheManager manager]deleteCachesForObjId:displayID projectInfo:[MSIProjectInfo defaultProjectInfo]];
      [[MSICacheManager manager]retrieveCacheForObjectId:displayID withPriority:MSMCachePriorityHigh withElementsPromptAnswers:nil andValuePromptAnswers:nil andProjectInfo:[MSIProjectInfo defaultProjectInfo] completionHandler:^(MSIDocumentCache *documentCache, NSError *error) {
      }];
    }

Now, instead, suppose that you want the application to delete all existing caches and reload all caches each time a user launches the application between 10 am and 4 pm. You could accomplish this by creating a custom AppDelegate class that overrides two methods:

  • Override the didFinishLaunchingWithOptions method and add code to force the application to reload every minute between 10 am and 4 pm.
  • -(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{
      BOOL res = [super application:application didFinishLaunchingWithOptions:launchOptions];
      NSDate* now = [NSDate date];
      NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
      NSDateComponents *dateComponents = [gregorian components:(NSCalendarUnitHour  | NSCalendarUnitMinute | NSCalendarUnitSecond) fromDate:now];
      NSInteger hour = [dateComponents hour];
      if(hour <= 10 && hour >= 16){
        [[MSICacheManager manager]deleteAllCaches];
        [NSTimer scheduledTimerWithTimeInterval:60.0
        target:self
        selector:@selector(reloadHomeScreenDocument)
        userInfo:nil
        repeats:YES];
      }
      return res;
    }

    The code checks to see if the time is between 10 am and 4 pm. If it is, it deletes all existing caches, sets a timer with an interval of 60 seconds, and calls the reloadHomeScreenDocument method.

  • Override the reloadHomeScreenDocument method and add code to delete the cache and fetch it again each time the Home screen is opened.
  • -(void)reloadHomeScreenDocument{
      MSIHomeScreenSettings* homeScreenSettings = [[[MSIPreferencesStore preferencesStore]masterPreferences]valueForKey:@"homeScreen"];
      NSInteger homeScreenType = [homeScreenSettings homeScreenType];
      if (homeScreenType == HomeScreenTypeResultSet) {
        NSString *displayID = homeScreenSettings.resultSet.displayObject.ID;
        [[MSICacheManager manager]deleteCachesForObjectId:displayID projectInfo:[MSIProjectInfo defaultProjectInfo]];
        [[MSICacheManager manager]retrieveCacheForObjectId:displayID withPriority:MSMCachePriorityHigh withElementsPromptAnswers:nil andValuePromptAnswers:nil andProjectInfo:[MSIProjectInfo defaultProjectInfo] completionHandler:^(MSIDocumentCache *documentCache, NSError *error) {
      }];
    }

    The code checks to see if the the screen type is the Home screen and if it is, it deletes the old caches and retrieves the new caches.