Doing Good 2014-08-24

I’m excited to announce that I’ve taken a position as a developer at Coursera, an educational company started by former Stanford University faculty.

I've always held education high in my list of values. As the first member of my family to complete a University degree, I know first hand the difference my education has made for my life. For many people, however, education is simply not possible. That’s were an idea, and a company like Coursera, comes in. By providing the tools, people can pursue their educational goals in an increasingly complex world. A quality education can open more doors of opportunity for people. In the United States in particular, the cost of an education, similar to the one I received, is growing even faster than the cost of health insurance.

As I mentioned in a talk I gave at the AltConf at WWDC in 2014, I personally have been looking for opportunities where I feel I can make a positive impact on the world. One of those good karma opportunities came when I helped build a client app called RocketKeys. Helping physically disabled people communicate with the rest of the able-bodied world is just the right thing to do. Since then, I've kept an eye open for more opportunities like that.g

I am lucky to be in a position where I can not only do what I love doing, but make a decent living and support myself and my family at the same time. I strive to use my developer powers for good and help to solve some of the real problems in the world, and not just chase down market segments for the sole purpose of making money. Making a university level education accessible and available to more people, in the USA and around the world, is one of those problems for which I’d gladly give up the dream of an indie life...

Why contextForCurrentThread Doesn't Work in MagicalRecord 2013-09-15

As many of you may know, when I first started writing iOS apps for clients, I authored MagicalRecord. This library came directly from my work in discovering how to properly use Core Data. That is, once I figured out all the subtleties of working with various aspects of Core Data, I decided that I didn't want to write that code again, so I made myself a personal library to make sure I don't make the same mistakes again. MagicalRecord has reduced the boilerplate code required not only for fetching, but for threading as well.

One of the most common mistakes when using Core Data is crossing threads. Threading in general is not an easy thing to handle in any app, but when used in conjunction with Core Data, and the potential for crashes increases. That isn't to say Core Data doesn't work with threads. It just means you need to be very careful.

I originally wrote MagicalRecord before Grand Central Dispatch (GCD) was released, so we only had the classic threading model and NSThread APIs to work with. It was back then that contextForCurrentThread was submitted as an addition to MagicalRecord. At the time, it was a great addition. However, now, as more of you (and the heart of MagicalRecord) is using GCD, contextForCurrentThread is no longer safe for use in your apps.

The way contextForCurrentThread works is basically creating a single NSManagedObjectContext for a single thread, and storing that in the thread's dictionary. The thread dictionary is basically a way to hold on to arbitrary values across the life of the thread. In theory, this is great because you don't have to recreate a context all the time, or any items fetched in that context are already present in that thread. This isn't always necessary, but it's great if you need it. However, it's this long life of the context for a given thread is what can cause crashes for apps at seemingly random times.

GCD is a terrific API that takes care of managing and reusing threads for you. Your primary interface into GCD is via queues. And to do work on a queue, you simply schedule a block to it, and eventually, the queue will execute the block. The block, while running on a single queue, can potentially run on any thread managed by GCD. This is where problems start to arise. Say you have a context created via the contextForCurrentThread method, and then hold on to a reference to that context. You then submit more blocks onto the queue, and use the same context. There is an eventual possibility that one or more of the newly submitted blocks will be run on a thread that is not the thread in which the context was created. And, while this alone doesn't mean sudden death for your app, there will eventually be a crash because the context was access on the wrong thread, even though the queue is the same.

The way to handle this in the world of GCD is simple. Every time you perform some Core Data work in a block which will be run on a GCD queue is to create a new context for that block. Yes, you need to create a new context; some of you might think this is wasteful, but NSManagedObjectContexts are rather light weight (as defined by Apple). I'd prefer to take a slightly slower app that's stable over a lightning fast app that crashes unpredictably. MagicalRecord provides a simple API for this case, use the [-MagicalRecord saveWithBlock:] and related methods. These APIs will create a new block with a fresh new NSManagedObjectContext for you, set it up to merge so that your data is available in the rest of your app, and save the context for you once your data manipulations are complete. Of course, you should follow the code examples so that your objects are properly transferred to each of these contexts. This works simply because of the nature of GCD queues, since a block can run on any thread, and once a block is running, it's (essentially) a serial operation on that thread. Each block has it's own NSManagedObjectContext and thus all data operations will only be accessed on the same thread. Yes, you're making far more contexts, and doing a bit of work in making sure you're using objectIDs to transfer data across contexts, but this is how Core Data works best with threads.

I hope this explains a bit why contextForCurrentThread is (now) a dangerous pattern, and will be removed from MagicalRecord in the near future. I urge you all to use -[MagicalRecord saveWithBlock:] and other methods provided by MagicalRecord to handle your Core Data threading needs.

