But how do I use that code?

That’s a question I’ve seen quite a few times on the Adobe labs and pre-release forums over the past months. And the question is used in relation with the code being generated by the web service introspection wizard.

Although we’ve tried to make the code as simple and versatile as possible, as in to cover most use-cases, it seems to still need some explaining. It is possibly caused by change. The way in which you used web services has changed substantially, and disruptive changes are not always easily understood. We’ve gone from a full run-time experience to strong-types and ActionScript representations of the service. So I’ve tried to put together a small application that uses a web service and shows how to use this new nifty feature.

The example will stretch over two posts/parts, each covering a way of using the generated code to arrive at the same result, structured like this:

  • Part 1 – the biggest, I will explain all the parts of the application, the service and use the generated ActionScript code to call methods on the service.
  • Part 2 – mostly the same as part one, but I will rewrite the invocation code to use MXML and data binding as much as possible.

When the idea of playing around with this feature some more came to me I started looking around for an interesting service. And since it’s the video age, I’ve picked one from eCoComa which searches videos from google, youtube and msn by a specific keyword. See the service description here (it’s the last one in the list) and the wsdl file.

The webservice defines two methods, fairly similar at least in terms of input and output structure. Let’s see what the input/output looks like:

To call any of these two operations you must provide:

  • The KeyID – this is a string identifier that eCoComa provides on the same page as the web service. This is used to allow non-registered users to call operations.
  • The DomainID – this string should be passed on by users that are registered to the site, instead of the KeyID. It serves authentication purposes.
  • The Keyword – this is the actual keyword on which videos are searched. That;s what will be entered in the UI
  • Include and Exclude fields – for more advanced search options. Will not be used in this example.

The definition of what needs to be sent is inside the types section of the wsdl file, like this:

   1:  <s:element name="GetVideo">
   2:      <s:complexType>
   3:      <s:sequence>
   4:  <s:element minOccurs="0" maxOccurs="1" name="KeyID" type="s:string"/>
   5:  <s:element minOccurs="0" maxOccurs="1" name="DomainID" type="s:string"/>
   6:  <s:element minOccurs="0" maxOccurs="1" name="Keyword" type="s:string"/>
   7:  </s:sequence>
   8:  </s:complexType>
   9:  </s:element>

.csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, “Courier New”, courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }Both operations return a RSS like structure, having one channel element which is in fact an array of ‘items’ – the name of the logical unit used to encompass all of the return information. An item contains the following information:

  • The title of the video, as given by its creator.
  • A link to the page where the video can be accessed.
  • A description of the video content, if provided by the author.
  • The publication date – the date when the video was uploaded to the service (be it YouTube, MSN or other).
  • A thumbnail of the video, to provide a visual representation of what it will look like.
  • The embedding code, stored in the swf element.

The definition for an item inside the wsdl is as follows:

   1:  <s:complexType name="item">
   2:  <s:sequence>
   3:  <s:element minOccurs="0" maxOccurs="1" name="title" type="s:string"/>
   4:  <s:element minOccurs="0" maxOccurs="1" name="link" type="s:string"/>
   5:  <s:element minOccurs="0" maxOccurs="1" name="description" type="s:string"/>
   6:  <s:element minOccurs="0" maxOccurs="1" name="pubDate" type="s:string"/>
   7:  <s:element minOccurs="0" maxOccurs="1" name="thumbnail" type="s:string"/>
   8:  <s:element minOccurs="0" maxOccurs="1" name="swf" type="s:string"/>
   9:  </s:sequence>
  10:  </s:complexType>

The application must allow a user to type in a keyword (let’s say AIR) and get back a list of video items that match the query. This means that the application will have three possible states (two can be deduced from above, the third is added by me):

  1. The initial state, where only the search dialog box is displayed
  2. The results state, where, aside the search box a vertical list of items is displayed.
  3. The viewing state, which is similar to the results, but it also contains an html display control, to actually allow viewing the selected video.

The workflow is: search (s1) > pick from a list (s2) > watch.(s3).

I’ve looked into what the webservice returns, and in the swf field it puts the entire html embedding code (if available) or a link to a web-page (if embedding is not available, like for MSN). That said, and giving that AIR applications written in Flex have a nice control that displays html properly, I’ve decided to make the app an AIR one.

