Paid Placement

July 2nd, 2006

I hadn’t heard of PayPerPost before reading Robert Scoble’s stance on it earlier today. The gist is that a blog author signs up with the service and then browses for “topics” of interest. These are topics that were hand chosen by paying advertisers. The author write an article on the subject and if PayPerPost approves it, she publishes it and gets paid.

In other words, it’s a mechanism for totally freaking selling out.

This would be a very short post – even a mere link – if there wasn’t some good debate on the table. My gut thumbs-down reaction made me feel right at home on Robert’s and Marshall Kirkpatrick’s pages, but not everybody agrees that PayPerPost is evil.

Elliott Back’s take on the matter is that as long as the articles are no different from what the author would have written anyway, there is no ethical dilemma:

If you use PayPerPost to supplement your blogging income by writing stories for it that you would have written anyway, or that are true to your actual opinions, disclosure is not needed, because you are not blogging differently because of the money.

This sounds like great marketing copy for PayPerPost! Come on, you were going to write it anyway. We’re just here to pay you for what you’re already doing! Elliott goes on to make the powerful suggestion that this service is merely opening up to average bloggers a mutual back-scratching arrangement that magazines and other media have enjoyed for decades:

Big blogs–like big magazines–probably sit closely with the subjects they write on in a behind the scenes agreement. Now, small blogs can automatically tap into that revenue flow.

Oh my, I’m being swayed! This is starting to sound like a people’s blogging revolution. Come to think of it, I’m not getting any richer writing this blog. The products I write about and the pages I link to are like gold-laden earth just begging to be mined. Am I foolish to not take advantage of these bounties? Apparently there are scads of business people waiting with dollars in clenched fists to reward me for things I’m already saying. Heck, maybe I could have gotten paid for this very post. I wonder, does PayPerPost list itself on the roster of payers?

The Revolution Will Not Be Subsidized

Before I get carried away, let me get back to my roots. I’ll take a few deep breaths, do some yoga or something and ground myself back in my idealistic, California-raised, corporate-fearing liberal view of the world. Elliott’s two major points are that blog content does not have to be compromised, and that bloggers will receive “what is due” by this age-old system of reciprocity in marketing. His interpretation of reality is very convenient, and believe me, I wish it were true. But it’s one unlikely version of reality that rests tenuously amidst a universe of competing, more realistic scenarios.

Let’s assume that his first contention is true. Bloggers will just write whatever they were already planning to write, but get paid for it. What has to transpire for this to be true even for one post, let alone every post the blogger makes in perpetuity?

First, the author has to resist searching PayPerPost for topic ideas. In order to remain true to herself, she must come up with an interesting idea in isolation of the knowledge that there are lucrative keywords and links out there. Next, she will write and edit a complete entry. At this point she must “declare it complete” and vow not to edit it regardless of what bounties may exist. She searches PayPerPost for matching terms. If there’s no match: ah well, it was a nice try but this article must be published with no compensation. If there are close-but-no-cigar matches, she must ignore them, because modifying her article now would be a compromise for money, something that happens all the time – but not on most of our blogs.

On the other hand, let’s assume there is a matching keyword, link, whatever. Hallelujah! She wrote about Ambrosia Software’s awesome Easy Envelopes Dashboard widget and, what do you know, Ambrosia is prepared to pay fifteen dollars for the link. That’s real money! The dream lives. PayPerPost even shows that the advertiser in this case is willing to pay for “negative reviews.” That’s great, because although she thinks Easy Envelopes is “the bomb,” she is not a huge fan of Dashboard itself, so there are negative aspects to the article. She is confident they will accept her finely crafted article as-is, so she submits the piece and waits.

When PayPerPost reviews the article, they are mostly satisfied. There are just a few “minor problems.” The product is actually called “EasyEnvelopes,” with no space. The advertiser doesn’t want the “google-ability” of the name to be lost, so they are requesting that all of the articles properly spell the name of the product. This seems like a reasonable request, and that’s just the problem. “Reasonable” requests break the rule of true independence. The blogger may evaluate the request and convince herself that it’s still a post she would have written. But is it? What if the advertiser objects to profanity in the piece? Our blogger used to think that Easy Envelopes was the “fucking best Dashboard widget” she’d ever seen. Now it’s just the “darnedest tootinest best Dashboard widget.” But oh, those tantalizing dollars …

