Tuesday, February 01, 2011

XCode Build and Archive menu disabled - grayed out

Man, I spent an inordinate amount of time on this. The drop-down combo box at the very top left of XCode where you specify the iOS version and SDK...it's on Simulator. Change it to "Device."

Hopefully this helps someone. RTFM also helped for me.

Wednesday, November 24, 2010

Upload Image from Camera in Mobile Adobe AIR Android

For some reason I really struggled to upload a File (bytes) that I had in memory. It's easy to upload with the FileReference class, but that has an order of what methods can be called dependent on the browse() method being called. In this case, I have an Android <s:MobileApplication> app that uses the CameraUI class to take a picture and upload.

The key is taking the File that is returned, reading the bytes, and using a 3rd party library called MultipartURLLoader (which URLLoader can't do) to upload it.


private var myCam:CameraUI;
private var pictureFromCamera:File;
private var myByteArray:ByteArray;



/** This method you're used to seeing. The handler for when a user takes a picture */
protected function creationCompleteHandler(event:FlexEvent):void
{
      if (CameraUI.isSupported)
{
myCam = new CameraUI();
myCam.addEventListener(MediaEvent.COMPLETE, onPictureTakenComplete, false, 0, true);
}
}


/**
 * Handler for when user closes camera with a picture. MediaEvent (AIR only).
 */
private function onPictureTakenComplete(evt:MediaEvent):void
{
myByteArray = new ByteArray();
pictureFromCamera = evt.data.file;
//load file into bytes
var myFileStream:FileStream = new FileStream();
myFileStream.open(pictureFromCamera, FileMode.READ);
myFileStream.readBytes(myByteArray);
 myFileStream.close();
}


/** method that uploads to server using a 3rd party lib */
public function upload_clickHandler(e:Event):void
{

var ml:MultipartURLLoader = new MultipartURLLoader();
ml.addEventListener(Event.COMPLETE, onUploadComplete, false, 0, true);
//add variables
ml.addVariable('title', titleField.text);
//add file bytes
ml.addFile(myByteArray, pictureFromCamera.name, 'file');
//submit
ml.load('http://justinbieberistheworst.com/upload.do');
}

Monday, November 22, 2010

Alfresco Flex AIR Upload File Basic Authentication Error

See the wiki page for the Alfresco Upload Webscripts, but with these files, I was unable to upload files without always getting the Basic Authentication popup window always appearing. The key was adding the 'alf_ticket' request parameter to the URL string:

fileRef = new FileReference(); //instantiated earlier

urlVars = new URLVariables();
urlVars.title = 'my title';
urlVars.desc = 'my description';

urlReq = new URLRequest();
urlReq.method = URLRequestMethod.POST;
urlReq.data = urlVars;
//ticket was returned after logging in
urlReq.url = "http://<<myserver>>/alfresco/service/site/upload?alf_ticket="+this.ticket;
//
fileRef.upload(urlReq, 'file');

Login code...

var svc : HTTPService = new HTTPService();
svc.resultFormat = 'e4x'
svc.addEventListener(ResultEvent.RESULT, onLogin);
svc.url = "http://<<myserver>>/alfresco/service/api/login";
var params : Object = {};
params.u = 'bsmith';
params.pw = 'password';
svc.send(params);


  protected function onLogin(event:ResultEvent):void
  {
     this.ticket = XML(event.result).text().toString();
  }

Tuesday, October 19, 2010

A Simple JQuery Mobile RSS Example

With the jquery mobile framework in alpha release, I took it for a spin drive. I hadn't worked a lot with jquery much at all prior to this so it was a good learning experience all around. A couple gotchas I had learned the hard (timely way).

1.) The jquery $.get() and $.ajax() methods cannot load rss feeds from other websites. You have to use a proxy, or download the rss file and access it locally.

2.) Just because you have that rss xml file saved in the same directory as your html file doesn't mean squat. Again, you'll have to load your files onto a server like tomcat and test that way.

Here's the completed example. It loads a RSS file and creates a jquery mobile list. VERY few lines of code, which is why jquery rocks so well. Amazing for API calls, parsing, and accessing the html DOM.

Click to view source from there: http://vandalaysolutions.com/sva/sample2.html

Note, there is a bug in the framework with the <ul> not refreshing after I append (add)  a new <li> item...so after looping through and adding all the RSS items, I manually refresh the <ul> calling listview on line 26:

list.listview();

If you're new to JQuery, check out this post. It explains why/how the "$" signs are OK as Javascript declarations and some great examples of useful DOM transversing.

Monday, April 12, 2010

