Flash(AIR for iOS/Android)でTwitterからユーザー名と画像URLを取得する

##ググって引っかかるTwitter用ライブラリの大半はAPI1.0時代のものなのでお気をつけ下さい
そんな中、Oauth用ライブラリと暗号化用ライブラリを使ったFlexでのTweetサンプルを書いている記事を発見。
[Twitter API in AIR Mobile App | RJDesignz](http://rjdesignz.com/adobe-flex/twitter-api-in-air-mobile-app/)
[Twitter API 1.1 in Adobe AIR Mobile | RJDesignz](http://rjdesignz.com/tutorials/twitter-api-1-1-in-adobe-air-mobile/)

これをFlashへ移植しつつGetリクエストなものへ改変する。

##開発環境
・MacOSX 10.8.5
・Flash CC 2014 + Flash Builder 4.7
　- エディタ担当：Flash Builder 4.7
　- 書き出し担当：Flash CC 2014
・パブリッシュのターゲットはAIR for iOS/Android

###使用ライブラリ
[oauth-as3 - Actionscript 3 library for oAuth - Google Project Hosting](https://code.google.com/p/oauth-as3/)
[as3crypto - Cryptography library for ActionScript 3, including partial TLS 1.0 support - Google Project Hosting](https://code.google.com/p/as3crypto/)
**※.swcで導入するとエラーを吐くのでソースコードを導入する**

上記ライブラリには**mx.utils.UIDUtils**も必要になるので、下記にあるframework.swcを使用します。
/Applications/Adobe Flash Builder 4.7/sdks/4.6.0/frameworks/libs/framework.swc

##こんな感じになりました
画面の四角をタップ
↓
認証開始
↓
trace()でユーザー名と画像URLを出力


```Twlogin.as
package
{
	import flash.display.Graphics;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.HTTPStatusEvent;
	import flash.events.IOErrorEvent;
	import flash.events.LocationChangeEvent;
	import flash.events.MouseEvent;
	import flash.filesystem.File;
	import flash.filesystem.FileMode;
	import flash.filesystem.FileStream;
	import flash.geom.Rectangle;
	import flash.media.StageWebView;
	import flash.net.URLLoader;
	import flash.net.URLRequest;
	import flash.net.URLRequestMethod;
	import flash.net.URLVariables;
	
	import org.iotashan.oauth.OAuthConsumer;
	import org.iotashan.oauth.OAuthRequest;
	import org.iotashan.oauth.OAuthSignatureMethod_HMAC_SHA1;
	import org.iotashan.oauth.OAuthToken;
	import org.iotashan.utils.OAuthUtil;
	import org.iotashan.utils.URLEncoding;

	public class Twlogin extends Sprite
	{
		public const TWITTER_CONSUMER_KEY:String = "xxxxxxxxxx";
		public const TWITTER_CONSUMER_SECRET:String = "xxxxxxxxxx";
		// API URLs
		public const VERIFY_CREDENTIALS:String = "https://api.twitter.com/1.1/account/verify_credentials.json";
		private var twitterRequestURL:String = "https://api.twitter.com/oauth/request_token";
		private var twitterAuthURL:String = "https://api.twitter.com/oauth/authorize";
		private var twitterTokenURL:String = "https://api.twitter.com/oauth/access_token";
		public var twitterAccessObj:Object = {};
		private var requestToken:OAuthToken;
		private var accessToken:OAuthToken;
		private var oAuthConsumer:OAuthConsumer;
		private var twitterWebView:StageWebView;
		private var webViewStartLocation:int;
		private var accessRequest:OAuthRequest;
		private var thisProfile:Object = {};
		private var userName:String;
		protected var signature:OAuthSignatureMethod_HMAC_SHA1 = new OAuthSignatureMethod_HMAC_SHA1();
		// View Creation Complete
		private var urlRequest:URLRequest;
		private var loader:URLLoader;
		private var imgURLOriginal:String;

		public function Twlogin():void{
			stage.scaleMode = "noScale";
			stage.align = "TL";

			var sprite:Sprite = new Sprite();
			stage.addChild(sprite);
			var g:Graphics = sprite.graphics;
			g.lineStyle (5, 0xAA0000, 1.0);
			g.beginFill (0xFF4444, 1.0);
			g.drawRect (0,0,100,100);
			sprite.x = 100;
			sprite.y = 100;
			
			sprite.buttonMode = true;
			sprite.addEventListener(MouseEvent.CLICK, onTwitterRequest);
		}
			
		private function onTwitterRequest(event:MouseEvent):void
		{
			//Read details from any existing file
			readTwitterAccess();

			//Check if the Access Key and Access Token already Exist
			if(twitterAccessObj.accessKey && twitterAccessObj.accessSecret)
			{
				verifyAccessToken();
			}
			else
			{
				oAuthConsumer = new OAuthConsumer(TWITTER_CONSUMER_KEY, TWITTER_CONSUMER_SECRET);
				var oauth:OAuthRequest = new OAuthRequest(OAuthRequest.HTTP_MEHTOD_GET, twitterRequestURL, null, oAuthConsumer);
				var request:URLRequest = new URLRequest(oauth.buildRequest(new OAuthSignatureMethod_HMAC_SHA1()));
				var loader:URLLoader = new URLLoader(request);
				loader.addEventListener(Event.COMPLETE,onLoaderComplete);
			}
		}

		//Loaded Twitter Access Token Request URL
		private function onLoaderComplete(e:Event):void
		{
			requestToken = OAuthUtil.getTokenFromResponse(e.currentTarget.data);
			var authRequest:URLRequest = new URLRequest('https://api.twitter.com/oauth/authorize?oauth_token=' + requestToken.key);
			
			// StageWebView to Authorize the App
			twitterWebView = new StageWebView();
			twitterWebView.viewPort = new Rectangle(0, 0, stage.stageWidth, stage.stageHeight);
			twitterWebView.stage = this.stage;
			twitterWebView.assignFocus();
			twitterWebView.loadURL(authRequest.url);
			twitterWebView.addEventListener(LocationChangeEvent.LOCATION_CHANGE, onLocationChange);
		}
		// Web View Location Change
		private function onLocationChange(e:LocationChangeEvent):void{
			var location:String = e.location;
			
			//Here we need to extract the oAuth Verifier URL from the redirect URL
			if(location.search("oauth_verifier") != -1)
			{
				var oAuthVerifier:String = location.substr(location.search("oauth_verifier") + 15);
				onPin(oAuthVerifier);
			}
		}
		
		// We now have the PIN, use this
		private function onPin(oAuthVerifier:String):void
		{
			var params:Object = new Object();
			params.oauth_verifier = oAuthVerifier;
			
			accessRequest = new OAuthRequest(OAuthRequest.HTTP_MEHTOD_GET, twitterTokenURL, params, oAuthConsumer, requestToken);
			var accessUrlRequest:URLRequest = new URLRequest(accessRequest.buildRequest(new OAuthSignatureMethod_HMAC_SHA1()));
			var accessLoader:URLLoader = new URLLoader(accessUrlRequest);
			accessLoader.addEventListener(Event.COMPLETE, onAccessRequestComplete);
		}
		
		// Got the required details. Dispose the web view and write details to local storage.
		private function onAccessRequestComplete(e:Event):void
		{
			var namePoint:Number = e.currentTarget.data.indexOf("screen_name=");
			userName = e.currentTarget.data.substring(namePoint+12);
			trace("userName:", userName);
			
			accessToken = OAuthUtil.getTokenFromResponse(e.currentTarget.data);
			twitterAccessObj.accessKey = accessToken.key;
			twitterAccessObj.accessSecret = accessToken.secret;
			
			twitterWebView.dispose();
			writeTwitterAccess();
			onGetTwitter();
		}

		// Post the message on Twitter
		private function onGetTwitter():void
		{
			var consumer:OAuthConsumer = new OAuthConsumer(TWITTER_CONSUMER_KEY, TWITTER_CONSUMER_SECRET);
			var token:OAuthToken = new OAuthToken(twitterAccessObj.accessKey, twitterAccessObj.accessSecret);
			var getRequest:OAuthRequest = new OAuthRequest(OAuthRequest.HTTP_MEHTOD_GET, "https://api.twitter.com/1.1/users/show.json", {"screen_name":userName}, consumer, token);
			
			urlRequest = new URLRequest(getRequest.buildRequest(new OAuthSignatureMethod_HMAC_SHA1()));
			urlRequest.method = URLRequestMethod.GET;
			var loader:URLLoader = new URLLoader(urlRequest);
			loader.addEventListener(Event.COMPLETE, onTwitterGetComplete);
			loader.addEventListener(IOErrorEvent.IO_ERROR, onTwitterIOError);
			loader.addEventListener(HTTPStatusEvent.HTTP_STATUS, onTwitterHttpStatus);
		}

		// Credentials already exist, verify these
		public function verifyAccessToken() : void
		{
			trace("verify access token");
			var consumer:OAuthConsumer = new OAuthConsumer(TWITTER_CONSUMER_KEY, TWITTER_CONSUMER_SECRET);
			var token:OAuthToken = new OAuthToken(twitterAccessObj.accessKey, twitterAccessObj.accessSecret);
			var oauthRequest:OAuthRequest = new OAuthRequest( "GET", VERIFY_CREDENTIALS, null, consumer, token );
			var request:URLRequest = new URLRequest( oauthRequest.buildRequest( signature, OAuthRequest.RESULT_TYPE_URL_STRING ) );
			request.method = "GET";
			
			loader = new URLLoader( request );
			loader.addEventListener( Event.COMPLETE, verifyAccessTokenHandler );
			loader.addEventListener(IOErrorEvent.IO_ERROR, onTwitterIOError);
			loader.addEventListener(HTTPStatusEvent.HTTP_STATUS, onTwitterHttpStatus);
			loader.load(urlRequest);
		}
		
		//Successfully Posted on Twitter
		private function onTwitterGetComplete(e:Event):void
		{
			trace("Twitter Success!");
			var obj:Object = JSON.parse(e.target.data);
			var imgURL:String = obj.profile_image_url;
			imgURLOriginal = imgURL.replace("_normal", "");
			trace("imgURL:",imgURLOriginal);
		}
		
		// Twitter IO Error
		private function onTwitterIOError(e:IOErrorEvent):void{
			trace("Twitter IOError!");
		}
		// Twitter HTTP Status Error
		private function onTwitterHttpStatus(e:HTTPStatusEvent):void
		{
			trace("Twitter HttpStatus!");
		}
		// Access Token Exists
		protected function verifyAccessTokenHandler(event:Event):void
		{
			trace("Valid Access Data Exists");
			trace(userName, imgURLOriginal);
		}
		
		public function readTwitterAccess():void
		{
			var file:File = File.applicationStorageDirectory.resolvePath("tw.file");
			var fileStream:FileStream = new FileStream();
			if(file.exists)
			{
				fileStream.open(file, FileMode.READ);
				var obj:Object = fileStream.readObject() as Object;
				twitterAccessObj.accessKey = obj.twitterAccessKey;
				twitterAccessObj.accessSecret = obj.twitterAccessSecret;
				fileStream.close();
			}
			else
			{
				trace("No File Present");
			}
		}
		
		public function writeTwitterAccess():void
		{
			var file:File = File.applicationStorageDirectory.resolvePath("tw.file");
			var fileStream:FileStream = new FileStream();
			fileStream.open(file, FileMode.WRITE);
			var obj:Object = {};
			obj.twitterAccessKey = twitterAccessObj.accessKey;
			obj.twitterAccessSecret = twitterAccessObj.accessSecret;
			fileStream.writeObject(obj);
			fileStream.close();
		}
	}
}
```