With the details out of the way, let’s dive into code (which is attached to this post and you should download):

  • First create the new project inside Flex Builder – New Flex Project and check the Destkop application radio button.
  • Open the Import Web service wizard from the Data menu. In the second step paste the URL to the service’s wsdl and hit Finish.
  • What happened? Well, you should now have a new package in the project – if you used the default it will be com.ecocoma, with a bunch of as classes inside, like ArrayOfItem, BaseVideo_Service, etc. These are the classes that the wizard has generated based on teh service descriptor. Most of the classes are as models of the types defined inside the wsdl – Item.as, Rss.as, ArrayOfItem.as, but also some ‘standard’ classes:
    • BaseVideo_Service.as (or the rule is Base<servicename>.as) this class contains the as model for the wsdl file; it defines the service, port, operations and messages. It also has plumbing for doing the actual call as well as managing multiple calls. It also defined the bindings between the remote and as types
    • BaseVideo_ServiceSchema.as (rule: Base<servicename>Schema.as) – this class stores the type schema for the service – actual definitions inside XML variables, namespaces and relations between the various schemas. This is used by the webservice to generate the service’s SchemaManager.
    • IVideo_Service.as (or I<servicename>.as) – is the interface that the main service implementation will follow. If you need to do anything that involves passing the service around, you can use the interface.
    • Video_Service.as (or <servicename>.as) – this is the as service implementation. This is the one that you will use when calling operations, attaching event handlers, setting headers or request variables, and even in bindings. It uses the base<servicename> class as its underlying webservice class. Each operation in the service descriptor is a method in this class.
    • GetVideo_request.as (rule: <operationname>_request.as- wrapper class for an operation’s input arguments. This is generated for use with mxml syntax, as it will allow defining the actual <request> tags.
    • GetVideoResultEvent.as (rule <operationname>ResultEvent.as) – this class defines a custom event that will be fired when the result of the operation comes back from the server. It is dispatched by the service implementation after casting the result to the correct type. This means that the .result and .header properties are strong-typed and you can work with them directly.
    • ArrayOfItem.as – types that are an array of something (like an array of strings, or other complex types) have a different structure from a regular as class. They subclass ArrayCollection and provide a set of methods that allow you to retrieve the strong-typed element from inside the array (like GetStuffAtIndex())
  • Once everything is generated, using the service is quite easy. You just need to follow three basic steps:
    • Create an instance of the webservice
      var vidService:Video_Service = new Video_Service();

      .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, “Courier New”, courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }

    • Attach the custom event listener and the fault event listener
      vidService.addVideo_ServiceFaultEventListener(handleFaults);
      vidService.addgetVideoEventListener(handleSimpleVideo);

      .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, “Courier New”, courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }

    • Call the operation
      vidService.getVideo("VDO-M89901795F","",keyword);
    • Write the handleSimpleVideo and handleFaults that do something when

      the result returns or a fault happens. You can see the code I’ve used in the application source code that’s attached.

  • In the result handler you can access the event.result property to actually do something interesting. As shown in the wsdl structure, the result is of type Rss, a class with only one property, named channel. The channel is in fact an array of items, and an item is the logical unit that holds all of a video’s details. The code generator has created a class for Rss, a class for Item and a class for ArrayofItem. The ArrayOfItem extends ArrayCollection, which makes it bindable, and adds some methods to allow extracting typed elements. One thing about collections is that they are as anonymous as it gets: you put in strings, numbers, items, whatever, and it comes out Object. Now, if you do not know what to expect beforehand it may be a little confusing. This is why the generated implementations of arrays have additional methods for getting at the underlying type. For instance, in this class you will find methods like getMyItemAt(index:int) or addMyItemAt(index:int). This reads like – the type below is Item; go look in that class for what this method will return (or just ctrl-click on the return type). In this particular case the type name also has a My particle in front, because otherwise it would override the base class methods (addItemAt(), etc).
  • Considering the above, you can directly wire up the result that comes from the service to a UI element, like a data grid:

       1:  private function handleSimpleVideo(e:GetVideoResultEvent):void {
       2:     videos.dataProvider = e.result.channel;
       3:  }
  • videos is a TileList which uses a custom item renderer to display the video thumbnail, title and description. Again, see the attached code for more details.

And this covers the web service part inside the application. You can download the application source code here. Be aware that one of the arguments of the call for videos requires a key ID, This key changes, and is displayed on the eCoComa website, so you should always head on there and get the new key before trying to run the code.

And this is how the application should look like after it fetches some video results – the list is a TileList with a simple mxml component used as item renderer:

videosearch_results

In Part 2, most to all of the ActionScript code will go away, and it will be replaced by MXML tags. This will show how to call a method using the service.method_send way, how to set the request arguments and bind to the correct result

Advertisements

5 thoughts on “But how do I use that code?

  1. Pingback: Flex API contest extended | Cristi's Thoughts
  2. The memory leaks are incredible! Have you tried calling the service 10 times and profile the memory? Any idea why?
    Thx

  3. No, I haven’t played with the profiler on this project. Do you refer to this project in particular, or any project that uses the generated code? Also, its a good idea to try and reuse handlers, events and other type of objects because you cannot rely on GC to immediately clean things up.
    But I will do a profile soon to see what happens in this scenario – thanks for pointing that out.

  4. Nice job cristi!

    I was just wondering where’s part 2 of this article? 😉

    I wanna utilize MXML in mine application and I was wondering when are you gonna publish that part.

    Thanks!

  5. yeah, I’ve been really lazy on that front 😀 I guess I can blame it on the fact that I prefer ActionScript over MXML. But I will get part two cleaned up and posted in one-two days tops.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s