Debugging Installed AIR Apps

We’ve been trying to debug an run-time error in an AIR app that only is happening on our PM and client’s computers. None of our developers can see it. We tried putting in a logging system that would log the stack trace of the error, but when the error gets to our handler, the stack trace is null. So we wanted to get our PM to be able to see the RTE dialogs we’d see if we were debugging. How to do that?

Xavi Beumala has the answer. In his post, he tells about how you can enable RTE dialogs in installed AIR apps. It’s super simple. You just go to the application’s install directory, then go into the META-INF/AIR directory and create a directory named debug there. You don’t have to put anything into it. You just make the directory and you’ll get RTE dialogs in your AIR app. Pretty useful.

I should note that Xavi has quite a few other suggestions in his post that may be more useful for debugging, but this was a quick win.

Posted in AIR | Tagged , , | Leave a comment

CKEditor is Awesome!

I’ve been working on a ColdFusion site for a client that needs to let them edit HTML, but in a limited fashion. We want to keep them using our styles and not be able to access every color or typeface under the sun. We opted to use the CKEditor, and I am exceptionally glad we did.

CKEditor is a Javascript-based rich text editor that is super easy to implement and has an amazing breadth of functionality. All it requires is an include of the JS file and giving a text area tag a particular class. Boom. That’s it.

Of course, there’s a lot of configuring you can do. You can configure the different toolbars used in the editor, removing or adding functionality. You can specify stylesheets that get incorporated with the editor. There’s a whole host of options that I didn’t explore, but for even for the basics, it is tremendous.

One thing that impressed me quite a bit was how it handles images. People can include images that are already on the web in a handy dialog box. If you configure CKEditor correctly, you can even put in the means for users to upload images. You specify a page that handles image uploads, and the dialog automatically populates the URL field with the URL your page returns.

That subject, however, brings up one of the sore points with CKEditor. The documentation is pretty good at telling you what code you need to put in for configuration, but not where pieces of code need to go. And in the case of image uploading, it took me a long time to find the information on what the image upload page needed to do in order to get the image URL back to the upload dialog.

So here are the two things I learned that I wanted to pass on:

  1. You can configure all the CKEditor instances in your site from one config file. However, if you want to configure one instance of the editor differently, you can put in configuration code into the page to override the global config. The trick is that you need to put in that configuration code AFTER the text area that will be used for CKEditor. Otherwise it gets ignored.
     <textarea id="myHTML" class="ckeditor" name="myHTML"> #html# </textarea>
    <script type="text/javascript"> // <![CDATA[
    CKEDITOR.replace( 'myHTML', { toolbar : 'Basic' });
    // ]]> </script>
  2. When you create the form page that uploads the image, what it needs to return is this:
     window.parent.CKEDITOR.tools.callFunction( 'CKEditorFuncNum', 'imageURL', 'myMessage');
    The imageURL and myMessage are replaced with the image’s URL and any message you want displayed. The message parameter is optional. The CKEditorFuncNum is replaced with a parameter of the same name that is also passed in with the form.

Other than that, I have few complaints. This is an incredible piece of code and functionality that is given away for free. I have barely even touched on its awesomeness. So if you need a rich text editor, give CKEditor a try, and you’ll be wowed.

Posted in ColdFusion | Tagged , , | 1 Comment

The Heartburn of SSL and CFLDAP

It’s been a while sense I’ve posted about ColdFusion. However, I’ve got to post this. We were trying to use the CFLDAP tag to authenticate users against an Active Directory service over a secure connection. I didn’t know much about Active Directory and LDAP, but I couldn’t even get connected to the server. I just kept getting a ColdFusion error telling me “Connection to LDAP server failed” and no more info. Well, thanks, ColdFusion. After searching the Internet for solutions, we found many people solved the issue by installing a certificate from the LDAP server to the ColdFusion server. We gave that a try, but to no avail. So we tried a bunch of other things, including switching the user the ColdFusion was running as from “Local Service” to a user name that has access to the LDAP server. No dice. We were running out of options, so I revisited the certificate idea, and praise the Lord, I found this:
http://objectmix.com/cold-fusion/410669-querying-secure-cfldap.html
The gist of it is, the Adobe documentation for adding a certificate to ColdFusion’s keystore is wrong. There are multiple cacerts keystores on ColdFusion, and it tells you to add it to the cacerts in {ColdFusion9}\runtime\jre\bin. However, there is another cacerts. It resides in {ColdFusion9}\runtime\jre\lib\security. That is the one you actually want to add your certificate to. It’s especially confusing since you must run the keytool from the jre\bin directory, but you’re adding to a keystore in a different directory.

One other thing I found was that on Windows 7, in order to add the cert to the keystore, you have to run CMD as an Administrator. Otherwise the keytool will say it added the key, but then could not find the keystore because access was denied. Once I ran CMD as an admin, all was well with the world. I restarted ColdFusion and was able to connect using CFLDAP. I don’t think of LDAP as exciting, but once I got this working, I wanted to run a victory lap around our office.

 

