What is the iPad?

Inventing a new device category is hard. If it wasn't, the category would probably already exist. So there should be no surprise that Apple's iPad announcement has yielded wildly different responses. Here is my take.

First, as the happy owner of a Kindle 2, buying a $499 media pad is something I can contemplate. The Kindle DX at $489 with the same sized screen becomes a very tough sell versus the entry level $499 iPad. I love my 6" Kindle, and while it is in a different league at $259, I would have to stop and think about whether I'd buy it again today. Now, about that iPad...

The iPad is not a mobile device in the same sense as your phone. You will not carry the device around in your pocket. It is not a big phone. Instead, it is something new. I see three usage scenarios for it.

1. It is a device you use at home to access media, and play games. Videos, Pictures, Books, and the web. It is a couch device, a bed device, a kitchen table device. When you get home from work, you can leave your laptop in your bag, and just use the iPad.

2. It is a laptop replacement on trips. Headed on a short business trip, or on vacation? Don't want to take your laptop, but don't want to be stuck reading your iPhone for a few days? The iPad is a great alternative. You can take a keyboard with and catch up on emails from your hotel, but have a small device to carry in your bag during the day to spend 15-30 minutes checking in throughout the day.

3. Business/Education - Developing specialized applications and using the iPad as a computing platform. Whether it is kids in schools reading their textbooks and doing homework or sales associates at the local retail outlet showing you color alternatives, there are tons of special purpose applications that can leverage a device in this category. And the rate of development of iPhone applications to date certainly makes this seem reasonable.

Personally, I think the non-3G versions are great alternatives, as I don't envision myself using a device like this out of Wi-Fi range. So the base model is actually very appealing, and at $499 is still somewhat reasonable. That said, I'm not going to run out and buy one on day one. But I can see the second version as a great replacement for my Kindle.

No Flash on the iPad is the Right Choice for Apple

Apple finally announced the Jesus Tablet iPad, launching what they believe to be a new device category. It remains to be seen whether they are correct (although I have my guesses), but the launch of the iPad has rekindled an existing fight between Apple and Adobe.

Apple refused to implement (or allow others to implement) Flash on the iPhone. John Gruber has written about this topic extensively over the past two years. He correctly (though not surprisingly) predicted that the iPad would not support Flash. I say not surprisingly, because all the reasons they had for not supporting Flash on the iPhone still exist for the iPad. OK, one reason: CONTROL. I won't rehash John's arguments, but the summary is, Apple wants to control the experience (and commerce) on the iPhone (iTouch, iPad, etc.), and Flash bypasses that control.

As a newer Apple 'fanboy' (I apprecited Gruber's take: 'There’s a whole class of recent switchers who define “Apple fanboy” as “anyone who’s been an enthusiastic Mac user since before I switched to the Mac”.'), I long avoided Apple because of their demand for control. But after dipping my toe in with iTunes and an Airport Express, I finally gave in and switched to a MacBook Pro and iPhone 3GS (and love them).

I've seen two very different points of view in the past 24 hours regarding Flash on the iPad. When my wife and I were talking about the iPad, I suggested that it could be an alternative to her 13" MacBook, as it does nearly everything she needs. She quickly pointed out that without Flash, it was unappealing to her. (The keyboard is also an issue, but that's a topic for another post).

The second point of view was a post on the Adobe blog by Adrian Ludwig. He pointed out the iPad's lack of Flash, some of the sites that will be unavailable to the iPad users, and that "50 of our partners in the Open Screen Project are working to enable developers and content publishers to deliver to any device". I thought it was a pretty good post from Adobe, pointing out their frustration in a reasonably neutral tone (given their obvious interests). I was a bit surprised by the comments. I didn't do a full tally, but I'd say 90% of the comments were anti-Flash. They complained about the state of Flash on the Mac, and already run Flash blockers on their desktop.

So I see two camps, the general users, who just want the websites to work, and the super users (blog readers) who have a negative perception of Flash and just want it to die. As someone who has built Flash applications, and enjoyed the process and results, I have a biased viewpoint. However, I also have the debug version of the Flash Player installed, so I see first hand how many uncaught exceptions there are in nearly every Flash application I see. There are tons of poorly written Flash applications deployed on the web.

