Page 1


Editor’s Note Adventures in ActionScript

This time I would like to tell you more about our special column by Huw Collingbourne. I think that all of you read his previous articles and all of you are waiting for the next one. Huw tells the new story in every issue and I hope you have a lot of fun reading them. In this issue, you can read about his next adventure in ActionScprit. You can read how it was when he first wrote a game, many, many years ago, and he made one huge mistake. Why? Please go to page 36 and read the next article written by our columnist. In this issue, you learn more on ActionScript. We have many articles on that. You need to read article written by Sachin Patil. In this article you will play with local files and its contents. You will see how to access these files from browser containing flash movie with and without use of server side scripting. The next worth-reading article is on Creating Custom Visual Classes by Louis DiCarro. He will explain that it is possible to draw buttons as needed using the Graphics class and this keeps the button scalable without distorting the graphics and, with a little preplanning, gives you a lot of control over the look and function of the control. If you are fan of 3D, you should read the Ahmed Eslam article on GPU-3D in Flash. He tells you more about Molehill. And if you are reader you need to check Marc Pires article on TDD. This time you shows you how to write the test which then you will implement a log class. So without further ado let’s get started. Please go to page 40. We have more product reviews for you. Just start reading our column The Best Products 2011 from page 12. In this issue we reviewed LockLizard FlashGuard, Anicca Digital Solutions and Netromedia. If you have any comments, just email me at ewa.dudzic@ffdmag.com. Please go to the next page for other articles published in the March Issue. As always we have a few good articles for you. I hope you will find them useful and practical. Like always I would like to thank the Beta Testers and Proofreaders for their excellent work and dedication to help make this magazine even better. Special thanks to all authors that help me create each issue. Please keep up the great work and send in your articles, tutorials and product reviews, questions, ideas or advises. Enjoy reading! Ewa Dudzic & FFD team

Editor in Chief: Ewa Dudzic ewa.dudzic@ffdmag.com Proofreaders: Betsy Irvine, Patrick French, James Deagle DTP Team: Ireneusz Pogroszewski ireneusz.pogroszewski@software.com.pl Art Director: Ireneusz Pogroszewski ireneusz.pogroszewski@software.com.pl Senior Consultant/Publisher: Paweł Marciniak Flex/ActionScript 101 Section Editor: Marc Pires marcpiresrj@gmail.com iPhone Development Section Editor: Ryan D’Agostino ActionScript in Action Section Editor: Huw Collingbourne Games Section Editor: Chris Hughes Contributing Editors: Pedro de La Rocque, Ali Raza, Csomák Gábor

All rights to trade marks presented in the magazine are reserved by the companies which own them. Thanks to the most active and helping beta testers: Russell TangChoon, Lee Graham, Jassa Amir Lang, Ed Werzyn, Yann Smith-Kielland, Justus, Csomák Gábor, Kevin Martin, Charles Wong, Ali Raza, Almog Koren, Izcoatl Armando Estanol Fuentes, Lionel Low, Michael J. Iriarte, Paula R. Mould, Rosarin Adulseranee, Sidney de Koning To create graphs and diagrams we used company.

program by

Publisher: Software Press Sp. z o.o. SK ul. Bokserska 1 02-682 Warszawa Poland Worldwide Publishing

The editors use automatic DTP system Mathematical formulas created by Design Science MathType™

Software Press Sp. z o.o. SK is looking for partners from all over the World. If you are interested in cooperating with us, please contact us by e-mail: cooperation@software.com.pl

Distributing current or past issues of this magazine – without permission of the publisher – is harmful activity and will result in judicial liability.

Whilst every effort has been made to ensure the high quality of the magazine, the editors make no warranty, express or implied, concerning the results of content usage. All trade marks presented in the magazine were used only for informative purposes.

4

FFD magazine is available on iPad thanks to MONOGRAM Interactive, s.r.o.

ATTENTION!

DISCLAIMER!

The techniques described in our articles may only be used in private, local networks. The editors hold no responsibility for misuse of the presented techniques or consequent data loss.

03/2011 (21)


CONTENTS Case Study

Video Hosting Platform

06 PlugrMan: The Universal API Toolkit

22 Creating a Distributed Video Hosting Platform

BY ALMER/BLANK

BY ANDREY CHERNIH

Special Report

PHP and ActionScript 3.0

08 Developing an Enterprise Flex Application Strategy

26 File handling with AS 3.0

BY CHRIS GIAMETTA

InBrief 10 News BY CSOMÁK GÁBOR

Tools 12 LockLizard FlashGuard BY ALI NEKOU POUR

13 Anicca Digital Solutions BY ALI RAZA

14 NetroMedia BY JOSEPHINE LIANG

3D in Flash 18 GPU-3D in Flash BY ESLAM AHMED

BY SACHIN PATIL

ActionScript 3.0 32 CREATING CUSTOM VISUAL CLASSES BY LOUIS DICARRO

ActionScript in Action 36 Adventures In ActionScript – Serializing Objects BY HUW COLLINGBOURNE

Flex/ActionScript 101 40 Test Driven Development Or How Not To Be Trapped In A Nightmare. Part 3 BY MARC PIRES

iPhone Development 44 Preparing Your Application To Use Push Notifications BY BRANDON TREBITOWSKI, CHRISTOPHER ALLEN, AND SHANNON APPELCLINE

Interview

Tip of the issue Fight Monotony With “CTRL + Y”! source: Drew Blomquist In most programs CTRL + Y is “redo”, but in Flash it is “repeat”; and If you’re performing repetitive actions it can be very useful. Let’s say you have 20 different movieclips of different shapes on different frames throughout your timeline and you want to apply a consistent drop shadow �lter to them all. You can apply the drop shadow to the �rst item, set the properties the way you like, then use the �lter copy/paste buttons in the �lters panel to apply the �lter to the next movie clip once. After that you can simply hop through the timeline, select movie clips, and hit CTRL + Y to reapply that same �lter. You can use CTRL + Y with instance names, color properties, alignment, whatever can be repeated in one action. Tedium shmedium!

03/2011 (21)

48 Interview With Lance Snider, Envato BY ALI, NEKOU POUR

50 An Interview With Demetrio Fortman, CEO of MotoCMS.com BY FFD TEAM

Recommendation 53 Top 3 Book Recommendations BY ALI RAZA

Sponsors of the Issue Influxis www.influxis.com ..........................................1, 2, 3

Flash&Math www.flashandmath.com .................................... 21

PlugrMan www.plugrman.com ........................................... 6-7

MonoGram CoverPage ™ www.monograminteractive.com ....................... 25

Manning Publications www.manning.com ............................................ 11

SPTechCon www.sptechcon.com ......................................... 54

SapphireSteel Software www.sapphiresteel.com .................................... 17

iPhone/iPad DevCon East www.iphonedevcon.com ................................... 55

5


TOOLS

R Blank, CTO, Almer/Blank

“PlugrMan is an applica�on designed from the ground-up to accelerate API development. By supplying useful features that remove redundant tasks from your workflow, PlugrMan improves the process of authoring AMF-based APIs for Flash Pla�orm applica�ons.” The Toyota Dealership Network

When the world’s largest automobile manufacturer was in need of a custom content management solu�on that would allow them to manage rich media delivery across their large network of US dealerships, they turned to BLACKBOX.tv, specialists in big brand experiences. Faced with an arduous task and a �ght deadline, Lead Architect/ Engineer Omar Gonzalez, turned to PlugrMan to deliver solid quality, quickly. “A�er having worked with it on an enterprise-scale, mul�-pla�orm applica�on produc�on run for The Toyota Dealership Network (TDN), I can say with confidence that PlugrMan is the go-to applica�on for working with remote API integra�on in Flash. It has several features, but there are four key features in PlugrMan that helped me to quickly complete work on the TDN implementa�on of BLACKBOX. It was perfect for the task because we designed this BLACKBOX implementa�on as a Flex 4-based content management and delivery system that uses the Adobe OSMF framework to deliver high quality on-demand dynamic streaming video across a na�onwide network of Toyota dealerships.” Strong-Type AMF API Debugging

“I found PlugrMan’s ability to debug strongtyped AMF APIs to be par�cularly unique. This enabled my team to validate our APIs from a Flash client which gave us an added level of confidence that the APIs we were calling were working as expected from a Flash

6

client without having to write a custom Flash interface or tester to do so. Because of PlugrMan, the en�re API development team was able to test their strong-typed arguments directly from a Flash client. As a result, all of the APIs were verified in Flash before we ever had to start wri�ng one line of Ac�onScript 3. And, since I’m usually having to architect and develop mul�ple applica�ons like this simultaneously, I really appreciated this capability. The setup to use the strong-typing feature was fast and simple too. PlugrMan just needs access to the remote classes that the AMF API sends and receives from Flash. To provide PlugrMan with that access I compiled a SWF file that contained the project’s AS3 classes (VOs, DTOs, etc) using an AS3 interface, that’s included with the PlugrMan Support download, in the SWF file document class. For the TDN project we had to communicate with an AMFPHP API that used strong-typed parameters for all of the remote methods to be called from the Flash client. This is in contrast to the service browser included with the AMFPHP library, which is restricted to sending generic data objects ([object Object]). PlugrMan let us hook right into the project’s API and test the API methods quickly and easily.” Object Editor (building mock data)

“Once the strong-typing feature was set up, PlugrMan’s robust mock data object editor allowed us to enter test data for the remote methods we needed to integrate. Even when we had to test APIs that were not strongtyped, PlugrMan’s object editor allowed us to freely add and remove proper�es to the mock data before tes�ng a method. If you’ve ever tried doing this using manually input JSON objects with the AMFPHP service browser, you’ll LOVE the PlugrMan experience. The object editor even figured out all of the test

03/2011 (21)


PlugrMan

data’s structure automa�cally! All we had to do was supply the mock data and PlugrMan makes that fast and easy. And, as if that weren’t enough, PlugrMan also remembers the test data for each API method. This seriously boosted efficiency because it allowed us to rapidly switch between methods without losing any of our work or was�ng �me repeatedly re-entering the same data.” Code Generation and Implementation

“One of the biggest �me-saving features in PlugrMan is its ability to generate Flash client code. This feature saved us tons of �me by completely elimina�ng the need to write Flash API client code. We implemented the generated code without having to alter or rewrite any of it. The code appeared designed to be as non-intrusive as possible and provided two different ways to invoke API methods. This gave us a couple of code style op�ons to choose from. Implementa�on was a breeze and the code easily integrated into the PureMVC architecture that we u�lized on the project (the generated code is flexible enough to fit into any other AS3 framework, such as RobotLegs). Because of the power of features like this, I really can’t see us using anything other than PlugrMan for AMF API integra�on in our Flash Pla�orm applica�ons.” Unit Testing

“The unit tes�ng feature in PlugrMan extended the features of the main test screen, where the object editor let us define mock data for each remote API method. Because the object editor stores the mock data for each API method, we were able to use the

03/2011 (21)

enhanced automated unit tes�ng features to gain cri�cal insight into the overall health of our API. To start, we could run all stored API method tests with a single click! Once the tests were complete, PlugrMan graphed the dura�on of method execu�on. By scrolling through the report, we could quickly see if any of the remote API methods either failed, indicated by grayed out columns, or if an API method was taking too much �me, indicated by a very long bar in the list. The remote API call �me was also displayed in milliseconds for more detail into how long the API call actually took. PlugrMan also includes the op�on to output the full API test report (including detailed informa�on on the query and the response for each test) to PDF.” Conclusion

“All of PlugrMan’s capabili�es clearly helped my team improve the process of developing the AMF APIs used by The Toyota Dealership Network. The unit tes�ng and code genera�on screens automated redundant tasks, which literally saved us days of development work on just one project! By using PlugrMan, we were able to concentrate on what was important to make the TDN project a success. We were able to complete all API development and integra�on much more rapidly, and with fewer bugs which allowed us to build a solid founda�on on which TDN now stands.”

ALMER/BLANK

7


Developing an Enterprise Flex Application Strategy

I

f your business has invested in Adobe Flex or Adobe AIR, a powerful software development kit for web, mobile, and desktop, chances are you’ve also invested in the training and you have IT professionals that are familiar with the basics. Here is the challenge: Every business is unique and requires unique solutions for the web, mobile, and internally. Developing Flex or AIR applications can be done in many ways with many different development frameworks. However, there are several core issues that need to be dealt with when working on large-scale RIAs such as how to handle:

application we need to define a standard and consistent architecture for building our Flex applications. When determining what architecture to implement your Flex user interface with; you need to consider what fits your organization and developer’s skills best as each solution is different and generally based on different design patterns, or slight modifications of those patterns. There are a few Flex application development frameworks that present solutions for development through design patterns that can be applied to Flex and AIR. However, from our experience, most of these frameworks create various problems when developing enterprise applications such as:

• • • • • • • •

Application Context Module Management Application Navigation Style Management Resource Management Data Transport Error Management State Management

At AppFoundation, we have been developing Flex applications since 2005 and that experience has shown many issues with current options for development frameworks. From organizations who don’t allow opensource solutions to mostly issues with application consistency and size; AppFoundation has created its own development framework to address the core issues above. FxConnect cuts down on as much as 25% of development required to deliver Flex and AIR applications. The goal of FxConnect is to simplify development of large scale rich Internet applications (RIAs). The result is a framework that allows development of new features outof-the-box instead of worrying about core architecture issues that FxConnect addresses. As you might have experienced, you can see that Flex can be built out-of-the-box to obtain data from external data sources. This works fine with small Flex applications that only have one or few view states. However, when it comes to building enterprise scale applications in Flex the basics just won’t cut it. To avoid a big ball of yarn (many point-to-point connections between Flex components) infrastructure for your

8

• • •

• •

Applications that are difficult to maintain due to the over-use of events. Difficulty to track application flows when data is not persisted and passed through events exclusively. Application SWF sizes becoming larger than 1mb in size. This is not good for browser based RIAs. Inability to manage application styles. Application styles can change based on different entities viewing the application; such as an e-commerce site that has business partner sign-in. Each business partner could need a different style to match their branding. The ability to properly chunk the application into modular components. Strong user interaction and a clear separation of concerns when setting the application architecture flows and views.

The purpose of a development framework or architecture is to create a consistent development process that is repeatable and non-evasive. FxConnect has been built to streamline development of RIAs so that you can start developing features instead of worrying about application plumbing. The FxConnect platform programming model is made up of the following core components that should be core to any enterprise Flex application: •

Application Framework: The Application Framework is the main wrapping component for the Application that contains application context and is responsible for the setup/initialization of the application.

03/2011 (21)


• •

• • • •