ArgumentError: Error #1063: Argument count mismatch on mx.core::CrossDomainRSLItem(). Expected 5, got 7.
at mx.managers::SystemManager/http://www.adobe.com/2006/flex/mx/internal::initialize()[E:\dev\4.0.0\frameworks\projects\framework\src\mx\managers\SystemManager.as:1878]
at mx.managers::SystemManager/initHandler()[E:\dev\4.0.0\frameworks\projects\framework\src\mx\managers\SystemManager.as:2419]

This was an easy one to fix. Your main app is compiling with a different Flex SDK than one of your modules (RSL). Check each module Flex Project Compiler properties and make sure they're all on the same sdk.

Wednesday, September 16, 2009

FlexPMD Client for Viewing Generated XML files - Source Code

I recently came across FlexPMD, a neat little Java tool that runs through your Flex/AS3/Air code and creates an XML file of all the problems (violations). It should be something everyone does before committing files to their own repository. I didn't see a nice UI tool to view what can sometimes be a massive XML file, so I created a little AIR app that allows a user to select the xml file, navigate the classes, and view the detailed information of each error. Simply copy/paste this MXML code into your Flex Builder 4 AIR application (or remove the 's' and 'fx' namespaces if you're still on Flex 3).



<?xml version="1.0" encoding="utf-8"?>
<!--
    UI Client for viewing PMD xml generated files.
-->
<mx:WindowedApplication xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/halo"
minWidth="1024" minHeight="768" layout="vertical">
<fx:Script>
<![CDATA[
/** Browse a file to select */
private var file : FileReference;

/** Selected violation to display on right */
[Bindable] private var selectedViolation : XML;

/** Handler for when user selects a node */
protected function tree_itemClickHandler(event:Event):void
{
if(XML(tree.selectedItem).name() == "violation")
selectedViolation = XML(tree.selectedItem);
}

/** Label Function for Tree*/
protected function showLabel(item:Object):String
{
var itemXML : XML = item as XML;
if(item.name() == "violation")
return itemXML;
else
{
var firstChildXML : XML = XML(itemXML.violation[0]);
var numViolations : int = itemXML.violation.length();
return firstChildXML['@package'] + "." + firstChildXML['@class'] + " (" + numViolations + ")";
}
}


/** Load the selected file*/
protected function onSelect(event:Event):void
{
file.load();
}

protected function onComplete(event:Event):void
{
var pdmXmlFile : XML = new XML(file.data);
var allFiles : XMLList = pdmXmlFile.file;
var allErrors : XMLList = pdmXmlFile..violation;
//set tree and labels
resultsLabel.text = allFiles.length() + " classes with " + allErrors.length() + " violations."
tree.dataProvider = allFiles;
//clean up on aisle 3
file.removeEventListener(Event.SELECT, onSelect);
file.removeEventListener(Event.COMPLETE, onComplete);
}


protected function openFileHandler(event:MouseEvent):void
{
file = new FileReference();
file.addEventListener(Event.SELECT,onSelect);
file.addEventListener(Event.COMPLETE,onComplete);
                var arr:Array = [];
                arr.push(new FileFilter("XML", "*.xml"));
file.browse(arr);
}


]]>
</fx:Script>
<mx:HBox width="100%" horizontalAlign="left">
<s:Button label="Open File" click="openFileHandler(event)"/>
<mx:Text text="FlexPMD Client Violations" fontWeight="bold" fontSize="14"/>
<mx:Label id="resultsLabel"/>
</mx:HBox>
<mx:HDividedBox width="100%" height="100%">
<mx:Tree id="tree" width="50%" height="100%" labelField="@name"
itemClick="tree_itemClickHandler(event)"
labelFunction="showLabel"/>
<mx:VBox width="50%" height="100%" >
<mx:HBox width="100%">
<mx:Label text="Package:" fontWeight="bold"/>
<mx:Label text="{this.selectedViolation['@package']}"/>
</mx:HBox>
<mx:HBox width="100%">
<mx:Label text="Class:" fontWeight="bold"/>
<mx:Label text="{this.selectedViolation['@class']}"/>
</mx:HBox>
<mx:HBox width="100%">
<mx:Label text="Problem:" fontWeight="bold" />
<mx:Text text="{this.selectedViolation}" maxWidth="350"/>
</mx:HBox>
<mx:HBox width="100%">
<mx:Label text="Priority:" fontWeight="bold"/>
<mx:Label text="{this.selectedViolation.@priority}"/>
</mx:HBox>
<mx:HBox width="100%">
<mx:Label text="Line Number:" fontWeight="bold"/>
<mx:Label text="{this.selectedViolation.@beginline}"/>
</mx:HBox>
<mx:HBox width="100%">
<mx:Label text="Ruleset:" fontWeight="bold"/>
<mx:Label text="{this.selectedViolation.@ruleset}"/>
</mx:HBox>
<mx:HBox width="100%">
<mx:Label text="Rule:" fontWeight="bold"/>
<mx:Label text="{this.selectedViolation.@rule}"/>
</mx:HBox>
<mx:Spacer height="25"/>
<mx:Label text="Note: Priorities rank from 1-5, 1 being the most severe"/>
</mx:VBox>
</mx:HDividedBox>
</mx:WindowedApplication>
How to Write and Populate XML data into a PDF - Only on the Client.