In the end, Apple made the right choice for Apple. I have yet to see a major group of users who are likely iPad buyers in the next 12 months that are upset by the exclusion of Flash. The broader population who may eventually adopt the devices are simply not likely buyers in the short term anyway.

Apple is in a race against Flash. They are gaining huge marketshare in the mobile space, and pushing HTML 5 and the iPhone SDK as the chosen mobile development platforms. As the marketshare continues to grow, the 'Flash Only' sites will be forced to provide mobile or iPhone optimized versions to gain access to growing mobile user base.

We've seen this before. There was a point when web developers optimized their sites for IE 6 exclusively. Now there are websites that actively reject IE6 users, and focus their primary support on Firefox, Safari, and Chrome. This shift occurred because the users demanded it. They were fed up with IE and switched to alternative browsers, and the websites had to adjust or lose the traffic. Apple is attempting to do the same thing with Flash. If they can successfully build a mobile audience without Flash support, websites must respond.

I think HTML 5 and rich applications via plugins (Java FX, Silverlight, Flex) both have their place. Consumer facing high traffic sites should be HTML. The accessibility and SEO trade-offs are simply to great to justify using a plug-in RIA. For applications, whether they are corporate applications, games, or utilities, Flex, Java FX and Silverlight are great alternatives. They provide the benefits of the web deployment model with the power and speed of development of traditional languages.

Looking forward, high level rich languages (Java FX, Silverlight, and Flex) will merge with the increasing functionality of the underlying platform (JavaScript and HTML 5) to create high level languages that 'compile to the browser'. Google's GWT is a first generation example of this, but I believe there is much more to come. Eventually the debate over plug-in architectures will become moot.

The only question is, will it happen fast enough for Apple to avoid a user backlash?

Update: Gruber and Scoble appear to be making the same analogy to the changes Firefox forced on web developers.

The Complete Software Developer

The Software Development profession is still a relatively immature profession. There are few real certifications and no real licensing processes that provide any realistic guide to an individual's competency. The landscape evolves quickly and covers a very broad spectrum of skills. These reasons make it difficult to map out a career path that will lead to the development of a complete Software Developer. In this article, I intend to lay out what I feel is a solid career outline for a Software Developer, and why each step is important.

It is important to note that this is not the path to be a competent developer, but to be an outstanding developer. The tools and resources available today make it possible for someone to achieve reasonable levels of successes with minimal levels of skill and education. Instead, this is a roadmap to become what I consider to be a complete developer. This includes more than just pure technical skills, but someone who can work with others to solve problems.

Education

A favorite movie quote of mine is from 'Die Hard':
"'And when Alexander saw the breadth of his domain, he wept, for there were no more worlds to conquer.' Benefits of a classical education." - Hans Gruber
While a Computer Science or Computer Engineering degree is not required to develop software, it can provide an understanding of the foundational elements on which everything else is built. Understanding both how a computer actually works, and the fundamentals of algorithms, data structures, and operating system design will provide a solid theoretical foundation for an entire career. I also believe it is important that the degree focuses on theory more than practice. A Computer Science degree that spends time teaching how to use Visual Studio or Eclipse may produce students who can be more effective in year 1, but does them a disservice in years 2-n.

The only other degree I've seen with some regularity provide individuals with a solid understanding is Physics. Even so, they have had to learn the fundamentals along the way. I guess with the Physics background, they probably understand everything at a much deeper level anyway.

Consulting

I believe that every new college graduate's first job should be with a consulting company. Not just any consulting company, but one large enough and experienced enough that it provides real training on how to be a Consultant, in addition to how to develop software. Consulting is a skill, and it is one that will pay dividends through an entire career.

Working at a consulting company will expose new Software Developers to a variety of technologies, business domains, and cultures. Ideally, the consulting company works in a variety of technologies and new consultants get an opportunity to work on projects across multiple languages/technologies/platforms.

Travel is not a requirement, but can provide some added benefits. From the simple worldly benefits of seeing different parts of the country, to business dinners with clients, where new developers can gain a real insight into how business gets done. You may also get to eat some great meals along the way as well.

Consulting also helps new developers learn to market themselves. Since consulting companies really sell the competency of their staff, and their 'unique process', developers will learn how to position their skills and experiences to demonstrate competence and credibility. After consulting for a while, every future job interviews will be much less stressful.

Ideally, spend 2-3 years broken up into six month projects across at least two different platforms (Java, .Net, etc.), and with at least one project in a different city.

