Where to Find Help

You can get help and information from a variety of areas.

Documentation

Launch the language reference help from within your editor for language-specific information. I do not recommend using the search capability at http://help.adobe.com directly, as it directs you to the Adobe Support page, which is not specific enough for our purposes.

Type in a class name in the IDE text editor, and then select it. In Flash Professional, click the question mark on the top right. In Flash Builder, press Shift-F2. As shown in Figure 19-1, the information is presented in ASDoc style as HTML frames. The upper left frame lists packages, language elements, and appendixes. The lower left frame lists classes in the package in context. The right frame displays the class you are searching for. The content comprises an introductory paragraph and the list of properties, methods, and events.

Figure 19-1. Language reference help
Figure 19-1. Language reference help

The Internet

Use the Google search engine to find undocumented material starting with “as3” or “AIR”, especially now that you know the syntax of the class or API you are interested in. The Flash community is vibrant and posts solutions and examples, often before Adobe makes them official.

Read blogs for up-to-date information and code snippets. Visit websites for in-depth articles and application examples.

The Community

Post questions on the Adobe forums. This is a good place to ask beginner- to intermediate- level questions and gain access to the Adobe engineering team.

Attend conferences. Many sessions cover the latest in technology. In fact, it is often the arena chosen by software companies to make announcements and give sneak peeks.

Be active. Share your work. If you demonstrate interest and knowledge, you may be invited to be part of the prerelease lists. This will put you in the privileged position of testing and making suggestions on beta products. Be aware of Adobe bugs so that you can find workarounds for them, and if you witness new bugs, report them at http://bugs .adobe.com/.

Find a user group in your area. If one does not exist, create it.

Creating New Objects

Although IronPython has a wealth of built-in objects, you eventually need to create your own objects for an application of any complexity. If you’ve worked with other languages and scratched your head over some of the requirements for creating a class, you’ll find that IronPython is a welcome change. Creating and using custom classes in IronPython is amazingly easy. The following sections tell you how to create a basic class and then show how to use it.

Defining the IronPython Class

An IronPython class can have both attributes (properties) and methods, just as any class in any other language can have. However, IronPython classes have a few quirks as well. Listing 5-1 shows an example of a simple IronPython class.

Listin g 5-1: Defining a simple class

[code]

class MyGreetings:
# Greeting name variable.
Name = ‘Sammy’
# Provides a hello greeting.
def SayHello(self):
print ‘Hello there’, self.Name, ‘!’
# Provides a goodbye message.
def SayGoodbye(self):
print ‘See you later’, self.Name, ‘!’

[/code]

The class description starts out with the word class, as you might expect, and the name of the class. If you plan to inherit from another class, you enclose its name in parentheses behind the class name like this:

[code]

class MyGreetings(sys):

[/code]

In this case, the MyGreetings class would inherit from the sys class. A class definition ends with a colon, just like every other structure in IronPython. You use indentation, as normal, to signify the end of the class.

Attributes are simply variables that you declare as part of the class. As you can see, you normally define a default value for attributes. An attribute can be of any type.

Methods are simply a different kind of function in IronPython. You define them within the class as you might expect. A method uses def as the starting point, followed by the method name. Notice that both methods, SayHello() and SayGoodbye(), have an input variable named self. When you create an instance of a class, the interpreter automatically creates the self variable for that instance. The self variable contains all of the data associated with that instance, such as Name in this case.

As shown in the method code, you can use any of the data that self provides. In this case, the code accesses self.Name to obtain the name you assigned to the Name attribute (or the default, if you haven’t). If you were to try to access Name directly, the interpreter would display an error message.

Using Custom Objects in IronPython

At this point, you have a shiny new class named MyGreetings. Normally, you won’t place the class and the code that uses it in the same file, so the example places the test code in TestFirstClass.py. Consequently, the first thing the example does is import MyGreetings from FirstClass, as shown in Listing 5-2.

Listin g 5-2: Testing the simple class

[code]

from FirstClass import MyGreetings
# Create an instance of the class.
TestIt = MyGreetings()
# Set the Name attribute.
TestIt.Name = ‘George’
# Call the two methods.
TestIt.SayHello()
TestIt.SayGoodbye()
# Pause after the debug session.
raw_input(‘Press any key to continue…’)

[/code]

At this point, the code creates an instance of MyGreetings and places it in TestIt. Notice that the call to MyGreetings doesn’t require any data. If you want to request data from the caller during instantiation, you must provide an __init__() method in your class declaration. Otherwise, the interpreter provides a default declaration for you that creates the desired object.

The code changes the value of Name by assigning a new value to it. Notice that you assign the new value to TestIt.Name, just as you would in any other language.

Next, the code calls the two methods, SayHello() and SayGoodbye(). Notice that the method calls don’t require any input, and IronPython would complain if you tried to provide it. Remember that the interpreter provides self in the background. Figure 5-2 shows the output from this application.

Figure 5-2: The simple class outputs the expected information.
Figure 5-2: The simple class outputs the expected information.

Adding Documentation