I am currently on a project where a user will have very limited internet access, and they need the ability to enter form data which in the end, populates a PDF file and writes the PDF to their system (OS). One tends to think the only way to do this is with Java libraries or LiveCycle, but this is not the case. Both xdp and pdfxml are viable solutions.

The end solution I ended up going with is pdfxml. First, you need to install the Adobe Mars plugin for your Adobe Reader or Acrobat (I highly recommend using Reader/Pro version 9+).

In short, you take a PDF form, open it in Acrobat 9 Pro (I used the trial version), and click menu Forms->Add/Edit Fields. Here you can add fields using the field names you chose. Because you installed the Mars plugin for Acrobat 9, you will now see the option in File->Save As for a type "pdfxml". Save it.

Now, in your AIR Flex Builder project, add the pdfxml file to a 'pdfs' directory in your main 'src' directory, so it's included in the AIR file, and load the file like so:

var pdfxmlFile : File = File.applicationDirectory.resolvePath("pdfs/myFile.pdfxml");
mars = new MarsPackage(pdfxmlFile, this); //this being the mxml this code sits on

The MarsPackage class is from the Adobe examples source code. Adobe doesn't explicitly give you the Actionscript to parse out the XML, but I was able to piece it together. I would post the code, but I don't want to step on Adobe's toes since it's 99% their code.

To really understand how PDFXML works, install Adobe's PDFXML Inspector air app. Run the app and click File->Open and open either the pdfxml you created in Acrobat Pro or one of the sample pdfxml files from the Mars website. Click the 'form' node on the tree and then the 'form_data.xdfd' node. You'll see the XML data load to the right. If you don't see any data (fields) for the pdfxml you created, open your pdfxml in Pro, add a blank space or data, re-save it, and then re-open it in the PDFXML Inspector.

From this AIR app, you can udpate the data, and if you re-open the pdfxml in Reader/Pro..you'll see the data. No server needed!!

Note: If you add the fields with the LiveCycle Designer, the data instead is saved as xml...which I have had a lot of inconsistency with opening properly in Reader. Sometimes it works, sometimes it doesn't. Either way, use the 'Edit Fields' in Acrobat Pro and avoid Livecycle Designer and you will be worry free.

Tuesday, February 10, 2009

I recently came across this error: Main Thread (Suspended: Error: Key unsortedCuePoint was not found in resource bundle controls)

Thought I would blog it since no one else did. You get it trying to load/play a FLV on the Flex 2.0.1 VideoDisplay class, while your Flex Builder Project is pointed to the Flex 3 SDK. Change it back to Flex 2 and you're good to go.

Thursday, October 04, 2007

here is an example of accessing the browser title from Flex Beta 2 HTML Control.

To access the title of the current page you are on:
For <mx:HTML id="htmlControl"/>

call...

var title : String = htmlPanel.javaScriptWindow.document.title;

Thursday, September 06, 2007

So here is a simple example of dragging and dropping file attachments that exist on a server (from your OS to your AIR/Flex component and vice versa).





As a user initiates the drag on any UI component that implements DisplayObject, a URLLoader will be instantiated and the loader.load(urlRequest) will begin to download the attachment. The drag icon will also appear. When the user drops, the file is written to the disk using the FileStream class.

Here is a simple example of how to do that. There is both a mx.Button and rows within a mx.List that use the same simple piece of logic. I created a sublcass of both Button and List, which implement the same IDragFile interface. It is very simple. Here is the link to theAIR file with the source included within the AIR.

AIR
http://dev.xif.com/pronto/blog/1/blogger.air

ZIP (Source)
http://dev.xif.com/pronto/blog/1/blogger.zip

Wednesday, August 23, 2006

CairngormEvent Anti-Pattern!

We all know that the big downside to the Cairngorm framework when building Flex apps is the explosion of classes that result. My big issue is that to add, edit, and delete a widget, you have to create 3 seperate classes named "AddWidgetEvent", "UpdateWidgetEvent", and "DeleteWidgetEvent"....3 classes that are identical EXCEPT for their class name and command name that is passed to the contructor....

package com.widget.control{
import org.nevis.cairngorm.control.CairngormEvent;
import com.widget.control.WidgetController;
import com.widget.vo.WidgetVO;

public class AddWidgetEvent extends CairngormEvent
{
/** Constructor */
public function AddWidgetEvent(widgetVO : WidgetVO){
super(WidgetController.EVENT_ADD_WIDGET);
this.widgetVO = widgetVO ;
}
public var widgetVO : WidgetVO ;
}
}