This experience will do several things. First, it will teach new developers how to be a consultant. This includes everything from dressing professionally, to presenting ideas and concepts to non-technical customers, to understanding the business of selling services. Second, it provides a broad experience base while new developers are still young and impressionable. There are many different technologies and platforms out there, all taking different paths to solve problems. Seeing this diversity early insures that new developers do not become assimilated into the group think of a single platform or pattern. It is hard to work in different platforms like .Net and Ruby on Rails without developing a knowledge about how the underlying technologies work. Finally, new developers will also see the rich diversity of business and cultures across companies. It is an opportunity to learn the trade-offs of different business models and cultures, and how they impact the ability for software development teams to be effective.

Support

After spending some time in Consulting, it is time to move into a role where you can own and support a product. This can either be within an internal IT department, or for a Software as a Service company. A packaged software vendor provides many of these benefits but I believe that a critical part of this experience is 'carrying the pager', which packaged software usually avoids.

The key learning here is to own and support a system across several major releases. Building version 1.0 of an application as a consultant is very different from enhancing and maintaining an application across several minor and major releases. Being responsible (indirectly, if not directly) for the support and success of a production application is a critical learning experience.

Ownership is an important concept. This experience provides the ability for a new developer to really work on something over a long period and 'own' it. A developer can see the payoff of a bit of foresight or extra effort they put in 12 months ago. They can also feel the pain of taking shortcuts that were ill-advised. They can learn how those trade-offs work and begin to get a sense of when they are worthwhile.

In the end, working in IT or Engineering provides a different set of goals and drivers for Software Developers than Consulting can provide. These different goals force new developers to see software development through a different lens.

Performance and Scaling

The opportunities within most consulting and traditional IT/Engineering roles to really focus on high performance code and application scaling are limited. Within consulting, it is often a non-factor, as performance and scaling issues often do not appear until long after the initial deployment. Within IT/Engineering roles, there is often an opportunity to address issues, but only within the context of a single application and infrastructure.

Therefore, the next stop on the career path is Professional Services or other specialized consulting. Professional Service organizations often focus on providing extremely skilled resources for short periods to address critical issues. These can often focus on performance or scaling issues, and provide a great opportunity to gain exposure to a broad set of problems, architectures, technologies, and infrastructures. To be successful in this role, an individual needs both a deep understanding of the product they are supporting but also an understanding of how it fits into the greater ecosystem.

In a Professional Service or specialized consulting role, individuals often interact with very senior members of the customer's staff, allowing developers to gain experience and exposure to a individuals they may not traditionally interact with.

This type of experience provides an opportunity to solve a large number of very intense problems over a relatively short period of time. This provides a breadth of knowledge about how the different types of major systems in production, and the problems that they face. It also allows developers to build an impressive network of contacts across a broad range of companies.

What's Missing?

As a career outline, I believe this is a great start, but it is probably incomplete. There are many other valuable experiences that an aspiring Software Developer should experience. Some of these can be done in parallel with the above outline, others may be additional steps.
  • Build a product - Whether it is an Open Source application, shareware, or a commercial application, build something from scratch that other people will use. Interact with your user base and understand the challenges that product managers face.
  • Manage a team - Lead a team. Learn the interpersonal skills necessary to manage a team, and learn the leadership skills and qualities necessary to rally a disparate group of individuals into a team.
  • Work for a startup - As a side project or part of your career path, understand how a small company can often achieve more than a much larger firm.
  • Work for a Fortune 500 Company - In a consulting role or as an employee, understand how the right decision for an organization isn't always the right decision for an individual team or group, and the political and interpersonal issues that this can create.
  • Learn - Learn a new language every year, at least. Learn a new framework, pattern or approach ever quarter, at least. Understand how things work on the other side of the fence, you'll be amazed at how it can change your perspective.
  • Mentor - Learn to help others grow. If you can't teach someone else how to do it, you probably don't understand it well yourself.
  • Build your Network - It is a small world. You will run into folks again and again. The impression you make on them as a junior developer may be important a decade later.
  • Maintain your Network - Keep in touch with as many people as you can. Reach out to them and help them as much as possible. It will pay off.
Go Forth and Create

Now, focus on your passion. You have the background necessary to learn any new technology, solve any problem, and effectively communicate with others. It is time to focus on what you are passionate about, and become a leader in your chosen field.

