Hazel 3.3

October 20th, 2014 — 2:41pm

Hazel 3.3 is finally here. It has a bunch of neat additions that I think experienced users will find handy (in particular, all the things you can do with custom attributes now). I won’t list all the features here but check out the release notes if you want to learn more. Also, while 3.2.7 for the most part works fine on Yosemite, this version fixes all those pesky cosmetic issues, including the dark mode menubar icon which a lot of people seem to be fixated on. I think this is a great release as it ties up a bunch of loose ends and really opens Hazel up to workflows that weren’t able to be accomplished before without the aid of custom scripts. Speaking of which, Yosemite introduced JavaScript  alongside AppleScript as a way to automate apps, so JavaScript is now an option in Hazel as well. So for those of you who find AppleScript unpalatable, now you have an alternative.

While I will continue to do maintenance releases, my thinking at this point is that 3.3 will be the last of the version 3 series as I start shifting into thinking about version 4. I think version 3 has had a phenomenal run and I hope to make version 4 a worthwhile upgrade. It’ll be a while so for those fearing version 4 around the corner, you should’t worry. I’d be quite surprised if I get it out before the end of 2015.

Many thanks to all the testers who banged on 3.3 during its beta. Got a lot of great bug reports including some at the last minute which helped to make Hazel not explode (at least not yet – if yours does, blame it on tester #347).

Enjoy.

Comment » | Hazel, Noodlesoft, OS X, Software

My NSConference talk

October 14th, 2014 — 1:51pm

Just found out this weekend, somewhat belatedly, that my talk at NSConference 6, “Life Outside the Mac App Store”, is available on Vimeo. I don’t have the nerve to watch it myself but given recent events, you might find it interesting.

Comment » | Business, Conferences, Hazel, Noodlesoft, NSConference, OS X, Software

The Long and Winding Road

August 29th, 2014 — 4:13pm

There have been a bunch of posts lately about the feasibility of being an indie dev in the Apple world. Brent Simmons has been doing a good job of linking them all so I suggest checking out his blog.

I’ve been doing Hazel for over seven years and I think it’s fairly safe to say that I’ve been successful doing it. I’m making more money than I did employed at other companies and I’m much happier with my job.

But it wasn’t easy and it wasn’t overnight. A common sentiment I see among a lot of new devs is that if they aren’t living full-time off their app in the first year, it’s a failure. I know when starting out there is the hope that your app will be an immediate success. It’s fine to hope that; after all, its our dreams that drive us to succeed. But you shouldn’t expect it. I would say it took about three years before I could be comfortable living off of it full-time. Yes, I did quit my job to do Hazel full-time from the get-go but I was living off of substantial savings in the beginning. 

During that initial period where you are struggling to get your app recognized, you try all sorts of things. You keep coming up with that one thing that you think will cause your app to break through. Maybe it’s some killer feature. Or lowering the price. Or maybe some promotion. Those things may or may not help but in reality, there’s no panacea. Things did explode for me after my version 3 but there was no one thing that did it, but instead it was a culmination of all the hard work that went into the product up to that point.

One thing that I did learn is to have a healthy respect for randomness. Luck plays a huge role and you can’t always attribute one’s success or failure solely on their decisions and actions. I highly recommend reading Leonard Mlodinow’s book, The Drunkard’s Walk: How Randomness Rules Our Lives. I won’t recap the points therein but I consider it pretty mind-blowing as it debunks many notions of the correlation between success and performance. The point is that a good deal of your app’s success depends on luck. That doesn’t mean you sit back and just let fate decide; you still need to work to improve your chances. Just realize that there’s a big chunk you can’t control and that on some level, you need to be ok with that.

And speaking of sitting back and waiting, don’t rely on the App Store. Many devs I talk to seem to think that their job is done once they submit their app. I did a talk at NSConference earlier this year about the Mac App Store and I think a particular point from that is relevant here: Apple is not your marketer. I’m not the best person to speak about marketing and whole books can be written on the subject but, in short, you need to do your own. Looking at the top grossing apps in the Mac App Store, most of the third party apps there I first heard about about outside the App Store. Many of them were even big before the App Store and I’d say they’d still be successful without the App Store. Why? Because they marketed their product and built up the userbase themselves.

In the end, realize it’s a marathon and not a sprint. It’s a long, hard road and not everyone makes it. But whether the journey takes you to the promised land or not, value it for what it is. For me, I’ve learned a ton and am still having fun working on my app. Some day, I will stop developing it but until then, I am enjoying the ride.

Comment » | Business

Hazel in Books

June 27th, 2014 — 12:24pm

It’s nice to see Hazel in books. Even in digital form, the book format gives me more of a sense of permanency than say articles on some site. So, when I see Hazel mentioned in a book, I can’t help but think of Hazel as being a more permanent fixture in people’s computing lives. The most recent entry is Joe Kissel’s book “Take Control of Automating Your Mac” which has a little section talking about Hazel. While most readers of this blog are already familiar with Hazel and Mac automation in general, this book is a great introduction for the novice in your life who is ready to delve deeper into their Mac. It also contains coupons for many of the apps mentioned in the book.

And on the topic of Hazel in books, I’m way overdue in mentioning “Mac At Work” by David Sparks. This came out a while back but is a great intro to using your Mac in a work environment. Also, it’s available as a physical book, which is always useful for propping up an uneven couch leg (after you’ve read it, of course).

I’m still waiting for Hazel to be incorporated into some work of fiction. Too bad Stieg Larsson isn’t around anymore as he had a tendency to go into way too much detail about characters’ computer configurations.

Comment » | Books, Business, Hazel, Software

Understanding OS X Betas

June 3rd, 2014 — 12:41pm

With OS X Yosemite going public beta, I feel that it’s important that people understand what that entails. This happens almost every year but it seems worthy of a reminder.

Beta is the development phase where the product is not finished but ready to be tested. Operative term: NOT FINISHED. What does this mean to you?

  • There Will Be Bugs
  • Many apps will not work.
  • Things may be slow.
  • You may lose data.
  • Issues will be addressed on the developer’s schedule, not yours. Even until some time after Yosemite is released, apps may not be ready yet.

In short, if you use your machine for any type of important work, DO NOT INSTALL THE BETA. It’s not our, or Apple’s, fault or responsibility if you are unable to get anything done because you didn’t heed this advice. If you must install it, in the very least install it on another drive/partition or virtual machine (VMware, Parallels, etc.) so it doesn’t impact your main installation.

And remember the purpose of the beta is for the developer to test their product, not for you to get a sneak peek at what’s new. If you find a bug, report it to the developer. And I mean REPORT it. Do not instead:

  • Talk about the bug on some site that the developer will not see.
  • Review an app running on a beta OS or is in beta itself.
  • Tweet a complaint with few details (Twitter is horrible for bug reporting).
  • Stay quiet about it and assume the bug will be magically fixed.

If you really care about the bug getting fixed, then tell the developer directly, providing necessary details. If possible try and figure out if the bug is Apple’s or ours and email the appropriate party. In general, during the early beta stages, the bug is probably Apple’s. Near the end, it’s probably ours. We do want to fix things but not reporting them properly is counterproductive to that.

With everyone’s cooperation, hopefully the transition to Yosemite will be a smooth one. Ok, maybe not, but at least I tried.

1 comment » | Business, OS X, Software

Hardcoding Classes

May 15th, 2014 — 12:58pm

When referring to class object, you can refer to it directly by name. When creating an object, you can do:

[[Foo alloc] init]

There are cases though where you want it to be a bit more dynamic. Say you want a class method which creates an autoreleased instance. You might do something like:

+ (id)fooWithName:(NSString *)name
{
   return [[[Foo alloc] initWithName:name] autorelease];
}

The problem with this, of course, is that if you have a subclass, SubFoo, then +fooWithName: will return Foo objects, not SubFoo. To fix this, instead of hardcoding the class, refer to it dynamically:

+ (id)fooWithName:(NSString *)name
{
  return [[self alloc] initWithName:name] autorelease];
}