I don't see the point of creating separate CairngormEvents for each action. Instead, pass in the commandName into the single, resuable event. So the call would look like this:

var addEvent : WidgetEvent = new WidgetEvent(WidgetController.EVENT_ADD_WIDGET, widgetVO);
dispatchEvent(addEvent);

And the CairngormEvent for ALL the widget events can now be a single class like so:
package com.widget.control{
import org.nevis.cairngorm.control.CairngormEvent;
import com.widget.control.WidgetController;
import com.widget.vo.WidgetVO;

public class WidgetEvent extends CairngormEvent
{
/** Constructor */
public function WidgetEvent(commandName : String, widgetVO : WidgetVO){
super(commandName);
this.widgetVO = widgetVO ;
}
public var widgetVO : WidgetVO ;
}
}

Tuesday, July 18, 2006

On a current project I have, I had to build a Microsft Windows style windowing application that allows new TitleWindow compoents to be added and managed on a menu bar...with all the features of minimizing (docking), maximizing, and restoring windows.

I didn't see much in the community that had anything built like this so I dove straight in. It's by no means a polished product, but it works nice. Click the link below to demo it (and view source).

You'll notice that Minimizing the window docks it (I have not added Transitions in yet). Click the "Start" button to open a new window (which is added to the menu bar).

http://www.vandalaysolutions.com/flex/minimize/testMinimizable.html

keywords: Flex 2.0 2 Adobe Panel

Monday, June 12, 2006

I recently had a requirement where HTML was sent over the XMLSocket and I needed to display it within a Flex screen or browser window. The HTML I received from the server was a FULL HTML document. It had embedded 'style' tags 'class' attributes set on most of the components, and your basic 'p' and 'font' tags. Flex 2 (Beta 3) still is not able to handle HTML perfectly.

Christophe had a blog about embedding html in an iFrame, but this didn't help me since iFrames point to static HTML pages.

Here's an example of the working example where in-memory HTML is written to a new browser window:
http://www.vandalaysolutions.com/flex/html/testHTML.html

If you have a AS3 String like so:
var htmlStr : String = " this is my <b>bolded</b> and <i>italic</i> String";

Then by assigning it to the "htmlText" attribute of a mx:Text or mx:RichTextEditor tag, it will diplay correctly.

However, most HTML has far more crap in it, so you're really left with 2 options...parsing the HTML to get rid of all the crap (using RegEx) or pass the HTML off to the browser.

Using RegEx to parse everything was not a good solution for me b/c there are endless possibilites of how the HTML could appear. However, passing the HTML to the browser at first was causing problems.

The HTML that I received from the server had lots of empty lines....which the Javascript method was failing on.

var html : String = "<html>

<title>Website Title</title>

<body>
this is bold
</body>
</html>";

If you pass this to the javascript method via the ExternalInterface, you'll get the following javascript error:
Error: unterminated string literal
Source Code:
try { __flash__toXML(changeDocumentTitle("<html>

As you can see, the javascript can't handle the line break. So if you create a Regular Expression to replace all the line breaks and form feeds with an empty space, it essentially makes the HTML String one long String. Thus it can write the String to the new browser window:

//Flex method: htmlXML is of type: htmlXML : XML
var pattern:RegExp = /\n|\r|\f/gi
var htmlstr : String = htmlXML.toXMLString().replace(pattern, "");
var m:String = ExternalInterface.call("popNewWindow",htmlstr);
trace(m);//m is what the js method returns and Flex receives

//Method we need to add to the wrapper HTML page.
<script> language="JavaScript">
function popNewWindow(a) {
var generator=window.open('','name','height=550,width=700,resizable=yes,scrollbars=yes,status=yes,menubar=yes,toolbar=yes');
generator.document.write(a);
generator.document.close();
return "successful"; //passed back to Flex
}
</script>

The full code can be accessed here:
http://vandalaysolutions.com/flex/html/htmlExampleCode.zip


keywords: Flex Beta 3 adobe macromedia post html dynamic browser iframe mozilla firefox ie internet explorer ff

Thursday, June 01, 2006

"Quik-Schema Data Modeler" is a Flex 2 beta 3 application that provides a visual way to create your database tables and joins. It also provides the ability to generate the SQL code for the tables and columns you create. Due to time constraints of the Flex Derby deadline, the SQL Code generator only supports Oracle, but I plan to add MySQL soon. I'm also going to spend some time to clean up the code so I can make it publicly available. This app is featured on the Adobe labs Flex Derby website. Any suggestions are welcome.


Click to view Quik-Schema Data Modeler