View Components/Modules: Modules are used to chunk the application into smaller SWFs that are loaded through the Module Manager. These modules are the features and components of the application where you start to code the different views and flows. Application State: The Application State is responsible for holding important application attributes in a memory cache that is accessible from any part of the application that gets an instance of this model. Data Model/Sub-models: The model provides a layer to access and change application data through creating proxies. Proxy: Proxies represent a layer of abstraction that exposes business functions to the application. They are a means to engage with remote services such as Spring beans to retrieve data. They contain the data result and fault handlers that are implemented through the IResponder class. Module Manager: The module manager allows you to logically partition the application into manageable view modules. Effectively breaking download of the application into small chunks that allow the views to be displayed on demand. Navigation: This is a business object that manages view state for components and modules. In this class, you set up constants that are maintained here. Style Manager: The Style Manager allows you to dynamically load styles into the application and is initialized at run-time. State Engine: This utility allows the definition of application states and the valid transition to which other states are available. Resource Manager: This utility is used to handle internationalization (i18n) and localization (l10n) details. You specify a default resource bundle by component or by application that allows you to define string names for button labels, text areas, etc. Error Manager: Error management allows you to capture and store errors from anywhere in the application as well as use its internal pop-ups to display error messages.

A Real-World Example: Social Business Tool

We needed a way to better manage a variety of information such as clients, projects, and communication between the two. AppFoundation’s social business solution applies the full potential of Web 2.0 models like communities, collaboration, and user generated content in a secure, managed environment. The application is built using the Adobe Flex and AIR platform, and utilizes a series of Spring services for persisting its data. The combination of Spring and AIR offers a powerful deployment model with due to the ease of configuration required. The simple, yet robust, deployment is possible because the AIR runtime runs on the client machine.

03/2011 (21)

The AF Connect AIR application enables valid users to view projects they are tied to, messages for those projects, media, and client contact information if they are granted rights to those views. The list below shows what the application feature set is composed of: • • • • • • •

Social Media connection suite via FxConnect Account and Project creation Ability to assign members viewing privileges to selected accounts and projects Account and Project level messages, connections, and media Project management of project milestones, details, issues, and tasks User profile management Client details, notes, location, contacts, and URL links

With the power of the Adobe AIR and Spring platforms, it only took about 3 months to take the application from concept to a working production implementation. A team of designers, Flex developers, and Java developers worked on the application at different points throughout the implementation, working on both the backend data connectors and the user interface. Adobe AIR allows developers to create applications for the desktop using Web technologies such as HTML/ CSS, Ajax, Flash, and Flex. In addition, AIR provides offline support and a simple deployment paradigm for delivering the client applications. The mid-tier of this application is a balance of Spring and Java Servlets to handle the heavy lifting for data processing. This allows for a deployment mechanism where the AIR application runs on the user’s computer and data is managed by Spring. The pairing of AIR and Spring makes it possible to retrieve and visualize the data quickly for the users. With Flex and Spring, we were able to stand up this application at a very fast pace. The goal of any project is successful completion of all requirements and features. To successfully deliver your enterprise class RIAs, I hope you take a look at the core issues you need to address and choose the proper tools for the job.

CHRIS GIAMETTA Chris Giametta is an author and Managing Partner with AppFoundation Technology Group, Inc (www.appfoundation.com, Twitter @AppFoundation). AppFoundation (Af) is full-service �rm that provides custom web, mobile, and desktop application development. Af leverages innovative technologies to deliver premium user experiences that engage customers to drive satisfaction.

9


IN BRIEF

Update for Flash Player 10.2 Support on Tablets

Adobe will offer Flash Player 10.2 pre-installed on some tablets and as an OTA download on others within a few weeks of Android 3 (Honeycomb) devices becoming available, the first of which is expected to be the Motorola Xoom. Adobe made a great progress optimizing Flash for tablets, alongside partners including Motorola, and expect to continue. Over 20 million smartphones were shipped or upgraded with Flash Player in 2010 and over 150,000 consumers on the Android Market are rating it 4.5 out of 5 stars. According to Adobe, there will be over 132 million devices with installed Flash Player by the end of 2011. Consumers are clearly asking for Flash support on tablet devices and the good news is that they won’t have to wait long. Over 50 tablets that will ship in 2011 supporting a full web experience (including Flash support) and Xoom users will be among the first to enjoy this benefit. source: Adobe Flash Platform Blog

Digital Magazines Coming to Android Built on AIR

I’m sure you’ve heard about the Wired, Martha Stewart, and New Yorker magazines on iPad, right? Those were created with a new suite of tools that Adobe has been working on. The Digital Publishing Suite allows you to use your existing staff, skills, and Creative Suite publishing tools to design and deliver publisher-branded reading experiences to mobile devices. Currently these magazines were only available on iOS devices but at MWC Adobe announced that the Android viewer is now available. The application is actually built on AIR! Condé Nast, publisher of WIRED magazine, showed off the magazine at MWC on the Motorola Xoom running Honeycomb. source: Serge Jespers