Getting Started with GraniteDS, Spring, and Maven

This is a quick tutorial to get you up and running using GraniteDS, Spring, and Maven. My initial assumptions are that you already have a Spring project up and running using Spring WebMVC, and you want to add GraniteDS to the project to enable a Flex client. This just covers using GraniteDS for a basic RPC call using AMF. GraniteDS does much more, but this should at least get you started.

First, you need to add the GraniteDS dependencies to your pom. GraniteDS does not appear to be in the default Maven repository, so first you need to add a references to the Java.net Maven Repository:
<repositories>
<repository>
<id>Java.net</id>
<name>Java.net Repository</name>
<url>http://download.java.net/maven/2/</url>
</repository>
</repositories>

Next, you'll need to add the dependencies:
<dependency>
<groupId>org.graniteds</groupId>
<artifactId>granite-core</artifactId>
<version>2.0.0.GA</version>
</dependency>
<dependency>
<groupId>org.graniteds</groupId>
<artifactId>granite-spring</artifactId>
<version>2.0.0.GA</version>
</dependency>

You may also want to add additional GraniteDS artifacts, such as granite-hibernate, etc. You can see the entire list here.

You will need two additional configuration files, services-config.xml and granite-config.xml. The services-config.xml should be familiar to anyone who has used BlazeDS before.

WEB-INF/flex/services-config.xml - This file contains the core of the mapping config. The first block specifies the destination, including the beanName of the backing Spring Bean. You will need to replace [beanName] with the name of the Spring Bean you are exposing. You can tweak the URL and destination names, but otherwise this should be good for your simple RPC call as is.
<?xml version="1.0" encoding="UTF-8"?>

<services-config>

<services>
<service
id="granite-service"
class="flex.messaging.services.RemotingService"
messageTypes="flex.messaging.messages.RemotingMessage">
<destination id="test">
<channels>
<channel ref="my-graniteamf"/>
</channels>
<properties>
<factory>springFactory</factory>
<source>[beanName]</source>
</properties>
</destination>
</service>
</services>

<factories>
<factory id="springFactory"
class="org.granite.spring.SpringServiceFactory"/>
</factories>

<channels>
<channel-definition id="my-graniteamf" class="mx.messaging.channels.AMFChannel">
<endpoint
uri="http://{server.name}:{server.port}/{context.root}/graniteamf/amf"
class="flex.messaging.endpoints.AMFEndpoint"/>
</channel-definition>
</channels>

</services-config>

Note: If you are using AutoWiring in Spring, the beanName will just be the unqualified class name. So the class com.ericdaugherty.TestService would have a beanName: testService.

WEB-INF/granite/granite-config.xml - In this simple example, there is no configuration of real value in this file yet. As you delve deeper into GraniteDS's features, you can add configuration here.
<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE granite-config PUBLIC
"-//Granite Data Services//DTD granite-config internal//EN"
"http://www.graniteds.org/public/dtd/1.2.0/granite-config.dtd">

<granite-config scan="true">
</granite-config>

You will need to add some additional configuration to your web.xml. In addition to your SpringMVCServlet configuration, you will need the GraniteDS Filter and Servlet:
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/config/web-application-config.xml
</param-value>
</context-param>

<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>