Since this is a class method, self refers to the class object. Now, no matter which subclass you are in, the proper type of instance will be created. And if you are calling class methods from other class methods in the same class:

+ (void)doBlah
{
  [self doBlech];
}

Hardcoding the class here would call that specific class’s version of the method, even in subclasses, which is usually undesirable.

If you are in an instance method, you can likewise do something like:

- (id)copyWithZone:(NSZone *)zone
{
    return [[[self class] alloc] initWithName:[self name]];
}

Now, this is all well and good. In general, it’s a good idea to to use [self class] instead of hardcoding the name. But let’s take this example:

bundle = [NSBundle bundleForClass:[self class]];

Seems ok. You want the bundle where this class comes from. Or do you? Suppose Foo is in a Framework and SubFoo is in an app using that framework. The above code will return a different bundle for SubFoo than it does for Foo. Depending on what you want to do with that bundle, that can be a bad thing. For instance, finding a nib. Unless it is expected that the subclasses provide their own nib, chances are, the nib you are looking for only exists in Foo’s bundle and the above will fail. The fix? Hardcode the class:

bundle = [NSBundle bundleForClass:[Foo class]]

Here’s an odd case that I ran into some time back. Suppose Foo implements a protocol that has an optional method -bingo. In SubFoo, you implement -bingo but you’re not sure if the superclass (Foo) implements -bingo itself as part of the protocol. If it does, we want to call super but if it doesn’t we can’t. The documentation is silent on the subject so we can’t rely on any particular behavior. How do we check it at run-time?

