Connecting Flex Mobile to MicroStrategy

Starting with Flex SDK 4.5, Adobe began supporting compiling your application to natively run on iOS and Android.  This presented a great opportunity to write code one time and then have it functional on several platforms.  Unfortunately, MicroStrategy Visualization SDK currently only supports Flex SDK 4.1, just missing out on all of the Mobile goodness.  That got me thinking though, that I personally only use the VisSDK for simple data integration, which is a separate component of my visualizations.  I figured that I could just as easily build my own data integration layer that the Mobile version could use, and after tinkering with it off and on for several months, I finally overcame the final hurdle and am now ready to share my experience.

I’ve written a lot about the MicroStrategy Visualization SDK, and even posted an article about how to get your original visualizations to run natively in iOS.  This method is really more of a hack, and even in it’s follow up post where I was able to get it to communicate with MicroStrategy, the performance was still very bad, and it didn’t support a lot of Mobile-esque controls and optimizations.

Getting MicroStrategy Data
Instead of relying on the Visualization Framework to handle the data integration for me, I needed to do it myself.  The best candidate was to use the TaskProc which is a simple URL based framework that can return the results in plain XML.  I chose to use the URLLoader class to perform this job.

var loader:URLLoader = new URLLoader();

loader.addEventListener(Event.COMPLETE, completeHandler)

URLRequestDefaults.setLoginCredentialsForHost("biwebhost", "domain\user.name", "password");

var req:URLRequest = new URLRequest("http://biwebhost/MicroStrategy/asp/TaskAdmin.aspx?taskId=reportDataService&taskEnv=xml&taskContentType=xml&server=ISERVER&project=PROJECT&authMode=2&styleName=CustomXMLReportStyle&reportID=REPORTGUID");

loader.load(req);

The URLRequestDefaults.setLoginCredentialsForHost() method is something that tripped me up for a long time.  This simple call is how you can pass the login credentials if you’re using IIS with NT Authentication.  Secondly, notice that you need to use an extra character when passing domain\user.name, otherwise it won’t come across correctly.

Once the report is executed and the data is returned, the completeHandler() function will be called (via the Event Listener we added in line 2 above):

private var reportData:ArrayCollection;

private function completeHandler(evt:Event):void {

reportData = loadReportData(loader.data);

}

loader.data contains the actual XML response, and loadReportData is a function that will parse it into an ArrayCollection.  This is where it gets a little dicey.  I’m sure there’s probably a better way to do this, but this was the only method I could figure out.  It doesn’t look very elegant:

private function loadReportData(_data:String):ArrayCollection {
 var columnTitles:Array = new Array();
 var rows:Array = new Array();
 var xml:XMLDocument = new XMLDocument(_data);
 var decoder:SimpleXMLDecoder = new SimpleXMLDecoder();
 var data:Object = decoder.decodeXML(xml);
 var ac:ArrayCollection = new ArrayCollection(rows);
 if (data.taskResponse["mstr-report"].error)
  return null;
 for (var c:int=0;c<data.taskResponse["mstr-report"]["report-data"].titles.col.length;c++)
  columnTitles.push(data.taskResponse["mstr-report"]["report-data"].titles.col[c].value);
 for (var r:int=0;r<data.taskResponse["mstr-report"]["report-data"].rows.row.length;r++) {
  var o:Object = new Object();
  for (var l:int=0;l<data.taskResponse["mstr-report"]["report-data"].rows.row[r].col.length;l++)
   o[columnTitles[l]] = (data.taskResponse["mstr-report"]["report-data"].rows.row[r].col[l].value);
  rows.push(o);
 }
  return ac;
}

Basically, I get a list of the columns in the report first, then iterate through the rows and build an ArrayCollection with the values of each column.  The result is returned and the ArrayCollection reportData is ready for consumption.  This is now the same data state you’d have if you were loading this data out of the Derived Model.

So whatever functions you were using before to get your data out of MicroStrategy, you can replace it with this bit of code and now you are MicroStrategy independent for data integration.  You can now develop natively in Flex 4.5+ for your Mobile platform and deploy it.

You may also like...