<filter>
<filter-name>AMFMessageFilter</filter-name>
<filter-class>
org.granite.messaging.webapp.AMFMessageFilter
</filter-class>
</filter>
<filter-mapping>
<filter-name>AMFMessageFilter</filter-name>
<url-pattern>/graniteamf/*</url-pattern>
</filter-mapping>

<servlet>
<servlet-name>AMFMessageServlet</servlet-name>
<servlet-class>
org.granite.messaging.webapp.AMFMessageServlet
</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>AMFMessageServlet</servlet-name>
<url-pattern>/graniteamf/*</url-pattern>
</servlet-mapping>

I had to add the ContextLoadListener and specify the location of my web-application-config.xml file for GraniteDS to work, even though I didn't need it for Spring.

Note: if your SpringMVCServlet is mapped to your root (/), make sure the AMFMessageServlet mapping is first in your XML file.

Now, you simply need to create a Flex project and use RemoteObject to call your service. In Flash Builder 4, I was able to set it up as a BlazeDS project, point it at the src/main/webapp directory in my Maven tree, and it was able to auto-configure RemoteObject.

That's it. This is a very simple version of what you can do with GraniteDS, but it should be enough to get you started.

Flex, Adobe, and alternatives to LCDS and Flash Builder

Yesterday I came across two interesting articles, both relating to alternatives to existing Adobe commercial tools in the Flex space.

Flex/Flash Builder vs. IntelliJ IDEA

The first article was about a favorite of mine, IntelliJ IDEA. I've been an IDEA user (some may say fanatic) for a long time, and while I've used Eclipse based editors when necessary, I always feel more at home with IDEA. The article is an overview of the Flex/ActionScript support available in IDEA 9. My conclusion is: while the depth of support is impressive (refactoring, code analysis), it does suffer from what I think of as 'not my primary function' issues. Jesse's (the author) complaints are mostly around speed, and non-intuitive configuration issues. I'm also not sure how it stacks up against some of the code generation and BlazeDS/LCDS integration features of Flash Builder 4 (which is still in beta).

The 'not my primary function' issue is one of my strongest frustrations with Eclipse. I've always found IDEA more intuitive to use because the basic functions feel 'more built in' and less like a set of cobbled together plug-ins. In fact, one of my concerns with IDEA becoming a platform like eclipse (part of their new Open Source strategy) is the erosion of this advantage. I think these types of issues will crop up more and more as IDEA supports a wider set of platforms.

LCDS vs. GraniteDS


The second article was about Granite DS, an alternative to Adobe's commercial LCDS. The article is actually a 'response' to a pair of articles about the new features in LCDS 3 by fellow Gorilla Justin Shacklette. The article covered quite a bit of ground, so I'll touch on a few areas of interest.

Code Generation

Justin discusses the ability for LCDS to generate server functionality based on your Flex code.
"In LCDS 3, you write the UI and the model, and LCDS does everything else. Yep, LCDS handles everything below the UI using just the model. Not only that, but LCDS is constructs a performant, enterprise-class backend using just the model. No boilerplate code, no plumbing code, no serialization/deserialization, no Hibernate config, just a point-and-click Modeler and your UI code. Game changing."
If this works, I mean REALLY WORKS, it can be game changing. But we've all seen 'push this button for magic' before. More importantly, even if it works, is it 'how work gets done'. I think the SOFEA concept is more reasonable. In this concept Flex could be just one of many possible rich clients sharing a single set of services with other clients that could include iPhone, Android, Silverlight, JavaFX, GWT, JavaScript/Ajax, etc. clients. Obviously no application would use all of these, but having a Flex client an HTML/JavaScript/AJAX client and an iPhone client can be reasonable, especially in today's world of mobile optimized apps. And if this is the case, do you want your service layer generated by LCDS based on your Flex code?

GraniteDS takes the approach that your server code is the foundation of your application, and GraniteDS helps expose and integrate that into a Flex application. All of your modeling and service layer is written in traditional Java code, and then GraniteDS can expose the methods (via annotation) and generate ActionScript classes to map your model objects.

In reality, I think these approaches are targeted for different uses, and different audiences. Java shops that want to build a rich client will be attracted to the GraniteDS approach, while Flex applications that need small amounts of server data storage and persistence can benefit from the LCDS approach. As a long time Java developer, you can guess where I'll feel more comfortable.

Asynchronous Processing

One of the 'joys' of working with Flex is the interaction between its single application thread and asynchronous I/O. LCDS and GraniteDS approach these in separate ways. I won't rehash the comparison as I think the GraniteDS article does a good job. My view is that the LCDS way feels more like Flex, and the GraniteDS way feels more like Java. It isn't surprising giving the origination of the two projects. Both get the job done and are using the same underlying protocol, so it just boils down to a different API.

BlazeDS

Where does BlazeDS fit into all of this? As Adobe's Open Source alternative to LCDS, you might assume there was no point in the GraniteDS project. For simple RPC and messaging, BlazeDS will handle all your basic needs. With the latest release (3.2.0) well over a year old, it isn't a rapidly evolving project. However, it still provides a solid bridge between Java and Flex, so it doesn't necessarily need regular releases either.

In the end, GraniteDS is an alternative to LCDS, not BlazeDS. All three bring different feature sets to the table, so you will need to evaluate them in light of your specific needs.

What this means for Adobe

So what does this mean for Adobe? I think it is a classic good news/bad news situation. As far as I can tell, Adobe is a packages software vendor. While they have been making efforts to gain traction in the enterprise software space (ie LCDS) they are still very focused on selling packaged software: Flash Builder, Photoshop, Lightroom, Premier, etc. And in the Flex space, that means Flash Builder and LCDS licenses. If these licenses don't offset their efforts on the open source Flex SDK, why should they continue to champion the platform. (Well, there are other reasons, but the point remains).

Having strong competitors in the market for both products shows both a growing maturity and adoption of the Flex platform. It also means more competition for revenue. I think these CAN both be positive if they result in Adobe raising the bar on its efforts.

Flex, Unicode, and Regular Expressions (RegEx)

The internet really helps make the world smaller, and through my open source applications I've enjoyed interacting with a user base that includes many people from outside the United States. iTunes Export has seen adoption in many countries and has challenged me to continually think about internationalization (i18n) issues, from providing the application in multiple languages (English and French today) to handling character sets not traditionally seen in American music. Which brings me to the current challenge.

The problem is that iTunes allows users to create playlist names with characters that are illegal in the file system. This means that I cannot simply reuse the playlist names as the file names for the output playlist files without some processing. My earlier versions attempted to simply replace common illegal characters (such as \, /, ', ", etc.) with an _ character. However, this was rather haphazard, and required constant updates to the filter as I found new characters to filter out. I decided to be reverse the process, so I wrote a regex that replaced all the characters that were not explicitly legal. I started with \s\w which included alphanumeric characters and whitespace. I added additional characters that were legal in most file systems - . [ ] = $ & {}. My resulting regex was: /[^\s\w\-\.\[\]=$&{}]/g. This worked really well for my many of my United States users, but many users from other countries (and some from the US) found it too limiting. Common characters such as é, à, è, ä, ö, ü, Ä, Ö,Ü, and ß were filtered out to an _ even though they were legal characters for file names. So I went back and took another look at the regex.

(Note: \w matches alphanumeric characters but not accented characters like é. However, this is not a bug but matches the ECMA 262 spec)

To aid my efforts, I wrote a simple little utility to determine the Unicode character codes for certain strings, and then test out regex patterns. Here is the utility:

Flash is required. Get it here!

You can type in a string and it will convert it to the Unicode character codes. It also converts it to the regex pattern representation (simply a \x instead of \u). For example, the character é is \ue9 or \xe9. If you enter that as the regex pattern, and then enter the string Tést, you will see the é is matched.

Based on what I've seen, I needed to include the many of the characters from the Latin-1 Supplement Unicode block. Instead of including every character, I limited it to \uc0-\uff. I think that should cover all the normal use cases. The resulting regex patter in: /[^\s\w\-\.\[\]=$&{}\xc0-\xff]/g. This new regex will be included in the next release of iTunes Export (both Console and GUI). The same regex works in Java, although you will need to escape the \ characters, or in Scala use """[^\s\w\-\.\[\]=$&{}\xc0-\xff]""".

Give the above utility a try and feel free to suggest improvements.

For more information on Unicode and Regex: http://www.regular-expressions.info/unicode.html.

iTunes Export 2.2.0 Released

The 2.2.0 release features updates and bug fixes to the console and GUI versions

In both versions:
  • Added option to exclude 'Built In' playlists, including Music, Library, Genius, Movies, etc.
For the GUI version:
  • Added auto-update functionality. Checks for a new version every 7 days. Can be disabled in the 'About' window.
  • Resolved issue where Finish button causes error on 'Select Playlist' screen. Finish button is now disabled on this screen.
  • Added option to 'About' screen to change between languages. English and French currently supported.
  • Improved French translation. Thanks to MrDNA (mrdna@laposte.net) for doing the translation.
For the Console version:
  • Fixed issue with XML validation. This version no longer attempts to validate the XML file (required downloading DTD from apple).
  • Fixed issue where spaces were being converted to underscores in playlist names.
The new version can be downloaded from the project homepage: http://www.ericdaugherty.com/dev/itunesexport/

I have received several feature requests that I am still working on, and will try to get a new release out soon. However, there is enough here to justify a release now.

If you find any issues or have questions please email me (eric@ericdaugherty.com). Please include which application and version (GUI or Console, 2.2.0 etc.) of iTunes Export and the operating system you are using.