It’s important to add documentation to your class as soon as possible — preferably while you’re typing the code. Many IronPython developers work in the interpreter to create applications faster and rely on the help() function or __doc__ attribute to understand what a method does with considerably less effort than finding the documentation.

Adding documentation to your class is straightforward. You simply add strings immediately after the class or method definition. A string that documents your class is called a docstring. IronPython doesn’t recognize docstrings that appear in places other than class and method declarations. For example, if you place a docstring after an attribute, it won’t appear when you use the help() function or __doc__ attribute. However, third-party tools often pick up these additional docstrings and place them in any documentation they output. Listing 5-3 shows the example class with docstrings in place.

Listin g 5-3: Adding documentation to a class

[code]

class MyGreetings:
“”“Contains a list of messages that you want to send to the user.
Make sure you assign a value to Name before using any of the
greetings so the message is customize for that user.”“”
# Greeting name variable.
Name = ‘Sammy’
“”“Provides the user’s name.”“”
# Provides a hello greeting.
def SayHello(self):
“”“Outputs an interesting greeting to the user.”“”
print ‘Hello there’, self.Name, ‘!’
# Provides a goodbye message.
def SayGoodbye(self):
“”“Outputs a goodbye message to the user.”“”
print ‘See you later’, self.Name, ‘!’

[/code]

Docstrings can consume one or more lines. The standard convention is to place docstrings within triple quotes as shown in the listing. You can find a number of other docstring conventions at http://www.python.org/dev/peps/pep-0257/.

After you create your docstrings, start the IronPython interpreter and load your class. You can try the docstrings out using either the help() function or __doc__ attribute. Figure 5-3 shows the docstring output for the example class.

Figure 5-3: Docstrings add greatly to the usability of your application.
Figure 5-3: Docstrings add greatly to the usability of your application.