It’s easy to go on imagining nightmares associated with this high-minded stance. What about minor edits? Typo fixes, etc. Blogging is all about constant updates, as I see by the constant revival of blog entries as “unread” in NetNewsWire. Does PayPerPost’s requirement that an approved post stay live for 30 days mean that typos and minor grammatical reworking must be “re-approved”?

All of this might be worthy of our personal ethical negotiation if Elliott’s other point didn’t also collapse under scrutiny. It’s so tempting to believe that yes, our writing and links are valuable, and we should be getting compensated for them. After all, if PayPerPost is prepared to pay us money just for links in some cases, then who are we to refuse? This is probably a good time to remember some classic aphorisms. There’s no such thing as a free lunch. You get what you pay for. The early bird gets the worm, etc. Let’s apply a little logic here.

Who is going to pay for posts about their products? You can bet it won’t be Mint, or WordPress or any other product that people really love. Why? Because real bloggers will already be linking the hell out of these products, without financial prodding. Why would vendors of successful products pay for blog marketing? One more sappy aphorism: why buy the cow when you can get the milk for free?

The fact is, links you see on PayPerPost are going to be for crappy products that nobody really wants to talk about. Some wormy marketing person is going to suggest that “the blogosphere” is a powerful marketing weapon that they need to start utilizing. Instead of working on building a great product and becoming respected by the community, they will try the easy, paid way. What this means is that unless you’re a loser who likes to blog about sucky products (maybe there’s something in this for me, after all), you’ll never end up noticing that the topics you blog about just “happening to be” among the paid topics of the service.

Let’s scour this completely. Assume there are good products and services on that list. For some reason they haven’t gotten much buzz on the internet, but you completely agree that they are worth publicizing. If it makes you a few bucks in the process, why not? The problem is that if PayPerPost succeeds on a large scale, nobody but the big time bloggers will ever make a few bucks on anything. There’s only so much money to go around. So if your Easy Envelopes post makes you $15 now, it’s only because the company is desperate for publicity, and is willing to pay a high “price per placement.” When 50,000 other unknown bloggers catch on to the cash rush, your sold-out content will be worth the same few pennies as your Google Ads. And your blog will be soulless.

At least users can see the ugly Google Ads on your blog today.

Taking Stock

The best thing to me about Robert’s and Elliott’s articles is the debate it sparked in my own mind, leading to this entry and careful consideration of my citing practices. I obviously have strong feelings about this issue, but I have not had a clear policy “on paper” or even in my head before now. I have in fact received a few freebies from time to time – mostly software or books that are highly pertinent to Mac development. And they’re mostly good books, too. The fact that I haven’t blogged about them speaks more to my laziness than to my taking some ethical high-ground. But if I had blogged about them (and I still may), then I almost certainly would not have mentioned the fact that they were free gifts. I just wasn’t thinking on that level. I didn’t consider myself as enough of a “media outlet” to warrant such high-falutin disclaimers. But as Robert recognizes in his piece, there is too much room for personal-discomfort when full disclosure is not made.

In marking the occasion of this explicit policy shift, I wondered if I might have some past offenses to make amends for. Reviewing my post history, I think the areas where I have served as a promotional shill fall into three categories:

  1. DreamHost. They are my hosting provider and I generally like them a lot. If you click my link to them, sign up, and like them too, then I get a nice chunk of change. I have learned through experience that their uptime is not as good as I’d hoped, but I still feel they are an excellent value.
  2. Amazon referrals. When I point at a book from my blog, I include referral tags that allow Amazon to compensate me if you ultimately make a purchase. I don’t disclaim this because I’m not advocating Amazon per se – I’m advocating a book and using Amazon as a “de facto reference” for that book. I have not, to this date, promoted or linked to an Amazon book that was “comped” from the publisher or author.
  3. Products & Services. I often point at software products or services that I feel are meaningful to the Mac or larger computing communities. I have not to this point written about or linked to products or services that were comped to me. On the contrary, I seem to have a habit of writing more in-depth about products that I would never recommend, let alone buy. Just a negative guy, I guess!

Red Sweater Disclosure Policy

Going forward, I’m planning to abide by a specific, simple policy that will take any mystery out of the situation:

Give me free stuff. If I write about it, I’ll disclose the gift. If there’s no disclosure then I paid for the product, it was free, or a neutral third party gifted it to me.

This goes for both Red Sweater Blog and the tightly-affiliated Red Sweater Links.

Update July 3: It occurred to me that the policy as stated above leaves a lot of grey area, particular with regard to “freebies” I’ve received out of friendship or in exchange for some service. For instance, it’s not uncommon for one developer to send another developer a free license code when some mailing list response was particularly life-saving. I think for the record that I shall not consider these kinds of “reward” gifts as necessarily requiring disclosure. This is in contrast to a situation where the marketing department at some company sees that I wrote about one of their competitors and then, in a clear effort to gain visibility, offers to send me a free copy of theirs. In summary, the policy requires some discretion on my part. I will never try to fool you by pumping up a product I don’t truly love.

I like free stuff. Please, send me more! But do so knowing that I’ll only write about it or link to it if I think it, or some positive or negative impression I get from it, is important to my readers. Sending me a freebie “puts it on my Radar,” but by no means does it ensure publication or positive review.

This policy decision is a no-brainer for me. It feels like we’re on the brink, with the advent of sites like PayPerPost, of an era when such disclosure policies need to be more clearly stated. My thanks to Robert for bringing it to light. The personal blogging scene today feels somewhat like the internet felt back in 1994 or so. There were rumblings about an impending “business boom,” but many people held fast to the assumption that it would remain a non-commercial safe haven. Ads on the internet, you’ve got to be joking! It’s forbidden by USENET policy!

Paid placement on a personal blog? Not on this one. But you better start watching what you read and where you click a bit more skeptically.

Note: All products linked to in this post (with the exception of DreamHost) are counter-examples of paid placement. I link to them either because they are the focus of my scrutiny (PayPerPost) or because they are products that I love and for which I am receiving no compensation for mentioning.

Bloggiversary

June 26th, 2006

D’oh! My blog turned one year old this past Saturday, and I was so thoughtless I didn’t even send it a card.

Happy Birthday, Red Sweater Blog!

It’s been an interesting year. A place to speak one’s mind is a powerful tool, and I’m grateful to the internet for that. The 150 entries I’ve made during this first year must add up to at least 300 hours of time dedicated to researching, writing, editing, and responding to comments. It boggles the mind to consider it all in one retrospective lump, but I cry not over those well-spent hours.

I’ve met a lot of really interesting people through the endeavor, and the process of sharing technical facts and opinions helps to stimulate the ongoing development of my own thinking and working process.

All in all, I think it’s a win-win for writer and readers alike. Thanks for spending some of your valuable time here on my little piece of the internet.

Minimal Scriptability

June 26th, 2006

The Cocoa Scripting layer makes it extremely easy to expose manipulation of your application’s model to users via AppleScript. That said, for most developers the learning curve associated with this can be far from “easy.” The psychological burden of tackling scripting support seems to prevent many developers, even those within Apple, from providing even the barest of scripting support for their applications.

The promise of Cocoa Scripting is essentially that some robust AppleEvent parsing code in the Cocoa frameworks will translate the “yucky, raw events” into method dispatches that “just work” with your application’s attribute-based data model. Then, a different chunk of robust code will take the Cocoa objects that your application works with and automatically translate them into suitable AppleScript representations. For instance if you expose an NSString attribute from your application’s data model, the text contents are automatically converted to an AppleScript-native format suitable to the scripter’s needs. Similar bridging is done for objects as complex as windows and documents.

The power of this adaptive layer can be witnessed by taking an otherwise unscriptable application and “throwing the switch” that gives Cocoa permission to take over scripting. If you’ve got an unscriptable Cocoa-based application, why not use this as an opportunity to get your feet wet? In fact, Apple ships a good case study for this in Preview, so I’ll use that as a guinea pig while you follow along with whatever app you like. (thanks to John Gruber for pointing out this shortcoming and inspiring this article). Take the following script and paste it into Script Editor:

tell application "Preview"
	get name of document 1
end tell

When you run the script, even if you can see an open document in Preview, you’ll be met with a rather rude reply: “Can’t get name of document 1.” Please! You’re telling me you can’t even offer me that tiny glimpse into the application’s personal details? Unfortunately Apple didn’t “flip the switch” on Preview, so none of the easy freebies from Cocoa Scripting are exposed through it.