- (void)bingo
{
   ...
    if ([[[self class] superclass] instancesRespondToSelector:@selector(bingo)])
   {
       [super bingo];
   }
}

Besides the compiler warning that Foo may not implement -bingo, it looks like it works. If you are a SubFoo instance, it gets the Foo class and asks it if its instances can receive -bingo. Ah, but what happens when we have a subclass of SubFoo called ReallySubFoo. Let’s also say that Foo doesn’t implement -bingo. When the above code is called, from a ReallySubFoo instance, we get a SubFoo class which then gets asked if it responds to -bingo. It does because we implemented it in SubFoo. Problem is there is no super implementation of -bingo and we get a crash. Again, the fix is to hardcode the class:

- (void)bingo
{
  ...
   if ([Foo instancesRespondToSelector(bingo)])
   {
       [super bingo];
   }
}

In most cases, dynamically getting the class is the right thing to do but don’t do it indiscriminately. Take a moment to think about how it will play out in subclasses. You may be surprised.

Comment » | Cocoa, OS X, Programming

NSConference 6

March 26th, 2014 — 5:24pm

I should have posted about this before but since I already didn’t do that, I’m posting about it now after the fact. Last week I spoke at NSConference 6. I have to say it was an extremely well-run conference. Cheers to Scotty and his crew for putting together a great event. Being a speaker, I was more conscious of how things were run since there were more arrangements regarding travel and such but it was smooth sailing throughout. The staff at the venue were wonderfully attentive as well.

Had a great time. It was nice meeting people whom I might not see at conferences stateside. By the way, to those of you who followed me on Twitter after the conference: prepare to be disappointed as I hardly use it. But I do hope to see you all at future conferences.

This was my first time speaking at a conference. I think it went ok though I can think of a ton of things that didn’t go as planned but that’s mostly in my head (I think). I have to commend Scotty on making a bottle of scotch available on stage, which, as the audience observed, I was not shy about drinking. If there’s any interest, I may do a post on speaking at a conference for the first time.

The topic was “Life Outside the App Store” where I talked about my experiences with being solely outside the MAS. I tried to dispel any notions that apps are not viable outside it. After the talk, I was glad to hear from devs who were also doing their apps without the MAS. Much of the impetus of the talk was to get developers who were iffy about their app because of the MAS to actually realize their vision and know that their app can succeed, MAS or not. Hopefully there were a couple devs in the audience that took that lesson to heart.

In any case, for those that haven’t been, I highly recommend checking out NSConference next year. It’s definitely worth the trip across the pond for us Yanks. For you Europeans, well, you have no excuse since everything over there is like only a two hour drive away.

1 comment » | Conferences, NSConference

Hazel 3.2 with Mavericks tagging support

October 23rd, 2013 — 12:51pm

Apple just released Mavericks yesterday so I’ve released version 3.2 which specifically supports the new tagging feature. You can now create conditions based on a file’s tags and add/set tags via a new action. I’ve done a fairly faithful reproduction of Mavericks tagging UI so it should be a seamless experience.

Like Apple, I’m taking a more conservative approach to tag support as it’s still unclear how people are going to use the feature. One particular feature: the ability to create dynamic tags (i.e. not hardcoded into the rule) is definitely being considered. I’m sure many of you want this feature so here’s the deal: tell me how exactly you would use it. It’s not a question of “why” but of “how” so concrete examples will go a long way into determining how this feature will be fleshed out.

There are fixes in this release as well so even if you aren’t on Mavericks yet (though being free, what are you waiting for?), you should update. Many thanks to the people who beta tested. The beta version should update to the final release but if you run into any problems, contact me.

 

6 comments » | Hazel, Noodlesoft

ConnectionKit

July 10th, 2013 — 10:58am

In Hazel 3.1, I added the ability to upload files. Underneath the hood, I used ConnectionKit 2 to do the heavy lifting. It has an API similar to NSFileManager, making it very easy to add FTP, SFTP and WebDAV support without having to deal with the pesky details of those protocols. There were other factors on why I chose it, such as the fact that not only is it actively developed, but done so by people who use it in their own shipping commercial products. And it didn’t hurt that it’s maintained by my friends at Karelia.