Avoiding isKindOfClass: 2013-08-18

I've seen it time and again in various languages and code bases. 'isKindOfClass:' and its related methods in other Object Oriented languages are always present. However, the need to use these is few and far bewteen. I most often see this method used in a manner similar to this:

- (void) doSomething:(id<NSFastEnumeration>)parameter;
    for (id obj in parameter)
        if ([obj isKindOfClass:[NSString class]])
            [self performStringOperationOn:obj];
        else if ([obj isKindOfClass:[NSArray class]])
            [self performArrayOperationOn:obj]
        else if ([obj isKindOfClass:[NSDictionary class]])
            [self performDictionaryOperationOn:obj];

Talking Core Data on iPhreaks 2013-05-18

I recently had the pleasure of chatting with the crew at iPhreaks to discuss the basics of Core Data. Since I do my own podcast, it was quite interesting to be the one answering the questions this time. If you're new to Core Data and iOS development in general, I recommend checking out the iPhreaks podcast.

Back to Square One 2013-05-09

I was 12 going on 13. I wanted to play (American) football in high school as a freshman. I was always a big boy growing up, and I always enjoyed watching football on TV, so I thought I should give it a try. One of the more procedural things I needed to take care of in order to join the team was to get a physical exam. Sure, I was out of shape, but there wasn't anything wrong with me, right? Wrong. I was devastated to learn that I had Type II Diabetes. My life would be forever different. I had to poke myself with needles in my fingers to put some blood in the meter to calculate my blood sugar. I had to give myself shots of insulin twice a day. I would have to watch what I ate. I'd have to go to the doctor far more often than I wanted. It was a bummer, especially for a teenager (or almost teen).

After a few years, the diabetes didn't seem so bad. I could managed the finger poking and stuff. The shots only took a few minutes. Then, I finished college, and moved to Boulder, Colorado. I had a decent job writing code and learning about writing code. It was good. When I came home, my life was spent in front of the TV. It was during this time which I realized that watching other people's lives flash by on TV is a waste of time, and instead I should be living my own life, doing fun, crazy and creative things. I stopped watching TV cold turkey, and started to ride my bike to work. Sure, this wasn't a TV adventure, but it was time better spent than just sitting on my ass all the time.

I lived far enough away from the office so that I could ride my bike to work. My first apartment was only a mile from the office, and I was slow and out of shape. It took quite a bit of time to ride to work and back. Eventually, I moved to a new apartment 8 miles away from the office. It took 1 whole hour to get to the office. Granted, I went through back roads and side trails, but still, an hour to ride my bike 8 miles to work? Over the course of the next month, I rode to work every day. And I rode home every day. I brought my commute time down from 1 hour each way to 30 minutes each way. After 1 month, I lost 20 pounds. I changed nothing but the mere fact that I was riding my bike all the time. I continued to ride my bike for the next 8 years. I rode to work, to school, in event after event.

In my home town of Tucson, Arizona, there is an annual event called El Tour de Tucson. I decided to sign up for the 109 mile long event back in 2002. I had been riding my bike consistently for only about 4 months. I managed to finish with a time just under 9 hours. I signed up the next year and finished in under 8 hours. The following year I was under 6 hours. And the year after that, my peak, I completed the 109 mile course in under 5 hours. I rode at an average speed of 23 mph. I marvel at what a slow, fat overweight person like myself was able to accomplish back in the day.

At this point, my diabetes was all but gone. My continuous exercise routine of riding to work at least 3 days a week, and 2 longer rides on the weekend was more than enough to stimulate the insulin absorption in my body. I had a doctor visit and explained my fitness habits. He looked at my blood work, and told me the A1C number was back in the normal range, something that doesn't happen, even with recovering diabetics. I had kicked diabetes in the ass, and was better off for it.

And then we come to today. Today's visit to the doctor was good in that it reminded me that I always will be a diabetic. My blood sugar level was 218. Normal levels are 80-180 for diabetics. I don't know what my blood work will say, but I can't imagine it'll be good. I'm now back on medication for diabetes, to control the blood sugar levels. My fitness is no where near what it was at my peak fitness level.

I'm frustrated at myself for letting myself lapse this far. I've probably focused too much on my work, and not enough on my health. I've got to change my diet up a bit, and it's going to suck for a little while. But my health is important, it always was, it just took a small wake up call to realize it. I will return, perhaps not to my peak, but hopefully close enough so that I can once again live without medications, shots, or worse, an insulin pump.

Don't forget your health, without it, you are just a bag of mostly water.