So let’s flip the switch for them. Let’s pretend we work for Apple in the Preview group and our manager has finally given us the go ahead to investigate AppleScript support for Preview. Heck, let’s assume we’re the new intern, it’s day one, and we haven’t even been given source code access yet!

By navigating into the Preview.app package and opening the Info.plist document in Property List Editor (or an editor of your choice), we can add the requisite flag that instructs Cocoa Scripting to take over:

Now quit and relaunch both Preview and the Script Editor. Paste your example “name of document 1” script again and observe that the frontmost document’s name is returned!

Now you may be thinking, “Who cares? It’s just the title of the document, that’s not very useful.” But that’s not for you to decide! Let the script author decide. They’re the ones who have to use your program to get something done. The big deal here is that we turned an unscriptable application into a “scriptable beta” with the addition of a single Info.plist attribute. We didn’t even have to add a scripting dictionary!

Lest you think that the standard Cocoa Scripting functionality is only the name of the document, I will share a slightly more complex (albeit still contrived) example. Let’s suppose we have a hundred documents to review by hand with Preview. Based on some human-observable trait we want to open 25% of those documents later in Safari for printing or whatever. One option would be to go through and save a copy of each such document to a separate directory. When we’re done with the grueling day of work, we’ll drag the contents of that separate directory to Safari (or whatever application).

Using AppleScript and the “newly scriptable” Preview application, we can simplify this workflow by making the assumption that “any document with a tiny window” should be opened in Safari. Now as we go through the open documents one by one, we simply drag-resize the window to be less than 400 pixels wide. Later on, we run the following script, which makes a list of all such windows and opens the corresponding documents in Safari:

All of this for free! We make a kick-ass intern! And all on our first day with no source code.

By no means am I suggesting that developers should just flip the switch and ship. It’s very frustrating to see unscriptable apps, but even worse when a product claims scriptability but for all practical purposes is not. The point of this entry is merely to point out that Cocoa gives us a huge head start towards a decent scripting implementation, and to choose not to take advantage of that is cruel and unusual punishment to your users.

Just think how cool Preview will be when we add a dictionary that describes its document object model’s custom attributes.

Summer Xcode Tips

June 22nd, 2006

It’s summer! The sun is out and the sky is (leans right to peek outside), well, sort of greyish. While the world celebrates the changing seasons, we’re all leaning over our keyboards and squinting into the screen, working on our LCD tans. All this warm weather puts me in the mood for Xcode tips! I’ve been saving up a few “gotta share” revelations. Are these tips no-brainers? Maybe for some of you. But it took me a while to “get it” and I’m hoping some of you will also giggle with glee when you learn out about them.

Hint #1: Double-Click to Open in External Editor

As my projects become more complex, they inevitably become the gathering place for an assortment of file types that support the production of and testing of the final product. Most of these files are source files, and Xcode is good at editing them. But others, such as scripting definitions and carbon resource files, are best left to external editors. Unfortunately, there are a number of file types that Xcode thinks it’s a good editor for, when it really isn’t. Even some source files might be better edited by external applications, depending on the particular goal.

I’ve spent a lot of time right-clicking such files and selecting “Open in Finder” from the contextual menu. This has the desired effect of opening the file in whatever application you’ve specified as the file’s owner via the Finder. That’s not a bad solution, but it’s slightly annoying, and not nearly as streamlined as double-clicking. But when I double-click a typical file that Xcode claims understanding of, it opens in a separate Xcode editor window. Ugh! I wanted to open in the external application!

From the “File Info” window in Xcode, you can tell Xcode what type you want it to consider the file to be. This is handy for things like making it apply Objective-C++ rules to a “.m” file, but the list of file types it’s prepared to acknowledge is really vast. As I set out to convince Xcode to open my file with another app, I thought I surely needed to teach it more specifically what kind of file it is. It’s not a text file, it’s an XML text file. No dice. Xcode “handles” that, too.

The answer to this problem is surprisingly simple, but it requires counter-intuitive (to me) reasoning. Instead of being more specific about the file’s type, you have to be less specific. Among the myriad choices is an item called simply “file.” When a file’s type is “file,” what do you know, it opens up with the Finder when you double-click it.

