Crazy me

Learned something this morning from Wikipedia:

A truncated version of the "Crazy Ones" text has been reused in Mac OS X Leopard on the high-resolution icon for TextEdit.

Sure enough, here's the icon:

TextEdit icon

I came across this in a roundabout way. In comments on my earlier post about YoruFukurou (the desktop Twitter client I use), someone asked if it provides a way to find and follow people. I tested by searching for the name "Mike Morton", which turned up mentions of Mike's blog posts about WWDC. On Day 1 he writes:

Everyone got a nice "WWDC 11" sweatshirt. I’m giving mine to my friend Andy, who’s crazy enough that he flew all the way from New York to San Francisco despite having no ticket for the conference. (Andy was not crazy enough to wake up and join us for hours in line, though.)

I'm the crazy Andy. I wanted to reply with something about "Here's to the crazy ones…" and wanted to get the quote right. Hence the Wikipedia discovery.

Thanks, Mike, for the great sweatshirt!

MS online store saves password in clear text

I just bought Office for Mac from microsoft.com. To do so, I created an account. A bit later I realized I'd forgotten my password, so I clicked the necessary links to have it sent to me.

I expected to get either a random temporary password or a one-shot URL I could use to reset my password. Either of these approaches is standard practice. Instead I got an email containing my original password, which means Microsoft is remembering it in clear text.

To see how much more they're remembering I started a new purchase. I saw they had saved my credit card info and billing address. I don't know if the purchase would have gone through if I'd chosen to continue. For all I know they would have prompted me for my password before completing the transaction. Still, that password was exposed to employees of Microsoft and to anyone who hacks into their systems.

I would hope Microsoft does not save full credit card numbers. That would be monumentally stupid. On the other hand it appears Sony might have been that stupid, so who knows what to assume about big companies who should know better.

I deleted the credit card from my Microsoft profile. There is a separate option to delete my address, which I also did. I got to my account settings by following this link: http://buy.officeformac.com/store/msmacus/DisplayHelpPage. Microsoft included this link three times — once misspelled — in the confirmation email for my purchase. If I didn't have that email handy, it's not obvious to me how I would have gotten to my account info by navigating Microsoft's web site. But I admit I didn't study the web site very hard.

. . .

UPDATE: I realized I should change my password. I'm keeping the email they sent me so I can show anybody who asks. No point keeping my real password around in clear text after complaining that's a bad idea.

Here is that email. It begins, "Thank you for contacting us on Microsoft Office for Mac US Store." What kind of sentence is that? Between this sentence, the misspelled URL in the confirmation email, and the officeformac.com domain name, I wondered for a moment if I'd carelessly made my purchase through a hacker site. But no, microsoft.com links to officeformac.com.

Clear text password

keyPathsForValuesAffectingValueForKey: — doing it wrong

I just noticed this in the docs for the keyPathsForValuesAffectingValueForKey: method:

Your override should typically invoke super and return a set that includes any members in the set that result from doing that (so as not to interfere with overrides of this method in superclasses).

I've been doing it wrong. I've been doing it like this:

+ (NSSet *)keyPathsForValuesAffectingValueForKey:(NSString *)key
{
    if ([key isEqualToString:@"fullName"])
    {
        return [NSSet setWithObjects:@"firstName",
                                     @"lastName",
                                     nil];
    }
    else
    {
        return [super keyPathsForValuesAffectingValueForKey:key];
    }
}

It didn't occur to me that a superclass might also want to specify key paths that affect the fullName key. A correct implementation would have been:

+ (NSSet *)keyPathsForValuesAffectingValueForKey:(NSString *)key
{
    NSSet *keyPaths = [super keyPathsForValuesAffectingValueForKey:key];
    NSArray *moreKeyPaths = nil;
 
    if ([key isEqualToString:@"fullName"])
    {
        moreKeyPaths = [NSArray arrayWithObjects:@"firstName",
                                                 @"lastName",
                                                 nil];
    }
 
    if (moreKeyPaths)
    {
        keyPaths = [keyPaths setByAddingObjectsFromArray:moreKeyPaths];
    }
 
    return keyPaths;
}

