Easiest method to check network status on iPad with Adobe Air - actionscript-3

I would like to check the network status on the iPad with Adobe Air, at this moment i am checking by sending a URLREQUEST to Google.com. Is there any other better way to monitor the network status, and know if there is a connection or connection have been dropped. Thanks for any suggestion.

Tricky part here we are not ping some interval times. so we use
NativeApplication.nativeApplication.addEventListener(Event.NETWORK_CHANGE, onNetwork_ChangeHandler);
It will trigger when ever change net status change so performance wise also good.
Because Ping is very costly operation.So call start() URLMontior after network changed triggered then we call stop().
package com.abc.net
{
import air.net.URLMonitor;
import flash.desktop.NativeApplication;
import flash.events.Event;
import flash.events.EventDispatcher;
import flash.events.IEventDispatcher;
import flash.events.StatusEvent;
import flash.net.URLRequest;
[Event(name="networkStatusChanged", type="flash.events.Event")]
public class NetStatusMonitor extends EventDispatcher
{
private var urlMonitor:URLMonitor;
private var url:String;
public function KBNetStatusMonitor(url:String = 'http://www.adobe.com')
{
super();
this.url = url;
NativeApplication.nativeApplication.addEventListener(Event.NETWORK_CHANGE, onNetwork_ChangeHandler);
}
protected function onNetwork_ChangeHandler(event:Event):void
{
start();
}
public function start():void
{
urlMonitor = new URLMonitor(new URLRequest(url));
urlMonitor.addEventListener(StatusEvent.STATUS, onNetStatus_ChangeHandler);
if(!urlMonitor.running)
urlMonitor.start();
}
public function stop():void
{
if(urlMonitor.running)
urlMonitor.stop();
}
private function onNetStatus_ChangeHandler(event:StatusEvent):void
{
trace("event code " + event.code);
trace("event level " + event.level);
dispatchEvent(new NetStatusEvent(NetStatusEvent.NETWORK_STATUS_CHANGED,urlMonitor.available));
stop();
}
}
}
Event Class
package com.abc.net
{
import flash.events.Event;
public class NetStatusEvent extends Event
{
public static const NETWORK_STATUS_CHANGED:String = "networkStatusChanged";
public var status:Boolean;
public function NetStatusEvent(type:String, status:Boolean, bubbles:Boolean=false, cancelable:Boolean=false)
{
super(type, bubbles, cancelable);
this.status = status;
}
override public function clone():Event
{
return new NetStatusEvent(type, status, bubbles,cancelable);
}
}
}
Usage :
var netStatusMonitor:NetStatusMonitor = new NetStatusMonitor();
netStatusMonitor.addEventListener(NetStatusEvent.NETWORK_STATUS_CHANGED,function(event:NetStatusEvent):void {
statusCallBack.call(null,event.status);
});
netStatusMonitor.start();

Related

Where must be custom logic in pureMVC (as3)?

