Sunday, December 22, 2013
See the BFGNotificationBar repository on GitHub for more information
Monday, December 16, 2013
One thing that's been a pain is not having clean, readable documentation for Xcode 5's new
XCTest framework. (Or, at least, none that I could find.) So, I broke out
doxygen and generated a set. It's not the prettiest documentation, but it's functional. And can be nicely imported into Dash.
Download the .docset here (.tar.bz2)
Monday, September 23, 2013
I ran across this oddity today that rears its head in
UITextViews under iOS 7 (didn't occur under iOS 6). Essentially, the view allows text to be written past the bottom of the
UITextView's frame causing text to be hidden by a keyboard and/or keyboard accessory. This problem doesn't manifest if you're typing and the text word wraps; it only appears after tapping Return (whether after text or by itself). The following snippet (which goes in your
UITextViewDelegate) did the trick for me:
The call to
-scrollRangetoVisible mostly does the trick. When you start typing at the bottom of the
UITextView, the text will be hidden, but will immediately scroll up to become visible. A touch odd, but bearable. However, if you just tap Return, the text will continue to be non-visible. Thus, we check for a newline, and if so, adjust the
contentOffset for the view by an appropriate amount for your text (probably better to calculate the right size if you allow the user to choose a font and/or font size). The animation makes the adjustment smooth so the text view doesn't jerk each time text is changed.
Here's to hoping Apple gets this one fixed in the next point release or two. I'll be filing a Radar.
After working with the the original version some more, it had a number of shortcomings. This is the version I'm using now, which should be more robust and should properly account for font and font size changes.
Additionally, I've found adding this bit (from the
UITextViewDelegate) also helps things work more smoothly, as well:
Friday, September 6, 2013
Inspired by the following couple of tweets, I realized I had a similar problem. I tend to use smart playlists in iTunes to work through music to be rated. Since iTunes 11 was released, changing the rating of a track in a smart playlist where the track no longer belongs on the list causes the audio playback to stop.
Here’s how I'm using an “unrated” smart playlist to tame my iTunes Jazz library.— David Sparks (@MacSparky) September 4, 2013
Whoops. Here’s a link to the aforementioned iTunes Unrated Playlist workflow. http://t.co/FjEfhPzuHr— David Sparks (@MacSparky) September 4, 2013
Since I'm not a Keyboard Maestro user, I wanted to take advantage of the same workflow but in my favorite tool: Alfred. Wrote up some AppleScript to do the dirty work and embedded it all in an Alfred 2 workflow to trigger them with hotkeys and notify when the rating has been made. Happy listening and rating.
Friday, July 12, 2013
Those two digits so meticulously "preserved?" Irrelevant. Obviously,NSString *precisionTwoString = [NSString stringWithFormat:@"%.2f", ((minRequiredLabelSize.width + 16.0) / self.credentialInputTableView.frame.size.width)]; __labelProportion = [precisionTwoString floatValue];
ceil()was too complicated.
Tuesday, June 4, 2013
If you don’t have it, you need it. Byword 2.0 was released today for Mac and iOS with plenty of new goodies. Much better conflict management and, with an in-app purchase, the ability to publish to various blogging platforms.
For a full run-down, check out the MacStories review.
Monday, April 8, 2013
Today's piece of automation was creating a quick workflow to set message colors in Mail.app. Color options are the standard ones that AppleScript supports. Simply, select the messages you want to colorize and either bring up Alfred and use "label <color>" or set the hotkeys for each color and cut out some typing.
Download the Workflow
Before anyone asks, I have used Mail Act-On before. It's a great product, but I generally find I don't use most of the features. For me, a simple workflow does all I need.
Tuesday, March 26, 2013
That being said, I don't remember the last time I saw a floppy and anyone under 18 likely has never seen one other than in a toolbar in Microsoft Office. We don't necessarily save things to removable disks anymore. It could be to a hard disk, an SSD, a CD, a DVD, a network drive, a flash drive, an external disk, or somewhere in the "cloud." Heck, I can save a document to a cloud folder by printing the document. Save is not tied to media. In the case of iOS, disks have never existed on the platform.
Apple avoided the concept of what to do about the save icon by removing it and making save an automatic action you never need to worry about. But, there are times when you need an icon to indicate you want to save, such as when you want to "Save As…" or duplicate or "Save a Copy" of a file. Or, in my particular case, I'm working on an iOS app where the user has the option to save/keep/store his document if he or she wants to. Here, I need some sort of icon to put on a button (other than just using the word "Save" which doesn't fit the UI) that means, to the user, "I would like to save this one for later."
On one level, there's the concept of favorites or bookmarks, but these don't quite match the paradigm here. Down arrows generally mean "download" to me. Using a folder generally means "file" or "organize" (or, gasp, "Open…") to me. I, like others, will be wracking my brain on this one.
Do you, dear reader, have any ideas? Hit me up on Twitter or drop me an email. I'd love to hear your thoughts.
Thursday, March 14, 2013
Unless you've been living under a rock for the past 24 hours or so, you've probably read or heard somewhere that Google is shutting down Google Reader on July 1, 2013. This, of course, has led to weeping and gnashing of teeth, an onslaught of comments on social media, and unending blog posts about what may or may not come next. (Of which this is one.)
I agree with Marco Arment that Google shutting Reader down will finally lead to innovation on the feed consumption front. A number of years ago, RSS was a great idea to syndicate sites and allow you to receive easy, periodic updates. When Google came along back in 2005 with Reader, it changed the landscape. Throughout this time, Reader was the red-headed stepchild in Google's portfolio and never really received the support it needed internally (see here for some inside scoop). In fact, the API was never even official, despite its ubiquity. One could argue that Google Voice is in a similar predicament at this time, as well.
All in all, this tweet summed it all up from a business perspective:
Bigger revelation: Google built a service that you configure with all your interests and biases. They couldn’t make it profitable.— macdrifter (@macdrifter) March 14, 2013
Don't believe there's much more that can be said there.
Don't worry, Reeder won't die with Google Reader.— Reeder (@reederapp) March 14, 2013
And another popular reader app for iPad, Mr. Reader, tweeted the following:
Please don't switch overhasty to a Google Reader alternative. It will still work for ~3,5 months. Curious which alternative makes the race!— Mr. Reader (@mrreaderapp) March 14, 2013
Recent approaches to the feed problem have taken the magazine/newspaper presentation (Flipboard, Pulp, The Early Edition) and others have attempted to help float the most important articles to the top (Feedly, Cream, Fever). These are all noble attempts, but they don't generally solve the problem, and often both rely on Google Reader and don't address the multi-device needs of today's users.
In other words, the future is open. The next few months will be a watershed of innovation. It's time for our feed consumption to move to the next level, whatever that is. In today's world where users move from Mac to Windows to iPhone to iPad to Kindle to even their TVs, the way we consume our lifestream needs to accommodate it. This is likely one of the reasons behind Google Reader's demise and likely one of the reasons Mountain Lion didn't even ship with a bundled app that could read RSS (removed from both Mail and Safari).
As I've been looking at the alternatives, I've found that there are plenty of good options, depending on your needs, but for my needs, nothing quite meets my workflow. Yet. Is my developer's brain working on it? Sure is. As are probably many others. I, for one, have no plans to act on my ideas unless they gel into something that's truly revolutionary (I'll accept semi-revolutionary). The market, as they say, is ripe.
In the meantime, I'll stick with Google Reader until the lights go out.
Friday, March 1, 2013
Wednesday, February 13, 2013
As part of my automation, I set up a number of TextExpander 4 snippets to help me create recurring entries in my Day One journal. These snippets use a feature in TextExpander 4 that allows you to create fill-ins, or, essentially fill-in form elements you can use to replace pieces of your template.
When I tried to move this workflow to iOS I found out, to my chagrin, that TextExpander touch doesn’t support fill-ins (checking with @TextExpander on Twitter confirmed this, but I was unable to determine if it’s a shortcoming of iOS, the TextExpander touch SDK, or a limitation imposed by Apple). After racking my brain, I finally decided to buckle down and write the glue the process needed. After all, it’s just text parsing, right? I’m vaguely familiar with Python, though I’m an old school Perl guy–how hard can it be?
To make a long story short, I made it through. The script’s not my prettiest work, but it’s so far, definitely functional. You can grab the script here if you want to take a look at it. [Edit: Since releasing it, I’ve made a few changes to my own copy of the script. I’ve outlined those below.]
You can also download the code in a GitHub gist here. This should make it a bit easier to import into Pythonista using the gist download trick.
In order for this to work you need both TextExpander for Mac and TextExpander touch (for iOS). You’ll need to set up the snippets with fill-ins you want on the Mac and sync them to iOS. (Though, I suppose you could roll them yourself if you were masochistic.)
Once you have your snippets set up to your liking, you can set up the workflow.
Drafts is the key to making this work. The latest major release introduced custom URL actions which are used to trigger the whole workflow. Drafts also includes the TextExpander touch SDK allowing it to take advantage of TextExpander snippet expansion (make sure snippet sharing it enabled in the settings). If you enter your shortcut text in a draft, it will immediately expand. If your snippet has fill-ins in it, you’ll see them unexpanded in your text enclosed in %’s.
To create the workflow, open Drafts’ settings and create a custom URL action as follows:
This will send the current contents of your draft to Pythonista and run the Expander script stored within (you may need to tweak this if you’ve named the script something different). I saved my custom action as “Expand Fill-ins.” Once the rest of the steps are configured, you’re ready to go. All you need to do is expand your snippet in Drafts, select the Expand Fill-ins custom action, and your completed, filled-in, snippet will be posted to a new entry in Day One. The python script, when complete, posts a URL back to Drafts with the modified snippet and calls Drafts’ built-in Send to Day One action to complete the work.
If Drafts is the key to making this work then Pythonista is the lock. For the most part, the script takes care of all the havy lifting, but you will need to bring the script into Pythonista yourself (limitation of Apple’s App Store rules). The Pythonista site has some more details on this, but, personally, I opened the script in an editor (in my case, Textastic), copied out the text, and pasted it into a new script inside Pythonista.
When the script runs, it parses the TextExpander fill-in syntax and creates prompts for each on the Pythonista console where you can fill in the values. When you’ve completed the last one, the workflow continues as outlined above.
Currently, the expander script does not support the “optional section” fill-in type. It does support the other three (single-line, multi-line, and popup menu). The script is also entirely console-based and, while it does some basic validation checking, it doesn’t provide a GUI or the ability to edit your fill-ins before committing them. (The code is available under a non-restrictive Creative Commons license, so an enterprising soul could take this to the next level.)
Day One is the final step in this process. All that’s needed is you have it installed and the Send to Day One action be enabled in Drafts.
### MAIN ###:
You will also need to
import consoleat the top of the script. This does nothing more than clear the Pythonista console before it starts prompting. I find that this makes for a cleaner and less-confusing experience.
Smile has added fill-in support to the TextExpander touch SDK as of version 2.0. The change requires some additional work by each developer to implement it, so it may be some time before your favorite app has it available.