Posted in ColdFusion | Tagged , , , , , | Leave a comment

Multiheight Children in a VGroup

Since the move up to Flex 4, I’ve been disappointed with the layout of the VGroup/HGroup. Many times it will not resize or relayout when the size of a child has changed. Point in case was when I tried to put some dynamic configurable form fields into a container. Based on their state, they could be vertical or horizontal and could have an additional description line. This meant they could be many different heights. Unfortunately, once they were laid out, they kept reverting to their starting height, and the VGroup laid them out as if they all were 20 pixels tall.

I tried a variety of things involving invalidateSize and invalidateDisplayList to kick the VGroup in the head and get it to realize its children were a different height. Nothing worked. The final thing I did though, did work. Once the children were added to the VGroup, I added an event listener for FlexEvent.UPDATE_COMPLETE. In the handler for that, I immediately removed the listener and then looped through the children and set their height explicitly to their contentHeight. The contentHeight was unavailable before the display list had been updated, but afterwards, it had the correct height, while the explicit height was still wrong.

Here’s what I ended up with in the handler of my UPDATE_COMPLETE event:

private function _onUpdateComplete( event:FlexEvent ):void
{
	formContainer_vg.removeEventListener( FlexEvent.UPDATE_COMPLETE, _onUpdateComplete );
	var numChildElements:int = formContainer_vg.numElements;
	for( var i:int = 0; i < numChildElements; i++ )
	{
		var child:Group = Group( formContainer_vg.getElementAt( i ) );
		child.height = child.contentHeight;
	}
}
Posted in ActionScript | Tagged , , , | Leave a comment

Firebug was the Culprit

I was attempting to send a POST request from Flash to a client’s service. I was told to send it like an HTML form sends a POST request. I tried sending a standard POST request with URLLoader, and got back a failure from the service. I opened up Firefox and Firebug to take a look. Sure enough, when I submitted an HTML POST request, there was this block of parameters that my request from Flash didn’t have. That must be what was going on.

So I switched my URLLoader out for an HTTPService and looked at changing the request headers around. All to no avail. I couldn’t get the request to show up the same as from an HTML form. After pounding my head against the problem for a long while, I went home.

The next morning I separated out my code into a separate project and ran it. Shazam! The missing parameters object was there. I checked the response and it was a success. I went back to my identical code in the project and ran it. The parameters object was gone … but the response was success. What?! It looks like I had gotten the service to work long before, but because I was seeing the different response, I assumed it was still failing as it had before. Firebug was giving me different information for the same call made from different projects. Firebug! I trusted you!

I guess the lesson is: Always check the response.

Posted in ActionScript | Tagged , , , , | Leave a comment

Position is Relative. Trust the Rectangle.

Ever needed to get the real y position of a control in a vertical layout? I recently did. I had a form field in a dynamic form with a vertical layout. This field needed a custom tool tip to show up just beneath it vertically, but the tool tip needed to appear over everything else in the form. However, when I tried to get the y of the field, it kept coming back as 0, even though it should have been something more than 100.

After struggling with trying to get the y after all the layout updating had completed, I was stymied and started combing through the UIComponent methods looking for something to give me coordinates in a relative layout. Finally I gave getBounds a try. This did the trick. The rectangle returned by the method had the real y of the component. After a little localToGlobal action, I was able to get the needed y and position my little tool tip over the rest of the form.

Posted in ActionScript | Tagged , , , , | Leave a comment

Get Building for Blackberry

Blackberry is coming out soon (Q1 2011) with their Playbook tablet. I’m stoked that it will be supporting apps built in AIR, among other languages. I’m glad to see that Adobe is carrying through with their vision to get Flash on as many screens as they can.

I’m also stoked to see that if you get an app approved for the Blackberry App Store before the Playbook launches, you’ll get a free Playbook. Now that’s a good incentive for me to get going, especially since Blackberry is currently waiving the fee for getting set up as an App Store developer. The device looks pretty sweet and sports a dual-core processor. It also weighs in under a pound.

I’ve gotten a start with the development for my app idea. I definitely recommend listening to the webcast series on developing for the Blackberry Tablet OS in order to get started. They have some good advice on setting up the dev environment. They also cover some basic development stuff. If you’re already familiar with AIR dev, you might want to also watch the MAX session on Blackberry AIR dev which focuses in on the Blackberry specifics. Another good starting point is to get the SDK and Playbook simulator.

My app I have planned is niche enough that I’m not worried about anyone duplicating it, so I can safely recommend to all you developers to get developing and get your free Playbooks. I will note that I haven’t had the easiest time getting the dev set up. I can’t get debug to work on the simulator, but I can run my app on it. Thankfully the Blackberry developer community seems to be quite responsive in the forums for Blackberry AIR dev.

Now get coding!

Posted in ActionScript | Tagged , | 1 Comment

Please Pay Attention to the Camera