Serves me right for not reading the docs carefully. For pride's sake I was hoping this was a common mistake, but from a Google search it seems almost everybody else in the world does it right.

I must have been thinking of observeValueForKeyPath:ofObject:change:context:, where typically you check the given key path against various possible values and fall through to super if it doesn't match any of them.

In any case, I more often use the keyPathsForValuesAffecting<Key> approach anyway.

[UPDATE: Thanks to Christiaan Hofman for pointing out that my description of observeValueForKeyPath:ofObject:change:context: is also Doing It Wrong. So never mind that and pretend I wrote this instead.]

Being a CocoaHeads organizer

Last Tuesday, during the week of WWDC, there was a breakfast in San Francisco for CocoaHeads organizers, organized by Mark Aufflick, who runs the Sydney chapter, and hosted by Pivotal Labs. I got to meet Mark Dalrymple, the more visible cofounder of CocoaHeads ("AgentM" being the other). I got to hang with my friend Mike Morton, who organizes the NH/VT-ish CocoaHeads.

If we do this again next year (and I hope we do), I'll try to be more social. I didn't talk to as many people as I should have. I did meet the Boulder organizer and the former Taipei organizer. And I told a fellow from Sweden the one Swedish sentence I know ("Your wife is beautiful"). But there were lots of people I did not talk to. For example, I recognized but did not approach Graham Lee. It was a shame I didn't grab that opportunity to pick everybody's brains.

Among the people I did talk to, I noticed we all wondered the same things about each other:

  1. How big is your group?
  2. Is your group mostly about iOS?
  3. How do you get speakers?

Regarding question 1: I think a typical CocoaHeads-NYC meeting has about 15-18 attendees now that Google is hosting us. Maybe more. Ed Marczak, editor at MacTech magazine, is our sponsor. (On a related note, I want to thank Tekserve for kindly hosting us for a few years before we moved to Google.)

Regarding question 2: although many of us are iOS developers, our group has managed to stay focused on Cocoa. A lot of what we talk about translates to iOS, but I don't think we ever had an iOS-specific talk until last month. I haven't given much conscious thought to this, except to acknowledge that there are other meetups in New York that are iOS-specific, so there's no point in us being another one. And maybe the fact that I am not yet developing on iOS myself is a factor.

Regarding question 3: To me this is the most interesting question. I should probably be more systematic about getting speakers, but basically I wing it month to month. I've been lucky enough to get unsolicited volunteers along with friends who were willing to come up with something when I didn't have a speaker. On rare occasions I'll ask someone if they wouldn't mind presenting on a particular topic. And a few times I've either made myself the featured speaker or given a short talk in addition to a featured speaker's short talk.

Recently for a job I'm doing I learned about two new topics: Cocoa scripting and the keychain API. As I was taking notes, I realized I was itching to explain what I was learning to a group — partly just to share, partly to crystallize my own understanding, and partly so people can correct me where I misunderstand. When I get a chance, I'll prepare Keynote slides on these topics and hold them in reserve for when I need them.

Honestly? I would be perfectly happy to be the default speaker (or secondary speaker) at any given CocoaHeads meeting. But I want people to, you know, keep coming to our meetings, and it's safe to say they won't do that if CocoaHeads-NYC becomes The Andy Show. And besides, I learn such great stuff from other people. So I'll have to think about how to keep getting volunteers.

If you're a Cocoa developer in New York and there's something you'd like to present, let me know. It doesn't have to be fancy or super-advanced. It doesn't have to be a lecture — it could be a demo of an interesting project you're working on.

If you're a fellow CocoaHeads organizer, I'd love to know your approach to getting speakers. Do you ask what topics your members want to hear about? Do you have regular or semi-regular speakers? How far ahead do you schedule? Any other tips on running the group would be welcome too.