Self-documenting your application is great, but some people will prefer some sort of HTML documentation. Don’t worry; you can get a tool to handle this requirement as well. PythonDoc (http:// effbot.org/zone/pythondoc.htm) provides the same type of functionality that JavaDoc does. It’s akin to generating the documentation you need when you compile your application in Visual Studio. PythonDoc locates all of the comments in your code and uses them to create HTML documentation that others can use when working with your classes.

 

 

The StageWebView Class

The flash.media.StageWebView uclass is a new class for displaying and interacting with rich HTML content in an AIR for Android application. It is a subclass of the EventDis patcher class.

The flash.media.StageWebView class uses the web control as provided by the native system that may vary slightly from one device to another. There is currently very little interaction between AIR and the HTML content.

StageWebView is not a display object, and is therefore not adding to the displayList. Create a StageWebView object and set its stage property to attach it directly to the stage. It always lies on top of your content, so if you want other objects to occupy the same view area, you must remove it first:

[code]

import flash.media.StageWebView;
var webView:StageWebView = new StageWebView();
webView.stage = this.stage;

[/code]

The size of the area dedicated to web content is defined in the viewPort property as a rectangle. Here it covers the stage width and 75% of the stage height:

[code]

import flash.geom.Rectangle;
var verticalBounds:int = stage.stageHeight*0.75;
webView.viewPort = new Rectangle(0, 0, stage.stageWidth, verticalBounds);

[/code]

To load content, call the loadURL method and pass the URL of the site. Add a listener so that in case an error occurs you can notify your user. Location is the event property for the site to load:

[code]

import flash.events.ErrorEvent;
webView.addEventListener(ErrorEvent.ERROR, onError);
webView.loadURL(“http://www.npr.org”);
function onError(event:ErrorEvent):void {
trace(“not able to reach location: “, event.location);
}

[/code]

Once the website is loaded, you should see it inside your application. It displays and responds as expected.

There are several events you can register to monitor activity and collect information.

You can register for the LocationChangeEvent.LOCATION_CHANGE event that is fired after a location has been reached:

[code]

import flash.events.LocationChangeEvent;
var webView:StageWebView = new StageWebView();
webView.stage = this.stage;
webView.addEventListener(LocationChangeEvent.LOCATION_CHANGE, onChange);
webView.loadURL(“http://www.npr.org”);
function onChange(event:LocationChangeEvent):void {
trace(“you are now at: “, event.location);
var verticalBounds:int = stage.stageHeight*0.75;
webView.viewPort = new Rectangle(0, 0, stage.stageWidth, verticalBounds);
}

[/code]

To avoid displaying an empty screen while loading, only display the view when its content is fully loaded and complete by listening to Event.COMPLETE.

You can register for the LocationChangeEvent.LOCATION_CHANGING event that is fired just before a new web location is requested. You can use this event in three different scenarios. You can prevent navigating to the new location by calling the preventDefault function. Most importantly, you need to catch the event to prevent it from opening the
native browser and leaving your application. Force the new location to load into Stage WebView and its viewPort area:

[code]

webView.addEventListener(LocationChanged.LOCATION_CHANGING, onChanging);
// prevent going to a new location
function onChanging(event:LocationChanged):void {
event.preventDefault();
trace(“sorry, you cannot go to: “, event.location);
}
// load new location in the StageWebView
function onChanging(event:LocationChanged):void {
event.preventDefault();
webView.load(event.location);
}

[/code]

If your application needs to know when StageWebView is in focus, register for the FOCUS_IN and FOCUS_OUT events. These events get dispatched when clicking inside or outside the rectangle area:

[code]

import flash.events.FocusEvent;

webView.addEventListener(FocusEvent.FOCUS_IN, inFocus);
webView.addEventListener(FocusEvent.FOCUS_OUT, outFocus);
function inFocus(event:FocusEvent):void {
trace(“on webview now”);
}
function outFocus(event:FocusEvent):void {
trace(“off webview now”);
}

[/code]

You can force focus when first launching your application:

[code]webView.assignFocus();[/code]

StageWebView has methods that mirror the functionality of a traditional browser toolbar. In fact, you could re-create a navigation user interface if you wanted to simulate the desktop experience.

The title and location properties return the page information. The stop and reload methods will, as their names indicate, stop the loading of a page or reload it.

The historyBack and historyForward methods load pages that were previously visited. Check that the isHistoryBackEnabled and isHistoryForwardEnabled properties are true to ensure the pages exist in either direction. Currently, the history is not available as a whole. If you want to access it, you must store it yourself as the user navigates
through pages.

As mentioned before, StageWebView is not added to the display list. To remove it, use the dispose method. Setting the object and its viewPort property to null is meant to aid in the garbage collection process:

[code]

webView.viewPort = null;
webView.dispose();
webView = null;

[/code]

Design Considerations

You should design your application for the best possible user experience. Toward that end, here are some points you should consider.

First, you have full control of the viewPort dimensions, but not its content. The vast majority of sites are designed only for the desktop. The few that deliver a mobile version take stage dimension into account and offer an adaptive layout and optimized content.

You can reduce the locations to a limited choice using the preventDefault method as previously discussed. If you want to keep the user experience open, prepare your application to accommodate multiple designs as much as possible.

Present your application in landscape mode and full screen. Align your application to the upper-left corner. This will mirror the web experience and users’ expectations:

[code]

import flash.display.StageAlign;
stage.align = StageAlign.TOP_LEFT;

[/code]

If the web page is larger than the viewPort, the StageWebView displays a scroll bar and zoom controls. There is no option to suppress these controls.

If you choose to keep auto-rotation enabled, you need to set a listener for the stage Event.RESIZE event and prevent scaling:

[code]

import flash.display.StageScaleMode;
stage.scaleMode = StageScaleMode.NO_SCALE;
stage.addEventListener(Event.RESIZE, onStageResized);

[/code]

When the screen rotates, re-create the viewPort at the appropriate dimension. It does not resize dynamically:

[code]

import flash.events.Event;
function onStageResized(event:Event):void {
webView.viewPort = null;
var verticalBounds:int = stage.stageHeight*0.75;
webView.viewPort =
new Rectangle(0, 0, stage.stageWidth, verticalBounds);
}

[/code]

If you navigate between locations, the native back button takes you back to the previous open application or home. It does not work as a back button for StageWebView. This is the expected behavior, of course, because the Internet content is part of your application, not a separate intent.

Either provide an internal back button or override the native back button. Do consider that this is not a recommended Android practice. It is not possible to put elements on top of StageWebView, but you can simulate a top navigation above it.

The drawViewPortToBitmap function can be used to take a screen capture of the Stage WebView. You can take advantage of this feature to temporarily replace StageWebView with a bitmap and display other elements on top of it.

Local Use

You can package HTML files with your application and then load them inside Stage WebView. You can use this to display a help page for your users, or other HTML content.

Copy the HTML page into a temporary file and load it using its url:

[code]

import flash.filesystem.File;
var file:File = File.applicationDirectory.resolvePath(“assets/test.html”);
var local:File = File.createTempFile();
file.copyTo(local, true);
webView.loadURL(local.url);

[/code]

Note that it is possible to load a local HTML file to make an Ajax XMLHttpRequest on another domain or to make JavaScript calls, as demonstrated in the next paragraph.

The loadString method is for displaying HTML formatted text in the viewPort area. The text must be fully HTML formatted:

[code]

// define the string in html format
var myString:String =
“<html>”
+ “<body bgcolor=”#FFFF33″>”
+ “<font color=”#FF0000″>Hello</font color><br>”
+ “<font color=”#FFFFFF”>Look at me</font color><br><br>”
+ “<a href=”http://www.google.com”>Click Me</a>”
+ “</body>”
+ “</html>”
webView.loadString(myString, “text/html”);
webView.addEventListener(LocationChangeEvent.LOCATION_CHANGING, onChanging);
// load the Google site into the viewport when clicking on the text
function onChanging(event:LocationChangeEvent):void {
event.preventDefault();
webView.loadURL(event.location);
}

[/code]

At the time of this writing, this feature is limited and does not provide much more than a TextField with htmlText would provide. You cannot, for instance, use it to display local assets such as images. It is useful if you want text placed in the StageWebView area.

Mobile Ads

Local use in combination with JavaScript is handy when dealing with mobile ads.

At the time of this writing, mobile advertising providers do not offer an AS3 SDK. Rewriting their AS2 code into AS3 to use in AIR does not seem to get ad impressions. Using StageWebView to simulate the browser model seems to be the best solution.

Go to http://developer.admob.com/wiki/Android or http://developer.admob.com/wiki/Requests for instructions on how to set up an ad request for AdMob before we adapt them for AIR for Android.

You need an embedded HTML page that makes the request to the ad provider with your publisher ID and the StageWebView to load the page and monitor the navigation. The HTML page contains a JavaScript script that fetches the ad. It is important to set manual_mode to true. Set test to true during development or to false to receive live ads.

[code]

<html>
<head>
<title>Get Ad</title>
<script type=”text/javascript”>
var admob_vars = {pubid: ‘YOUR_ID’,
bgcolor: ‘FFFFFF’
text: ‘000000’
test: true,
manual_mode: true
};
function displayAd() {
admob.fetchAd(document.getElementById(‘ad_space’));
}
</script>
<script type=”text/javascript”
src=http://mm.admob.com/static/iphone/iadmob.js></script>
</head>
<body onload=”displayAd()”>
<div id=”ad_space”></div>
</body>
</html>

[/code]

Figure 13-1. AdMob ads with the test property set to true (top) and false (bottom)
Figure 13-1. AdMob ads with the test property set to true (top) and false (bottom)

The ActionScript looks like this. Put your ad request in a try catch block in case the ad provider site is down or it sends back invalid data:

[code]

import flash.media.StageWebView;
import flash.geom.Rectangle;
import flash.events.LocationChangeEvent;
import flash.events.ErrorEvent;
import flash.filesystem.File;
import flash.filesystem.FileMode;
import flash.filesystem.FileStream;
import flash.media.StageWebView;
import flash.net.navigateToURL;
import flash.net.URLRequest;

var view:StageWebView;
var local:File;
view = new StageWebView();
view.stage = this.stage;
view.addEventListener(LocationChangeEvent.LOCATION_CHANGE, onChange);
view.addEventListener(LocationChangeEvent.LOCATION_CHANGING, onChanging);
view.addEventListener(ErrorEvent.ERROR, onViewError);
view.viewPort = new Rectangle(0, 0, 480, 60);

var base:File = File.applicationDirectory.resolvePath(“adView.html”);
local = File.createTempFile();
base.copy(local, true);
try {
view.loadURL(local.url);
} catch(error:Error) {
}
function onChanging(event:LocationChangeEvent):void {
event.preventDefault();
navigateToURL(new URLRequest(event.location));
}
// when the user clicks on the ad
function onChange(event:LocationChangeEvent):void {
if (event.location != local.url) {
navigateToURL(new URLRequest(event.location));
try {
view.loadURL(local.url);
} catch(error:Error) {
}
}
}
function onViewError(error:ErrorEvent):void {
trace(error);
}
[/code]

Services and Authentication

Many services, such as Twitter and Facebook, require an authentication token that can only be obtained via an HTML web page. You can use StageWebView to call authentication methods to extract the token. Service data is then available and can be used inside your AIR application.

OAuth is a robust open standard authorization system. It allows users to hand out tokens instead of usernames and passwords. The token is for a specific site and resources for a defined duration.

Twitter uses OAuth. You can allow users to access their account for authentication and log in to your application so that they can use their account data seamlessly without leaving AIR. You need to register a URL on Twitter to obtain a Consumer key and a Consumer secret, both of which are necessary in your application (see http://twitter.com/oauth/ for more information).

Sandro Ducceschi offers a library called Tweetr that supports pinless OAuth (see http://wiki.swfjunkie.com/tweetr). For a similar application for Facebook, refer to Mark Doherty’s example at http://www.flashmobileblog.com/2010/10/14/facebook-connect-with-air-on-android/.

Limitations

Despite its benefits, StageWebView also has some limitations:

  • You cannot layer elements on top of StageWebView, although you can simulate it by taking a screen grab as described earlier.
  • The interaction between ActionScript and JavaScript is very limited. There is currently no support for ExternalInterface, even though you can fake URLs to communicate from HTML to AS.
  • You should not use StageWebView as a substitute for the native browser. Use it only as a bridge between your application and some needed Internet content. Android devices, for instance, do not support the QuickTime codec.
  • There is no direct way in ActionScript to prevent StageWebView instances from accepting cookies or to clear cookies.
  • The HTMLLoader class is supported in AIR for the desktop but not in AIR for Android.

If your application requires more advanced HTML features, consider using other tools. PhoneGap (http://www.phonegap.com), for instance, is an open source framework for developing applications for Android, iPhone, iPad, BlackBerry, and Symbian devices.

StageWebView and The Native Browser

StageWebView

WebKit is a layout engine that browsers use to render web pages and to support interactivity and navigation history. Developed by Apple in 2002 and open sourced in 2005, WebKit is the default browser built in for Android.

The AIR runtime for the desktop also includes a version of WebKit built in. However, AIR for Android does not include it, and instead leverages the device’s native implementation and gives you access to some of its features via StageWebView.

StageWebView brings the benefits of an Internet browser to your own application. In this chapter, we will briefly discuss accessing the native browser, and then go over what StageWebView has to offer.

The Native Browser

To access the Internet, you need to set the permission for it:

[code]<uses-permission android:name=”android.permission.INTERNET” />[/code]

You can launch the Android native browser from an AIR application using the naviga teToURL method. You pass a URL in the same way you do on AIR for the desktop:

[code]

function onPublicNews():void {
navigateToURL(new URLRequest(“http://www.npr.org”));
}

[/code]

You can also use this method to launch native applications, such as the Android Market, that in turn makes calls to the Internet. The following example opens the Android Market and sets the criteria of applications to display as a URLRequest. Note that the protocol used is market:// instead of http://:

[code]

function onSearchMarket():void {
navigateToURL(new URLRequest(“market://search?q=food”));
}

[/code]

In both cases, your application moves to the background and the native browser becomes the active application.

We need, instead, a solution whereby HTML content can be embedded inside an AIR for Android application. This is what the StageWebView class does.

 

What Are Blogs?

Wikipedia defines a blog as “A blog (a contraction of the term ‘web log’) is a type of Web site, usually maintained by an individual with regular entries of commentary, descriptions of events, or other material such as graphics or video. Entries are commonly displayed in reverse-chronological order. ‘Blog’ can also be used as a verb, meaning to maintain or add content to a blog.”

Sometimes blogs look like an ongoing diary or a journal on a site. Sometimes they look just like a traditional Web site. Traditional blogs have one author and are usually written in more conversational or informal style than most business materials and can include text, images, and links to other content such as podcasts, video files, or even Web sites. Web sites that are built on a blog engine have the look and feel of a traditional Web site, as well as the typical text, photos, and videos that you would find there.

Writing the actual content for your blog is referred to as blogging. Each article that you add to your blog is called a blog post, a post, or an entry in your blog. You are a blogger if you write and add entries or posts to your blog.

Blogs usually focus on one topic or area of interest, or at least they should focus on one type or area of interest. For example:

  • A person might have a personal blog about his or her trip through South Africa.
  • A market analyst might have a blog on his or her findings in the finance and investment industry—what’s happening in the industry, or news or articles on his or her latest research.

When setting up your blog, you have several options:

  1. There are a number of free blogging platforms. WordPress (http://wordpress.org) and Blogger.com (Figure 18.1) are the most popular. Both are very easy to use and have wizards to get your blog up and running in short order.
  2. You can also create your own blog using HTML.
Figure 18.1. Blogger is a free blog publishing tool owned by Google.
Figure 18.1. Blogger is a free blog publishing tool owned by Google.

Web-Based E-zines, Email E-zines, Using E-zines as Marketing Tools

Web-Based E-zines

There are many Web-based e-zines that have only an online presence. These e-zines are accessed through Web sites by browsing from page to page. They have the look and feel of traditional magazines and include lots of pictures and advertisements. Usually there is no charge to view Web-based e-zines, but some do charge a subscription fee. These Web-based e-zines tend to be as graphically pleasing as offline magazines.

Email E-zines

Although email e-zines can come as text or as HTML, these days we are seeing most in HTML as they get a much higher readership. Today we are seeing a blur between newsletters and email e-zines as most newsletters now are sent as HTML and most are content-rich on a specific subject.

Email-based e-zines tend to be very content-rich and, as such, tend to be more of a target-marketing mechanism. Email e-zines tend to be several screens in length with one main article or several short articles and, sometimes, they include classified advertising. The benchmark is that these e-zines should be able to be read in about five minutes. Circulation is often in the thousands. Most run weekly or biweekly editions and are free to subscribers.

People interested in the subject of the e-zine have taken the time to subscribe and have asked to receive the information directly in their email box. Once you have found an e-zine that caters to your target market, that e-zine could be a valuable marketing vehicle.

A major advantage when you advertise in this type of medium and place your Internet address in the ad is that your prospective customer is not more than a couple of clicks away from your site.

People subscribe to e-zines because they are interested in the information that is provided. Even if they don’t read it immediately when it is received, they usually read it eventually. Otherwise, they would not have subscribed. No matter when they take the time to read it, if you advertise in these e-zines or have your business, products, or services profiled, subscribers will see your URL and advertisements. For this reason, email e-zines are a great marketing tool.

Using E-zines as Marketing Tools

Online publications are superior marketing tools for online businesses for several reasons. They can be used in a number of ways to increase the traffic to your Web site. You can:

  • Advertise directly
  • Be a sponsor
  • Submit articles
  • Send press releases
  • Be a contributing editor
  • Start your own e-zine.

 

About the Microsoft Sync Framework

The Microsoft Sync Framework version 3.0 is designed to make it easy to allow synchronization of databases (including complete tables
and individual rows), file system content, and arbitrary data in a range of scenarios. The following are some of these synchronization scenarios:

  • Between on-premises databases and single or multiple cloud databases
  • Between multiple on-premises databases via the cloud (“data hub in the sky”)
  • Between multiple cloud databases
  • Between remote data store(s) and client applications
  • Between data stores and Microsoft Excel® spreadsheet software (Pivot) or other Microsoft Office applications such as Microsoft SharePoint® team services, Exchange Server, and other enterprise solutions
  • To populate remote databases from on-premises databases
  • To aggregate data from multiple remote databases to onpremises databases
  • To maintain a consistent view of data across “three screens” (mobile, desktop, and cloud)
  • To allow reuse of the same application model and logic with just a different user interface (UI) for each client type
  • To enable simple development of occasionally-connected (“offline-and-sync”) clients

The Sync Framework exposes changes to data using the OData Sync protocol. This is based on the Open Data (OData) protocol. OData allows a wide range of data sources to be exposed and consumed over the web in a simple, secure, and interoperable format. It uses well-established standards and web technologies such as XML, HTTP, Atom Publishing (Atom Pub), and JavaScript Object Notation (JSON). For information about OData, see the Developers page on the Open Data Protocol website (http://www.odata.org/developers). For a list of OData providers and tools, see the OData SDK page on the Open Data Protocol website (http://www.odata.org/developers/odata-sdk).

Figure 1 shows an overview of how the Sync Framework can be used in a Windows Azure service to synchronize data with different types of clients. The service exposes synchronization endpoints to which clients can connect. The way that the synchronization occurs depends on the type of client, and the synchronization protocols it supports. The synchronization is managed by the Sync Framework itself, and can optionally include custom business logic to perform tasks such as authentication, authorization, and management.

Overview of the Sync Framework capabilities

Components of the Sync Framework

To achieve the required fl exibility, the architecture of the Sync Framework consists of a central orchestration mechanism, a small synchronization runtime for each client, and individual pluggable providers for each of the data stores and client types.

In many cases, the synchronization runtime and provider can run on the client; this enables full integration with the sync framework as
well as the capability for peer-to-peer synchronization. Code on the client can access the functionality of the Sync Framework using the
simple API available in the provider runtime to synchronize with another data source, send changes to that data source, and access data
in the data source that has changed since the last synchronization. The mechanism also allows clients and data stores to specify rules on
how to resolve confl icts. Figure 2 shows a schematic of this process.

The components and process for synchronization with Windows clients

In cases in which the synchronization provider cannot execute on the client, such as with non-Windows devices or web browsers, developers can write code that accesses the provider on the remote data store using the OData Sync protocol to synchronize data, send updates, and get changes from the remote data store.

The server (in this example, running in Windows Azure) specifi es an endpoint that exposes changes using the OData Sync protocol.
Typically, this is a Windows Communication Foundation (WCF) service. The client may use a runtime and provider that understands the OData Sync protocol, or—where this is not available or practical—it can use custom code to read and parse the OData Sync information.
Figure 3 shows a schematic of this approach.

The components and process for synchronization with non-Windows clientsThe main advantage is that there is now a standard way to read and submit changes for synchronization between the data store, this client device, and other devices that use the same set of data.

Sync Framework Providers

Some providers are still under development, and others will be added to the list in the future. At present, the range of providers available, or soon to be available, includes the following:

  • SQL Server using tabular data stream (TDS) protocol over HTTP(S) and a wizard in SQL Server 2008 R2
  • SQL Server Compact Edition over HTTP(S)
  • SQL Azure™ technology platform using the TDS protocol over HTTP(S) and a wizard in SQL Server 2008 R2
  • Azure Web Roles using an HTTP(S) endpoint with access to Azure table and binary large object (BLOB) storage
  • Silverlight synchronization to isolated storage using HTTP(S) to synchronize data stored as collections
  • Windows Phone 7 synchronization to isolated storage using HTTP(S) to synchronize data stored as collections
  • Windows Mobile 6.x support over HTTP(S) to SQL Compact Edition
  • Synchronization to HTML 5 clients over HTTP(S) (coming in a future release)
  • Synchronization to any existing HTTP-enabled client using HTTP(S) with a custom proxy and code
  • File-based synchronization across computers and networks using standard network protocols

For more information about the Sync Framework, see the Microsoft Sync Framework Developer Center on MSDN® (http://msdn.microsoft.com/en-us/sync/default.aspx).

Interesting Ads

The following are more technology-advanced forms of advertising. They are interesting to viewers because they have attributes that are unique or unusual in some way. These attributes might be more apt to grab viewers’ attention and entice them to click on the ad.

  • Expanding ads. An expanding banner ad (Figures 15.1) is one that looks like a normal ad but expands when you click on it, keeping you on the same site rather than transporting you to another site on the Internet. Usually these say “Click to Expand,” and the viewer then can learn more about what the banner is promoting.
  • Animated ads. Animated ads contain a group of images in one file that rotate in a specific order. These ads are more likely to receive a higher click-through than a normal ad because moving images increase the chance of viewers being attracted to and reading the ad. These ads also allow you to deliver more information than in a normal ad because you can show different files, which contain different data. Limit your ads to two to four frames to keep your load time fast and to make sure your viewers read your information.

This is an example of an expanding advertisement. It displays the ad and then prompts the viewer to scroll to see more. When the banner expands, it prompts the viewer to click through to the advertiser’s site.

  • Drop-down menu ads containing embedded HTML. We are seeing an increase in ads containing embedded HTML. These allow viewers to select from a drop-down menu which site they want to visit. These ads are great because instead of making viewers click through and then navigate through your site, as with a conventional ad, these direct your viewers to the page of interest on your site. This type of ad also is great for co-op advertising programs. Several companies targeting the same target market, in a noncompeting way, can use this type of advertising to get more exposure for their dollar.
  • Interstitial ads. These are advertisements that appear in a separate browser window while your visitors wait for a Web page to load.
    Interstitial ads are more likely to contain large graphics, streaming presentations, and more applets than a conventional ad. However, some users have complained that interstitial ads slow access to destination pages.
  • Flash ads. These ads allow you to use rich media in your advertisements. By using this technology, you can incorporate animation and sound into your advertisement.
  • Floating ads and DHTML. These ads appear when you first view a Web page, and they appear to “fly” or “float” over the page for anywhere from 5 to 30 seconds. They tend to obscure your view of the page, and they often disable mouse input until the ad is finished loading so that you must watch it before being able to access the page content. They have a high click-through rate and are great for branding, although their intrusiveness has been questioned.
  • Unicast ads. A unicast ad is basically like a television commercial that runs in a pop-up window. It has animation and sound and can last from 10 to 30 seconds. Although they are like television commercials, they go a step farther in that a viewer can then click on the ad to obtain further information. They have a higher-than-average click-through rate.
  • Rich media ads. These advertisements use dynamic tools such as Flash, HTML forms, Java, ASP, Javascript, or other programming languages or applications that increase the appearance or the functionality of the ad. A rich media ad may include sound or a registration form and usually commands higher CPM levels than other banner ads.

 

Friday: Researching Your Competitor’s Keywords

Monitoring your competitor’s PPC efforts is a good way to keep your edge. By conducting competitive research, you can discover new variations of your core keywords, or completely new ones. There are reasons to take on your competitors head-on for the same keywords, and there are other reasons to make flanking maneuvers in order to avoid direct competition. You can think of competitive research as both a defensive and an offensive tactic.

First, let’s cover the defensive aspect of competitive research. There are going to be core keywords that will drive your business. Often there are several competitors who are also bidding on these core keywords. As we said earlier, you want to have bid on many variations of your core keywords, because your target audience is going to be made up of people from varying backgrounds and locations. Your competitors may have thought of terms that you’ve missed. Adding variations that you discover through competitive research can help you maintain a position as the toughest competitor.

Another goal of competitive research is to gain an understanding of your competitors’ messaging. What are your competitors saying in their PPC ads? Here’s what to look for:

Headline: Does their headline speak more clearly to your target audience? If so, why? If not, why not? Make a list of reasons why their headline is better than yours.

Ad copy: Are your competitors utilizing their limited ad copy more efficiently than you? What benefits and features do they highlight? Make a list of benefits you’re not using in your ads.

Call to action: How are your competitors motivating users to click on their PPC ads? Are they offering special deals, free shipping, or free information? Write down reasons why their offers are more compelling than yours.

Some people say the best defense is a good offense. Researching your competitors’ keywords will also help you think of new terms that neither you nor they are targeting. During this process, you’re looking for holes in your competitors’ keyword armor, so to speak. The motivation here isn’t to go head-on against your competition; rather, you are looking for terms that all your competitors are missing.

Now that you understand how competitive research is both a defensive and an offensive tactic, how exactly do you find out which keywords your competitors are targeting? You will never know exactly which terms your competitors are bidding on. None of the search engines will provide you with this information, and there is no reputable third-party tool that will provide precise insight into your competitors’ PPC keywords.

Competitive analysis shouldn’t be the cornerstone of your keyword research. Instead, this process should supplement the construction of your keyword list and make it stronger. There are numerous tools that you could buy to provide good insight into your competitors’ PPC activities, but to get you started, we’ll describe a few ways that you can do such research on the cheap.

The Ad Preview Tool

By now, you should have a grasp on which keywords are mission critical for your campaign. To gauge the level of competition for each term, you should conduct a search query for each of these. This will give you an idea of how competitive your core terms are, and let you create a list of the competitors with the highest visibility.

To conduct these competitive search queries, you should use the Google Ad Preview tool (https://adwords.google.com/select/AdTargetingPreviewTool). By using this tool, you won’t generate false impressions for yourself or your competitors (let’s play fair!). Another reason to use the tool: Each subsequent search query on Google may cause a different set of ads to be displayed. Google does this because if you don’t click any ads during a single search session, it’s assumed you are not interested in the set of ads being displayed, and eventually no ads will be displayed for the queries you are making from your computer and your IP address. The Google Ad Preview tool helps you avoid these issues.

When you conduct a search query by using the Google Ad Preview tool, you are not actually conducting a live search on Google; you are getting a preview of what the SERP may look like for that particular keyword. Figure 4.14 shows the results of a search conducted using the term organic white tea.

The Google Ad Preview tool can give you an idea of how a SERP will appear for your core keywords.

As you can see in the figure, the Ad Preview tool enables you to view ads as if you were searching from a different location. You can select to view ads as they may appear in a different country, state, region, and city, or even a location defined by longitude and latitude coordinates. This way, you can see how search results look in locations other than your own. For example, if you live in Indiana but you want to see what ads are being displayed in California for a certain term, you can do this by using the Ad Preview tool.

Competitors’ Website Review

Believe it or not, your competitors may just simply tell you their core keywords. For SEO purposes, companies will utilize a line of code called the meta keyword tag, which tells the search engines which keywords are most important to this particular page of their website.

Where do you find this information? When viewing your competitor’s website home page, at the top of the browser you should click View and then select Page Source from the drop-down menu that appears. A new window will open that displays the HTML code of this page. The meta keyword tag is usually located at the top of the code, and looks similar to Figure 4.15.

A home page’s meta name, meta description, and meta keywords tags

Third-Party Tools

The tools in this section are not free, but their publishers offer free features. They can give you some insight into your competitors’ keywords, messaging within their PPC ads, and traffic trends for their websites. Here are some of our favorites:

Compete (www.compete.com): As with any of the tools listed in this section, you’ll get much more competitive information with the paid version of this software, but the free version will get you started. For example, we entered a competitor’s website into Compete and received quite a bit of useful information, as you can see in Figure 4.16 and Figure 4.17.

SpyFu (www.spyfu.com): SpyFu offers two methods of competitive research: by keyword and by URL. When searching by keyword, you are provided with quite a bit of information, including projected CPC, clicks per day, and the average number of advertisers. Also, you can see top PPC domains for this term as well as samples of PPC ads. The information provided by SpyFu is helpful, and Figure 4.18 shows just the top of the results page—additional information is provided on the rest of the page.

 

In Compete, you can see traffic trends for your competitors, as well as visits and unique visitors.

You can also gain additional insight from Compete, such as site description, top referring websites, and some keyword ideas.

SpyFu can indicate how competitive a keyword may be and show the main advertisers bidding on the term.

You can use SpyFu to conduct competitive research by using a specific URL, and get the projected daily AdWords spending range, average ad position, top 10 paid keywords, and other information. You should not, however, take this information as solid fact, but rather as a point of reference. Figure 4.19 shows a sample URL analysis from SpyFu.

A SpyFu URL analysis

KeywordSpy (www.keywordspy.com): If you went ahead and hopped on the Compete and SpyFu bandwagons, you already have quite a bit of information about your competitors. Like the others, KeywordSpy provides speculative stats, top keywords, main competitors, and PPC ad variations. However, it also provides top organic keywords and competitors.

 

StageWebView

The StageWebView allows for web (HTML and Flash on supported devices) and video content to be loaded into a Flex application. StageWebView will utilize the native browser to load HTML into your application.

Let’s review the code below. First, you will notice there is a private variable named stageWebView declared, of type flash.media.StageWebView. Within application Complete of the application, an event handler function is called, which first checks to see if the device supports StageWebView by reading the static property of the StageWeb View class. If this property returns as true, a new instance of StageWebView and a new Rectangle (sized to fill the remaining screen and set to the viewport property of the stageWebView) are created.

There is a TextInput component with the id of urlAddress, which holds the address that will be shown in the StageWebView and a Button labeled GO.

Clicking on the GO button will call the button1_clickHandler method. Within the but ton1_clickHandler method, the loadURL method is called with the urlAddress.text property passed in. This triggers the StageWebView to load the URL.

The results can be seen within Figure 6-12:

<?xml version=”1.0″ encoding=”utf-8″?>
<s:Application xmlns:fx=”http://ns.adobe.com/mxml/2009″
xmlns:s=”library://ns.adobe.com/flex/spark”
applicationComplete=
“application1_applicationCompleteHandler(event)”>
<fx:Script>
<![CDATA[
import mx.events.FlexEvent;
privatevar stageWebView:StageWebView;
privatevar rect:Rectangle;
protectedfunction application1_applicationCompleteHandler
(event:FlexEvent):void
{
if(StageWebView.isSupported==true){
stageWebView = new StagewebView();
stageWebView.viewPort = new Rectangle(5,80,stage.width-10,
stage.height-90);
stageWebView.stage = this.stage;
} else {
urlAddress.text = “StageWebView not supported”;
}
}
protectedfunction button1_clickHandler(event:MouseEvent):void
{
stageWebView.loadURL(urlAddress.text);
}
]]>
</fx:Script>
<fx:Declarations>
<!– Place non-visual elements (e.g., services, value objects) here –>
</fx:Declarations>
<s:TextInput id=”urlAddress” left=”5″ right=”80″ top=”15″
text=”http://www.google.com”/>
<s:Button right=”5″ top=”5″ label=”GO” click=”button1_clickHandler(event)”/>
</s:Application>

StageWebView with the Google homepage loaded