Avoiding Design and Advertising Apathy

-

Monday, August 31st, 2009

I ran across the definition “Design is art optimized to meet objectives” by Shimon Shmueli of Touch 360. I have found myself defining what I do for family, friends and even clients. For clients, it is not something they usually ask but something we volunteer in the context of explaining, selling or defending a design or design process. When asked about the difference between a designer and a fine artist, I have said we are the whores of the art world. For a fee, we create art that meets the client’s needs. Or maybe it is that we work a client’s needs until it is art? I think I like Shmueli’s definition better.

I will often hear “I know you are the designer, but could you explore or change this or that”. I have gotten to the point I anticipate this and reply along the lines of “We really don’t design for designers. Almost everyone should be able to see, evaluate and critique design – even if you can’t necessarily design yourself.”

The truth is, we are not actually designing for them. Maybe I need to be more forthright about this? We are designing for a demographic that they may or may not be in tune to. We are hired to understand and execute a solution for that audience. Both client and designer can certainly get it wrong when we don’t listen close enough, run with a false preconception, or are just lazy and offer them exactly what we think they want.

Got Milk

An example of lazy, and my latest peeve are the ubiquitous “Got Milk?” rip-off campaigns. Just across the street at a Beauty Supply shop they have this fine advertising example:

There are similar billboards littered across the Wasatch front but this landscape flyer was inspirational. I ask for one last campaign to clean this up, maybe “Got An Original Idea?”

Designers are at fault when we give the client what they want instead of what they need. They used to say in school to throw out your first idea. That first idea is the one the client (and everyone else) also thought of. For a moment you share that magical connection in a tired, cliché design or concept. Amazingly the client may also pick the idea because they thought of it also! On two recent occasions I, or designers I know have wrestled with this. We had considered removing an inferior solution that we thought might be too gimmicky. I had even jokingly said “I bet they pick that one”. I will say the solution was not horrible in either case, but I believe their audience would have appreciated something a little more sophisticated or original, even if the client did not.

Better Brainstorming

Do we act the prima-donna and pout or do we accept this silent change in objective – do we trade inspiring the audience for stroking the client? Even worse is when we are the ones who suggested the “Got Milk?” in an attempt to flush out concepts or fill a pause in the conversation. But there are no bad ideas in brainstorming, right? Possibly, but there may be better ways to brainstorm than we are practicing now or we might need to better prepare ourselves for a brainstorming session. I liked the simple process presented at Business Balls including defining the objective, setting a time limit, and monitoring the follow up process. I would add the personal brainstorming outlined in this article is valuable preparation for a group brainstorming. Laziness is where both client and agency can run into problems. A client needs to value and understand why they hired us. The agency needs refine its processes and better prepare for the creative possibilities.

Creating JNIs in XCode

-

Friday, August 21st, 2009

Here at Rain we often argue over which language is the best.  Although I am primarily an ActionScript developer, my heart still belongs with Java.  Even though Java is a strict language and mistakenly has a bad rap for performance, I still enjoy it quite a bit because Sun has supported it so well, and it is now open-source which gives you access to all sorts of community libraries and samples.  However, the other day I came across something that simply did not exist in the community and the only way I would be able to accomplish the task was to write some native C code and use JNI to hook it up to Java.

Using XCode, I found that it was really easy to create a JNI, it just took a little effort and lots of googling.  To save some effort for the next go-round, I decided to write about how to create a JNI library in XCode.  Note that I am using version 3.1.2 of XCode.

Creating an XCode JNI project

First, go to File->New Project. Navigate down to the Java section and choose Java JNI Application. Then pick a name, I chose MyJNITest, and hit OK. You should have a fully configured project ready to go. You should see a src directory which contains a Java file and a C file, a resources directory which contains a Manifest used to build your jar, and some empty folders lib, bin, jars, and dist. First, go to Run->Console to open up your console, and then click on the “Build and Go” button. Voila! You should see a few trace statements called from the Java side of the application, as well as the C side of the application.

JNI_success

Now let’s dig into what is actually going on behind the scenes.

Understanding the Generated Code

Java side

First, open up the src directory and look at MyJNITest.java. Inside of the class definition, you will see a static block which tells the system to load the JNI named “MyJNITest”. This needs to happen before any calls are made to the JNI library so it makes sense why this line of code is executed before any other line. Underneath the constructor, you will see a function defined as:

native int native_method(String arg);

The “native” keyword defines a method that exists within your JNI Library C code. Finally, you have your main method which is used to create a new instance of MyJNITest, perform a call to the native_method defined in your C code, and display the result it receives from the native code.

C Code