Note, if Xcode has already “laid claim” to being editor of your file, it probably has an open file reference to it somewhere. It will not give up its role as editor until you close the file. You can do this by choose “Close File [Blah]” from the File menu while the file is focused, or by pressing the shortcut Cmd-Shift-W.

Hint #2: Eliminate Build Configuration Strain

Since Apple announced the transition to Intel, quite frankly the hardest development aspect for me has been keeping all the darned build settings straight. If you are willing to target 10.4 and later, things are pretty straight-forward. But if you live in the real world and need to continue supporting older release of Mac OS X, things get trickier. To support earlier than 10.3.9 and Intel in a single universal binary, you have to use separate compilers at a minimum, and probably separate SDKs as well.

If you’ve had to do this for one or more of your projects, you probably got used to locating, copying and pasting the build settings from one project to another. Yuck! Not only is this prone to error, but it is “stupid work” that takes up a lot of time and energy. Apple’s answer to this problem is the “.xcconfig” file, which allows you to specify a number of baselines build settings outside the scope of a build configuration.

These “.xcconfig” files are simple text files containing variable names and their desired values. For instance, here are the contents of a baseline file I use for “Universal builds that need to run on 10.2”:

ARCHS = ppc i386
SDKROOT_i386 = /Developer/SDKs/MacOSX10.4u.sdk
SDKROOT_ppc = /Developer/SDKs/MacOSX10.3.9.sdk
GCC_VERSION_i386 = 4.0
GCC_VERSION_ppc = 3.3
MACOSX_DEPLOYMENT_TARGET = 10.2

I call this file “Universal 10.2+” and keep it in a common location accessible to all of my projects. Now when a particular build configuration in any project needs to “inherit” these settings, I use the “based on” feature of Xcode’s build configuration system. You simply drag a reference to the “.xcconfig” file to your project, whereupon it becomes available in the appropriate popup menu:

Notice that in this case I’ve chosen to name the “inheriting” build configuration “Release 10.2+”. There is a method to this madness: by adopting a naming convention for build configurations that match the system requirements, I can easily ensure that libraries from dependent projects get built under the same settings. By using a consistent naming scheme, and pointing all such build configurations at the same “based on” configuration file, I can rest assured that changing the settings in one place will percolate out to all the affected targets.

Also notice that “Architectures” is not even set by the project (it would be bold if it were). The setting of “ppc intel” comes from the configuration file. The project yields responsibility for defining what “Universal” means. So if Apple adds the rumored support for the Z-80 processor, I’ll only have to change the settings in my “.xcconfig” file.

I’ve barely scratched the surfaces of these files’ power. On top of the “based on” notion from Xcode, the files themselves can also explicitly include other files to stack a great deal of common build-setting definition into your process before the project-specified configurations are even reached.

Hint #3: Install a Directory of Changing Supporting Files

Let’s say you’ve written an application with an awesome templating system. You allow your customers to write their own templates and use them as the basis for new documents. To get your users off to a good start, you include a bunch of built-in templates in your app. In fact, your system is so good that there are literally hundreds of built-in templates and you’re adding more in every release.

All you want Xcode to do is put your directory full of “Built-In Templates” into the resulting application’s “Resources” directory. If you’re like me the first thing you think of doing is simply adding the directory of templates to Xcode, and then dragging the resulting folder icon to the “Install Bundle Resource” build phase. After all, that’s what this standard build phase is for, right? Yes. But the standard build phase does something annoying. Instead of copying the directory to the resources folder, it copies each individual file over to the root of the resources directory. This makes for a very cluttered resources directory.

The good news is that a simple “Copy Files” build phase of our own can get the job the proper way. Just add a custom build phase to your target with target directory “Resources”, and copy your folder reference to that. For some reason the built-in resources phase is “smarter” than it perhaps should be.

Note: When you add your directory filled with templates to the Xcode project, make sure to check the box that requests “folder references” be created. This is how you tell Xcode to take the folder as it is at any moment. Instead of adding the contents of the folder to the project as a group, it will dynamically refer to the contents of the folder as they are at any time. Now when you add new templates to the folder, they’re automatically copied into the app’s resource folder when you next build.