I ran into an interesting problem with the Camera class, video playback, and AIR. A client was complaining of choppy video from an AIR POC app we had built. In it video was being broadcast between two separate apps via FMS. One was broadcasting and the other was consuming. I figured it was a simple matter of a bad buffer size. I was wrong.

The video was choppy in both apps, not just the receiving app. The broadcasting app was attaching the camera directly to a video object on the stage, so it should have been smooth as silk. Huh? What causes that? I checked the CPU usage, and it was not spiked.

After a further investigation, I found the culprit. The video in the broadcasting app would play smoothly, as long as that app had focus. As soon as I gave operating system focus to any other app, such as Flash Builder or the Task Manager, the video went choppy in the broadcasting app and shortly thereafter the consuming app would also go choppy as the feed coming into it went to pot.

I’m guessing that this issue has something to do with the OS (Windows 7 in this case) stripping away system resources from “idle” processes. I couldn’t replicate the behavior in Flash, so it must be an AIR thing. I couldn’t find anything online about this problem, though finding the right search terms is a challenge. So for now, it’s a mystery, but an identified mystery.

Posted in ActionScript, Flash Media Server, video | Tagged , , | Leave a comment

Smoothing with OSMF: Harder Than You’d Think

There’s one deployment scenario for using smoothing in OSMF that’s really easy. You create your video element using the default media factory and you set the smoothing property to true. Done and done. That’s super simple.

When you have a complex media element, involving proxy elements, sequences, and plug-in generated media elements, that simplicity gets stomped on with a big hobnailed boot. Let’s look at three plug-ins you might use. They’re all included in OSMF. The Captioning plug-in wraps the media in a proxy element. The MAST plugin takes your media element and puts it into a SerialElement with other media to display ads around your video. The Akamai Basic Streaming plug-in uses its own media factory items to generate its own media elements. Combine all these together, and the media element that comes out of that media factory is a complex structure you’d need to navigate to get to that VideoElement (or elements) at its center to turn that smoothing on. And through the power of OSMF there are infinite variations and complexities to the structure your media element can take. Proxies can wrap proxies which can wrap sequence and parallels and so on.

There’s no way to set smoothing before you generate your media element. Nor is there a way to set it on the player to make all videos smooth. After all, not all media elements use smoothing, so making the player or a resource have it doesn’t make sense. So, one way to do it would to build some devious, recursive function that burrows through complex, byzantine structures. But screw that. Screw recursion.

One solution I arrived at was to make a custom MediaFactory class. I can set the media creation function on my media factory items, so I can make them call a function that automatically sets smoothing on the generated VideoElement. Most plug-ins use the media factory’s default media factory items to generate their media elements and then wrap them in their proxy element. So, that works most of the time … but unfortunately, not all of the time.

The Akamai Basic Streaming plugin uses its own media factory items. There’s nothing wrong with it. However,  it hoses my solution for using custom media creation functions to set smoothing. The element is created inside the plug-in and then returned to private methods in the MediaFactory class to be swaddled in proxy elements, sequences and that whole convoluted mess we had just sidestepped. Here we are again, staring at a recursive solution. But remember, we said screw recursion. And I meant it.

Brian Riggs from the OSMF team helped me out here and suggested overriding the media factory items to use my own media creation functions. Unfortunately, this doesn’t work right away, because the plug-in’s custom media creation functions inject special code into the media element, and those are classes I don’t want to have to try to import. I certainly don’t want to try to duplicate the functionality of the plug-in in my media factory.

Using Brian’s suggestion as a springboard, I found a way around this quandary. The resolveItems method of the MediaFactory class is protected, which means I can override it in my custom media factory. It decides which media factory item to use to generate the media element. In my override of resolveItems, I grab the media factory item it is about to return and check to see if it is a custom item. If it is, I create a duplicate media factory item, but insert my own media creation function. I also store a reference to the original creation function. In my media creation function, I call the original creation function and then intercept the media element it creates. I can set the smoothing on the element and then return it without anyone being the wiser.

override protected function resolveItems(resource:MediaResourceBase, items:Vector.):MediaFactoryItem
{
var mfi:MediaFactoryItem = super.resolveItems( resource, items );
/*If a custom MFI is being used, hijack it and intercept the media element it returns to set smoothing on it*/
if( mfi.id.indexOf( 'org.osmf' ) < 0 )
{
_highjackedMediaCreationFunction = mfi.mediaElementCreationFunction;
var hijacker:MediaFactoryItem = new MediaFactoryItem( mfi.id, mfi.canHandleResourceFunction, interceptMediaElement );
return hijacker;
}
return mfi;
}
protected function interceptMediaElement():MediaElement
{
var element:MediaElement = _highjackedMediaCreationFunction();
if( element is VideoElement )
{
VideoElement( element ).smoothing = useSmoothing;
}
return element;
}

In this way, I can sidestep the whole structure of the media element and get right to the core of the media element. And that means recursion can suck it.

Posted in Uncategorized, video | Tagged , , | 5 Comments