If you click on the MyJNITestjnilib.c file, you will see two functions and an include statement. The include statement tells the C code to include a header file called “MyJNITest.h”. In most cases, you don’t even need to touch this header file because it is autogenerated automatically by XCode using the javah task. If you want to see what is autogenerated, open up Finder and go to MyJNITest/build/Release/Headers. If you double click on the .h file, you will see a method signature

JNIEXPORT jint JNICALL Java_MyJNITest_native_1method
(JNIEnv *, jobject, jstring);

which matches the method declaration in your .c file. XCode autogenerates this file whenever you build and run the application. It looks for any native defined functions in the .java file and creates a header definition that matches. Looking at this header file can be extremely important as you may want to copy the method declarations that are autogenerated and then paste them into your .c file to reduce the chance of miskeying the method signatures.

Now let’s look at the method signature in the header file (or the .c file, they are the same). The syntax for all JNI functions goes something like this:

JNIEXPORT return_type JNICALL Java_package_class_method(JNIEnv *env, jobject this, ...args)

In the case of your default application, the Java file is in the default package, so you won’t see a package in the JNI method name. Note that if you want to change the package for your JNI, it’s not as easy as you may think. I recommend this tutorial on changing your JNI package.

Adding to the default JNI Application

So, let’s be honest… printing out to the console is pretty lame. So, for our next step, we will create a native method to play a midi file through Core Audio. First, go to the .java file and add a new native method under the native_method declaration. I’ll do one called:

public native void playMidiFile(String path);

the path in this case is a URL to a Midi file on your machine. Note that I have made the method public so we can access it from other Java projects. Now, let’s build the application in order to re-generate the header file (make sure you have no errors, or the build will fail and your header file will not be updated). In the header file, you will see another method declaration that looks like this:

JNIEXPORT void JNICALL Java_MyJNITest_playMidiFile
(JNIEnv *, jobject, jstring);

Copy this declaration and paste it into the .c file underneath the native_method declaration. Now, let’s implement this method by doing the following:

JNIEXPORT void JNICALL Java_MyJNITest_playMidiFile(JNIEnv *env, jobject this, jstring midiURL)
{
// Need to convert jstring to a char* and then to a CFURLRef.
const char *chars = (*env)->GetStringUTFChars(env, midiURL, JNI_FALSE);
CFURLRef fileURL = CFURLCreateFromFileSystemRepresentation(NULL, (const UInt8 *)chars, strlen(chars), FALSE);

// Now convert the CFURLRef to a FSRef.
FSRef fileRef;
CFURLGetFSRef(fileURL, &fileRef);

MusicSequence sequence;
MusicPlayer player;

// Initialize the sequence and player.
NewMusicSequence(&sequence);
NewMusicPlayer(&player);

// Load the MIDI file into memory…
MusicSequenceLoadSMFWithFlags(sequence, &fileRef, kMusicSequenceLoadSMF_ChannelsToTracks);

// Set the sequence into the player.
MusicPlayerSetSequence(player, sequence);

// Tell the player to start playing the file.
MusicPlayerStart(player);
}

Now save and build the application and you should see a million errors in our .c file. This is because we haven’t imported the libraries we need to use. First, right-click on the MyJNITest project, choose “Add”, and then select “Add Existing Frameworks”. Then locate AudioToolbox.framework and choose “Add”. When the next dialog comes up, make sure that the JNILib Target is checked and the MyJNITest is not. Select “Add” again. Repeat the same process to add the CoreFoundation.framework as well.

Next, we need to tell our .c file to use these libraries. Underneath the line:

#include "MyJNITest.h"

enter the following lines:

#include <AudioToolbox/AudioToolbox.h>
#include <CoreFoundation/CoreFoundation.h>

finally, Save and Build and you should see no errors. However, our application will still not play our MIDI file unless we call the method from the Java end.

To do this, we will add some Java code to the main method underneath the generated code:

// Replace /Users/nateross/Desktop/trippygaia1.mid with a path to your midi file.
newjni.playMidiFile("/Users/nateross/Desktop/trippygaia1.mid");

try
{
// Tell Java to wait for 10 seconds so we can hear the MIDI.
Thread.sleep(10000);
}
catch (InterruptedException ex)
{
ex.printStackTrace();
}

this will tell our native c code to play a midi file for 10,000 milliseconds and then the application will finish, which stops the midi playback (ideally you would implement a stop method, but I won’t do that here). Now, build the application and run it and you should hear MIDI!

Adding the JNI library into another Java project

Now that we have built our JNI, it’s time to import it into another Java project. To do this, copy the .jar and .jnilib files that have been generated in MyJNITest/dist. Place the .jnilib in your Java global extensions directory (/Library/Java/Extensions) so it can be used by all Java applications running on your machine. Then, copy the .jar file into the library for your new project. Now, all you have to do is import the JNILib

