The other today I came across a blog post and some interesting comments on Twitter about Interface Builder and its role in iOS development.
Every iOS developer seems to have an opinion about Interface Builder (generally referred to as “IB”). Many label the much-maligned tool as a crutch for beginners who don’t understand how to code a UI from scratch. Others claim to use it almost exclusively for UI development, even to the point of encouraging non-coders to dig their teeth into the world of
.xib files directly. I have a feeling most opinions are somewhere in the middle–torn between the “no IB whatsoever” and “use IB for everything” viewpoints.
While it’s true you can’t quite build an app entirely in IB, it’s still a powerful tool that lets you minimize the amount of boilerplate code you have to write to build an interactive UI. In recent years, its capabilities have grown with the addition of storyboards, gesture recognizers and autolayout support. Still, there are a few shortcomings that are difficult to overlook, including lack of support for resizable images, pattern colors, animations, and constants shared with code, just to name a few.
It seems clear to me that our tools will never be perfect, and both code and GUI-based UI development have a long way to go. Whenever I consider this situation, a couple maxims spring to mind:
Here are a couple of reasons why I think IB is not only a great choice for UI development, but should be understood and used by all app developers:
It’s an opportunity to replace code with static configuration files. It’s rarely the case that more code is better than less, and relying on a static file reduces the probability of bugs appearing in your app.
Interface Builder is one of the oldest, most deeply ingrained tools in the entire Mac/iOS ecosystem. It’s existed since the days of NeXT, and even plays a role in Apple’s Objective-C APIs (see
initWithNibName:bundle:). Something so integral to the way these platforms work is unlikely to disappear. On the contrary, all signs point to IB improving over time, making it a sound investment in the future of your software.
Consistency is better than perfection.
The best way I’ve found to take advantage of the most desirable properties of IB and code-based development is to come up with, and adhere to, some basic conventions. These conventions can be as simple or as complicated as needed, but here are a few examples:
Decide where to put
.xib files in your project so they’re not haphazardly scattered among your other source files.
Always define autoresizing masks (or autolayout constraints) in nib files and avoid complicated layout code whenever possible.
Define custom view classes and override
-layoutSubviews to encapsulate additional configuration and layout behavior if needed.
Every developer should at least have a few conventions in mind, but it might help to write them down somewhere. If you use GitHub, a wiki would be a great place to list these things out, along with any other general comments/instructions that don’t belong in code-level comments or a README file.
My opinions may evolve over time, but for now I plan to continue exploring Interface Builder’s capabilities, and to stay as rational as possible when it comes to making decisions about which tools to use to get my job done.
It occurred to me today that I consume a lot of information. Too much information. All those productivity blog posts that talk about anxiety from the little red notification badges? That’s where I am right now (as my ability to reference such blog posts should tell you). I’ve decided to take control of my information consumption habits, with the following goals in mind:
- Maximizing the signal to noise ratio. It’s 2012; I should be reading/hearing only what’s relevant to me.
- Spending less time consuming and more time thinking. I’m finally accepting that there’s just too much information out there for me to process, even after it’s completely filtered, and spending more time consuming means less time thinking, doing and creating.
Here are the top three actions I’m taking to work toward these goals.
- Unsubscribe from all email newsletters and notifications. I’m adopting a zero-tolerance policy when it comes to email newsletters and notifications. In lieu of relying on email for relatively unimportant notifications from services like Facebook and Twitter, I’ve decided to put my trust in Apple’s push notification system.
- Trust the experts. I spend a lot of time working through feeds in Google Reader every day. I’ve become pretty efficient when it comes to choosing the articles I think are most interesting or relevant to me. But for some people, separating out the best articles from the rest is a full-time job. When it comes to many sources of information, I’m willing to trust those people to do the filtering for me.
- Return to long-form reading. I spend a lot of time reading, but it’s usually blog posts from RSS feeds, and I usually spend no more than five or ten minutes reading at any given time. For many of the topics I’d love to learn more about, that’s simply not going to be enough. I have stacks of novels and non-fiction books at home that I’m itching to spend some time with.
The epiphany I had today is that just reading (or listening, or otherwise “getting”) information is not, in and of itself, productive or fulfilling. I’m hoping that realization will serve me well going forward.
Just came across an interesting use of preprocessor
#defines in one of Apple’s Grand Central Dispatch headers:
#error "Please #include <dispatch/dispatch.h> instead of this file directly."
#include <dispatch/base.h> // for HeaderDoc
If you look at
dispatch/dispatch.h, you’ll see the following:
Seems like a good way to manage complex multi-file compile-time dependencies. I’m sure there are lots of other cool preprocessor use cases hiding in these headers, too.
This post has been written before, but it’s such a useful hack that I figured I’d share it here for those who haven’t seen it. It’s particularly useful for people who want to use separate “home” and “work” Dropbox accounts.
Running two instances of Dropbox.app
The trick is to get Mac OS X to run multiple instances of Dropbox.app at the same time. As far as I’m aware, there’s no way to do this through the Finder (for any application). Fortunately, it’s easy to do in two Terminal commands:
mkdir -p "$HOME/.dropbox-alt"
HOME="$HOME/.dropbox-alt" open -n -a Dropbox.app
(You can replace
.dropbox-alt with whatever you want).
The first line simply creates a new hidden folder in your home folder, if it doesn’t already exist. Although it looks like the second line should be two commands, it’s really just one. Invoking
open with the
-n flag causes a new instance of the application to launch (and if you use the
-a flag, you don’t need to specify the full path to the Dropbox app). Setting the
HOME environment variable to its new value fools the new Dropbox instance into thinking your home folder is at
$HOME/.dropbox-alt. Since Dropbox normally stores its settings in your home directory, you can have a new set of preferences in this folder that doesn’t conflict with your primary account.
After you run those lines in Terminal for the first time, the new Dropbox instance will prompt you to set up your account. Once you go through the initial setup, running those commands will simply launch the second Dropbox instance and begin syncing your files.
Launch a second Dropbox instance automatically
While it’s not difficult to run these commands, it can get tedious after a few logins. Wouldn’t it be nice if you could start your alternative Dropbox from Finder, or start it automatically when you log in? With Automator, you can do just that.
Here are the steps:
- Launch Automator (/Applications/Automator.app).
- Create a new “Application” document.
- In the Actions library, search for “Run Shell Script”.
- Double click or drag the “Run Shell Script” action into the workflow (on the right).
/bin/sh from the “Shell” menu, and paste the two Terminal lines above in the text area.
- Save the result to your Applications folder (call it “Dropbox Alt.app” or something similar).
Now you can launch your secondary Dropbox instance by running the application you just created! To add it as a login item:
- Go to System Preferences and search for “Login Items” in the search bar.
- Click the plus and add your “Dropbox Alt” application.
Hope you find this as useful as I do!
It’s been a while since I’ve posted anything around here, and I’d like to change that. Part of the reason for the lack of updates (or so I tell myself) is because nanoc, while extremely flexible and customizable, proved increasingly difficult to use over time. A major version update broke my build process, and I ended up spending more time engineering my blog than writing–I even had to write my own gem to deploy my site to GitHub. I’m hoping that using a system that integrates better with GitHub will let me get back to what I originally set out to do with this site.
I’ve been using Oplop for a while now. It’s a great alternative to database-style password management programs like 1Password, providing the same level of security without compromising portability. While 1Password lets you take your passwords with you via an encrypted file and mobile, web and desktop apps, Oplop makes it so you don’t have to take anything with you at all!
One thing I don’t like about Oplop, however, is having to go to oplop.appspot.com every single time I need to retrieve my passwords. So I decided to implement the algorithm as a Python script with a simple command line interface.
"""Generate a password using the Oplop password hashing algorithm.
For more information: http://code.google.com/p/oplop/wiki/HowItWorks"""
from sys import argv, stdout
from hashlib import md5
from base64 import urlsafe_b64encode as b64
PASS_LEN = 8
DIGIT_RE = re.compile('\d+')
def oplop(nickname, master_password, pass_len=PASS_LEN):
hashed = b64(md5(master_password + nickname).digest())
digits = DIGIT_RE.findall(hashed[:pass_len])
if not digits:
digits = DIGIT_RE.findall(hashed)
hashed = (digits and digits or '1') + hashed
if __name__ == '__main__':
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument('nickname', help='Account nickname')
parser.add_argument('master_password', help='Master password')
args = parser.parse_args()
From here, I just need to come up with a way to get passwords generated by the script into web forms and applications automatically. For now, Alfred (+ Powerpack) and
pbcopy are doing nicely.
Here’s the Gist.
One of my projects at Aviary necessitated generating a static UIImage from a UIView. Fortunately, Quartz makes it really simple to do this. Here’s a quick category on UIView showing how it can be done.
-createImageFromRect: method generates an image by rendering the portion of the view bounded by “frame” in an image context. Note that CALayer’s
-renderInContext: method renders the entire layer tree, creating a flat image from the view hierarchy.
/* implementation UIView (UIImageCreation) */
- (UIImage *)createImageFromRect:(CGRect)frame
CGContextRef context = UIGraphicsGetCurrentContext();
CGPoint origin = [self bounds].origin;
CGPoint offset = frame.origin;
CGContextTranslateCTM(context, origin.x - offset.x, origin.y - offset.y);
[[self layer] renderInContext:context];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
- (UIImage *)createImage
return [self createImageFromRect:[self bounds]];
/* end */
Check out the Gist here.
A lot has happened in the past month or two, but the biggest news from me is that I started working at Aviary, Inc. in mid-July. I’ve been spending a good deal of time at the office, and I’m loving every minute of it. Our building is in the heart of Manhattan, right next to Penn Station and Madison Square Garden. We have an amazing roof and a really sketchy elevator. Hmm, reminds me of somewhere in Bushwick.
It’s been an eventful year since I graduated last summer, made the transition from Cambridge to Bushwick. There’s much more to this story, but I’m hoping this quick retrospective will kickstart this blog back into action.
A year ago was an exciting time for us: some friends and I had made a successful iPhone app together, been profiled by the Wall Street Journal, and received enough money from AT&T to work on mobile apps for schools AND live off of for a year. Times were good.
We worked hard to get our work off the ground, finding our way with AT&T, some of their partner companies, and of course, universities, and ended up deploying the Columbia Business School mobile app last month after a year of hard work. While we didn’t quite take our business to the level we wanted, we ended up with a product we can be proud of.
As our team heads off in different directions, things are getting exciting once again. I’ll have more to tell in a little over a week.
I’m convinced I’m a different person than I was when I arrived in New York City. It took a long time for me to get over how dirty, crowded and expensive it can be, but I’m learning to love it here–there really is no place like it. I’ve particularly enjoyed the live music scene.
Bushwick has been great to me, and I’ll miss it when I leave for Manhattan. I’m consistently amazed at how lucky we got with our apartment–even though our building has been an unexpected (or unwanted) adventure at times, we’re around the corner from the L train, we now have a 24-hour grocery store across the street, and there are restaurants and shops popping up everywhere. We couldn’t have asked for a better introduction to the city.
Happy New Year, NYC!
I have lots of goals for the next year: getting a bike and commuting above-ground, getting more involved in the NYC startup scene, and meeting more people, to name a few. It’s definitely going to be a busy year. Oh, and more concerts.
And, once again, I hope to make this blog worth reading!
I went to a birthday party at a top-floor room at the Thompson LES (LES = “Lower East Side”) on Sunday. As far as I can tell, it’s the tallest building in the area, which made for an absolutely spectacular night-time view from the private deck. The room spans the length of the building and faces west, making for a perfect view of both the financial district, the Brooklyn Bridge, and midtown. I shudder to think what it would cost to actually stay here, and I’m glad the only cost to me was a bottle of rum.
This is the first of what will hopefully be an ongoing series about places and businesses I’ve visited.
New Ashiya is a sushi restaurant on 1st Ave in the East Village. It looks pretty innocuous on the outside, but walk inside and you’ll immediately see that this isn’t your average Japanese restaurant. In addition to their regular menu, they have an all you can eat and drink option for $33 per person. For 2 hours, you can order as much sushi, sake and beer as you can handle (without going overboard–the menu warns of additional charges for wasted food). We opted to try every special roll on the menu (about 10 different kinds), plus some tuna and salmon sashimi. The highlight was definitely the black pepper tuna roll, something I’ve never seen or tasted anywhere else. Oh, and we did lots of sake bombs.
Since my last post on identity theft/worst case scenarios regarding user accounts on the web was a bit technical/unclear, I figured I’d follow up with a better answer to the question: “so what should I do about it?” Since weak passwords and site-specific attacks are the biggest threat, I think the best way for me to answer that question is to walk through my current account management scheme.
My system runs on one simple rule: don’t use the same password twice. When I register new accounts online, I use a different password every time. That way, if one site I use gets compromised, my other accounts won’t be affected. Obviously, this would be impractical if I had to remember every single password I registered with, or even if I had to keep them all written down. So here are the supporting requirements of my system:
- Keep memorization to a minimum. I don’t want to waste brain power memorizing hundreds of passwords.
- I should be able to access my passwords quickly–only slightly slower than the same amount of time it would take to recall them from memory and type them out.
- I should be able to access my passwords wherever I am.
I’m basically looking for the convenience of using a single password everywhere, but with much better security. Fortunately, this is easily accomplished using a few tools and some initial setup time.
Oplop (Web-based) - https://oplop.appspot.com/
Oplop is actually a specification for generating passwords, but there is also a web-based implementation you can actually use. You choose a master password and a “nickname,” and it spits out a strong password. The beauty of Oplop is that given the same nickname and master password, it generates the same output every time. What this means is that you don’t actually need to store anything at all; just pick a single master password and use an easily memorizable nickname for each of your accounts (like “amazon” for your Amazon account). That way, you only need to remember one master password, but you end up with separate passwords for each of your accounts online. You just need to use the generator each time you want to access your password (which, once you get used to it, is only a slight inconvenience that can be mitigated by using 1Password and a web browser plugin).
1Password (Mac, Windows, iOS, Android) - http://agilebits.com/onepassword
You may be familiar with storing passwords for your various web user accounts in your browser (like when it asks if you want to “Save this password” for later). Rather than storing your information in the browser, you can store it in 1Password, which serves as a central repository for your sensitive information (in this way, it’s similar to the Keychain feature of Mac OS X, but better). Everything you enter is protected by a master password and strong encryption. You can even store 1Password’s database file (the “.agilekeychain” file) on a web-accessible file system like Dropbox and access it via an HTML interface. I use 1Password in addition to Oplop for a few reasons: to have an offline-accessible “database” of my passwords and other info; to be able to log in using a keystroke via the included browser plugins; and, to sync my information to Dropbox/my iPhone for mobile access.
These two tools allow me to satisfy my three requirements above. Both of them allow me to avoid memorizing any passwords except the master. When I’m on my own computer, 1Password’s browser plugins allow me to fill out login forms with a single keystroke. When I’m on someone else’s computer, I can look up my password on my iPhone or use Oplop to retrieve it.
This isn’t necessarily the simplest system to set up–after all, it requires you to change all your current account passwords and your behavior. But I can guarantee that if you do both, you’ll be protecting yourself better than most other internet users.
Most people don’t worry about keeping themselves safe online. However, like backing up your files, it’s something that many only realize they need when it’s too late.
Yesterday, a friend of mine met with an unpleasant surprise when she logged into her iTunes account: someone had gained access to her account, and had made a $100 purchase using her credit card. While this charge can and will be quickly revoked, she faces a more serious problem. Like most people, she uses the same password for many other accounts online, meaning that her other accounts could also be compromised.
First, let’s look at a couple of the possible ways she could have gotten hacked:
She is a victim of session hijacking.
Many sites use HTTPS to protect their users’ data from being intercepted by a third party. However, many sites still use the faster, but less secure HTTP protocol. Using tools like the widely publicized Firesheep, attackers can take control of a user’s login session. While most sites wouldn’t allow them to change the account password without access to a registered email account, they could still access sensitive information and generally wreak havoc. As more sites adopt the use of HTTPS by default, this will become less of a problem, but a universal solution has not yet been implemented.
In order to protect yourself from this kind of attack, you should do the following:
- Think twice before accessing an HTTP-only service on a public wi-fi network. You can tell if you’re using HTTP or HTTPS by looking at the beginning of the URL in your browser’s address bar (
- Enable HTTPS as the default protocol on sites that offer the option. For example, in Facebook, go to your account settings and enable “Secure Browsing (https)” under “Account Security”.
- Use a secure proxy service like the cloak or similar, or (for more advanced users), tunnel your traffic to a trusted server via SSH.
As with all of these attacks, if you become a victim, you should change your password immediately.
The attacker knows her password, either by guessing or by exploiting a vulnerability in another site.
This is by far the most dangerous situation. It’s only likely to happen if you use the same password for many sites, but this is, unfortunately, the case for many people. Let me put this as simply as I can: you should not rely on sites to keep your password safe. Recently, users registered on the Gawker network learned this the hard way.
The best way to protect yourself against site vulnerabilities is to use a different password for every account you register. It’s not as hard as you might expect, and there are a lot of different utilities out there that make it very easy to do. I use a combination of oplop and 1Password. Both of these utilities rely on the idea of a single “master” password that you memorize, but instead of exposing this master password to the outside world by using it to register accounts, you use it to generate and protect your set of unique, account-specific passwords, none of which are important to memorize. It’s an extremely secure system, and very convenient once you get used to it.
The attacker found and exploited a security vulnerability in iTunes that allowed him/her to gain access to the account.
This is similar to the situation above, and the only way to protect yourself is to change your account password. If the service you’re using is unreliable, you should strongly consider removing all personal information from your account and using something else.
In all situations, the best thing you can do is change your password(s), and be eternally skeptical any time a site guarantees the safety of your information. With our increased reliability on internet services to accomplish vital tasks like online banking, it is always a good idea to be overly cautious.
Also, I could write an entirely different post about this, but continuing in the spirit of being prepared for disasters: go back up your important files NOW. With free services like Dropbox readily available, you have no more excuses not to.
I got the title from some random ad in my subway station, but it’s kind of true. Music has been an integral part of my life from piano lessons—for about 8 years of my life—to singing in high school and college, to playing guitar and listening to music on my iPhone and computer just about 24/7. Programming, traveling, relaxing: music plays a part in nearly everything I do.
In all the ways I’ve interacted with music, one mode has affected me more than all the others: being at concerts. Back in middle school, I saw Tom Petty at Red Rocks, and I’ve been absolutely addicted ever since. Unfortunately, rather than satisfying that addiction, I’ve spent most of my time having withdrawals and flashbacks to the last great show. It’s not that the Denver area hasn’t historically attracted some big names—the Beatles even made a stop at Red Rocks on their 1964 world tour—and I certainly had a decent selection while I was in Boston. It’s just been all too easy for life and school to get in the way.
One of the great things about living in New York is that almost every artist I currently listen to has performed in the city during the time I’ve lived here (since June 2010). Add decent public transportation to an abundance of great concerts, and you get a recipe for awesome. Or spending a lot of money on concert tickets. Or both.
It’s true, concerts are loud (sometimes eardrum-splittingly so), crowded, messy and expensive. But there’s really nothing quite like hearing your favorite songs being played by their creators for you, and for me, there’s no expense too great to have that. This is one addiction I don’t plan on giving up for the rest of my life.
In case anyone is curious/cares, here is basically every major concert I’ve been to:
- Tom Petty and the Heartbreakers (Red Rocks Amphitheater - Morrison, CO)
- Weird Al Yankovic (Pepsi Center - Denver, CO)
- Interpol (Fillmore Auditorium - Denver, CO)
- Death Cab for Cutie (Fillmore Auditorium - Denver, CO)
- Foo Fighters & Weezer (Pepsi Center - Denver, CO)
- Paul McCartney (Pepsi Center - Denver, CO)
- Kid Sister, The Cool Kids & Kanye West (American Museum of Natural History - New York, NY)
- Third Eye Blind (Harvard Yard - Cambridge, MA)
- MIA (Worcester, MA)
- Black Kids (Boston, MA)
- Wu Tang Clan (Harvard Yard - Cambridge, MA)
- Jason Mraz (Orpheum Theatre - Boston, MA)
- Bob Dylan (Wang Theatre - Boston, MA)
- Ratatat (Harvard Yard - Cambridge, MA)
- The Flaming Lips (Terminal 5 - New York, NY)
- Robyn (Radio City Music Hall - New York, NY)
- Interpol (2/17/11 - Radio City Music Hall - New York, NY)
- Cold War Kids (Radio City Music Hall - New York, NY)
- Fleet Foxes (United Palace Theatre - New York, NY)