since the former has only been available for about 6 months and AIR has only been available for a little more than 3 months! While the momentum has been astonishing, there are still some questions on how Flash Player is performing on mobile devices. Tim Siglin, an editor at Streaming Media and co-founder of Transitions, Inc., wanted to find out for himself and published his findings in his whitepaper Performance or Penalty – Assessing Flash Player 10.1 Impact on Android Handsets (http:// workflowed.blogspot.com/2011/02/flash-player-101-forandroid.html). It is an in-depth look at the performance of Flash Player on a number of mobile devices, and the results may surprise you. Key highlights from the whitepaper include: •

• • • •

For the vast majority of video content delivered for Flash Player on mobile devices, performance is equivalent to the full frame rate experience on desktop. This is a huge improvement vs. video played back on previous devices. The most significant factors impacting mobile battery life for video playback, for both Flash Player and the native device player, is appropriate video encoding and optimization. There is minimal, if any, impact on mobile device battery life with Flash Player, even with multiple apps running. All web content, running in Flash Player or not, consume battery power at consistent rates over WiFi in the native browser. GPS, 3G and other resources on a phone consume more power than Flash Player, including when highly interactive content is viewed. Flash Player 10.1 performance was 350% better than equivalent content in HTML, running an average of 24 frames per second for Flash Player 10.1 and 7 fps for HTML. source: Adobe Flash Platform Blog

FFDMag is going to FITC MWC 2011 and Flash Platform: Good Amsterdam! Progress and Good Performance If you are going to FITC Amsterdam With Mobile World Congress closed in Barcelona, Adobe is seeing tremendous momentum for theFlash Platform runtimes on mobile devices. Some of the latest devices that are announcing and launching this year: tablets are the Motorola XOOM, RIM Blackberry PlayBook and Samsung Galaxy Tab 10.1 and smartphones like the Samsung Galaxy S II, Sony Ericsson Xperia pro and neo and the five new Android smartphones from HTC. With beautiful web content for Flash Player and rich apps built with AIR, these devices highlight the wide adoption of both the Flash Player and AIR, especially

10

this year, you can meet our editor Csomák Gábor there. If you are not going to Flash In The City, you can read his twitter page where he will post frequent updates of the festival. Check http://twitter.com/csomak out! So if you are interested, follow Csomák Gábor to get the feeling of a great event.

News selected by Gábor Csomák

03/2011 (21)


Restlet in Action

Jerome Louvel and Thierry Boileau http://www.manning.com/louvel/

Secrets of the JavaScript Ninja John Resig and Bear Bibeault http://www.manning.com/resig/

Android in Practice

Charlie Collins, Michael D. Galpin, and Matthias Kaeppler http://www.manning.com/collins/

Liferay in Action

Hello! Flex 4

Peter Armstrong

http://www.manning.com/armstrong3/

Flex on Java

Bernerd Allmon and

The Official Guide to Liferay Portal De- Jeremy Anderson velopment http://www.manning.com/allmon/

Richard Sezov, Jr

http://www.manning.com/sezov/

Hello! Silverlight

Adobe AIR in Action

Bill Reiss and Dave Campbell http://www.manning.com/reiss/

Flex 4 in Action

Joey Lott, Kathryn Rotondo, Sam Ahn and Ashley Atkins

Tariq Ahmed, Dan Orlando, John C. http://www.manning.com/lott/ Bland II, and Joel Hooks http://www.manning.com/ahmed2/

About Manning

Manning publishes computer books for professionals-programmers, system administrators, designers, architects, managers and others. They key people work from their own offices across the US, all communicating with the center in Greenwich, CT, and with each other and our authors by email, Web, phone and mail. Manning is a small, personal, old-world publisher where an author’s opinion is sought and a reader’s message is answered. Manning’s focus is on computing titles at professional levels. They care about the quality of our books. They work with our authors to coax out of them the best writing they can produce. The books are designed without gimmicks. Their main goal is elegance and readability. www.manning.com


TOOLS

LockLizard FlashGuard Pros: • •

Easy and fast usage. High security with licensing feature

Cons: • •

Available only for Windows systems Special Flash player from LockLizard has to be used to view the result.

So Users have to install the LockLizard Player to view the secure encrypted flash content.

Figure 1. Online Account License Settings

LockLizard Flash Player is available only for Windows. The installation process is easy and goes its standard way. After the Installation process your find the LockLizard Writer Tool in you Start Menu. After starting and selecting you Flash SWF File inside the Writer Tool you can setup different options like: Expiration and Validity Options (i.e. setting up a license which is configurable over your online account at locklizard.com or setting up Expiration on an specified Date or prevent starting the flash content after X-Days). Setting up Print and View Options (i.e. defining a limited amount of views or prevent printing) It‘s handy and simple interface makes it really easy to secure and encrypt your flash content. After applying the settings it will protect your content and shows you the status over a separate window. As a result, you‘ll find a .pfd file which is symbolized with a lock-icon. It needs a special Flash Player to view or run the protected file which you have to download from the locklizard site. So your consumers or purchasers need to have this Player, too of course. With your FlashGuard online Account you can manage your encrypted files and view the settings you defined during the protection phase and you can easily create licenses or accounts for your consumers over the web platform. Unfortunately there is no OS X Version of FlashGuard. Compared to other protection or obfuscator tools like Zinc 3.x or SWF Secure and SWF Protect you don’t need a separate Player and so you‘re able to use your content on any platform. But those don’t offer a license and managing feature.

ALI NEKOU POUR

Figure 2. Print and View Settings

12

Ali Nekou Pour, 27 years old Adobe Flash Platform Evangelist, over �ve years of Flash/Flex coding experience, living in Germany/Berlin and currently working for Scholz & Friends Interactive.

03/2011 (21)


Tools

Anicca Digital Solutions Websites shouldn’t be difficult...

I

f you have a business, a product or a service that targets common consumers, consumers who don’t know the difference between a Flash website and a Rich Internet application, then your website should be really simple and straight forward in order to convey its message efficiently to the user. Anicca Digital Solutions, a Leicester-based digital agency took this idea religiously and has been providing web services for over 5 years.

They offer four different types of websites for personal, small to mid-size businesses – Standard Brochure Site, Premium Brochure Site, Database Driven Website and Database Driven Website with e-Commerce. Anicca solutions has developed their own customized content management system named as Reflex that enable their customers to maintain their websites with ease. It has almost all the required features that one can expect from a CMS with simplicity at its core. If you have more questions or you would like to discuss your project with Anicca, contact them for a free audit or 2 hours consultancy. It is worth mentioning that Anicca is one of the few UK-based companies that are accredited or approved by East Midlands Development Agency (EMDA), Google (Google AdWords Certified Partner), and Microsoft (Microsoft adExcellence accredited company), Guild of Master Craftsmen and Chartered Institute of Marketing (Chartered Marketer). Along with web services, Anicca solutions also provides web design, development, SEO, marketing, training and consultancy services.

Anicca Solutions Ltd.

5 Castle View Leicester LE1 5WH Fax: 0871 429 0499 Email: enquiries@anicca-solutions.com

03/2011 (21)

ALI RAZA

Adobe Certi�ed Instructor, Sun Certi�ed Java Programmer, Zend Certi�ed Engineer; www.manofspirit.com

13


TOOLS

NetroMedia

N

etroMedia, a cloud based streaming media provider, allows anybody to start broadcasting video or audio online without a formidable cash outlay. NetroMedia’s setup is very impressive, it not only has the capability of servicing individual to enterprise conferencing events and large-scale live concerts, but also does a superb job of delivering video on-demand (VOD) and streaming online Radio or TV. Some of the highlights of NetroMedia’s services include: • • • • •

Support for live and on-demand streaming in multiple formats (Flash, Windows Media, QuickTime, ShoutCast, etc.) Streaming to multiple devices (Mobile, PC, Mac, Set-Top, iPad, etc.) 24/7 reporting and analytics access, including realtime reporting Pooled bandwidth across multiple channels Embeddable media players for web. Easy integration with 3rd party applications and websites.

How to Start Using NetroMedia?

Say you are an event promoter and you would like to broadcast a live concert online – you can use NetroMedia! Or perhaps you have a library with thousands of videos, but cannot setup your own streaming server due to the cost or lack of know-how, NetroMedia can help you – and these are only two examples, in a long list of scenarios. Using NetroMedia is extremely simple – you start by creating an account at http://www.NetroMedia.com, (Figure 2). Choose a channel name, provide your email address and then choose one of the four available streaming programs. NetroMedia also offers a Free

Figure 1. Simple Steps to Start Streaming

14

Trial program, that will give you enough bandwidth and storage to test drive the system. Once you have created your account, a password will be sent to you from NetroMedia. With your email address and password, you can login to NetroPortal – NetroMedia’s streaming management system. NetroPortal allows broadcasters to manage live and on-demand streaming channels online. If you have multiple channels, you can provision the channels with bandwidth allocations so that you save money on unused bandwidth. NetroPortal also provides you with advanced analytics reports, generated in readable form from the streaming server’s log. The key reporting features and benefits includes: • • • • •

Real-time statistics Aggregated reports generated on-demand Ability to segment reports based on date ranges and geographic location Exportable statistics (to share with advertisers, royalty payment etc.) Projected reports (display predicted monthly bandwidth, connections and user hours).

NetroPortal also features advanced user control. You can add different users who have different responsibilities into the system. For example, members of your Accounting Department can log in with their own username and password to pay bills. Basically, you can manage a team

Figure 2. Example enterprise bandwidth report

03/2011 (21)


Tools

Figure 5. Example Encoder Setting

Figure 3. Setup active stream channel

of people with different access to the management portal. What can you expect from NetroMedia? •

Live and on-demand streaming with multi-format support: • Windows Media (WMV/WMA) • Flash (FLV and H.264 video, MP3, and HE-AAC audio) • QuickTime (.mp4, f4v, .mov, .m4v, .mp4a, .3gp, and .3g2) • HTML5 video tag supported (only available where the browser supports html5 video) • Sliverlight (Smooth Streaming) and SHOUTcast Live Streaming with Multi-Device Capabilities supports: • Containers: MPEG-4 with H.264/AAC • Protocols: RTMP, HTTP, MMS, RTSP/RTP, MPEG-TS, • Devices: PC, Mac, mobile (iPhone, Blackberry), Set-Top boxes, Tablet PCs

With Adobe’s Flash Media Live Encoder, I was able to get a live streaming going within seconds! What you have to do is: 1. Login to NetroPortal by going to https:// login.NetroMedia.com/ 2. Go to Services > My Active Services 3. If you do not have a channel created, you can create a new streaming channel by filling the form at Add a New Streaming Channel, if you want to use an

Figure 4. Example result from speedtest.net

03/2011 (21)

existing channel, you can click on that channel’s name from the listing at Active Streaming Channels 4. It will bring you the Configure Services Screen, since it has my username and password, I will not share the screen with you. But this is where you should get the following information (Figure 3): 4.1. FMS URL 4.2. Stream (the name of the stream) 5. Test your internet connection by going to speedtest.net, click on start testing, and note the speed (The network I am on now while writing this article is obviously very slow; Figure 4) 6. Start your Adobe Flash Media Live Encoder 7. Configure the Encoder. The easiest way to configure the encoder is to use the Preset menu, the bandwidth you choose must be lower than your internet connection’s upload capacity, or choose custom. 8. Choose your desired devices and bitrates – the most common online bitrate is 268 video and 32K Audio 9. On the right hand side of the encoder, you will find following 3 fields: FMS URL, Stream and Backup URL. The FMS URL is case sensitive, Backup URL can be left blank. 10. You can achieve your live stream broadcast by checking the Save to File and input a file name to the Save to File textbox. Once these details are all set, simply click the Large Green Start button at the bottom ( make sure that you did not click the connect button right below the stream name. You can view your stream by going to the Public Link you can also embed your stream onto any webpage by copying and pasting the embed code.

Figure 6. Encoder Setting for Mobile Streaming

15


��� �� �� �

TOOLS

������������� �����������

�� �� ��

�������������

������������ ���������� ��������

������

���������������� ����������

������������

����������������� ������������

���

����������

���

������� ��������������

Figure 7. How does netromedia work

Both can be obtained at your channels’ configuration page at NetroPortal. Smartphone devices have become indispensible in a lot of people’s lives. In order to reach people on the go with your live streaming, you might want to try to broadcast to mobile as well. As with broadcast to the web, testing mobile broadcasting is truly NetroMedia style – simple and elegant. Before we begin, you first make sure that your mobile services are enabled, if you are not sure, you can call your account manager at 1-888-818-3846, once your mobile streaming is enabled, they will email you the mobile access links. OK, now we can get our feet wet and start messing with the encoder: We will use the Flash Media Live Encoder again to demonstrate how easy it is: 1. Configure the encoder: Video Format: H.264, Profile Baseline and Level 1.3 Audio Format: AAC – Windows users must obtain a license to use the AAC plugin from http:// www.mainconcept.com/aacencoder (Figure 5) 2. Click on the wrench next to your video Format, set the profile to Baseline and Level to 1.3 (Figure 6) 3. fill in the FMS URL and stream name as for the web. 4. Click on the large green start button. With the mobile link that NetroMedia emailed to you, you can view your broadcast on your iphone, android, ipad, blackberry et al. It is advised to make sure to at least use a stable Wi-Fi connection, in big events (concert, in the wilderness), people usually get a Satellite connection (need big bucks), or choose a venue with dedicated fiber.

How does NetroMedia do it?

As an end user, all of this seems like black magic – an illusion that NetroMedia has spent a major investment

16

to create for you. To make all this possible, NetroMedia has created a global Content Delivery Network (CDN) based on their unique Streaming Media Matrix architecture introduced in 1999, designed to deliver maximum flexibility, stability and scalability using a matrix-style network infrastructure. All routing within this system is done by a global DNS system. Broadcasting media feeds are routed to the closest acquisition server and the acquisition server, in turn, is then routed via DNS to a strategically placed Point-of-Presence (POPs) around the globe. When the end-user requests a stream, he is routed via DNS to the closest distribution server. NetroMedia’s network is connected to major private peering Tier-1 backbone networks. With advanced DNS and Dual/Geo-Separated Load Balancers, NetroMedia is able to distribute content using the fastest route possible, rather than the most convenient, cheapest or easiest route (Figure 7).

Conclusion

Netromedia is a versatile, reliable service for broadcasters. This short article can not cover all what netromedia has to offer. The netromedia network has great redundancy built-in in every layer of the infrastructure. It was a great pleasure reviewing the netromedia service.

JOSEPHINE LIANG Josephine Liang is a computer science geek whose interests range from Artificial intelligence to optimum health for humans. She enjoys web application architecturing, web and mobile application development, especially social networking and multimedia web applications. She likes both the technique and human side of the technology world. She currently works for NBC Universal.

03/2011 (21)


3D IN FLASH

GPU-3D in Flash If you haven’t heard the news, the next major Flash Player upgrade from Adobe will include an extensive 3D API that will support direct paths to OpenGL and DirectX-based 3D rendering on the GPU. What you will learn…

What you should know…

• New Syntax feature in action script 0.3 • Adobe Graphics Assembly Language (AGAL)

• Action Script 0.3 • Basic 3D knowledge in �ash

I

t allows true next-gen hardware accelerated 3d graphics that can rival Unity, Xbox and Playstation games, as well as a new software 3D renderer fallback that will aim to provide the vast majority of computers with fast, reliable, 3D rendering in Flash.

What is Molehill?

Molehill is the code name for a new set of low-level, GPU-accelerated 3D APIs that will enable advanced 3D experiences across screens through the Adobe Flash Platform runtimes. These new low-level APIs will provide advanced 3D and 3D engine developers the flexibility to leverage GPU hardware acceleration for significant performance gains. Today, Adobe Flash Player 10.1 renders thousands of non z-buffered triangles at approximately 30 Hz. With the new 3D APIs, developers can expect hundreds of thousands of z-buffered triangles to be rendered at HD resolution in full screen at around 60 Hz. Using the new 3D APIs in Flash Player and AIR will make it possible to deliver sophisticated 3D experiences across almost every computer and device connected to the Internet. The 3D capabilities enabled by the new APIs will also be available to the broader developer community through popular ActionScript 3D frameworks, such as Alternativa3D, Away3d, Flare3D, Sophie3D or Yogurt3D. Molehill will rely on DirectX 9 on Windows and OpenGL 1.3 on Mac OS X and Linux. On mobile platforms like Android, Molehill will rely on OpenGL

18

ES 2. Technically,the Molehill APIs are truly 3D, GPUprogrammable, and shader-based. They will expose features that 3D developers have been wanting for a long time in Flash, such as programmable vertex and fragment shaders, to enable things like vertex skinning on the GPU for bones animation as well as native zbuffering, stencil color buffering, cube textures, and more.

How does Molehill API work?

Adobe recently introduced the concept of Stage Video in Flash Player 10.2, available as a beta on Adobe Labs. Stage Video relies on the same design, by enabling full GPU acceleration for video, from decoding to presentation. With this new rendering model, Adobe Flash Player presents the video frames or 3D buffer not inside the display list but inside a texture sitting behind the stage painted through the GPU. This allows Adobe Flash Player to directly paint on-screen the content available on the graphics card memory. No more read back is required to retrieve the frames from the GPU to push them onscreen through the display list on the CPU. As a result, because the 3D content sits behind the Flash Player stage and is not part of the display list, the Context3D and Stage3D objects are not display objects. That means you cannot interact with them the same way you interact with any DisplayObject, and rotations, blend modes, filters, and many other effects cannot be applied. The Molehill APIs do not use a

03/2011 (21)


GPU-3D in Flash

fixed function, which means that you will have to work with vertex and fragment shaders to display anything on-screen. For this, you will be able to upload your shaders as pure low-level Adobe Graphics Assembly Language (AGAL) bytecode as a ByteArray on the graphics card. As a developer, you have two ways to do this: You can write your shaders at the assembly level, which requires an advanced understanding of how shaders work. Or you can use a higher level language like Pixel Bender 3D, which will expose a more natural way to program your shaders and compile the appropriate AGAL bytecode. In order to represent your triangles, you will need to work with VertexBuffer3D and IndexBuffer3D objects by passing vertices coordinates and indices. Once your vertex shaders and fragment shaders are ready, you can upload them to the graphics card through a Program3D object. Basically, a vertex shader deals with the position of the vertices used to draw your triangles, whereas a fragment shader handles the appearance of the pixels

used to texture your triangles. We can only prepare for the upcoming revolution in online gaming by studying the API as discussed in Adobe’s lectures from their recent conferences and here are the AS3 programming techniques that will be used to get amazing 3d graphics in your Flash games (see Listing 1). Buffers are created for each model in your game. Once you define a model this way, you can render it as many times as you want using a single line of code. In this example, we defined the buffer as six entries of three numbers (x,y,z) each, but you can embed more info like x texture coordinates as well. // Create a vertex and index buffer

var vertexbuffer = context3d.createVertexBuffer(3,6);

You only have to upload models once, during startup. Vertex buffers are lists of x,y,z points in space. Each vertex represents a corner in your 3d model. In this example, we use x,y,z,r,g,b (6 floats per vertex).

Listing 1. Create a rendering context lets �ash decide between openGL, directX and software rendering var context3d: Context3D = new Context3D(Context3DRenderMode.AUTO);

//Put this 3d view on the stage underneath any flash gui elements stage.stage3Ds[0].attachContext3D(context3D); //Generally a game will only have one context3dbut could have more than one viewport stage.stage3Ds[0].viewPort = new Rectangle(0,0,688,528); //Set up the buffer for double buffered rendering each frame, you swap buffers for display context3D.setupBackBuffer(688,528,1,true);

Listing 2. Create a vertex var av:AGALMiniAssembler = new AGALMiniAssembler();

av.assemble(Context3DProgramType.VERTEX,"m44 op, va0, vc0\n mov v0, va1\n"); // Then create a fragment program (a shader) which tells the renderer how to draw it (color, texture) var af:AGALMiniAssembler = new AGALMiniAssembler();

af.assemble(Context3DProgramType.FRAGMENT,"mov oc, v0"); //Then upload the compiled bytecode to the 3d context var program = context3d.createProgram();

program.upload(av.agalcode, af.agalcode);

03/2011 (21)

19


3D IN FLASH

Listing 3. Render loop // This is what gets run EVERY FRAME Clear the frame to solid black (r,g,b,a) context3d.clear(0,0,0,1); // tell flash which program to use (which shader to use) context3d.setProgram(program); // tell flash which vertex streams to use (which models to render) context3d.setVertexStream(0,vertexbuffer,0,Context3DVertexFormat.FLOAT_3); context3d.setVertexStream(1,vertexbuffer,3,Context3DVertexFormat.FLOAT_3); vertexbuffer.upload( Vector.<Number>([-1,-1,0, 1,0,0, 0,1,0, 0.75,0.8,0.3, 1,-1,0, 0,0.5,0.9] ),0,3);

Start at offset 0, then count 3. Index buffers are lists that define which vertices are used by which triangle since multiple triangles can share the same vertex when they are touching. In this example, we define the buffer as 3 entries. var indexbuffer = context3d.createIndexBuffer(3); indexbuffer.upload(Vector.<uint>([0,1,2]),0,3);

Programs are essentially shaders that define how to draw each element you send a string of assemblylanguage-like commands. Flash will compile them into efficient bytecode but first compile the assembly language source for a vertex program. This tells the renderer how to draw the shape. The opcode m44 is short for a 4x4 transform matrix (see Listing 2). Now all set up is done! That takes care of the initialization. In three short steps, you created a rendering context, set up a viewport, defined a model by uploading vertex data, and created a vertex and fragment program that tells the 3d engine how to handle this data for drawing. Now you can use all this data during your render loop. The amazing thing (and the reason that Molehill will be able to render hundreds of thousands of polygons in full screen resolution at a smooth 60 frames per second) is that you can upload tons of models with thousands of polies during the inits and render them below using only a couple lines of code. In previous versions of flash you essentially have to re-send each polygonâ&#x20AC;&#x2122;s data every single frame, resulting in thousands of inefficiently repeated draw calls each frame. The new way batches this data for reuse in the same way that you would set up vertex objects in openGL or DirectX using C++ (see Listing 3).

20

Set program constants send variables used by the programs that change every frame. This is how you interface with your programs. You can enable animations or color changes this way or define vectors for use in shaders or lighting in this case we tell the program where the model is. context3d.setProgramConstantsMatrix(Context3DProgramType .VERTEX, 0, mvpMatrix, true);

Draw the model! This one line can render thousands of polygons in one fast call. You would draw each model in your scene using calls like this. You could draw the same model (e.g. a tree) multiple times in different locations for efficient use as props by changing the mvpMatrix using another set ProgramConstantsMatrix call. In this example, we just draw one shape. context3d.drawTriangles(indexbuffer,0,1);

Update the display! Do this once you have drawn all models you want rendered. It will display the backbuffer that we just drew on. context3d.swap();

Naturally, Molehill has not been released yet. This functionality will not be available until mid-2011, at which time developers will be able to download a .SWC compiled flash file that they can include in their AS3 projects which exposes the Molehill beta API prior to release. Until you have this beta SWC file, the code above will not compile in Flash. Please consider it only a general example of the techniques that you will be using to create next gen 3d flash games next year.

ESLAM AHMED Flash Developer

03/2011 (21)


����� ����

������������������� ��������������� ���������

������������ ������������� ����������� ���������������

��������������� ��������������������


VIDEO HOSTING PLATFORM

Creating a Distributed Video Hosting Platform This article is about some technical aspects of creating the free video upload service – VideoBam.com. This server allows users to upload, convert and share videos online. Server software configuration will be covered in the article. Some commands, configuration blocks and code examples will be shown here. What you will learn…

What you should know…

• • • •

• UNIX command shell • The moderate knowledge of installing and con�guring Linux server software • The basic knowledge of PHP

How to build scalable distributed �le storage system How to take the video screenshots using mplayer How to transcode videos with ffmpeg How to setup the video streaming using nginx web-server

W

ith browsers now supporting HTML5, videos can be embedded using native <video> tags. Each browser supports a certain amount of containers and codecs. This support is well described here: http://diveintohtml5.org/video.html#what-works. One of the most important system requirements was the support of Apple devices (iPhone, iPad, iPod). These devices are only able to play the video in MP4 format and not in Adobe Flash format. That’s why we have initially chosen the H264 video and AAC audio codecs in MP4 container as the video storage format. We are using the free implementations of these codecs – libx264 and libfaac. For the browsers and devices which do not support these codecs, we are using automatic Flash fallback.

Architecture

The system architecture is pretty simple and consists of 2 types of servers: • •

conversion server (which also acts as application and database server); file server (the videos are being transferred to after processing).

The content delivery work horses are the file servers. The main idea is to transfer the processed video from the conversion server to the file server as soon as possible to avoid the network interface load. To

22

determine which server the video is located at the moment, we are using the linking database table videos_servers. Each server has a streaming module installed. We are moving the files between servers using NFS protocol. The conversion queue is managed by beanstalkd (http://kr.github.com/beanstalkd/). Tests are showing that on a twelve core server the 30 parallel workers are running fine with keeping the page generation time within acceptable range. We have not performed tests with greater count of workers, but we have a good amount of power ready in case the number of workers needs to be increased.

Server software

Debian Lenny is installed on the all servers.

Media conversion software

To convert the videos into MP4 format we are using the most popular solution ffmpeg (http://www.ffmpeg.org/). ffmpeg is converting the video from the various formats and can use multiple processor cores. We are using great utility called MP4Box from the gpac package (http://gpac.sourceforge.net/) for post-processing. The post processing is necessary because ffmpeg stores the moov-atoms (video meta information) in the end of the file, however, this data needs to be stored at the beginning to give the users the ability to seek the video until it fully loaded. MP4Box moves them at the

03/2011 (21)


VIDEO HOSTING PLATFORM

beginning and processes the file making him match all the required standards and appropriate for streaming through the module. $ ffmpeg -vpre videobam -y -i input.avi -s 320x240 -vcodec libx264 -acodec libfaac -threads 0 -ab 64k -b 400k -bt

bugs. Particularly, we’ve met the problem of stuttering sound after conversion of some QuickTime movies. The problem has been solved by updating the libfaac and libfaad libraries.

Server modules

500k -g 24 -r 24 temp.mp4

Note: for compiling h264 streaming module sometimes this patch http://pastie.org/1405286 is required

We should pay attention on the -g 24 option. It defines after how many frames each keyframe will be saved. It’s important to store keyframes in order to allow the user to seek through the video while the video is still loading. This ability is realized by the streaming module. Client (browser or Flash-player) sends the GET-parameter start to the web-server which is being processed by the streaming module and means the number of seconds from which video should start.

$ cd nginx-0.8.53

GET /output.mp4?start=856.733 HTTP/1.1

}

Besides, the -threads 0 parameter will significantly increase the speed of conversion by automatically detecting the number of processor cores to be used. We also need to declare the number of frames (framerate) using the -r 24 option. We had problems with some video files because of high framerate value (mostly from screencasts). The conversion time was too high for such files. For each video we are creating screenshots at the defined moments of time to allow the user to briefly see what this video contains. The examples of such screenshots (thumb sheets) can be viewed at http:// videobam.com/tour. ffmpeg can not make those screenshots fast and that’s why we are using mplayer (http://www.mplayerhq.hu/) which takes screenshots almost immediately jumping through the video by the keyframes.

Let’s restart the web-server and try to download the video starting from the 10th second:

$ MP4Box -add temp.mp4 output.mp4

$ ./configure --add-module=../nginx_mod_h264_streaming-2.2.7/ --add-module=../ngx_http_secure_download/

Video streaming is made by h264 streaming module for nginx web server (http://h264.codeshop.com/). It’s pretty easy to configure this module: /usr/local/nginx/conf/nginx.conf location ~ \.mp4$ { mp4;

$ mplayer -ss 00:00:04 -sstep 12 -frames 16 -vo jpeg: outdir=/tmp/pictures/ -nosound output.mp4

All software is compiled from sources. The bundled Linux packages are often outdated and have a lot of

$ wget -O temp.mp4 “http://videobam.com/test.mp4?start=10.0”

For hotlinking protection we are using HTTP Secure Download module (http://github.com/replay/ngx_http_ secure_download). It allows to encode the link using the defined salt. /usr/local/nginx/conf/nginx.conf location ~* /videos {

secure_download on;

secure_download_path_mode file;

secure_download_secret saltsaltsalt$remote_addr; if ($secure_download = „-1”) { }

}

}

rewrite /expired.html break;

if ($secure_download = „-2”) {

rewrite /bad_hash.html break;

if ($secure_download = „-3”) { return 500;

mp4; }

�����������������

rewrite ^(.*)/[0-9a-zA-Z]*/[0-9a-zA-Z]*$ $1 break;

And that’s how we can generate the link using PHP: �������������

�������������

Figure 1. Conversion Server

03/2011 (21)

���

�������������

public function secure_url($url) {

$ts = time() + 3600;

23


VIDEO HOSTING PLATFORM

On the ‘Net Software: • • • • • • • • • •

beanstalkd http://kr.github.com/beanstalkd/ VideoJS http://videojs.com/ �owplayer http://�owplayer.org ffmpeg http://www.ffmpeg.org/ mplayer http://www.mplayerhq.hu/ gpac (MP4Box) http://gpac.sourceforge.net/ nginx 0.8.53 http://nginx.org/en/ nginx h264 streaming module http://h264.code-shop.com nginx http secure download http://github.com/replay/ngx_http_secure_download nginx upload progress module http://github.com/masterzen/nginx-upload-progress-gimodule

Additional reading: • • • • • • •

http://diveintohtml5.org/video.html http://rob.opendot.cl/index.php/useful-stuff/ffmpeg-x264-encoding-guide/ http://sites.google.com/site/linuxencoding/x264-ffmpeg-mapping http://x264dev.multimedia.cx/ http://rodrigopolo.com/ffmpeg/cheats.html http://e-mats.org/2010/01/�xing-stuttering-audio-with-ffmpeg-and-quicktime/ http://www.videohelp.com/tools/mp4box $ts_in_hex = dechex($ts);

$secret = ‘saltsaltsalt’ . $_SERVER[‘REMOTE_ADDR’];

$hash = md5($url . ‘/’ . $secret . ‘/’ . $ts_in_hex); }

return $url . ‘/’ . $hash . ‘/’ . $ts_in_hex;

NFS and autofs

We are working with the file servers using the NFS protocol. The automatic mounts are handled by the autofs. It mounts the file servers by request. All NFS-partitions are mounted in soft mode to avoid the process hang in case of server failure.

Client side

As I mentioned previously, we are using VideoJS (http:// videojs.com) for playing and styling the HTML5 video. Besides, VideoJS performs more smart Flash fallback (when the browser does not support the MP4-video). We are using flowplayer (http://flowplayer.org) as the Flash video player.

/etc/auto.storage

0 :/var/www/shared/local_storage

1 -fstype=nfs,rw,async,soft,intr,timeo=20,rsize=64000, wsize=64000 f1.videobam.com:/var/storage

2 -fstype=nfs,rw,async,soft,intr,timeo=20,rsize=64000, wsize=64000 f2.videobam.com:/var/storage

3 -fstype=nfs,rw,async,soft,intr,timeo=20,rsize=64000, wsize=64000 f3.videobam.com:/var/storage

4 -fstype=nfs,rw,async,soft,intr,timeo=20,rsize=64000, wsize=64000 f4.videobam.com:/var/storage

The structure of the files and folders is the same for all file servers and that’s why we are working with paths using the simple server ID substitution. It’s important to keep in mind that ext3 partition has files & folders count limitation within the particular folder. We are saving the videos in the folders with the videos/a/ab/abcdefg.mp4 names where a and ab are the first letters of the video file name.

24

ANDREY CHERNIH Ruby on Rails and PHP backend developer. Graduated Kazan State Technical University, currently resides in Kazan, Russia. Area of interest: web-development, startups, Apple devices. Email: andrey.chernih@gmail.com Github account: http:// github.com/AndreyChernyh

03/2011 (21)


PHP AND ACTION SCRIPT 3.0

File Handling With AS 3.0 Touching local files from browser with help of Action Script 3.0 In this article we are going to play with local files and it’s contents. We are going to see how to access these files from browser containing flash movie with and with out use of server side scripting (Here consider PHP as server side scripting). What you will learn…

What you should know…

• Uploading local �les with help of Server Side Scripting (Single �le and Multiple �le upload). • Communication with PHP and ActionScript 3.0. • Downloading �les from Server Side. • Accessing Data from local �les without uploading to Server. • How to open and save �le from �ash.

• • • •

F

rom many years, Flash proved itself and make his own place on web browser. For advertising, games, banners etc. as the days gone Flash reached to next level with improvement in OOP techniques Action Script 3.0. Now it becomes so powerful that it can make Online Editors, Tools, Web sites, and many more things. Some times user need to access their own files stored on their machine. Lets see how to use their files. In the following examples I played with Image files which is same as text files, audio files, video files. Just difference is while using contents of file you need to type cast it some where.

Multiple Local File Uploading with Help of PHP

Single Local File Uploading with Help of PHP

Downloading File to Local Disk From Server

Please see Listing 1 for Action Script 3.0 code for single file uploading. Focus of this article is how to use local files data and main advantage of file uploading is you can use that local file any where any time on browser because its now on server. I’ll explain code line by line. Once file is uploaded and you know exact path of file, You can use it in your Flash project as shown Listing 2.

26

Flash cs4. Basics of Action Script 3.0. Embedding SWF �le on web browser. Basic of PHP.

Now, lets see how to upload multiple files at the same time. Advantage of multiple file uploading is, you do not need to open browse window each time to upload file. But while using these files be careful about sequence of uploading. The difference between Multiple file uploading and Single file uploading is FileReferenceList. Lets see ActionScript 3.0 Code in Listing 3. Flash cannot create file or cannot connect to database so we need server side scripting language like PHP. The code for uploadFile.php is shown in Listing 4. This method is quite simple to download any file from server. navigateToURL(new URLRequest(„http://www.mysite/FileGodown/ abc.zip”));

or navigateToURL(new URLRequest(„http://www.mysite/FileGodown/ abc.jpg”));

03/2011 (21)


Touching local files from browser with help of Action Script 3.0

Listing 1. Single Local �le Uploading var fileRef:FileReference

/*we need a file reference (consider file pointer) to connect with local file*/ var fileName="xyz.abc"

/*This is name of file we are going to store on server. Its good to be known already as we need it while accessing the uploaded file in server*/ UploadBtn.addEventListener(MouseEvent.CLICK,AddFile); function AddFile(_e:MouseEvent):void

{

fileRef= new FileReference();

/*Here instance for file reference is created */ var _FileFilter:FileFilter=new FileFilter("Images (*.jpg, *.jpeg, *.gif, *.png)","*.jpg;*.jpeg;*.gif

;*.png");

/*File Filter is used to validate which file types are only accessible to user*/ fileRef.addEventListener(Event.SELECT, FileSelectHandler);

/* Flash dispatches this event when user select file from browse window*/ fileRef.addEventListener(IOErrorEvent.IO_ERROR, FileIOErrorHandler);

/* Flash dispatches this event if accessing selected file has error */

fileRef.addEventListener(ProgressEvent.PROGRESS, FileProgressHandler);

/* Flash dispatches this event while uploading file. It gives information about progress of uploading*/ fileRef.browse([_FileFilter]);

/* Browse window box opens */ }

function FileProgressHandler(e:ProgressEvent):void

{

var file:FileReference = FileReference(e.target);

trace("File Progress name=" + file.name + " bytesLoaded=" + e.bytesLoaded + " bytesTotal=" + e.bytesTotal);

}

/* ProgressEvent gives detailed information about file which is uploading */ function FileIOErrorHandler(e:IOErrorEvent):void

{

trace("File Error: " + e);

}

/* IOErrorEvent gives Error about file if there is Error in uploading */ function FileSelectHandler(event:Event):void

{

var file:FileReference;

file = FileReference(event.target);

/*Here we assign file FileReference for currently selected file*/ fileName=file.name

/*We get file name with extension using name property. We never get full path of local file.*/ file.addEventListener(Event.COMPLETE, completeFileUploadHandler); file.addEventListener(IOErrorEvent.IO_ERROR, FileIOErrorHandler);

file.addEventListener(ProgressEvent.PROGRESS, FileProgressHandler);

var request:URLRequest = new URLRequest("http://www.mysite/uploadFile.php?fName="+ fileName );

}

file.upload(request);

function completeFileUploadHandler(e:Event):void

{

Trace("File uploaded.") }

03/2011 (21)

27


PHP AND ACTION SCRIPT 3.0

Listing 2. Accessing �le from server var request:URLRequest = new URLRequest("http://www.mysite/FileGodown/"+ fileName); var ImageLoader:Loader=new Loader();

ImageLoader.load(request);

ImageLoader.contentLoaderInfo.addEventListener(Event.COMPLETE,ImageDownloading); function ImageDownloading(e:Event):void

{ }

addChild(e.target.loader.content);

Listing 3a. Multiple Local �les Uploading var fileRef:FileReferenceList

/*It is a list of file references consider as list of pointers for each file selected. */ var totalFiles:Number=0;

/*Variable to store no of files selected*/ var currentFile:Number=0;

/*Variable which tells current no of file downloading */ var filenameArray:Array;

/*Array to store path of files uploaded. So that we can use it later.*/ UploadBtn.addEventListener(MouseEvent.CLICK,AddFile); function AddFile(_e:MouseEvent):void

{

fileRef= new FileReferenceList();

/*For multiple file uploading we need to use FileReferenceList insted of FileReference */ var _FileFilter:FileFilter=new FileFilter("Images (*.jpg, *.jpeg, *.gif, *.png)","*.jpg;*.jpeg;*.gif

;*.png");

fileRef.addEventListener(Event.SELECT, FileSelectHandler);

fileRef.addEventListener(IOErrorEvent.IO_ERROR, FileIOErrorHandler);

fileRef.addEventListener(ProgressEvent.PROGRESS, FileProgressHandler); }

fileRef.browse([_FileFilter]);

function FileProgressHandler(e:ProgressEvent):void

{

var file:FileReference = FileReference(e.target);

trace("File Progress name=" + file.name + " bytesLoaded=" + e.bytesLoaded + " bytesTotal=" + }

e.bytesTotal);

function FileIOErrorHandler(e:IOErrorEvent):void

{ }

trace("File Error: " + e);

function FileSelectHandler(event:Event):void

{

var file:FileReference;

/*file is FileReference used to assign FileReference in FileReferenceList */ var selectedFileArray:Array = (FileReferenceList(event.target)).fileList;

/*For use of simplicity we convert FileReferenceList into Array.*/ totalFiles=selectedFileArray.length;

/*Length of Array is no of files Selected for uploading.*/ filenameArray=new Array();

for (var i:uint = 0; i < selectedFileArray.length; i++)

28

03/2011 (21)


Touching local files from browser with help of Action Script 3.0

Listing 3b. Multiple Local �les Uploading {

file = FileReference(selectedFileArray[i]);

file.addEventListener(Event.COMPLETE, completeFileUploadHandler); filenameArray[i]=file.name;

/*File name of current file is stored in Array.*/ var request:URLRequest = new URLRequest("http://www.mysite/uploadFile.php?fName="+filenameArray[i]);

file.upload(request);

/*Current file is send to uploadFile.php }

file with file name.*/

}

function completeFileUploadHandler(e:Event):void

{

/*As soon as file is uploaded it is ready to use in Flash. We have array of file names and server path. We use it here.*/ var request:URLRequest = new URLRequest ("http://www.mysite/FileGodown/"+filenameArray[currentFile]);

currentFile++;

var ImageLoader:Loader=new Loader();

ImageLoader.load(request); }

ImageLoader.contentLoaderInfo.addEventListener(Event.COMPLETE,ImageDownloading);

function ImageDownloading(e:Event):void

{

If(currentFile== totalFiles)

trace("All files added in flash.")

addChild(e.target.loader.content); }

Listing 4. PHP support for Uploading Local �les <?php

$file = $_GET['fName'];

//$file variable contain name of file to be uploaded. $finalDir = "FileGodown/";

//server contain "FileGodown" directory where files are stored. move_uploaded_file($_FILES['Filedata']['tmp_name'], $finalDir.$file); $directory = opendir($finalDir);

//opens directory for writing new file. $files = array();

while($file = readdir($directory))

{

array_push($files, array($finalDir.$file, filectime($finalDir.$file))); }

print_r($files);

closedir($directory);

//Closes directory for writing new file. ?>

03/2011 (21)

29


PHP AND ACTION SCRIPT 3.0

Listing 5. Downloading �le from �ash var _file:FileReference=new FileReference();

_file.addEventListener(Event.COMPLETE, ImageDownloading);

_file.addEventListener(IOErrorEvent.IO_ERROR, FileIOErrorHandler);

var request:URLRequest = new URLRequest("http://www.mysite/FileGodown/abc.jpg");

_file.download(request,fileName) }

function ImageDownloading(e:Event):void

{

trace("File downloaded.") }

/*Here you will get proper save window to save file. */

Listing 6. Loading local �le content without uploading var fileRef:FileReference=new FileReference();

var fileFilter:FileFilter=new FileFilter("Images: (*.jpeg, *.jpg, *.gif, *.png)", "*.jpeg;*.jpg;*.gif;*.png"); var bytArr:ByteArray

fileRef.browse([fileFilter])

fileRef.addEventListener(Event.SELECT,select); function select(e:Event)

{

fileRef.load()

/*We are going to load selected files data*/ fileRef.addEventListener(Event.COMPLETE,loadComplete); }

function loadComplete(e:Event)

{

bytArr=e.target.data

/*When load is completed. We will convert it into ByteArray.*/ var ldr:Loader=new Loader()

ldr.contentLoaderInfo.addEventListener(Event.COMPLETE,addImage) ldr.loadBytes(bytArr);

/*As we have now local files data, we can use it as we want. Here I am going to load that ByteArray. As it is an Image I used loadBytes method of loader. If data is text u can directly insert that text into any text box. Same like sound. If local file is sound file you can directly play it once you converted it into Byte Array.*/ }

function addImage(e:Event)

{

addChild(e.target.loader.content) }

30

03/2011 (21)


Listing 7. Loading and Saving �le without uploading and downloading var fileRef:FileReference=new FileReference(); var fileFil:FileFilter=new FileFilter("Images:

(*.jpeg, *.jpg, *.gif, *.png)",

var bytArr:ByteArray

"*.jpeg;*.jpg;*.gif;*.png");

var saveFil:FileReference=new FileReference()

/*We took another FileReference

to save file.*/

fileRef.browse([fileFil])

fileRef.addEventListener(Event.SELECT,select); function select(e:Event)

{

fileRef.load()

fileRef.addEventListener(Event.COMPLETE,comp); }

function comp(e:Event)

{

bytArr=e.target.data

/*When load is completed. We will convert it into ByteArray.*/ saveFil.save(bytArr)

/*FileReference.save() method will ask you location and name of file*/ }

/*Browser will ask you for save or open file.*/

Another method is presented in Listing 5.

Loading Local File Data Through Byte Array Without Uploading to Server

We are going to use ByteArray (Listing 6). Lets see example how to load image and save same image in local disk (Listing 7). I think it became pretty big article. I hope you will get all things without boring. If you have any query regarding this article you can mail me chinu50patil@gmail.com. I am tired but happy with actionscripting.

SACHIN PATIL Sachin Patil is a Flash/Flex developer from India, having good experience in rich internet application ,gaming , papervision3d. http://www.sachinpatilaction.blogspot.com/

03/2011 (21)


ACTIONSCRIPT 3

Creating Custom Visual Classes When creating a dynamic visual class, it is sometimes easier to draw the visual elements than trying to constantly load images. I have found in my experience that it is possible to draw buttons as needed using the Graphics class. This keeps the button scalable without distorting the graphics and, with a little preplanning, gives you a lot of control over the look and function of the control. What you will learn…

What you should know…

• How to create a custom class with events

• Flash Builder 4 • ActionScript 3

T

here are plenty of premade classes available to accomplish this task as well as components built into Flash Builder. Often, these components are missing features that you are looking for or are too rigid for your needs. Rolling your own button class will give you the flexibility and features that you need. Also, if you know how to create your own class, it makes it easier to understand classes from other sources. The class will create and draw the button based on the parameters passed to the class. This will include a gradient background, color stroke and custom text. There will also be three events built into the button, rollover, rollout and click. The rollover and rollout events will change the background colors of the button to another color passed in during the constructor. When the button is clicked on, the class will dispatch a generic event that the parent class can listen for. Most of the code is going to involve set up in the constructor. Once the button is created and added to the stage, it is going to sit and wait for events from the mouse – either rollover, rollout or click. Because we are setting up a sprite with multiple elements, we need to pay attention to how the elements are layered. Otherwise, you may get your text behind the background. Open a new text document and set it up with the ActionScript 3 skeleton. Be sure to include the package, class definition and constructor as in Listing 1. Also include the import for the flash.display.Sprite class since our custom class is going to extend it.

32

You may name the class whatever you would like, but we are going to call it CustomButton. If you name it something different, be sure to replace all instances of CustomButton with the new name. There are a lot of classes that need to be imported so we are going to add them all now and reference them as we go through the code. The imports are going to handle the visual elements, the events and the text field. It may look like a lot at first, but once the code is complete, you will see the relevance. After the import statement, add the following: import flash.display.Graphics;

import flash.display.GradientType; import flash.event.Event;

import flash.event.EventDispatcher; import flash.event.MouseEvent; import flash.text.TextFormat; import flash.text.TextField;

import flash.text.TextFieldAutoSize;

Most of these classes will be familiar if you have been working with AS3. As stated earlier, the imported classes are broken into three areas – display, event and text. Now we can begin setting up the class constructor. The first element that we are going to create is the background. Within the class definition, create a private variable of type Sprite and initialize it. We do

03/2011 (21)


Creating Custom Visual Classes

not want to make the background accessible outside of the class, so we make it private. There may be cases where the background should be accessible and you can make the variable public in those cases. This is why are creating a custom class, to handle these special instances. private var background:Sprite = new Sprite();

We are going to use the graphics class to draw the display elements of the element. The graphics class is part of the flash.display class and allows easy methods for creating filled shapes, drawing custom shapes and creating fills and strokes. There are three basic steps when it comes to drawing shapes using the graphics class. Set the fill, draw the shape, end the fill. In the most basic form, you can use the beginFill() function to pass in the fill color of the shape. Then, use the drawRect() method to actually create the visual element. The drawRect() takes four parameters â&#x20AC;&#x201C; left origin, top origin, width and height. Finally, clear the fill by using the function endFill(). This last function takes no parameters and is not completely necessary, but is good practice to do. Looking at the documentation for the Graphics class, you see there are variations to the first two functions. Instead of a solid fill, a gradient fill can be used with the beginGradientFill() function. Also, there are pre-built methods to create a circle, ellipse or rounded rectangle in addition to a rectangle. To make our button a little more stylized, we are going to use the beginGradientFill() and drawRoundRect() and pass in parameters to set the display of the button. First we are going to look at the beginGradientFill(). Some parameters we are going to make static and some variable. Any of the parameters can be set with variables. For now, we are only going to allow the colors to be passed in. background.graphics.beginGradientFill(GradientType.LINEAR,

public class CustomButton(color1:uint, color2:uint)

Now that the color is set, we are going to draw the background using the drawRoundRect() function. The method accepts six parameters for x, y, width, height, radius width and radius height. In this class we are going to make all of these variable except the x and y values. We do not want any offset of the button once it is placed on the stage. background.graphics.drawRoundRect(0,0,width,height, radius,radius);

The radius values are the width and height of the radius in the rounded corners. Notice that radius variable is used twice. This is because we want the rounded corners to be symmetrical. You can pass in extra values if you like to make the corners not symmetrical. Add the width, height and radius to the parameters of the constructor in addition to the colors we added earlier. Each parameter is of type Number but you could also use int. public function CustomButton(width:Number, height: Number, radius: Number, color1:uint, color2:uint)

Finish the drawing of the background by using the endFill() function which takes no parameters. Then, add the element to the stage with a call to addChild(). this.addChild(background);

The next step will be to add an outline to the button. We are making the outline a separate sprite so when the mouseover event is received, the background can change independently of the outline. The process to create the outline is the same as the background with the difference of how the shape is styled.

[color1,color2], [1,1], [0x00,0xff]);

Listing 1. The ActionScript 3 skeleton

The first parameter sets the type of gradient and is done using the constants from the flash.display.Gradie ntType class. The two constants from the GradientType class are GradientType.LINEAR and GradientType.RADIAL . For this class, we are going to use the linear gradient. The last three required parameters are color, alpha and ratios and each take an array as the argument. The last two (alpha and ratios) are going to get hard coded in the class itself. The color array, we are going to pass two uints for the starting and ending colors. In the parenthesis for the constructor, add in the color1 and color2 variables as below.

package

03/2011 (21)

{

import flash.display.Sprite; public class CustomButton extends Sprite

{

public function CustomButton():void

{

}

}

}

33


ACTIONSCRIPT 3

Instead of using beginFill(), we are going to use and not define a fill. Since we used the endFill() function on the background, the fill has been cleared. Any shape that is drawn will not have a fill color until the fill is set again. This is why it is good practice to use endFill(). The lineStyle() function takes a minimum of two parameters, line thickness and line color. The thickness is a number between 0 and 255 where 0 is a hairline and 255 is the thickest line. If no parameter is set for thickness, the line will not be drawn. The second parameter, line color, is actually optional but I always set it just to be thorough. The color is passed a uint which we will allow to be passed in through the constructor parameters. If no color is set, the line color will be black. Drawing the actual outline uses the same drawRoundRect() function as the background. We are using the same parameters and variables as the background so it matches with it. Once the outline has been drawn, add it to the stage but be sure to put the addChild() call after the background. Flash will draw elements in the order that they are called. If you put the background after the outline, the outline will get drawn first and the background over it â&#x20AC;&#x201C; hiding the outline. Adding the outline to the display stack after the background ensures that it will be on a higher layer and visible. The last element to add is the text field. If you have used the text field before, you know that there a lot of parameters that you can change to style the text. In this class, we are going to hard code most of the parameters and the style sheet associated with the text. The only parameter we are going to pass in to the class is the text label of the button. There are several methods to note here that affect how the button acts. The first is the text field property called selectable. By setting this property to false, it will keep the user from selecting the text and giving the user unexpected results when they are trying to click on the button. The other property is mouseEnabled, which is also set to false. mouseEnabled tells Flash whether the element can receive events from the mouse, since we want the events to bleed through to the background, we set it to false. We also want to set the width and position of the text field so the text falls in the middle of the background graphic and does not bleed off the end. A simple calculation sets the text box 10 pixels from the left origin of the button and 10 pixels away from the right side. The width and position of the field must be set after it is added to the stage. To get the button label styled, a TextFormat must be set up. The object could be set up in the class or lineStyle()

34

passed in from the calling class. We have chosen to pass a TextFormat object in fro the calling class to allow more flexibility of the display. The object is not in the constructor (although it could be) to allow the format to be changed on the fly. Create a public function called setStyle() that will be called in the calling class. The function takes a TextFormat object that needs to be set up in the calling class. This function can be called any time after the button is initialized and can be updated as the program runs. To add more flexibility to the button, a getter and setter is added for the label of the button. The getter and setter functions allow your class to have properties that are updatable from outside of the class but are not directly affecting the private variables. We are setting the label in the constructor, but this allows the button to be updated after it has been added to the stage.

Events

Now that the visual elements have been created, it is time to add the events to interact with the user. There are only three events that we are going to worry about on this class, mouseover, mouseout and click. Each of these events will have functions to react to the event. Instead of adding the event listeners to the class itself, we are going to add it to the background sprite. We do this because the class, when created, does not always have a width and height to react to a mouse event. Setting the events on a sprite not only gives definition to what will react and what will not, it also give the ability to create an invisible hit area by creating a transparent sprite. Attach the event listeners to the background sprite and set up a private function for each handler. We also set mouseEnabled and buttonMode properties to true so it will receive the mouse events and the cursor will change to a pointer when the mouse is over the element. The mouseEnabled() method can apply to almost any element in the flash.display package. this.background.mouseEnabled = true; this.background.buttonMode = true;

this.background.addEventListener(MouseEvent.CLICK, handleMouseClick);

this.background.addEventListener(MouseEvent.MOUSE_OVER, handleMouseOver);

this.background.addEventListener(MouseEvent.MOUSE_OUT, handleMouseOut);

In the mouse over and mouse out handlers, we want to add a glow when the user rolls over the button and remove it when they roll out. In these two handlers, you can add any action that you want. You could

03/2011 (21)


Creating Custom Visual Classes

change how it the display looks or send information. In this case, we are going to add a glow filter to the background. Add a private variable to the class called glow of type GlowFilter from the flash.filters package. All of the parameters of the glow filter initializer are optional but we are going to change the color of the glow from the default to yellow. You could also have this as a parameter that the user can pass into the constructor. To attach the glow filter to the background sprite, set the filter property to an array with the glow variable as the only element in the handleMouseOver() function. To remove the filter, set the same filter property to an empty array in the handleMouseOut() function. Background.filters = [glow]; Background.filters = [];

The last event that needs to be handled is when the user clicks on the button. Because we are trying to keep the functionality of the button as generic as possible all we are going to do is tell the parent classes that we have been clicked. This will allow the outside classes to respond to the click event and proceed as needed. The button will not dictate what happens when it is clicked. Add a constant to the variable declarations at the top of your class to define the message broadcast when the button is clicked. This constant can say anything you want it to, but the more direct the message – the better. In this example, we name variable BUTTON_CLICKED and the string that is passed button clicked. Public static const BUTTON_CLICKED:String = ‘button clicked’;

Constants are values that should not change as the program runs, such as event messages from the class or mathematical values such as PI. Using the public keyword allows the message to be seen outside of the class so parent classes can listen for it. Lastly, the static key word allows the value to be called using the Class.VALUE paradigm. For example, in most events that we deal with, we use MouseEvent.CLICK . MouseEvent is the class and CLICK is the value. Now when the button is clicked, we need to send the BUTTON_CLICK message to the other classes. In the

function, add a dispatchEvent() call from the flash.events package. The dispatchEvent() sends messages out for other classes to listen for. We pass this method a new event object with the parameter CustomButton.BUTTON_CLICK. Now the outside class can listen to the custom button for the CustomButton.BUTTON_ CLICK message and react to it as necessary. handleMouseClick()

Using the Class

The class we have created is ready to use. Looking at the constructor line tells us everything we need to pass to the class to initialize it. Create a new project and include the CustomButton class in it. Set a new variable of type CustomButton and add it to the stage. Add an event listener to listen for the CustomButton.BUTTON_CLICK event and add a handler for the event. Also you will want to set up a TextFormat variable and call the set function of the custom class. Declare a variable of type TextFormat and initialize it with the styles you want to show up on the label of the button. Because the TextFormat can be updated, you can set up and change the variable values at any time. Now when you run the project, you should see the button on your stage. Rolling the mouse over and out of the button should add and remove the glow filter. Clicking the button should be handled in your button handler.

Conclusion

While there are plenty of libraries and components on the Internet to create a button or some other visual element, sometimes you can not get the flexibility that you need. Writing your own class to handle these cases can often be faster than trying to find the perfect component to match your project. In addition, knowing how a custom class like this works makes it easier to work with other third party classes by knowing the mechanics under the hood. Creating a custom class for simple element such as a button will give you the basis for setting up your own classes. More complex buttons or other gui elements can all be created by looking at the basic shapes of the component. Once you break down an element into its visual components, you should be able to create any element using the Graphics class.

LOUIS DICARRO

Figure 1. Result of the button code

03/2011 (21)

Louis DiCarro is a consultant based in NYC and has been working with Flash since the �rst version. He has taught web development at the college level and has worked for numerous large clients. He can be reached at louis.dicarro.ffd@gmail.com.

35


ACTIONSCRIPT IN ACTION

Adventures In ActionScript – Serializing Objects Saving complex objects to disk sounds difficult. In fact, it’s remarkably easy if you use ByteArrays as Huw Collingbourne explains. What you will learn…

What you should know…

• How to serialize complex objects to byte arrays • Saving and loading single objects or collections • Registering class aliases

• The fundamentals of Object Orientation in ActionScript • Some experience of File IO • Some understanding of event-handling

W

hen I first wrote a game, many, many years ago, I made one huge mistake. I spent about a year creating a map containing treasures, creatures and puzzles. But what I didn’t do was build in some way of saving and restoring the game state so that players could resume games at the point where they had left off. I left the problem of saving and loading games until I’d finished writing the rest of the program – and it caused me a huge headache! That’s because the data that describes a game can be quite complex. In a text-based adventure such as the one I’ll create in this series, you will end up with a large network of linked objects. For example, a Map object will contain many Room objects and each Room object may contain one or more Treasure objects. It is even possible that some Treasures may contain other Treasures and there may also be interactive characters, including the game player, who may themselves collect Treasures. One way of saving game data would be to write out a simple text file – or possibly an XML file – containing sequential records representing each object in the game. When one object contains another object, you could save the contained object’s name as a simple string. When you restore the game, you would read in the data, recreate the objects and then, in a second pass through the data, you would wire up the object relationships by linking one object to another and so on. This would be an acceptable solution but it would

36

be hard work to implement – you’d have to take time to deconstruct object relationships when saving data and reconstruct those relationships when loading data. Fortunately, there is a much simpler alternative. ActionScript’s ByteArray class can do the hard work for you. It has methods that can save streams of data to disk and reconstruct objects from that data when it is read back again. This is called serialization and, once you’ve learned how to do it, it will save you a huge amount of programming effort.

Basics of ByteArray

This game has a very simple user interface which was designed using the Amethyst IDE (Figure 1) but the

Figure 1. The game I’m creating uses a simple Flex-based user interface (seen here being designed with Amethyst). However, the same techniques could be used with a game created using the Flash IDE

03/2011 (21)


Adventures In ActionScript – Serializing Objects

code is also compatible with Adobe’s Flash Builder. The game play is simple. You click on buttons to move around a map (Figure 2) and you can save and load game data using file dialog boxes (Figure 3). Before looking at any code, let me briefly explain the essential features of serialization with ByteArrays. Adobe’s documentation on this class begins with this promising description: The ByteArray class provides methods and properties to optimize reading, writing, and working with binary data. But just in case you get over-excited by the possibilities this opens up, it is immediately followed by this warning: The ByteArray class is for advanced developers who need to access data on the byte level. I think this description slightly undersells the value of the ByteArray class. It’s true that there are easier ways to save simple data. However, when you want to save complex data types, and especially when you want to save custom object types, ByteArrays are your friends. No matter what type of data your program uses, it is represented in memory as a series of bytes. This means that, at a low level, all data – strings, integers, arrays or user-defined objects – can be represented by a ByteArray. This has advantages and disadvantages. The main advantage is that a ByteArray can save and restore anything, even arrays of arrays of arrays containing all kinds of mixed data types. The disadvantage is that ByteArrays do not automatically verify that the data is correct. Usually in ActionScript when you declare something to be an int it cannot be used as an array or a Button or some other type of object. If an attempt is made to do so, you will receive an error message at compile time and you can go and rewrite your code to fix the problem. But a ByteArray is compatible with everything so, if you aren’t careful, your programs could try to do impossible things with inappropriate objects at runtime. That, fundamentally, is why Adobe warns that they are intended for advanced developers. They are not really all that difficult to use but they do place extra demands on the programmer.

Put simply, if you use them carelessly your program may crash.

Figure 2. The game uses a map (an array of Rooms) which can be traversed by clicking direction buttons. A map can be saved and reloaded by click the saveMap and loadMap buttons

Figure 3. When you load a game, a dialog box pops up to let you pick a saved data �le. Be warned – there is no error checking yet so you need to make sure the data �le is valid

03/2011 (21)

ByteArray Methods

ByteArrays are provided with a number of methods for reading and writing common data types. These include readBytes() and writeBytes(), readInt() and writeInt(), readFloat() and writeFloat(), readUTFBytes() and writeUTFBytes(). For our purposes, however, none of these is particularly useful. My game contains linked networks of custom Room objects so they can’t be written and read using any of the methods listed above. Luckily, ByteArray has another pair of methods, readObject() and writeObject(). These can be used to read and write any type of object. However, they do need a bit of extra programming to help them do that – and that is the subject of this article. Saving an object into a ByteArray is easy. You just pass it as an argument to the writeObject() method like this: var bytes : ByteArray = new ByteArray( ); bytes.writeObject( Cave );

Having done that, it’s a good idea to set the position in the byte array back to the start (at 0): bytes.position = 0;

You can then save the data to disk. I’ve used the save() method of the FileReference class to do this. The save() method pops up a dialog to let the user specify a file into which the data will be written. I’ve put this code inside a method called saveGame() in a class called SaveLoad: public function saveGame( someData : ByteArray ) : void { fr = new FileReference( );

}

fr.save( someData );

37


ACTIONSCRIPT IN ACTION

registerClassAlias( „room”, Room ); bytes.writeObject( Cave ); bytes.position = 0;

sl = new SaveLoad( ); }

sl.saveGame( bytes );

When you read this data back into your program you must be sure that the class is registered with the same alias within the scope of the executing method like this:

Figure 4. Having saved an array of Room objects I try to reload it without �rst registering a Room class alias. The data loads but the Amethyst debugger shows me that they are instances of Object, not Room

I’ve used FileReference quite a bit in my SaveLoad class. However, I don’t plan to go into any detail on its use in this article. If you need help with this class see the box Going Further and be sure to download the Adobe ActionScript 3 Reference Guide.

Registering A Class Alias

The only problem with my code so far is that when I write the object to the ByteArray I haven’t specified the actual type of object. In order to be able to save and load custom object types reliably, I need to register the class of my object using the registerClassAlias() method from the flash.net namespace. This method takes two arguments: a string alias and the class itself. This is an example from the Adobe documentation: registerClassAlias(„com.example.eg”, ExampleClass);

It is up to you how you name the alias. For the Room class I use a simple string, room. This is the complete code of a method that saves a single Room object (here this is the Cave variable): private function saveBtn_click( event :

flash.events.MouseEvent ) : void {

var bytes : ByteArray = new ByteArray( );

registerClassAlias( „room”, Room );

var o : * = loadedData.readObject( ); Cave = o;

Notice, incidentally, that in my code, I have only assigned the loaded data after my SaveLoad object’s Event.COMPLETE method has fired, which delegates to my afterLoading() function. This is to ensure that data-assignment is only attempted after all the data has been loaded into memory. Event-handling is beyond the scope of this tutorial but the topic is well covered in Adobe’s documentation.

Serializing Collections

So far I’ve only tried to save and load a single Room at a time. In a real game, of course, I would need to save and load many rooms. One way of doing this would be to iterate through the rooms to save them one by one. But there is a simpler alternative. Remember that I can serialize any type of object using a ByteArray. This means I can serialize a collection object such as an array. And I can create an array of Rooms. So to save multiple rooms at once all I have to do is serialize my array of Rooms. That is what I do in the saveMapBtn_ click() function: var bytes : ByteArray = new ByteArray( ); registerClassAlias( „room”, Room ); bytes.writeObject( map ); bytes.position = 0;

sl = new SaveLoad( ); sl.saveGame( bytes );

Note that I have once again had to register an alias for the Room class. Loading back the map array is just as easy as loading a single Room. You’ll find the code in afterLoadingMap(): var loadedData : ByteArray = sl.ba; loadedData.position = 0;

Figure 5. If I attempt to treat data that was loaded as an Object as if it were a Room, an exception will be thrown since an Object cannot be coerced to a Room

38

map = [];

Cave = null;

TreasureRoom = null;

03/2011 (21)


Adventures In ActionScript – Serializing Objects

Going Further

Adobe has lot of useful ActionScript information online. Here are some vital resources to provide more information. ByteArrays save data in Action Message Format or AMF. There are two versions of AMF called AMF0 and AMF3. The AMF0 format was the default with earlier versions of ActionScript. AMF3 is the default with ActionScript 3. For a formal description of ByteArrays see Adobe’s documentation here: http://help.adobe.com/ en_US/FlashPlatform/reference/actionscript/3/flash/utils/ ByteArray.html. For more information see Working With Byte Arrays http://help.adobe.com/en_US/as3/dev/WS5b3ccc516d4 fbf351e63e3d118676a5388-8000.html which includes a link to a pdf document on the Action Message Format speci�cation. For help on FileReference see here: http://help.adobe.com/en_US/FlashPlatform/reference/ actionscript/3/�ash/net/FileReference.html For help on registerClassAlias see here: http:// help.adobe.com/en_US/FlashPlatform/reference/actionscript/ 3/�ash/net/package.html#registerClassAlias%28%29 For a more comprehensive guide to ActionScript, be sure to download Adobe’s ActionScript 3 (PDF) Developer’s Guide: http://help.adobe.com/en_US/as3/dev/as3_devguide.pdf TrollRoom = null;

CrystalDome = null; DragonsLair = null; SmallHouse = null; here = null;

registerClassAlias( „room”, Room ); map = loadedData.readObject( ); here = Room( map[0] );

First I set all existing objects to null and make sure the map array is empty. Then I read the data back into the map array and set the player’s position to the first room (map[0]). You might, in fact, want to save and restore the player’s position too. For now I’ll leave you to figure out how to do that. I’ll add that feature to my game in a later version.

Get The Source Code

The archive containing all the source code for this game is available for download from the SapphireSteel Software site at: http://www.sapphiresteel.com/tutorials/amethyst-tutorials/ actionscript-programming/article/adventure-game

Incidentally, the variables, such as Cave and TreasureRoom, are not initialized with the loaded data. These variables are no longer of any interest to me. They are only used as a convenient and descriptive way of creating links from one room to another when the map is created, as explained in last month’s column. If you have access to a good debugger you might want to put a breakpoint on the final line – trace( map loaded ) – of afterLoadingMap(). Comment out this line: registerClassAlias( „room”, Room );

Now run the program in the debugger. When you examine the map array you will see that, while it contains the objects which were loaded from the data file, these are not recognized as instances of the Room class (Figure 4). If you try to use them as Room objects an exception will be thrown (Figure 5). That is why registering class aliases is so important. Uncomment the line above and run it again in the debugger. This time the Room class is registered so the data items are correctly read back as Room objects (Figure 6). In next month’s column I’ll explain how to create a class hierarchy for an adventure game.

HUW COLLINGBOURNE

Figure 6. To load custom objects correctly you must register a class alias. Now the Amethyst debugger shows me that my map array has been correctly initialized with Room objects

03/2011 (21)

Huw Collingbourne is Director of Technology at SapphireSteel Software. Over more than 20 years, he has programmed in languages ranging from Ruby to C# and has been a technical columnist for computer magazines such as PC Pro and PC Plus. He is the software lead of the Amethyst Designer, the Flex user interface design environment of the Amethyst IDE for Visual Studio. SapphireSteel Software: http:// www.sapphiresteel.com/

39


FLEX/ACTIONSCRIPT 101

Test Driven Development or “How not to be trapped in a nightmare” Part 3 In our last article, we updated the app structure. Now it’s time to write the test will be using and then we will implement a log class to be tested. So without further ado, let’s get started. What you will learn…

What you should know…

• Use FlexUnit to unit test your code

• Basic knowledge of ActionScript • Basic knowledge of OO Programming

The TestSuite

Last month, we added the TestRunner.mxml the initUnitTestsNow that will run after the its creation and also added the <mx:Script source=”logic/tests/test.as”/> to this file. The test.as file (Listing 1) will be responsible for initializing (initUnitTestsNow) and adding our test class to the Test Suite (CreateUnitTest). After this point, we will be ready to run any test we create. All of our tests will be placed inside the unitTests folder (Figure 1).

Listing 1. Importing Flex Unit package import flexunit.framework.TestSuite; import unitTests.*;

//Create a our Test Suite and add the LogTests to it. private function createUnitTest() : TestSuite

{

Creating the test

As said, the object of our testing will be a Log class that would be responsible for sending the data to a database. In this example, our class will not really send any data, but for now, it’s sufficient to exemplify the subject of this article.

var unitTest : TestSuite = new TestSuite();

unitTest.addTestSuite(LogTests); }

return unitTest;

//Initialize and start the tests. private function initUnitTestsNow() :void

{

}

testsConsole.test = createUnitTest(); testsConsole.startTest();

Figure 1. Unit Test folder

40

03/2011 (21)


Test Driven Development or How not to be trapped in a nightmare Part 3

So let’s go through our Log test step-by-step: First and foremost we have to import the TestCase class from the flexunit package and then declare the LogTests class and its constructor where we call it’s superclass constuctor and pass a method name – the LogTests method (Listing 2). The testLogData method is where we place all the things we want to test. Note that after the code in test.as is run – where we initialized and added our test class to the test suite, Flex Unit will run any method that follows the testMethodName convention. In the testLogData method we instantiate the Log class, fill the formData – the data that we’ll be sending to the server – with some data, and call the save method (Listing 3). Listing 2. The test case package unitTests

{

import flexunit.framework.TestCase; import logic.Log; public class LogTests extends TestCase

{

public function LogTests(methodName:String=null)

{ }

super(methodName);

Listing 3. He test for log class public function testLogData():void

{

var productData:Log = new Log();

productData.formData.name = 'Ipad';

productData.formData.prodCode = '12';

productData.formData.price = '999.00';

Figure 2. Running the TestRunner application

After we call the assertTrue, passing as arguments a message that will be presented if the test fails and the productData.getResult() that return true or false if the logging operation fails (Listing 4).

The Test Subject

Now that we wrote our test, let’s see the test subject – the Log class. In this class, we have the formData and serverData properties, their getters and setters. In the constructor, we initialize them. The real work is done in the save method, where I’d call a remote service using AMF. But for simplicity and space, I’m just checking if the formDataObject has the id property. If it doesn’t, the serverData will contain the type of exception at index 0, at index 1, its return value, and the exception description at index 2. The getResult method returns the serverData[1] value that indicates if log operation went well or not. There’s also the exceptionDescription method that returns serverData[2] and the exception description (Listing 5).

Running the tests

application (Figure 2) and see that our test will fail, ensuring that it’s working as intended (Figure 3). For this test to pass, the formData object has to have an id property, so get back to LogTests.as and uncomment the 20th line – productData.formData.id = 12; – and run the test again (Figure 4). The example app for this article will available for download at http://code.google.com/p/flashcapabilities/ downloads/list. TestRunner

productData.save(); //IF everything is ok this must be true

}

Listing 4. Making the assertion assertTrue("After logging this data result must be

true",productData.getResult());

Figure 3. Test assertion failed

03/2011 (21)

41


FLEX/ACTIONSCRIPT 101

Listing 5. The class to be tested package logic

{

{

import mx.controls.Alert;

if(this.formData.hasOwnProperty(â&#x20AC;&#x2DC;idâ&#x20AC;&#x2122;))

{

public class Log

this.serverData[0] ='';

{

this.serverData[1] = true;

private var _formData:Object;

private var _serverData:Array;

} {

public function set formData(formData:Object):void

}

[0] -> type of Exception [1] -> true if saved without problem [2] -> Exception Description

//--------------------------------------------------

{ }

*/ Exception';

return this._formData;

}

{ }

this.serverData[0] = 'Missing attribute this.serverData[1] = false;

this.serverData[2] = 'Object';

}

//-------------------------------------------------private function set serverData(serverData:Array):

//Problem Occurred, return the exception /*

this._formData = formData;

public function get formData():Object

this.serverData[2] = '';

else

//--------------------------------------------------

{

//data was saved successfully

//--------------------------------------------------

void

public function exceptionDescription():String

this._serverData = serverData;

{ }

//--------------------------------------------------

return this.serverData[2];

//-------------------------------------------------private function get serverData():Array

{ }

public function getResult():Boolean

return this._serverData;

{

if(this.serverData[1])

{

//-------------------------------------------------public function Log()

}

return true;

else

{

{ this.serverData = new Array();

}

//Check the result to see if no problem occurred

this.formData = new Object();

}

}

return false;

//--------------------------------------------------

//-------------------------------------------------public function save():void

42

}

}

03/2011 (21)


Test Driven Development or How not to be trapped in a nightmare Part 3

See you soon. Questions regarding this article will be welcome and appreciated. See you there.

Figure 4. Test assertion passed

Final Statement

In this three articles series, we saw the importance and advantages of TDD, upgraded a previous example to support Unit Testing, and wrote our first test. Thereâ&#x20AC;&#x2122;s much more about TDD that we will see soon. But thatâ&#x20AC;&#x2122;s it for now. I hope this series has been useful for every developer who wanted to embrace the TDD. a

03/2011 (21)

d

v

e

r

t

MARC PIRES Marc Pires is a RIA Developer at RGSistemas. Contact information: @MarcPires (Twitter) IChat: marcpiresrj@aim.com www.rgweb.com.br

i

s

e

m

e

n

t

43


IPHONE DEVELOPMENT

iPhone and iPad in Action

Excerpted from

Introduction to SDK Development Brandon Trebitowski, Christopher Allen, and Shannon Appelcline For Source Code, Sample Chapters, the Author Forum and other resources, go to

This article is taken from the book iPhone and iPad in Action. The authors walk you through all of the steps necessary to get your application ready to receive and process push notifications.

Preparing your application to use push notifications

L

eave it to Apple to make the preparation more complex than the coding. You will find that more time is spent on creating an uploading the signing certificates than actually writing the code to receive the push notifications. We will explain how. Let’s begin by setting up the signing certificates.

so, you will need to add your application bundle identifier to this list. The format for this should be reverse domain. An example of this might be com.rightsprite.pushtest. Make sure that you don’t use any wildcards because the system must be able to uniquely identify your application.

Setting up your application certificate

The first thing to note is that you must have a valid Apple developer account to test push notifications. We will be showing you how to generate two items that are required. The first item we will be generating is a special provisioning profile. This profile will be used to sign the application when deploying it to your iPhone. The second is a client SSL certificate. The push provider will use this to establish a connection with Apple’s push notification servers. Start by logging into your Apple developer account. Once you have logged in, open up the program portal and navigate to the App IDs tab. If you haven’t already done

Figure 1. Con�guring the app to receive push noti�cations

44

Figure 2. The wizard for creating a push certi�cate

03/2010 (21)


iPhone and iPad in Action

Once you have added your application, you must now configure it to receive push notifications. You have the option to configure the app for development as well as production. It is always good practice to use the development certificate when testing and switch to the production one when you are ready to submit to the app store. Figure 1 shows what this section should look like. After pressing the Configure button, the following screen gives you the option to configure either the development or the production certificate. For this example, we will be configuring the debug certificate; however, the steps for both are exactly the same. Figure 2 shows what this process looks like. Clicking Configure will open up a wizard with steps that will guide you through the process. This process is very similar to creating any other provisioning profile. After completing this step, you need to download this certificate and install it in your keychain by doubleclicking on it.

Setting up you provisioning profile

Now that we have created the signing certificate, we will need to create the provisioning profile to allow the application to be installed on your iPhone. Again, you don’t want to use your generic developer certificate. You must generate a new one that is specific to your app’s full bundle id. Go to the Provisioning tab. Since we created a push certificate for debug, we must also create a debug provisioning profile. Had we created a production certificate, you would need to create an app store or adhoc certificate. Click on the New Profile button within the Development tab. As you may have seen before, there are quite a few options that need to be set up. The first is the profile name. This can be anything you want; however, your best bet is to be very descriptive. Name it something like [Application Name] Debug. Next, you will select the certificate that the profile will be using. If you are a single user, you should only see your certificate in the list. However, if you are on a team, you should see a certificate for every one of your team members. Just check the boxes of the teammates that will be testing the push notifications. Note that when creating a build for the app store, you will select your distribution certificate. Following the certificate, you will need to select the app id that the profile will be used for. Finally, you must select the devices that the provisioning profile will work on. Figure 3 shows an example of what this form looks like completed. After creating this profile, you will need to download and install it. That is about it for the certificate creation. We will now be discussing how to implement the

03/2010 (21)

methods in your client application to enable and receive push notifications.

The code for handling push notifications

As we mentioned earlier, the code to handle push notifications is quite simple. In fact, there are only three methods that need to be implemented. We will be walking through each of these methods and discussing their use. The first method is the applicationDidFinishLaunching method. This method is already implemented for you in any application that you create. You simply need to add one line of code that will tell your application to register for push notifications. The code (Listing 1) shows you how to do this. Your application will have other setup tasks in this method; we just wanted to show you the line of code that must be added to register for push notifications. The code above will tell the device that this application wants to receive push notifications in the form of alerts, badge numbers, and sounds. You can omit any of these properties if you choose not to send them. One thing you might be wondering is why this must be done more than once. The reason for this is the token that gets generated when setting up push notifications is not guaranteed to be the same. So, we want to touch base with Apple every time the application launches to make sure everything is correct to receive notifications. As you may have guessed, there are some delegate methods that must be implemented to react to events generated by this registration call. The code (Listing 2) shows a simple implementation of these methods. The first method fires upon successful registration for push notifications. When you register to receive push notifications, your application communicates with Apple and receives back a unique device token. This token is used in all push communication with your device. Notice we call a method sendProviderDeviceToken in our class. This is a custom method you should create to send the device token to your push provider. You may do this via a web service interaction. The method didFailToRegisterForRemoteNotificationsW ithError is for error handling. It fires when you get an error registering for push notifications. Most likely, if this method gets called, your signing certificate is invalid or

Figure 3. Provisioning pro�le form

45


IPHONE DEVELOPMENT

the device doesn’t have an Internet connection. Make sure you put some code in this method to notify the user that there was a problem registering for notifications and they will not receive any at this point. Now that the application has registered to receive push notifications, the next step is to handle them when they come in. Apple gives us a few methods that will allow us to control what happens when the user presses the View button on the notification alert. The first way of handling an incoming push notification is to simply implement the code in the applicationDidFi nishLaunching method. You would want to go this route if the notification was just used to open the application and did not pass any additional data. The code (Listing 3) shows a simple way to respond. The first and most important thing you must do here is reset the badge number to 0. If you don’t do this, the badge count will stay at whatever number was sent by the push notification. After that, you should perform any updates that are needed. In the above code, we assume that some data has changed on the server and call a method to download the updated data. If the notification contains a custom dictionary, you must use the application:didFinishLaunchingWithOptions: method. The options variable will be an NSDictionary containing the custom values passed in. In the event that the user is currently running the application, you must implement the application:

method. It will be called automatically and passed a dictionary containing all of the standard information including badge number, message, sound, and any custom dictionaries that were sent to the device. After implementing the aforementioned methods, your application should now be ready to receive push notifications. One final step in preparation is to format any audio files that will be played in response to a push notification. didReceiveRemoteNotification:

Preparing audio files

As noted before, when a push notification is received, it can invoke the playback of an audio file included with your application. There are many interesting scenarios for when different audio files might be appropriate. One example might be during a chess match. If a player receives a notification informing them it’s their turn, the system might simply play the default audio file. However, if they receive a notification related to a piece being captured, the system might play some sort of battle sound effects. The more creative you get with this, the more value it may add to your application. The first thing to note when considering the audio file to play is that the file must be stored in your application’s main bundle directory. This is just the root folder that your applications files are stored in. Your

Listing 1. The applicationDidFinishLaunching method - (void)applicationDidFinishLaunching:(UIApplication *)app { [[UIApplication sharedApplication]

registerForRemoteNotificationTypes:( UIRemoteNotificationTypeAlert |UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound)]; }

Listing 2. The delegate methods - (void)application:(UIApplication *)app didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)devToken { [self sendProviderDeviceToken: devToken]; }

- (void)application:(UIApplication *)app didFailToRegisterForRemoteNotificationsWithError:(NSError *)err { }

NSLog(@"Error in registration. Error: %@", err);

Listing 3. How to implement the code in the applicationDidFinishLaunching method - (void)applicationDidFinishLaunching:(UIApplication *)application { application.applicationIconBadgeNumber = 0;

}

46

[self getUpdatedDataFromServer];

03/2010 (21)


iPhone and iPad in Action

For corresponding display in the terminal, see Figure 4. You will need to do this for every sound file that you wish to invoke from a push notification.

Summary

As we have seen, push notifications offer a very simple solution to a complex problem. They give developers the ability to mimic the functionality of running their application in the background while conserving the system resources on the iPhone. Apple has provided us with a very robust service that we are able to use free of charge. This service is the centerpiece of the entire push notification system and allows us to send simple messages from a provider to a specific iPhone with very little delay. In order to receive the push notifications, applications must be prepared and signed with a special signing certificate generated on Apple’s website. You must create a signing certificate for use in development mode as well as debug mode when testing push notifications in your application. This certificate is used in conjunction with your private key to create the SSL certificate needed to communicate with Apple’s servers.

Figure 4. Provisioning pro�le form

audio file must be in the format of aiff, wav, or caf and limited to 30 seconds. In order to convert the audio file to one of these formats, you must use the afconvert command on you Mac. To do this, open the Terminal and navigate to the directory of the audio file you wish to convert. Next, type the afconvert command followed by -f caff -d LEI16 {INPUT} {OUTPUT}. The following shows an example of using this command to convert the file track2.mp3 to track2.caf. /usr/bin/afconvert -f caff -d LEI16 track2.mp3 track2.caf

a

03/2010 (21)

d

v

e

r

t

i

s

e

m

e

n

t

47


INTERVIEW

Interview with

Lance Snider Let us know more about yourself and your background?

My name is Lance Snider. I’m 29 years old and am currently living about an hour south of Salt Lake city Utah. I started out my career thinking I was going to be the world’s greatest designer. After realizing I wasn’t very good I ventured out, discovered actionscript, and quickly fell in love. I spent the next few years working in house and as a freelancer. By chance I happened across ActiveDen, a site that sells stock Flash. The thought of making passive income while building whatever I wanted was irresistible to me. I quickly rose in the ranks becoming a top 20 author, making enough to pay my mortgage and all my bills, whether I happened to upload something that month or not. When the opportunity came up to actually run ActiveDen, I jumped at the chance. Now instead of developing, all of my time is spent trying to help my authors make more money as well as helping Flash developers understand the value of using stock to enhance and speed up their freelancing. When I’m not working on ActiveDen, I’m playing the drums, kayaking, or getting punched in the head... literally. I’m an amateur MMA fighter with a Jiu Jitsu background.

Tell us a little about ActiveDen.

ActiveDen is the largest seller of stock Flash on the web with over 10,000 files and almost 700,000 members. It’s a place where you can buy as well as sell Flash, Flex, and now Unity 3d files. Many of our authors sell stock on the side, but there are several who’ve quit their full time jobs and sell

48

with us exclusively. Making $70,000 per year is not uncommon for the top Envato authors. We have a couple who make around $25,000 every month! We sell a lot of out-of-box solutions, like site templates, to people who need something quickly and on a budget. We also sell a lot of files to hard-core freelancers who are looking to save time.

What was the first Envato site and how did it come to be?

The very first site was FlashFox, which became FlashDen, which finally became ActiveDen. Don’t worry, we plan our site names a little more carefully now. :) It was started by Collis and Cyan Ta’eed, a pair of freelancers with dreams of starting their own business. Little did they know that ActiveDen would grow to be the largest site selling stock Flash on the web. I’m sure if you’d told them it would one day grow into 8 marketplaces, 10 tutorial sites, 8 blogs, and a publishing company, they’d have laughed at you.

How do you find authors and convince them to sell on your marketplaces?

To be honest, we hardly have to do any advertising to get authors. Developers see people making ridiculous amounts of money building whatever they want, whenever they want, and they join. Like I said earlier, we have a couple selling with Envato who makes around $25,000 ever single month. Selling stock just might be the best job on the planet.

Using stock is sometimes looked down upon by hard-core freelancers. How do you combat that?

03/2011 (21)


Interview with Lance Snider

It’s true – a lot of top guys feel that using stock in their projects is somehow cheating or taking the lazy route. Of course, if you have a client paying top dollar for unique work, it better be unique. Fortunately, that doesn’t mean you can’t still use stock. You just need to make sure you use it appropriately for the scenario. I’ve used stock files in major projects for big-name clients, but customized them in a way that no one would ever notice. Yes, the code was stock, but the visuals were still 100% unique. This practice has saved me an insane amount of time and money over the years. It’s really no different than using a code library like TweenMax or Papervision. This is a relatively common practice among top freelancers who understand that time really is money.

Currently ActiveDen offers Flash, Flex and Unity files. Are there any plans for more technologies?

Yep, we’re about to start selling JSFL extensions in the next few weeks. There are so many great tools out there, but no single repository for people to buy and sell them. This is especially exciting as extensions, more than any other category, are going to appeal to hardcore developers.

What’s next for Envato?

Envato is a fun company to work for because we’re constantly adding new sites, whether they be marketplaces or something else. The next one on the list is PhotoDune – a stock photography site. Yes, stock photography is an already crowded niche, but we have a huge network of buyers to back it up.

What technologies or CMS’s do you use for setting up and administrating the Envato platform?

Everything is custom made by our very talented development team. We have our own homemade queues, search system, and even forums built in Ruby on Rails.

Do you spend any free time with the other employees, and how?

Though there’s a main office in Melbourne, most of us (including me) are spread all over the world. Even though we work remotely, we still manage to get together and have fun. In fact, in September we got staffers from the US, UK, Germany, and Australia together for a meetup in Chicago. Yes, we got a lot done, but there was also a lot of playing. When we’re not on the same continent, we still hang out and play Team Fortress 2. Nothing is more satisfying than shooting up your coworkers at the end of a long day.

03/2011 (21)

Which is the most successful Envato marketplace?

Right now it’s ThemeForest, which specializes in Wordpress themes and other web templates. That said, ActiveDen has been growing steadily, despite some of the bad press Flash has gotten lately, and I hope to catch up again soon.

How do you handle licensing and protection issues?

Just like with any digital product, protection is an issue for ActiveDen. That said, we have a few things to help combat it. The first line of defense is our encryption software. We use Kindisoft’s secureSWF, which I’m a huge fan of. We also have an employee whose entire job is to seek and destroy stolen files. His unofficial title is pirate hunter. If we don’t catch something, the community will. They’re fantastic when it comes to helping us fight piracy. There’s actually one more thing we do, but unfortunately it’s top secret. The more people know about it, the less effective it becomes. Suffice it to say – it’s a really satisfying way to stick it to the thieves.

Is HTML5 something you plan to sell at Envato?

Actually, we already do. We sell html5 components on CodeCanyon.net and offer high-quality html5 tutorials over on Net Tuts+. A lot of people in the Flash world are nervous of html5, but I don’t think they should be. Good developers should use the best tools for the job, not just what they’re used to. If that happens to be html5 in certain cases, embrace it. Flash is still the best tool for a wide range of applications and won’t be killed off any time soon. To say one will kill the other or that they can’t live together in harmony is, in my opinion, naive. Thanks, Lance for the great interview. Interviewed by Ali Nekou Pour

49


INTERVIEW

Demetrio Fortman, CEO of MotoCMS.com, speaks out! We would like to introduce a person who stands behind MotoCMS Company, who is the heart and soul of the truly revolutionary project that changed views of many people on Flash website creation process. Dear readers, please meet Demetrio Fortman, a creator of an advanced and feature rich Flash content management system – Moto CMS. He has been involved with computers for his entire life, and has always had a keen interest in how things worked and what one can do with the technology to make people’s life better people’s life. He specializes in dynamic site and application development using Flash CS3, Papervision 3D, etc. But let him personally speak about himself and his invention. Please visit www.motocms.com for more information.

Demetrio, can you share with us a little bit of your history. What did you study in college and how did you learn to design and develop?

I studied computer science, programming and software development in college. So, my love for IT and web technologies comes from there. I was taught to create, strive for innovations and be up to date as to all new that takes place in the development sphere. And of course, I spent much time working alone: I was discovering new things, trying them, failing sometimes… But when I succeeded, it was so great. And I always had a great pleasure from the process of studying the subject I was extremely interested in.

What made you turn towards Flash and Papervision 3D?

I first started learning 3D from the layout; then I went on with programming, script languages, PHP and Javascript. But my passion for Flash was getting even stronger with all the knowledge I accumulated. I was grabbed by Flash. I liked the opportunity to create interesting and useful applications, the applications that are more complex than just to create a primitive banner or simple animation. Then Flex came into our

50

lives As I evaluated its potential and opportunities, my interest in Flash became even more intense.

How did you solve the problem of managing complex Flash websites for yourself before you started selling the solution to others?

I think all flashers who have ever solved the problem of managing complex websites, will agree with me that most of the solutions were developed by them using PHP, on some sheet of paper or so. There weren’t powerful tools like WYSIWYG editor; usually the developers used the admin panel with some simple login through HT access, edited by means of an ordinary data provider. Some admin panels were more complex with the appearance of more dynamic Flash websites, XML websites, so we had to work on XML editing. There we had more complex solutions, but is has always been a problem for a developer to combine several control panels for developing one Flash website. For example, control panel for gallery, for some shop, for some articles, a guest book… Basically, we had to combine many control panels with different user logins. So, we had to combine all this stuff for one client. Sometimes it was so difficult, and we had to develop several control panels for

03/2011 (21)


Demetrio Fortman, CEO of MotoCMS.com, speaks out!

managing complex websites with the help of popular content management systems like WordPerss, Joomla, Drupal, etc. But unfortunately, these systems didn’t offer WYSIWYG editing opportunity that would be so convenient for ordinary end users. You know that HTML alone doesn’t give an opportunity to display custom fonts or create great visual effects, in contrast to editing in Flash environment.

What is Moto CMS peculiar for and what makes it stand out among the range of other content management systems for Flash?

Moto CMS is a unique Flash content management system. It is the only system that offers a full-fledged WYSIWYG editor. With Moto CMS you can implement any design ideas: you are not limited with effects, animation or FLA file structure. The user can add an unlimited number of pages, pop-ups and link them between. Not every system offers such wide opportunities for its users. As to SEO abilities, Moto CMS is search engine friendly and functional; it has all the tools and instruments for building a truly search engine optimized Flash website. There are such opportunities as Google Analytics & Google Webmasters Tools integration, the ability to provide unique Meta tags, HTML titles for each page, deep linking, rewritable URLs, etc. Moto CMS doesn’t require additional programs such as Photoshop, Dreamweaver, etc. It provides all necessary tools: a powerful Image Editor with the ability to perform plenty of functions, to add such effects as brightness, contrast, adjust color, etc. A very useful peculiarity of the system is the

03/2011 (21)

ability to use the 404 and under construction pages; i.e. if the website is in process of development or under maintenance, the user can activate the under construction mode right within the control panel. Also, it is possible to select a template for the mode and write your own custom message. Media library is like a file manager for Moto CMS. It is possible to upload images, media files and use them on the website. Media library is not for media content only – it may also contain .PDF images, text documents that can be linked between. Also, I’d like to mention the fact that Moto CMS is a multi-lingual system: the control panel is translated into many languages. We even have a separate portal: translate.motocms.com where anyone can add their own translation. At the moment, the system is translated into more than 15 languages. Generally, it is possible to add text in any language to your Moto CMS website. It is achieved by adding custom fonts – users’ own fonts that contain glyphs of different languages. A user can upload their own font in order to create a Flash website using his own languages. One more absolute advantage of Moto CMS is the ability to integrate your own modules and widgets to the control panel. Various modules can be integrated to the system: from basic animated buttons with plenty of properties to full-fledged modules and widgets with their own control panel. Moto CMS combines many rare ready-made solutions and components that are so necessary for developers. It is no secret that developers have to search and then modify the necessary components in order to develop a Flash website. Especially, it is a problem for those

51


INTERVIEW

who used to work with Actionscript 2.0 and recently started working with Actionscript 3.0. In Moto CMS we combined all necessary components: they are universal and work well for any solution. We have found and integrated such solutions as scrollbars with plenty of settings, various loaders for media content, arrangers, paginators, the set of basic modules: drop down menu, gallery, mp3 player, contact form, catalog module, etc. So, all these components are integrated into the system; you can extend them, create your own designs for these modules, or just use them according to your needs. We work non-stop on developing new features that are regularly added to the system. Generally, every item, every element of a Flash website can be edited and managed by means of Moto CMS.

What was your primary goal when creating Moto CMS? Is there anything you would like to change or improve in your product?

Our primary goal was to create a universal solution for Flash website editing. We wanted to give developers the opportunity to create such universal solutions for their clients – end users with the help of convenient control panels. At the expense of developing modules and easier website customization, the developers will earn more. Regarding the product improvements… Our main source of ideas is our feed deck which we created for Moto CMS clients and all those who would like to share their ideas, thoughts and wishes. We are always happy to get feedback on our products, and we take all the suggestions into account. We try to realize new features and implement them into products in the shortest terms. Overall, there are plenty of directions that our team is capable to support and follow.

Can you imagine your project in 5 years?

It is not easy to answer this question right away, because every year we have fresh news, changes and innovations in IT and web sphere. I can say that MotoCMS is flexible and may be converted into various instruments, e.g. for video editing, presentations, banners, and all those that cannot be realized without Flash technology.

Are there any myths regarding Moto CMS you would like to be busted?

We used to mention this topic in one of the posts published on our blog… The main myth is that 90% of system setup issues appeared because of the client’s environment doesn’t meet the product requirements. Practically, all the issues we manage to solve. Another myth is related to activation server: If the main site doesn’t work then all the clients’ products won’t work

52

too. It is really a huge myth: the accounts server is not connected with the main site. We have developed a special system and created additional servers for a smooth activation process. So, even in case some problems appear with the server (even the connection with the server failed), the activation process will run smoothly. At the moment, some special algorithms are in the process of development and going to be realized in the nearest future. So, very soon we will have the system that is absolutely secure and reliable in this respect.

Here are some burning issues of the day. The iPhone and iPad throw a harsh spotlight on Flash. But how do you see the future of Flash?

Interesting question… Well, if iPhone and iPad will not still support Flash, in this case, most likely, Moto CMS will generate a special version of the website for these devices. Regarding the future of Flash on the whole, I think Flash will always have its own niche: it doesn’t have worthy rivals in such directions as video production, interactive effects and many Rich Internet application solutions. But up to this time we see that many Javascript and HTML5 applications are still unsolved to compete with Flash. You see, I am not against HTML5 and other IT innovations. The question is: what’s better for the users. If necessary, MotoCMS will generate versions for IPad, IPhone, and also will start working with HTML5. It depends on how matters will stand in IT sphere. We are flexible and will adapt to any changes.

What blogs/magazines/articles would you suggest reading in order to broaden one’s knowledge?

I would advise you to follow the blogs of other Flash developers. I would pay attention at the work of such talented Adobe evangelists and Flash developers as Lee Brimelow, Mike Chambers, Sean Moor, Ryan Stewart, Serge Jespers, and others. Thanks, Demetrio for the great interview. We wish you success and prosperity. Just continue on the same lines! Cheers!

03/2011 (21)


Top 3 Book Recommendations Adobe Flex 4 Books Worth Reading

Flex 4 Cookbook Real-world recipes for developing Rich Internet Applications

With this collection of proven recipes, you have the ideal problem-solving guide for developing interactive Rich Internet Applications on the Adobe Flash Platform. You’ll find answers to hundreds of common problems you may encounter when using Adobe Flex, Flex 4 Framework, or Flash Builder, Adobe’s GUI-based development tool.

Developing Flex 4 Components Using ActionScript & MXML to Extend Flex and AIR Applications

The first book to completely demystify leading-edge component development with the Adobe Flex 3 platform – How to build components for Flex and AIR applications using ActionScript 3.0 and Adobe’s powerful MXML user interface markup language – Covers expert techniques most books ignore, including component metadata, error handling, documentation, and creating Flex components in Flash using the Flex.

AdvancED Flex 4 Using ActionScript & MXML to Extend Flex and AIR Applications

AdvancED Flex 4 makes advanced Flex 4 concepts and techniques easy. Ajax, RIA, Web 2.0, mashups, mobile applications, the most sophisticated web tools, and the coolest interactive web applications are all covered with practical, visually oriented recipes.

From Ali RAZA (ACI, MCPD, SCP, ZCE)


���������������������� ���������� ���� � � � � � � � �� �� ��� ���

������

����������������������

��

���������������������

��������

�����������������

���� ��� ���������� ����������

� �� ����� �����

�������������������������������� ����������������������������������

�������� � ����������

�������������������������������� ����������������������������������� ������������������������������������������������������ �������������������������������������������������������� �������������������������������������������������

�������������������������������������������������� � ����������������������������������������� ����������������������� �������������������������������������������������

�����������������


� �� ����� �����

������������������� ���������������

�������� �����

��� �����

������ ������������ ����������������� ������������ �������������������� ���������������� ���������� ��������� ��������

����������� ������� �� � ��������� �� �� ����� ���� ������� ��� ����� ��� ���������� ���������� �� ����� ����

��������������� ��������������� ����������������������������������� ������������������������������������������ �������������������������������������������� �������������������� ����������������� ���������������������������������������� ����������������������������������� �� ����������������������� ������������������ ������� ������������������������������ �������������������������������������������� ��������������������������������������������

���������������

������

����������������������� ��������������������������������� ������������������������������� ������������������������������ ��������������� ����������������������������������������������������������������

������������

����������������������� ��������������������


Adventures  

Adventures Test

Advertisement
Read more
Read more
Similar to
Popular now
Just for you