If you have used this feature in Hazel, you would have encountered this interface:

ckopenpanel1.png

It should look a bit familiar. It’s a homegrown, from scratch, implementation of NSOpenPanel made to work on top of ConnectionKit. I felt it important to provide a familiar interface instead of coming up with something new in this case. I did a bit of work to make sure it operated as closely to NSOpenPanel as was reasonable. It has multiple view types (icon, list, and column) and most of the controls you’d expect.

Of course, browsing a filesystem via various network protocols is a different beast so some things had to be done differently. The main thing is that the UI is asynchronous from the network stuff so no beachballing while waiting for responses from the server. The UI should be responsive at all times, even allowing you to cancel the panel at any point. In the upper right, there’s a reload button that changes to a progress indicator to indicate activity and you will see a loading message when trying to fetch the contents of directories that haven’t been loaded yet.

Visually, the biggest difference is the header up top noting which server is being browsed. Also, the sidebar is missing. There aren’t many standard locations that can be put there and I felt that favorite URLs should be managed elsewhere as it didn’t seem likely that users would want to hop from server to server by clicking different entries in the sidebar. The one common directory that I could think of was the home directory and so instead, I gave that its own button (note that not all servers/protocols have such a concept of a home directory and it also depends on what URL you use to connect to the server so YMMV).

Another omission is the search field. Since there’s no notion of Spotlight in any of these protocols, doing an exhaustive search of the remote filesystem would be resource intensive and not very friendly to the servers involved. While I may consider adding it back in to search the current directory, you can get much of the same effect by just typing out the name of the file. Just as in NSOpenPanel, it will end up selecting the entry starting with those characters. I also dropped the Arrange button and the Coverflow view, mainly because I didn’t think people actually used those things. Especially for Coverflow, it wouldn’t be particularly useful since we can’t get file previews without downloading the whole files themselves.

But besides all of that, I think you’ll find it to be a pretty decent facsimile of NSOpenPanel. You might be surprised by how much of NSOpenPanel’s behavior is replicated here, including some features many people don’t know that NSOpenPanel has.

And the resemblance is more than skin deep. CK2OpenPanel (the name of the NSOpenPanel implementation) has a nearly identical API to that of NSOpenPanel. It’s a mostly drop-in replacement for NSOpenPanel so programming to its API should be just as familiar. Why would you care? Well, you should care because I’ve contributed the code for CK2OpenPanel to be included in ConnectionKit. You can see all the code, warts and all. Play around with it. Use it in your own projects. Print it out and wallpaper your home with it. I felt it was the least I could do for all the work that’s been done on the backend. Also, I thought it would be nice if people adopted it so that there was a standard UI for this type of thing.

You can find everything on the ConnectionKit GitHub page. In particular, you want to check out the v2.x-beta branch. Note that there are separate targets/frameworks in the project for the back end (ConnectionKit) and front end (ConnectionKitUI), with the latter dependent on the former. Make sure to check out the README as it should answer a lot of your questions. And if you are interested in contributing to ConnectionKit, please do as there are a bunch of things that need work. S3 support would be nice, for instance.

Last but not least, a big thanks to Mike Abdullah at Karelia for working with me to provide the backend support for this. Rest assured that he will be receiving beers from me at the next conference we both attend.

Enjoy.

Comment » | Cocoa, Downloads, Hazel, OS X, Programming, Software, User Interface

Hazel 3.1 is here

June 19th, 2013 — 3:40pm

Fresh from the Noodlesoft Danger Labs is Hazel 3.1 with a bunch of spiffy new things. The two main features this time around are file uploading and matching against file contents. If you don’t use Hazel, maybe these sound a bit abstract to you but for people that use it, it fills a couple big holes in their workflows.

But instead of elaborating on these myself, I’ve been fortunate to have a couple users do the work for me. Demonstrating use of the new file upload facility, Sid O’Neill shows his workflow for resizing and uploading images to his server

Next up is David Sparks (MacSparky and MacPowerUsers Podcast) showing how to match and extract dates out of your files and use them for renaming. Includes a great video so definitely check it out.

Of course, there are a bunch of other things in this release. You can find the full list here.

The response from customers have been great. I’ve gotten a lot of wonderful emails from people so far which has solidified my dedication to the product even more. As mentioned in my last post, I will be looking into Mavericks support, with a particular interest in its tagging feature, in a future release.

Also, in regards to the new upload feature, watch this space in the coming weeks as I’ll have something for you developers.

 

2 comments » | Business, Downloads, Hazel, Noodlesoft, Software

Back to top