I tried to write small as3 program based on framework pureMVC.
I understood basic principles of it, but I can't understand, where I must place custom logic.
For example, I must load 10 images. I created command, that init Proxy.
package app.controller
{
import app.model.GalleryProxy;
import dicts.Constants;
import org.puremvc.interfaces.INotification;
public class LoadFilesCommand extends BaseCommand
{
public function LoadFilesCommand() { }
override public function execute(note:INotification):void
{
facade.registerProxy(new GalleryProxy(Constants.FILES_LIST));
}
}
}
And Proxy is:
package app.model
{
import dicts.Constants;
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.Loader;
import flash.display.LoaderInfo;
import flash.events.ErrorEvent;
import flash.events.Event;
import flash.events.IOErrorEvent;
import flash.net.URLRequest;
import org.puremvc.interfaces.IProxy;
import org.puremvc.patterns.proxy.Proxy;
public class GalleryProxy extends Proxy implements IProxy
{
public function GalleryProxy(list:Vector.<String>)
{
super(Constants.PROXY_GALLERY);
_fileList = list;
_total = _fileList.length;
load();
}
public function get currentImage():Bitmap
{
return _images[_index];
}
//--------------------------------------------------------------------------
// PRIVATE SECTION
//--------------------------------------------------------------------------
private var _fileList:Vector.<String>;
private var _total:uint;
private var _loaded:uint = 0;
private var _images:Array = [];
private var _index:int;
private function load():void
{
var loader:Loader;
for (var i:int = 0; i < _total; i++)
{
loader = new Loader();
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, imageLoadHandler);
loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, errorHandler);
loader.load(new URLRequest(_fileList[i]));
}
}
private function imageLoadHandler(event:Event):void
{
var info:LoaderInfo = LoaderInfo(event.currentTarget);
_images[Constants.FILES_LIST.indexOf(info.url)] = info.content;
info.removeEventListener(Event.COMPLETE, imageLoadHandler);
info.removeEventListener(IOErrorEvent.IO_ERROR, errorHandler);
_loaded++;
if (_loaded >= _total)
sendNotification(Constants.COMMAND_SHOW_MAIN);
}
private function errorHandler(event:ErrorEvent):void
{
throw new Error("bad link or internet disconnect");
}
}
}
Now my Proxy is loading images independently (functions load() and imageLoadHandler)
Is it correct?
Or I must move this logic to Command class?
Or I must create some LoadService.as, which will contains this logic?
What is the correct variant for pureMVC?
Do you want to load your 10 images on application startup? If not, make load() public and call it from a Mediator, responding to a UI event.
If so, what you have will work fine. One alternative would be writing GalleryProxy so it doesn't call load() in the constructor - instead, you could have the Command register the proxy, load the image list, and call proxy.load(images[i]) in a loop.

as3 StageWebView in a class not displaying

I am sure this is an easy one. I have one Main.as class calling a another class that is loading a StageWebView. If called by itself the StageWebView works fine, but when I call it from another class it will not display. What simple thing am I forgetting?
Perhaps it has something to do with the "stage" in the loaded class?
Main.as
public function addPopeNews()
{
thePopeNews = new popeNews();
addChild(thePopeNews);
}
PopeNews.as
package com
{
import flash.display.MovieClip;
import flash.display.StageAlign;
import flash.display.StageScaleMode;
import flash.events.*;
import flash.net.URLRequest;
import flash.media.StageWebView;
import flash.geom.Rectangle;
public class popeNews extends MovieClip
{
public var backBar:popeNewsBar;
public var webView:StageWebView;
public function popeNews()
{
webView=new StageWebView();
webView.stage = this.stage;
webView.loadURL("www.myUrl.com");
trace("POPE NEWS!!!"); /// trace works!
backBar = new popeNewsBar();
backBar.width = Main._screenX;
backBar.scaleY = backBar.scaleX;
webView.addEventListener(Event.COMPLETE, webLoaded);
webView.addEventListener(LocationChangeEvent.LOCATION_CHANGING,onChanging);
}
public function webLoaded(e:Event)
{
trace("web loaded"); // trace works!!
if (webView.isHistoryBackEnabled)
{
addChild(backBar);
backBar.bb.addEventListener(MouseEvent.CLICK, goBack);
webView.viewPort = new Rectangle(0,backBar.height,Main._screenX,Main._screenY - backBar.height);
}
else
{
webView.viewPort = new Rectangle(0,0,Main._screenX,Main._screenY);
}
}
public function goBack(e:Event)
{
if (webView.isHistoryBackEnabled)
{
trace("Called GO BACK");
webView.historyBack();
removeChild(backBar);
backBar.bb.removeEventListener(MouseEvent.CLICK, goBack);
return;
}
if (webView.isHistoryForwardEnabled)
{
webView.historyForward();
return;
}
}
public function onError(e:ErrorEvent):void
{
//infoBox.text="Page is not available. Try reloading.";
}
public function onChanging(e:LocationChangeEvent):void
{
//webView.viewPort = null;
trace("Called CHANGING!!!");
}
///
}
}
You are right, the stage is null in the PopeNews constructor. You should put your initialization code into a new method, and listen for the ADDED_TO_STAGE event.
public function popeNews()
{
addEventListener(Event.ADDED_TO_STAGE, addedToStageHandler);
}
private function addedToStageHandler(ev:Event):void
{
webView=new StageWebView();
webView.stage = this.stage;
webView.loadURL("www.myUrl.com");
trace("POPE NEWS!!!"); /// trace works!
backBar = new popeNewsBar();
backBar.width = Main._screenX;
backBar.scaleY = backBar.scaleX;
webView.addEventListener(Event.COMPLETE, webLoaded);
webView.addEventListener(LocationChangeEvent.LOCATION_CHANGING,onChanging);
}
Also, by convention class names are capitalized.