import MyJNITest;

and then call it’s playMidiFile native method by doing this:

MyJNITest jniTest = new MyJNITest();
jniTest.playMidiFile("/Users/nateross/Desktop/trippygaia");

and you should be good to go!

Rain joins the ranks of international elite – man, we are good.

-

Thursday, August 20th, 2009

Society of Digital Agencies (SoDA) Expands Worldwide with New Digital Agencies

The Society of Digital Agencies (SoDA) today announces the global expansion of SoDA with new member agencies in Brazil, Russia, Australia, France and the UK. The current round of organization expansion wasn’t just limited to international firms, with many well-known U.S. digital agencies joining forces with SoDA also. In total SoDA has welcomed 18 new digital agencies maturing the organization with a representation of over 30 top agencies worldwide.

San Francisco, CA (PRWEB) August 19, 2009 — The Society of Digital Agencies (SoDA) today announces the global expansion of SoDA with new member agencies in Brazil, Russia, Australia, France and the UK. The current round of organization expansion wasn’t just limited to international firms, with many well-known U.S. digital agencies joining forces with SoDA as well. In total SoDA has welcomed 18 new digital agencies maturing the organization with a representation of over 30 top agencies worldwide.

Additional new members include: Bloc, Colossal Squid, Deep Focus, Evolution Bureau (EVB), GRAPE, Great Fridays, Gringo, IE, Mekanism, Obscura Digital, Profero, Rain, R/GA, SOAP Creative, Soleil Noir, Terralever, and Unit 9. The new members have been invited for their industry leadership and expertise to join an already elite group of SoDA members that includes: 360i, AgencyNet, Big Spaceship, Blitz, Domani Studios, Exopolis, Firstborn, GrupoW, IQ Interactive, Odopod, Schematic, Struck, WDDG and WhittmanHart.

SoDA has grown from its inception in 2006 when 13 agency executives got together in South Beach Miami for Mojitos and engaging conversation about the various aspects of the digital marketing business. SoDA members meet several times a year to discuss and propose initiatives for the business of digital marketing related to best practices, education, and advocacy. In addition to the annual members-only conference, SoDA hosts their signature “unConference” at key industry events each year, including Adobe’s MAX Conference, SXSW, and the OneShow.

While SoDA has had an international following since its inception, it began to see more and more international agencies attending industry events in the U.S., and in many cases solely to attend the SoDA unConferences. The result was an engaging dialog on the similarities and sometimes, great differences in the digital business overseas. These valuable conversations led to an acceleration of our membership expansion plans to bring a global perspective to our business.

About SoDA:
The Society of Digital Agencies is the voice of digital marketing professionals with a mission to advance the industry through best practices, education, and advocacy. SoDA is a non-profit industry organization with Adobe Systems as its founding sponsor.

For more information about SoDA visit www.societyofdigitalagencies.org or join the conversation at www.sodaspeaks.ning.com.

The Formic War Model for Interactive Application Development

-

Wednesday, August 12th, 2009

Before we get too far into this blog post, you’ll need to present your Geek Card™ at the door for verification purposes: if you’ve never read the sci-fi classic Ender’s Game series, it’ll be hard to keep up. In any case, this story is a favorite of mine, and as with many war stories, there’s a hint of software development wisdom in the plot that can be peppered across almost any important effort. After a recent re-read, here’s my war plan for galactic domination, interactive agency style.

Craft Your Team Carefully

One of the main characters in the series, Colonel (and later Minister) Graff is a ruthlessly efficient planner. You can question his motives and ethical underpinnings, but you can’t question his results. He masterminds the Battle School experience, hand-picks child warriors, and shepherds the experiences of each of those children in a very specific way to meet his end-game goals. Ender and Bean are even genetically engineered, more or less. Agencies, especially smaller groups, must craft perfect teams, and create and protect their culture.

Crafting a perfect team does not mean you always hire the best people for the job. It means you hire the Bean to complement the Ender. Too many alpha males, a prima donna, or a weak link in a team group can cause disaster. Hiring is difficult master, especially in organizations where teams live and die like the projects they complete. Not only do you need a great employee, but that person needs to perform well in any ad hoc team they end up working inside of.

Practice Formations

If you’re doing the same thing everyone else is, you’ll probably not get very far. One thing I love and hate about working at Rain is our tendency to take on impossible projects. You really have to innovate and approach problems differently to succeed. We’ve all heard about out-of-the-box thinking, but what percentage of the day do you spend in that mode?

