Posts Tagged URLLoader

Connecting to Google Analytics Data Api using AS3; my failures

EDIT:
Finally I turned my failures into success you can read it here:
How to connect to Google Analytics Data API in AIR
How to connect to Google Analytics Data API in Flash

These past three days I have spent my time trying to connect from an AIR application to Google Analytics Data Api and I have failed. Sometimes you just admit to yourself thatwhat you want to do is just impossible. The problem is that I know it is feasible, Desktop Reporting is doing it with their AIR application called Polaris. Now all I think about is how I can solve this problem. In this post I’m going to show what I tried in order to accomplish this so that it might help others or that others can help me.

The big obstacle at the root of my problem is the fact that you can’t set the Authorization header in ActionScript which is required to make request to the Google server to get data. Here is how I found out about this:

var request:URLRequest = new URLRequest("https://www.google.com/analytics/feeds/accounts/default");
 
request.method = URLRequestMethod.GET;
var tempHeader:URLRequestHeader = new URLRequestHeader("Authorization", "GoogleLogin auth=" + _authToken);
request.requestHeaders = [tempHeader];
var  _secondLoader:URLLoader = new URLLoader();
_secondLoader.addEventListener(Event.COMPLETE, _onSecondLoaderComplete, false, 0, true);
_secondLoader.dataFormat = URLLoaderDataFormat.TEXT;
_secondLoader.load(request);

This resulted in the following runtime error:

ArgumentError: Error #2096: The HTTP request header GoogleLogin auth=DQA … -lQ
cannot be set via ActionScript

From that point on I was aware that you couldn’t set the Authorization request header even thought you see misleading information around the web that doesn’t help. My next try was using HTTPService from the Flex library here is what I tried:

gService.url = "https://www.google.com/analytics/feeds/accounts/default";
 
gService.headers["Authorization"] = "GoogleLogin auth=" + _authToken;
var token:AsyncToken = gService.send();
token.addResponder(new Responder(onResponse, onFault));

This ended up with the same result (obviously).

My next try was using the as3httpclient library which I did in this way:

var client:HttpClient = new HttpClient();
var uri:URI = new URI("https://www.google.com/analytics/feeds/accounts/default");
var request:HttpRequest = new Get();
request.addHeader("Authorization", "GoogleLogin auth=" + _authToken);
 
client.listener.onData = function(event:HttpDataEvent):void {
trace (event.readUTFBytes)
};
client.request(uri, request);

This seemed to work a bit better but it always traced “200″ and not the xml feed it was supposed to return.

So I am at this point very frustrated because I am not able to do something I know is feasible. I have other step I can take in my project and I have some not very optimal way of getting the data, but I have a very bitter taste left in my mouth.  If anyone can help me with this, it would be really appreciated.

, , , , , , , , ,

12 Comments


Sending byteArray and variables to server-side script at the same time

While using the URLLoader classyou can send two types of data to the server. You can either send variables through the URLVariables or by giving a ByteArray to the data property of the URLRequest class. Here is how you would send variables:

package {
  import flash.display.Sprite;
  import flash.net.URLLoader;
  import flash.net.URLRequest;
  import flash.net.URLVariables;
 
  public class URLVariablesExample extends Sprite {
    public function URLVariablesExample() {
      var url:String = "http://www.[yourDomain].com/receiveFile.php";
      var request:URLRequest = new URLRequest(url);
      var variables:URLVariables = new URLVariables();
 
      variables.exampleSessionId = new Date().getTime();
      variables.exampleUserLabel = "guest";
 
      request.data = variables;
 
      var loader:URLLoader = new URLLoader();
      loader.load(request)
    }
  }
}

If you wanted to send a ByteArray, let say to save an image made in your flash on the server, here is how you would pass the data (I’m using the coreLib to convert bitmapData to JPG format which will return a ByteArray) :

package {
  import flash.display.Sprite;
  import flash.net.URLLoader;
  import flash.net.URLRequest;
  import flash.net.URLRequestMethod;
  import flash.display.BitmapData;
  import flash.utils.ByteArray;
  import com.adobe.images.JPGEncoder;
 
  public class ByteArraySendExample extends Sprite {
    public function  ByteArraySendExample() {
      var url:String = "http://www.[yourDomain].com/receiveFile.php";
      var someBitmapData:BitmapData = new BitmapData();//let say we have some bitmapdata
 
      //using the jpeg encoder from the core library
      var jpgEncoder:JPGEncoder = new JPGEncoder(80);
      var myByteArray:ByteArray = jpgEncoder.encode(someBitmapData);
 
      var request:URLRequest = new URLRequest(url);
      request.method = URLRequestMethod.POST;
 
      request.data = myByteArray;
      var loader:URLLoader = new URLLoader();
 
      loader.load(request)
   }
  }
}

The thing is, there is no actual documentation when you want to send both a byteArray and variables. As you can see in the examples, when you send variables, you set the data property of the URLRequest equal the your URLVariables, but when you send a byteArray you also set the data property equal to your byteArray. So you cannot send both type of data at the same time this way. The way I found is actually pretty simple and I don’t why others have not blogged about this (trust me I have looked for this). What you do is you set the data of the URLRequest equal to the byteArray, but you put your variables in the url String of the URLRequest. Here is some code showing it:

package {
  import flash.display.Sprite;
  import flash.net.URLLoader;
  import flash.net.URLRequest;
  import flash.net.URLRequestMethod;
  import flash.display.BitmapData;
  import flash.utils.ByteArray;
  import com.adobe.images.JPGEncoder;
 
  public class   ByteArrayAndVariableSendExample extends Sprite {
    public function  ByteArrayAndVariableSendExample() {
      var url:String = "http://www.[yourDomain].com/receiveFile.php?exampleSessionId="new Date().getTime() + "&exampleUserLabel=guest" ;
 
      var someBitmapData:BitmapData = new BitmapData();//let say we have some bitmapdata
 
      //using the jpeg encoder from the core library
      var jpgEncoder:JPGEncoder = new JPGEncoder(80);
      var myByteArray:ByteArray = jpgEncoder.encode(someBitmapData);
 
      var request:URLRequest = new URLRequest(url);
      request.method = URLRequestMethod.POST;
 
      request.data = myByteArray;
      var loader:URLLoader = new URLLoader();
 
      loader.load(request)
    }
  }
}

Then in your server-side script you recover the variables in the query string and the byteArray in the post part. It’s that simple.

, , , , , , ,

34 Comments