MicroStrategy ONE

Iterate through Data in iOS

Any class that extends the MSIWidgetViewer class can gain access to the widget's underlying grid data by calling the API [widgetHelper dataProvider];. The returned object is a MSIModelData object which wraps all the MSIHeaderValue objects that compose the grid.

You can get information about the underlying grid, such as the grid’s total rows and columns, as well as getting pointers to the grid’s data by using the APIs provided in the MSIModelData object.

The following dataset is used by the code samples in this topic to show how to gain access to the grid’s data:

      

There are two different types of axis cells in the grid: 

  • ROW_AXIS cells

    The row axis cells correspond to the attributes that are placed in the rows of the grid. The row index and column index for the cells in the columns of the grid are color-coded in the two left columns of the table below. 

  • COLUMN_AXIS cells

    The column axis cells correspond to the attributes that are placed in the columns of the grid.  The row index and column index for the cells in the rows of the grid are color-coded in the top two rows of the table below.

 

Instructions and code samples for each step to iterate through data are provided below:

Row count and column count

You can get the row and column count using the following ModelObject APIs:

MSIModelData *modelData = (MSIModelData *)[widgetHelper dataProvider];

[modelData rowCount]; -> Will return 5, since we have 5 rows at the Country|City level.

[modelData columnCount]; -> Will return 4, since we have 5 columns at the Year|Month level.

Getting access to column and row headers

You can access the grid’s row and column headers using the MSIModelData object’s rowHeaderArray and columnHeaderArray APIs. These APIs provide arrays of AttributeHeader objects. Using these APIs with the dataset defined in the table above yields the following results (memory addresses of objects will be different): 

Copy
MSIModelData *modelData = (MSIModelData *)[widgetHelper dataProvider];
 
// when printing this value on the debugging console, the following output is displayed
(lldb) po [modelData rowHeaderArray]
<__NSArrayM 0x16511fd0>(
<AttributeHeader: 0x16511330>,
<AttributeHeader: 0x16511040>
)
(lldb) po [modelData colHeaderArray]
<__NSArrayM 0x16511fb0>(
<AttributeHeader: 0x16510e30>,
<AttributeHeader: 0x16510c70>,
<TemplateMetricsPlaceHolder: 0x16510bb0>
)

Iterating over Data

The main API used to iterate over the grid’s data is defined in the MSIModelData object:

Copy
- (NSMutableArray*)arrayWithHeaderValueOfWholeRowByAxisType:(AxisType)iAxis andRowIndex:(NSInteger)row;

AxisType can be either ROW_AXIS or COLUMN_AXIS depending on the axis where you want to iterate and where RowIndex identifies the row for which the value will be retrieved.

Using this API with the dataset defined in the table above to retrieve a row in the grid yields the following results (memory addresses of objects will be different):

Copy
MSIModelData *modelData = (MSIModelData *)[widgetHelper dataProvider];
NSMutableArray *row = [modelData arrayWithHeaderValueOfWholeRowByAxisType:ROW_AXIS andRowIndex:1];
 
// when printing this value on the debugging console, the following output is displayed
(lldb) po row
<__NSArrayM 0x17d0ee70>(
<AttributeElement: 0x17e28130> {headerValue: 111},
<AttributeElement: 0x17d0edb0> {headerValue: bbb},
<MetricValue: 0x17e21420> {headerValue: (null)},
<MetricValue: 0x17e213a0> {headerValue: (null)},
<MetricValue: 0x17e21320> {headerValue: (null)},
<MetricValue: 0x17e212a0> {headerValue: (null)}
)

Using this API with the dataset defined in the table above to retrieve a column in the grid yields the following results (memory addresses of objects will be different):

Copy
MSIModelData *modelData = (MSIModelData *)[widgetHelper dataProvider];
NSMutableArray *column = [modelData arrayWithHeaderValueOfWholeRowByAxisType:COLUMN_AXIS andRowIndex:1];
 
// when printing this value on the debugging console, the following output is displayed
(lldb) po column
<__NSArrayM 0x17e21b00>(
<AttributeElement: 0x17e27950> {headerValue: 2012},
<AttributeElement: 0x17e27440> {headerValue: Feb 2012},
<DataElement: 0x17e273e0> {headerValue: Profit}
)

Retrieving information from Header objects

You can access the different headers for rows, columns and metrics using the MSIModelData object rowHeaderArray, colHeaderArray, and metricHeaderArray APIs. These APIs return the Header objects, from which you can retrieve the underlying DisplayInfo object that represents either the attribute or the metric in the metadata, and from which both the object ID and the name can be retrieved.