as3 calling a function in Main.as Document Class from another class

I am sure this is a popular question but I can't find the exact answer I need. I simply need to access a function or functions created in the Main.as document class. I have tried several methods and they do not seem to work. Here is one example I tried.
anotherClass.as // This needs to access functions Main.as
package com
{
import Main;
public class anotherClass
{
private var stageMain:Main;
public function anotherClass()
{
// tries to call a function in Main.as called languageLoaded. NO WORK!
stageMain.languageLoaded("English");
// in the Main.as languageLoaded is a public function
}
}
}
The cleaner way is to simply pass a reference to Main to the constructor of the class you want to be able to access it.
For example, your AnotherClass could look like this:
class AnotherClass
{
private var _main:Main;
public function AnotherClass(main:Main)
{
_main = main;
_main.test(); // Success!
}
}
And your main class:
class Main
{
public function Main()
{
var another:AnotherClass = new AnotherClass(this);
}
public function test():void
{
trace("Success!");
}
}
public class MainDoc extends MovieClip // as long as it extends eventDispatcher you re fine
{
private var otherClass:OtherClass;
public function MainDoc()
{
otherClass = new OtherClass();
otherClass.addEventListener("otherClassCustomEvent", onOtherClassReady);
otherClass.startLogic();
}
public function onOtherClassReady(event:Event = null)
{
trace("from other class:", otherClass.infoToShare) // traces "from other class: YOLO!"
}
}
public class OtherClass extends EventDispatcher // must extend the event dispatcher at least
{
public var infoToShare:String;
public function OtherClass()
{
}
public function startLogic()
{
// do what you got to do
// when you have your data ready
infoToShare = "YOLO!";
dispatchEvent("otherClassCustomEvent");
}
}
Once you're confortable with that, you can start looking into building custom events that could carry the variable to send back
Ok I got the following code to work. It's really a messy solution but I didn't know of a better way. It works. I just hope it's stable and does not use a lot of resources.
If you have a much better Idea I am open.
Here is the MainDoc.as
package {
import flash.display.MovieClip;
import flash.events.*;
import com.*;
import com.views.*;
import flash.display.*;
import flash.filesystem.*;
import com.greensock.*;
import com.greensock.easing.*;
import flash.system.System;
public class mainDoc extends MovieClip
{
/// (Get Main Doc flow) this creates an instace of the main timeline
/// and then I send it
private static var _instance:mainDoc;
public static function get instance():mainDoc { return _instance; }
/// Calls the defaultVars.as in to "vars".
var vars:defaultVars = new defaultVars();
public function mainDoc()
{
/// Makes this class ready to be passed to defautVars.as
_instance = this;
// Sends the _instance to defaulVars.as to be accessed later.
vars.getMainDoc(_instance);
// Calls a function in defaultVars.as and loads a var
vars.loadButtonVars("English");
}
}
}
Here is the defaultVars.as
package com {
import flash.display.Stage;
import flash.events.*
import flash.net.*;
import flash.display.*;
import flash.filesystem.*;
public class defaultVars
{
/// Makes the MainDoc.as a MovieClip
// Not sure if this is good but it works.
public var MainDoc:MovieClip;
public function defaultVars()
{
}
public function getMainDoc(_instance:MovieClip)
{
trace("CALLED" + _instance);
/// receives the _instance var and its converted to a MovieClip
// This can now be used in any function because I declared it a public var.
MainDoc = _instance;
}
public function loadButtonVars(Language:String)
{
myLoader.load(new URLRequest("Languages/" + Language + "/vars.xml"));
myLoader.addEventListener(Event.COMPLETE, processXML);
function processXML(e:Event):void
{
myXML = new XML(e.target.data);
/// Home Screen Buttons
homeT = myXML.Button.(#Title=="homeT");
homeB1 = myXML.Button.(#Title=="homeB1");
homeB2 = myXML.Button.(#Title=="homeB2");
homeB3 = myXML.Button.(#Title=="homeB3");
homeB4 = myXML.Button.(#Title=="homeB4");
homeB5 = myXML.Button.(#Title=="homeB5");
/// HERE IS WHERE I CALL FUNCTION from MainDoc after xml is loaded.
/////////////////
trace("xml loaded!!!! " + homeB1);
MainDoc.languageLoaded(Language);
}
}
}
}

Facebook abobe as3 api for air for mobile

I am planing a project that involves a cross platform (Android and I.O.S) mobile app that logs in using Facebook. I have no experience with the face book API and cant find any use full material for newbies. I want to use air for its cross platform capabilities so want to avoid multiple solutions for each platform. I have done many searches for help but haven't found much. Can any of you point me to resources you found use full starting off with this sort of thing.
The AS3 Facebook API is all you need. ( http://code.google.com/p/facebook-actionscript-api/ ) Maybe you will have to change a few things (like the JSON methods in there) but otherwise it seems to work alright. You can download several examples from there as well, you can see the usage for different types of environment.
Also, read this article from Tom Krcha http://www.adobe.com/devnet/games/articles/getting-started-with-facebooksdk-actionscript3.html
If you have more specific questions, ask. This one is too generic.
EDIT:
Here is a class I wrote some time ago for a small project
package com.company.social {
import com.facebook.graph.FacebookMobile;
import com.company.AppConst;
import com.company.IDestroyable;
import com.company.Main;
import com.company.displayassets.WebViewCloseStripe;
import com.company.events.FacebookControllerEvent;
import com.company.events.TwitterControllerEvent;
import flash.display.BitmapData;
import flash.display.PNGEncoderOptions;
import flash.display.Sprite;
import flash.display.Stage;
import flash.events.EventDispatcher;
import flash.events.MouseEvent;
import flash.geom.Rectangle;
import flash.media.StageWebView;
import flash.utils.ByteArray;
import flash.utils.clearTimeout;
import flash.utils.setTimeout;
public class FacebookController extends EventDispatcher implements IDestroyable {
private static const APP_ID:String = "1234512345"; // Your App ID.
private static const SITE_URL:String = "some_url";
//Extended permission to access other parts of the user's profile that may be private, or if your application needs to publish content to Facebook on a user's behalf.
private var _extendedPermissions:Array = ["publish_stream","user_website","user_status","user_about_me"];
private var _stage:Stage;
private var _webView:StageWebView;
private var _topStripe:WebViewCloseStripe;
private var _activity:String;
private var _timeoutID:uint;
public static const ACTIVITY_LOGIN:String = "login";
public static const ACTIVITY_POST:String = "post";
public function FacebookController(stage:Stage) {
_stage = stage;
init();
}
private function init():void {
_activity = ACTIVITY_LOGIN;
startTimeout();
FacebookMobile.init(APP_ID, onHandleInit, null);
}
private function onHandleInit(response:Object, fail:Object):void {
if (response) {
stopTimeout();
dispatchEvent(new FacebookControllerEvent(FacebookControllerEvent.LOGIN_COMPLETE));
//FacebookMobile.api("/me", handleUserInfo);
}
else {
/*trace("no response, login -->");
for(var prop in fail["error"]) {
trace(prop+": "+fail["error"][prop]);
}*/
loginUser();
}
}
private function startTimeout():void {
trace("timeout start");
clearTimeout(_timeoutID);
_timeoutID = setTimeout(timeout, AppConst.TIMEOUT_TIME);
}
private function timeout():void {
trace("timed out");
clearTimeout(_timeoutID);
dispatchEvent(new FacebookControllerEvent(FacebookControllerEvent.TIMEOUT));
}
private function stopTimeout():void {
trace("timeout stop");
clearTimeout(_timeoutID);
}
private function loginUser():void {
stopTimeout();
_topStripe = new WebViewCloseStripe();
_topStripe.getCloseButton().addEventListener(MouseEvent.CLICK, closeClickHandler);
_stage.addChild(_topStripe);
_webView = new StageWebView();
_webView.viewPort = new Rectangle(0, _topStripe.height, _stage.fullScreenWidth, _stage.fullScreenHeight - _topStripe.height);
FacebookMobile.login(handleLogin, _stage, _extendedPermissions, _webView);
}
private function handleLogin(response:Object, fail:Object):void {
if(_topStripe) {
_topStripe.getCloseButton().removeEventListener(MouseEvent.CLICK, closeClickHandler);
_topStripe.destroy();
_stage.removeChild(_topStripe);
_topStripe = null;
}
if(_webView) {
_webView = null;
}
if(response) {
dispatchEvent(new FacebookControllerEvent(FacebookControllerEvent.LOGIN_COMPLETE));
//FacebookMobile.api('/me', handleUserInfo);
}
else {
dispatchEvent(new FacebookControllerEvent(FacebookControllerEvent.LOGIN_ERROR));
}
}
private function closeClickHandler(e:MouseEvent):void {
dispatchEvent(new FacebookControllerEvent(FacebookControllerEvent.CLOSE));
}
private function handleUserInfo(response:Object, fail:Object):void {
if (response) {
for(var prop in response) {
trace(prop+": "+response[prop]);
}
}
}
private function handleUploadImage(result:Object, fail:Object):void {
stopTimeout();
if(result) {
dispatchEvent(new FacebookControllerEvent(FacebookControllerEvent.POST_COMPLETE));
}
else {
dispatchEvent(new FacebookControllerEvent(FacebookControllerEvent.POST_ERROR));
}
}
public function postWithImage(message:String, imageData:BitmapData):void {
_activity = ACTIVITY_POST;
var byteArray:ByteArray = imageData.encode(new Rectangle(0, 0, imageData.width, imageData.height), new PNGEncoderOptions());
var params: Object = new Object;
params.image = byteArray;
params.fileName = "image.png";
params.message = message;
startTimeout();
FacebookMobile.api("/me/photos", handleUploadImage, params, "POST");
}
public function reset():void {
FacebookMobile.logout(handleReset, SITE_URL);
}
public function handleReset(response:Object):void {
dispatchEvent(new FacebookControllerEvent(FacebookControllerEvent.RESET));
}
public function destroy():void {
if(_webView) {
_webView.dispose();
_webView = null;
}
if(_topStripe) {
_topStripe.getCloseButton().removeEventListener(MouseEvent.CLICK, closeClickHandler);
_topStripe.destroy();
_stage.removeChild(_topStripe);
_topStripe = null;
}
_stage = null;
}
}
}
Alternatively you can use a native extension like this:
http://www.milkmangames.com/blog/tools/#iosgv
There are free versions from other publishers available as well.

Flex 4.5 Not listening to custom event dispatched in custom AS class

I have the following situation:
I have an event handler, that displays small messages in my application's statusbar.
These messages get passes through by dispatching events from custom components.
A simple message could be like "HTTP Error" or so.
Now, the main event listener, in the main application file, listens to the event dispatched by any custom component, but seems to refuse listening to events dispatched by custom AS classes.
Here is my code for the custom event:
package main.events
{
import flash.events.Event;
public class ShowNoticeEvent extends Event
{
public var message:String;
public static const SHOW_NOTICE:String = "showNotice";
public function ShowNoticeEvent(type:String, msg:String, bubbles:Boolean = false, cancelable:Boolean = false)
{
super(type, bubbles, cancelable);
this.message = msg;
}
override public function clone():Event
{
return new ShowNoticeEvent(type, message);
}
}
}
This is the event listener in the main application file:
addEventListener(ShowNoticeEvent.SHOW_NOTICE, showNoticeListener, true);
And this is the custom AS class that dispatches the custom event. I pasted all the code, so you could see the whole part of it.
package components.dashboard
{
import components.dashboard.models.*;
/* Event imports */
import flash.events.*;
import main.events.*;
import mx.controls.Alert;
import mx.core.UIComponent;
import mx.rpc.events.FaultEvent;
import mx.rpc.events.ResultEvent;
import mx.rpc.http.HTTPService;
[Event(name="showNotice", type="main.events.ShowNoticeEvent")]
public class Controller extends UIComponent
{
private var baseUrl:String;
public function Controller(baseUrl:String)
{
this.baseUrl = baseUrl;
}
public function getRunningQuotations():void
{
var runningQuotationsList:RunningQuotationsList = RunningQuotationsList.getInstance();
execService("index.php?a=1", runningQuotationsList.updateList, "pnlRunningQuotations");
}
public function getRecentProjects():void
{
var recentProjectsList:RecentProjectsList = RecentProjectsList.getInstance();
execService("index.php?a=2", recentProjectsList.updateList, "pnlRecentProjects");
}
public function getLatestCustomers():void
{
var latestCustomersList:LatestCustomersList = LatestCustomersList.getInstance();
execService("index.php?a=3", latestCustomersList.updateList, "pnlLatestCustomers");
}
private function execService(url:String, listener:Function, component:String):void
{
var basicService:HTTPService = new HTTPService(baseUrl);
basicService.showBusyCursor = true;
basicService.addEventListener(FaultEvent.FAULT, function(e:FaultEvent):void{httpFault(e, component)});
basicService.method = "POST";
basicService.resultFormat = "text";
basicService.url = url;
basicService.addEventListener(ResultEvent.RESULT, listener);
basicService.send();
}
private function httpFault(event:FaultEvent, component:String = null):void {
var faultstring:String = event.fault.faultString;
var eventObj:ShowNoticeEvent = new ShowNoticeEvent(ShowNoticeEvent.SHOW_NOTICE, faultstring, true);
dispatchEvent(eventObj);
trace(faultstring);
}
}
}
So to sum it all up:
- The event listener listens to the custom event dispatched by any custom component.
- The event listener does not listen to the custom event duspatched by an AS class.
Those who wonder, the event really gets dispatched, that's why I added a trace call.
The instance of Controller Class would have to be added to stage for that to work.
by doing
addEventListener(ShowNoticeEvent.SHOW_NOTICE, showNoticeListener, true);
in the main file you are adding the listener to the stage.
So basically you are doing.
stage.addEventListener(ShowNoticeEvent.SHOW_NOTICE, showNoticeListener, true);
If controler instance is not on stage you won't see the event.
You might want to look into a Singleton type pattern for your data management as that would fit this setup pretty good.
Main:
Controller.getLastInstance().addEventListener(ShowNoticeEvent.SHOW_NOTICE, showNoticeListener, true)
.
package components.dashboard
{
import components.dashboard.models.*;
/* Event imports */
import flash.events.*;
import main.events.*;
import mx.controls.Alert;
import mx.core.UIComponent;
import mx.rpc.events.FaultEvent;
import mx.rpc.events.ResultEvent;
import mx.rpc.http.HTTPService;
[Event(name="showNotice", type="main.events.ShowNoticeEvent")]
public class Controller extends UIComponent
{
static public function getLastInstance():Controller { return _instance; }
static private var _instance:Controller;
private var baseUrl:String;
public function Controller(baseUrl:String)
{
_instance = this;
this.baseUrl = baseUrl;
}
public function getRunningQuotations():void
{
var runningQuotationsList:RunningQuotationsList = RunningQuotationsList.getInstance();
execService("index.php?a=1", runningQuotationsList.updateList, "pnlRunningQuotations");
}
public function getRecentProjects():void
{
var recentProjectsList:RecentProjectsList = RecentProjectsList.getInstance();
execService("index.php?a=2", recentProjectsList.updateList, "pnlRecentProjects");
}
public function getLatestCustomers():void
{
var latestCustomersList:LatestCustomersList = LatestCustomersList.getInstance();
execService("index.php?a=3", latestCustomersList.updateList, "pnlLatestCustomers");
}
private function execService(url:String, listener:Function, component:String):void
{
var basicService:HTTPService = new HTTPService(baseUrl);
basicService.showBusyCursor = true;
basicService.addEventListener(FaultEvent.FAULT, function(e:FaultEvent):void{httpFault(e, component)});
basicService.method = "POST";
basicService.resultFormat = "text";
basicService.url = url;
basicService.addEventListener(ResultEvent.RESULT, listener);
basicService.send();
}
private function httpFault(event:FaultEvent, component:String = null):void {
var faultstring:String = event.fault.faultString;
var eventObj:ShowNoticeEvent = new ShowNoticeEvent(ShowNoticeEvent.SHOW_NOTICE, faultstring, true);
dispatchEvent(eventObj);
trace(faultstring);
}
}
}
Not Ideal since you could only ever have 1 of them.
But I think better than having to turn a simple EventDispatcher into DisplayObject and add it to stage just to Simply bubble.