It may also be important to realize that there are entirely different levels of thinking that you can apply to a project. In the novel, Ender uses one brilliant strategy after another to win his battle room episodes. He spurns tradition, focuses on the game’s win conditions, and outsmarts more experienced teams, even when crippled and outnumbered. That’s one level of innovative thinking. The super-level is the fact that he’s playing these games as part of a master plan to eradicate a hostile alien enemy. The over-arching strategy is brilliant in and of itself.

Software Development Requires the Thorough Victory

While Ender’s extreme victories are an ethical and philosophical topic that underlies the series, the principles really can be brought across to software development. Every software bug must be treated like the invading buggers. Every miscommunication to the client, every imperfection in the final delivery needs to be wiped out like a Bonzo Madrid or Stilson on the attack. Ender really is right about one thing—allowing the enemy a second chance to attack may be your last decision.

While crafting the perfect team is a part of this, developers and managers need to maintain a vigil against bleeding problems. A performance issue that goes ignored, a sidestep from your tried-and-true process will almost always end in disaster. From a technical standpoint, every shortcut or sloppy implementation is a withdrawal from the glory fund you plan to cash in at the end of the project. You won’t get a second chance with an important client anymore than you would mercy from the invading alien army.

Protect the Children from the Horrors of War

As a project manager, I try to take a Graff-like stance on protecting my team from the pressures surrounding the project. Client complaints and inter-office politics should never be a worry for the development team. If you can turn development into a game, your team will be much more happy and productive in the long run. Unless you happen to be in the xenocide business, I think your developers will be pleasantly surprised to know about the war they accidentally won after the project is complete.

Summary

Should you be unfortunate enough to find yourself in a Rain-sponsored Call of Duty 4 match, you’ll find me shelling and bunny-hopping under the callsign “Bean”. I do that for a number of reasons, but the main reason is to help me remember one important part of doing something well: trying harder isn’t enough. Too many people who aren’t doing well at something seem to try to apply positive mental attitude magic to their workday, hoping that somehow the extra effort will make a difference. One important part of the Ender story is his focused, analytical approach to getting better at a game. Folks, if you can programatically and purposefully get better at the game, you’ll end up winning the war.

Flex: Loading Remote Modules Throws the following: “Error: Unable to load resource module from…”

-

Friday, August 7th, 2009

Recently I was working on localizing a Flex project to handle multiple languages.  There are a bajilion examples on the web of ways to do this, and I found a few helpful ones.  The most helpful was this one.

Since the strings are changed by the client in a php admin console, the server was compiling these modules for each language I needed.  So, the Flex app had to load the resource modules at run time, AND they were coming from a different domain (S3 in our case).  I played with the security settings for loading a remote module as suggested by sites like this: And I was able to get my app to load the resource module from an external domain when I ran the Flex app from localhost, but when I tried to run the app locally, I kept getting this error:

“Error: Unable to load resource module from http://domainname.com/locales/en_US.swf”

I didn’t want to always debug my app from localhost, (that’s lame) so I needed a way around the Flex security restrictions.

I dug around a while looking for something to get my by, and I found people with the same error here and here. Along with one result in Russian, which I didn’t understand.  Generally the answer was to load things from localhost and that should solve your issue, but like I said didn’t want to run things from localhost.

Then a beam of light crested over the horizon, licking the hopeless feelings which had me on the verge of desisting. I asked coworker, and fellow Flexer Aaron Hardy what he recommended, and he pointed me to something he had done for loading style modules.  He said: “Try this. It might work” So I gave it a whirl, and BAM! It worked first try baby.  So here is what I had:

private function loadLocaleResource():void
{
var eventDispatcher:IEventDispatcher =
resourceManager.loadResourceModule("FULL_URL_TO_MODULE");
eventDispatcher.addEventListener(
ResourceEvent.COMPLETE, resourceCompleteHandleer);
}

and after getting the RemoteStyleMarshaller from Aaron, this is what I changed it to:

private var moduleLoader:RemoteStyleMarshaller;
//loads the module with the locale resources
private function loadLocaleResource():void
{
moduleLoader = new RemoteStyleMarshaller("FULL_URL_TO_MODULE", false);
moduleLoader.addEventListener(StyleEvent.COMPLETE, resourceCompleteHandleer);
moduleLoader.loadStyleDeclarations();
}

You can find a full explanation of what Aaron’s class does at his blog. Basically what his RemoteStyleMarshaller does is skirt around the security settings of Flash by loading in the bytes of the module.

Hopefully this post, along with Aaron’s class will help anyone running into the same issue.

NOTE:  After working through this issue with Aaron, he may post an update to his code on his site, since now it is apparent that his RemoteStyleMarshaller does more than just marshall style modules. Aaron is the hero of the day.