Using these APIs with the dataset defined in the table above to retrieve different Header and DisplayInfo objects would yield the following results: 

Copy
MSIModelData *modelData = (MSIModelData *)[widgetHelper dataProvider];
NSMutableArray *rowAttributeHeaders = [modelData rowHeaderArray];
    NSMutableArray *columnAttributeHeaders = [modelData colHeaderArray];
    NSMutableArray *metricHeaders =[modelData metricHeaderArray];
    MSIHeader *attributeHeader = [rowAttributeHeaders firstObject];
    MSIDisplayInfo *attributeInfo = attributeHeader.displayInfo;
    MSIHeader *metricHeader = [metricHeaders firstObject];
    MSIDisplayInfo *metricInfo = metricHeader.displayInfo;
 
// when printing this value on the debugging console, the following output is displayed
(lldb) po attributeInfo.displayName
Country
(lldb) po attributeInfo.displayInfoID
CCFBE2A5EADB4F50941FB879CCF1721C
(lldb) po metricInfo.displayName
Profit
(lldb) po metricInfo.displayInfoID
4C051DB611D3E877C000B3B2D86C964F

Retrieving value from MSIHeaderValue objects

You can access the cell’s value using the MSIHeaderValue object’s headerValue API. This applies to retrieve both attribute and metric values.

Using this API with the dataset defined in the table above to retrieve a cell’s value yields the following results:

Copy
MSIModelData *modelData = (MSIModelData *)[widgetHelper dataProvider];
NSMutableArray *row = [modelData arrayWithHeaderValueOfWholeRowByAxisType:ROW_AXIS andRowIndex:1];
MSIHeaderValue *attributeCell = [row objectAtIndex:0];
NSString *attributeValue = attributeCell.headerValue;
MSIHeaderValue *metricCell = [row objectAtIndex:2];
NSString *metricValue = metricCell.headerValue;
 
// when printing this value on the debugging console, the following output is displayed
(lldb) po attributeValue
111
(lldb) po metricValue
$200

MSIHeaderValue Semantics

You can retrieve information about the type of data that a given cell contains using the semantics API defined in the MSIHeaderValue class. A cell can have one of the semantics values defined in the BaseFormSemanticType enumeration:

Copy
typedef enum _BaseFormSemanticType {
   SemanticTypeNone = 0,
   SemanticTypeNumber = 2,
   SemanticTypeReplaceText = 3,
   SemanticTypePicture = 4,
   SemanticTypeUrl = 5,
   SemanticTypeQuickSymbol = 10}
BaseFormSemanticType;

Metric thresholds

You can retrieve threshold information using the MSIHeaderValue object. A threshold can be represented in several ways, such as changing the formatting of the cell or replacing the text with a quick symbol. To know the value type, you must first retrieve the semantic of the MSIHeaderValue object. If the semantic value type is SemanticTypeNumber, you can retrieve the formatting information as shown in Retrieving Formatting Information. If the semantic value type is SemanticTypeQuickSymbol, you can retrieve the QuickSymbol as shown in Retrieving Images and Quick Symbols.

Looping through rows

The code snippet below illustratees how to iterate on the grid’s underlying data to gain access to the grid’s rows MSIHeaderValue objects. With access to the MSIHeaderValue objects, you can obtain all the information related to a grid’s cell, such as the cell’s content and the formatting information.

Copy
MSIModelData *modelData = (MSIModelData *)[widgetHelper dataProvider];
    
int rowCount = [modelData rowCount];
NSMutableArray *current;
MSIPropertyGroup *propertyGroup;
for(int i=0;i<rowCount;i++){
    current = [modelData arrayWithHeaderValueOfWholeRowByAxisType:ROW_AXIS andRowIndex:i];
    MSIHeaderValue *value = current.firstObject;
    propertyGroup = value.format;
        
    //get cell font color
    NSString *fontName = [propertyGroup propertyByPropertySetID:FormattingFont propertyID:FontFormattingName];
        
    //get background color
    NSString *colorValueFill = [propertyGroup propertyByPropertySetID:FormattingPatterns propertyID:PatternFormattingFillColor];
    int bgrValueFill = [colorValueFill intValue]; // We got B G R here, but we need RGB
    int rgbValueFill = (bgrValueFill >> 16) + (bgrValueFill & 0x00FF00) + ((bgrValueFill & 0x0000FF) << 16);
    NSString *colorFill = [NSString stringWithFormat:@"%06x", rgbValueFill];
    NSLog(@"Row %d:%@, Font:%@, Color Fill:%@",i,value.headerValue,fontName,colorFill);
}