November 2010

Are You A Gamer, A Tinkerer, Or A Maker?

Filed in Miscellaneous | Comments Off on Are You A Gamer, A Tinkerer, Or A Maker? |

Gamer? Me? Not So Much

I have a confession: I am not very good at playing video games. Most of my time on the family XBox 360 is playing multiplayer games with my kids, and on that machine my gamer tag is “Target”, so that should give you a good idea of my proficiency at Halo, Call of Duty, or whatever the game of the week is around here.

I don’t have any problem with folks who love to take the time to beat games. Both of my college age sons love the challenge of a good game when they have the time.

I guess I’m just not a gamer at heart.

A Tinkerer At Heart

I think I could be a lot better at video games, but that would require a lot more time playing by myself than I care to give. My main problem is I am more interested in how it was done than I am in finishing whatever task is set before me. I would rather try to figure out how to do even a small part of what I see, than to finish playing. That same all tinker, no finish, bleeds into other areas of my life at times as well.

I love to tinker. On my mac, in the garage, in the yard, wherever. Doing something for the first time, usually without instructions and just a vague idea of what I want is one of my favorite ways to waste some time.

I have other marks of a tinkerer as well. I’d rather start something new than take something that I think is “good enough” and finish and polish it. Every time a new idea crosses my path, I’m tempted to play too long with the new shiny instead of pressing forward and finishing the old.

I Want To Be A Maker

I still feel the call of the tinkerer within, but I am getting better at resisting. Both personally and professionally, my goal is to increase my finishing percentage, and I am reasonably pleased with my progress.

I do not want to be known as just a tinkerer, I want to finish things well.

I want to be known as a maker, a maker of good things.

p.s.

Now that I’ve come clean about my abysmal gamer credentials, I only hope that the geek overlords do not find out and revoke my geek card.

Winston Churchill's Keys To Success

Filed in iDevBlogADay, Miscellaneous | Comments Off on Winston Churchill's Keys To Success |

One of the difficulties in discussing success is that each of us may have a different definition. I believe that ultimate success in life depends on my relationship with my creator1, but I also believe there are many aspects of success that all of us can agree on.

Lessons from Winston Churchill

I would not equate building an application or creating a game with the major events surrounding Winston Churchill’s life and career, but there are lessons we can apply from what he said and wrote.

On Failure

“Success is the ability to go from one failure to another with no loss of enthusiasm.”

“Success is not final, failure is not fatal: it is the courage to continue that counts.”

Learn from your failures rather than let them discourage you from continuing.

On Quitting for the Wrong Reasons

“Never give in. Never give in. Never, never, never, never–in nothing, great or small, large or petty–never give in, except to convictions of honor and good sense. Never yield to force. Never yield to the apparently overwhelming might of the enemy.

There are times to quit and there are times to persevere.

It is difficult to tell the difference, but if you think it might be time to quit, wait until you are thinking clearly and can evaluate the situation properly before making that decision.

On Criticism

“Criticism may not be agreeable, but it is necessary. It fulfills the same function as pain in the human body. It calls attention to an unhealthy state of things.”

Not every bit of criticism is valid, but I have found that most criticism contains at least a kernel of truth — find that kernel and decide if you need to make corrections.

On Mediocrity

“I am easily satisfied with the very best.”

Try very hard not to settle for mediocre results. Often it is better to cut something out completely rather than include some half-baked feature.

On Difficulties

“Mountaintops inspire leaders but valleys mature them.”

“The pessimist sees difficulty in every opportunity. The optimist sees the opportunity in every difficulty.”

Sometimes the only reason one person succeeds where others have tried and failed is simply because they pushed on through the valley to the other side when no one else did.

On Worries

“When I look back on all these worries, I remember the story of the old man who said on his deathbed that he had had a lot of trouble in his life, most of which had never happened.”

“Let our advance worrying become advance thinking and planning.”

Do not focus on things that might happen. You have enough things that are happening right now that you should handle.

Final Thoughts

Winston Churchill experienced things I never will, through times that I hope to never see.

But, his perspective and wisdom, though not perfect, can be invaluable when thinking about success. I hope you found a nugget that helps you this week.


As an indie developer, one of the best things you can do is to find like-minded developers that will provide encouragement and motivation while pursuing a commitment. A great collection of indie iOS developers have helped me stay on track, many of them are either developers associated with iDevBlogADay, or those I have met through the 360iDev conferences. I also encourage you to find local NSCoder nights, developer meetup groups, or other user groups to keep your motivation on track. If there aren’t any meeting locally, try to find one other developer and start one.

Also, here is a little more information about me, Doug Sjoquist, and how I came to my current place in life. You should follow me on twitter and subscribe to my blog. Have a great day!


1. Matthew 16:25-26 “For whoever would save his life will lose it, but whoever loses his life for my sake will find it. For what will it profit a man if he gains the whole world and forfeits his soul? Or what shall a man give in return for his soul?”

Reply from Ohio Senator Sherrod Brown in response to my email about TSA

Filed in Miscellaneous | Comments (0) |

I sent emails to my senators yesterday through their websites, and to the subcommittee leadership. My points were the scanners were intrusive, most likely a waste of money better spent on other forms of security, and that the TSA pat downs were highly offensive.

Sherrod Brown is the first to reply. Evidently he does not see much of an issue. Here is his email, without further comment.
—————————————-

Dear Mr. Sjoquist:

Thank you for sharing your views about the use of millimeter-wave scanners, also known as body image scanners, at airports nationwide.

The Transportation Security Administration (TSA) is increasing the number of millimeter-wave scanners in airports around the country. This new technology is able to detect concealed plastic and ceramic weapons as well as explosives that evade traditional metal detectors.
However, passengers who feel uncomfortable being screened by the body image scanner may decline to go through and will be patted down by a TSA officer as an alternate security measure.

I support bolstering the safeguards in place to prevent terrorists from entering our country. However, it makes sense to explore whether there are strategies other than millimeter-wave scanners that could be employed to discover concealed explosives and other weapons that are not detectable by traditional methods. Should relevant legislation be considered by the Senate, I will keep your views in mind.

Thank you again for getting in touch with me.

Sincerely,

Sherrod Brown
United States Senator

Stay connected with what’s happening in Congress. Sign up here for regular updates on the issues you care about the most: http://brown.senate.gov/newsletter/landing

Will Code For Fun

Filed in 360iDev, iDevBlogADay, iOS Development | Comments Off on Will Code For Fun |

My work is fun.

It usually is challenging and non-trivial, but it is also fun.

My clients find the results valuable, but it is still fun.

I attended 360iDev this week which was great fun — but it is not why my work is fun.

Working with smart and creative people is fun — but they are not really why my work is fun either.

My work is:

  • Long hours of head down struggles with conflicting demands and confusing requirements;
  • Opportunities and possibilities rattling around my head for days;
  • Researching problems and fixing them cleanly;
  • Struggling with multiple design iterations to find what works best;
  • Discovering what will best meet people’s needs;

I’ll be honest, not every day is fun, nor is every task, but almost every one could be. I’d like to explore what it takes to turn the drudgery into fun, and move from just slogging through tasks to actual enjoyment.

What is “Fun”, Anyway

In A Theory of Fun, Ralph Koster says:

fun is the act of mastering a problem mentally.

My work certainly has problems that can only be solved with the mind, and successful work definitely includes mastery. So, by Koster’s definition, it is possible for my work to be fun.

Jesse Schell says in The Art of Game Design that:

fun is pleasure with surprises.

Well, my work often has surprises, but they do not all bring pleasure. But, his definition seems to have enough room in it to say that my work can be fun.

I Recognize “Not Fun” When I See It

But what about work that seems *not fun* by any reasonable definition. What is it that takes those problems, mental challenges, and surprises and transforms them into fun? The process that Schell uses to define game has helped me understand what that transformation of work from “not fun” to “fun” might require.

He builds a definition for “game” by investigating what others say about fun, play, and other terms which made me think about what makes my work fun. Key among those terms is play, which he defines as “manipulation that satisfies curiosity”. The bulk of my work is manipulating things like ideas and algorithms, so this seemed like an interesting place to start.

Is It “Work vs. Play” or “Work and Play”

I manipulate things in my work, but what about satisfying curiosity? And what about fun?

Notice that Schell’s definition of play does not require it to be fun — you can play with something that turns out not to be fun. That seems to be close to work — you can work with something that turns out not to be fun. Since my desire is to make my work fun where I can, I think looking at play a little more might be helpful.

He quotes George Santayana on play:

Play is whatever is done spontaneously and for its own sake.

When I think of work, spontaneity does not leap to mind. But when I am free to choose projects and clients, there can be a spontaneous feel to it, and it definitely includes a “for its own sake” component. When I have control over what I work on, I will choose the more interesting work — work where I can learn, grow, and satisfy my curiosity about something. So the more freedom I have in choosing projects and clients, the more fun my work will be.

This leads to my first tip about making my work fun.

Tip #1 — Do not let current constraints on your work immobilize you, they should motivate you to find ways to have more control over your work.

Attitude Is King

But, there are always some tasks we must do that do not really appeal to us. Schell expands on “for its own sake” with examples and observes “an activity itself cannot be classified as a ‘work activity’ or ‘play activity’. Instead, what matters is one’s attitude about the activity”. This leads to another tip:

Tip #2 — While you cannot always choose work activities, you can always choose your attitude.

Schell combines several concepts and concisely defines a game as “a problem-solving activity, approached with a playful attitude”. I believe this applies directly to my work. Even unpleasant tasks can be made more palatable, and perhaps even fun, with the right attitude.

Adjusting My Attitude — The Key To Making Work Fun

Fresh Eyes

Two young developers I met this week at 360iDev illustrate how work can be fun. Santiago and Charlie, somewhere around 13 years old, are friends who share a love for making their iPhones do cool things. I won’t pretend to know them well enough to understand all their motives, but they were most definitely having great fun. They were right there in the front in most sessions, even participating in the 360iDev Game Jam until about 2am. It was a joy to watch them.

Watching them during the Game Jam leads to another tip:

Tip #3 –Look with wonder at the cool things that are possible.

(They both have several apps in the store. If you are interested check out Santiago’s Apps and Charlie’s Apps.)

Thankfulness

I am very blessed to be able play around with such cool and powerful stuff, which leads to the last tip:

Tip #4 — Remember to be thankful for the opportunity to attempt great things, whether or not you end up making a living from it.

My Work Is Fun, Yours Can Be Too

How fun is your work? If the answer is “not very”, remember these things:

  1. Find ways to have more control over your work,
  2. Choose your attitude towards your work,
  3. Look at your work with wonder at the possibilities,
  4. Remind yourself to be thankful that you can play with such cool stuff.

As an indie developer, one of the best things you can do is to find like-minded developers that will provide encouragement and motivation. A great collection of indie iOS developers have helped me stay on track, developers from local user groups, those associated with iDevBlogADay, or those I have met through 360iDev. I encourage you to find local NSCoder nights, developer meetup groups, or other user groups to keep your motivation on track. If there aren’t any meeting locally, try to find just one other local developer and start one.

Also, here is a little more information about me, Doug Sjoquist, and how I came to my current place in life. You should follow me on twitter and subscribe to my blog. Have a great day!

My Growing iOS Developer Toolbox — Logging With Levels and Categories

Filed in iDevBlogADay, iOS Development | Comments (0) |

I really love working with iOS and Objective-C, but I still feel like I am missing some items from my developer’s toolbox. (I am using the term ‘tool’ generically to cover anything from a fairly simple development pattern to a full fledged application.) Those missing items fall into several categories:

  1. Existing features within Xcode or other Apple tools that I have not yet found;
  2. Tools that are not needed within this new environment that I only think I need;
  3. Tools that have no direct one-to-one replacement;
  4. Tools that have some third party support that I have not yet found;
  5. Useful tools that really do not exist yet in the Objective-C world.

I usually learn a new language itself much faster than I get comfortable with the new environment, development style, and available tools. So, when I feel like something is missing, I know it might just be part of the learning curve. When I move to a new platform, I want to be willing to think differently and adapt to it rather than fight it — the difficulty is often deciding which category that missing piece falls in.

A Tool Missing From My Objective-C and iOS Development Toolbox

One of the the simple tools I use heavily during development in Java is Apache Commons Logging and Log4J. For those unfamiliar with the Java world, they are simple packages that allow you to easily manage development and production logging. They support multiple categories and multiple levels within each category, and are easily configured at runtime via a simple text file. For the majority of applications, you can leave the logging in place and just disable it in the configuration file with a negligible impact on performance. It is great to be able to come back to existing code to make changes and simply enable detail level logging for individual categories (usually based on class name) to more easily monitor what is happening.

When I first started heavily into iOS and Objective-C last winter, I went searching for replacement tools in several areas, including this one. I did not find a one-to-one replacement, mostly because of the difference in the development environment, but I still had a desire for something close. My searching found several people doing limited forms of this via custom macros to wrap NSLog statements. I like to credit those on whose worked I build, but I did not track the source of most of what I learned and it has been too long for me to remember. So feel free to use what you find here however you wish, knowing that much of it did not originate with me.

Requirements for Objective-C Logging

I have no desire to implement an entire framework to support logging, nor do I want to duplicate everything from the java packages, even though there are lots of useful things I am ignoring.

My simple requirements are:

  1. Control logging horizontally via debug levels;
  2. Control logging vertically via categories;
  3. Enable or disable logging via very simple changes;

Debug levels are important to me because usually I want only higher level log messages displayed to avoid unnecessary detail in the console log across all of my classes.

Categories are important to me because when I am focused on a particular subsection of code, or an individual class, I want to be able quickly disable logging at any level for all other categories. This allows me to more quickly find the pertinent messages and finish my task, whether it is debugging or implementing a new feature.

It is also important to me to not add configuration complexity to my project (Xcode has enough of that), so I wanted to have only one or two places where I could tweak the levels and categories.

Macros for Objective-C Logging

I reuse IGDebug.h across projects, so it does not contain any project specific definitions. For convenience, I include this file in my precompiled header.

I enable debug logging for a particular target by setting the value of Preprocessor Macro to IGDEBUG_MODE=1 in its configuration for the debug Distribution. By setting this only for your Debug distributions, you can ensure none of the debug logging is included in your release distributions.

My project specific categories are defined in a separate, project specific header file. I recommend placing the category defines in a single file, it makes it easy to find them, but the IGDebug macros do not care where you define your category.

IGDebug.h

/*
 *  Created by Douglas Sjoquist.
 *  Copyright 2010.
 *  Free to use or modify for any purpose.
 */


// Define IG_DEBUG_MODE for Debug distributions in project build config files

// if IG_DEBUG_MODE is set, then these macros are in effect, otherwise they do nothing
//   IGDStatement includes enclosed text as a statement, only simple statements will work
//      (intent is to used when a temporary object needs to be created to display in subsequent log message)
//
//   IGDLog takes 3 or more parameters
//      l   --  debug level, an integer value that is compared against the value of
//              IGDBG_MAX_LOG_LEVEL to determine how detailed of log messages should be displayed
//      c   --  additional condition that must be true to display log message
//              the intent is to allow specific classes to be turned on and off via individual
//				#defines, but it can be used for any purpose whatsoever
//      s   --  NSLog format string to use
//      ...     Var args that match the format string
//
// IGALog displays similar log messages, but is unconditional (no debug level, conditions, and ignores IG_DEBUG_MODE)
//
// IGDSLog and IGASLog behave the same, except they include the self pointer as well
// IGDFLog and IGAFLog behave the same, except they include the filename/linenumber as well
// IGDSFLog and IGASFLog behave the same, except they include the self pointer and filename/linenumber as well

#define IGDBG_TRACE 3
#define IGDBG_DEBUG 2
#define IGDBG_INFO 1
#define IGDBG_WARN 0

#define IGDBG_MAX_LOG_LEVEL IGDBG_INFO

#ifdef IG_DEBUG_MODE
#define IGDStatement( s ) s
#define IGDLog( l, c, s, ... ) if (((l) <= IGDBG_MAX_LOG_LEVEL) && (c)) NSLog( @"%@", [NSString stringWithFormat:(s), ##__VA_ARGS__] )
#define IGDSLog( l, c, s, ... ) if (((l) <= IGDBG_MAX_LOG_LEVEL) && (c)) NSLog( @"<%p> %@", self, [NSString stringWithFormat:(s), ##__VA_ARGS__] )
#define IGDFLog( l, c, s, ... ) if (((l) <= IGDBG_MAX_LOG_LEVEL) && (c)) NSLog( @"%@:(%d) %@", [[NSString stringWithUTF8String:__FILE__] lastPathComponent], __LINE__, [NSString stringWithFormat:(s), ##__VA_ARGS__] )
#define IGDSFLog( l, c, s, ... ) if (((l) <= IGDBG_MAX_LOG_LEVEL) && (c)) NSLog( @"<%p %@:(%d)> %@", self, [[NSString stringWithUTF8String:__FILE__] lastPathComponent], __LINE__, [NSString stringWithFormat:(s), ##__VA_ARGS__] )
#else
#define IGDStatement( s )
#define IGDLog( l, c, s, ... )
#define IGDSLog( l, c, s, ... )
#define IGDFLog( l, c, s, ... )
#define IGDSFLog( l, c, s, ... )
#endif

#define IGALog( s, ... ) NSLog( @"%@", [NSString stringWithFormat:(s), ##__VA_ARGS__] )
#define IGASLog( s, ... ) NSLog( @"<%p> %@", self, [NSString stringWithFormat:(s), ##__VA_ARGS__] )
#define IGAFLog( s, ... ) NSLog( @"%@:(%d) %@", [[NSString stringWithUTF8String:__FILE__] lastPathComponent], __LINE__, [NSString stringWithFormat:(s), ##__VA_ARGS__] )
#define IGASFLog( s, ... ) NSLog( @"<%p %@:(%d)> %@", self, [[NSString stringWithUTF8String:__FILE__] lastPathComponent], __LINE__, [NSString stringWithFormat:(s), ##__VA_ARGS__] )

Using IGDebug.h

The examples shown below include IGConstants.h, a project specific file I use to configure all my logging categories in a single place. There is no magic to it, it is just a list of #define statements to define the adhoc logging categories I use.

There are two types of macros defined in IGDebug.h: logging macros intended for use in debug distributions only, and macros that should produce log output in all distributions. The debug versions are prefixed with “IGD” and the always log versions are prefixed with “IGA”. There are four different macros in each set:

  1. IG?Log — functions as a simple wrapper for NSLog, adds no extra output
  2. IG?SLog — adds the self pointer to the log output using <%p>
  3. IG?FLog — adds the file name and line number to the log output
  4. IG?SFLog — adds the self pointer, the file name, and line number to the log output

The debug versions of these macros also include two additional parameters to control the logging level and assign it to a category. The logging level parameter should be an integer, and will be compared to the IGDBG_MAX_LOG_LEVEL definition defined in IGDebug.h. The category can be any value that evaluates to true or false — in my exmaples I use simple #define values of 1 or 0 to enable or disable log output for that category.

Example usage

IGConstants.h

#define GESTURE 1
#define SUBGESTURE 1
#define TOUCHINFO 1

IGTouchInfo.m

- (IGTimeAndPosition *) addCurrentTimeAndPositionInView:(UIView *) view {
    IGTimeAndPosition *timeAndPosition = [[IGTimeAndPosition alloc] initWithTime:[NSDate timeIntervalSinceReferenceDate] position:[touch locationInView:view]];
    IGDSFLog(IGDBG_DEBUG, TOUCHINFO, @"createCTAP: %@(rc=%u)", timeAndPosition, [timeAndPosition retainCount]);
    [timeAndPositionArray addObject:timeAndPosition];
    [timeAndPosition release];
    return timeAndPosition;
}

Caveats

Because these are macros, you may find cases where values you want to display confuse the preprocessor. As a workaround, I added a IGDStatement macro that simply wraps an existing single Objective-C statement. The intent is to be able to calculate a value to use in a logging statement that is only included when IG_DEBUG_MODE is defined.

Example usage of IGDStatement

...
    CGFloat movementRange = [touchInfo movementRange];
    NSTimeInterval timeDiff = [touchInfo timeDifference];
    IGDStatement(CGPoint min = [touchInfo minimumPosition];)
    IGDStatement(CGPoint max = [touchInfo maximumPosition];)
    IGDFLog(IGDBG_DEBUG, SUBGESTURE, @"min=%f,%f max=%f,%f range=%f, time=%f", min.x, min.y, max.x, max.y, movementRange, timeDiff);
 ...

Conclusion

Feel free to use IGDebug.h as-is or however you wish in your projects. If you have improvements, I’d love to hear about them in the comments or on twitter.

I have been using a form of this in my projects since spring, and it is finally becoming a habit for me. Whatever tools you use, getting to the “I don’t have to think about this” level is important for your productivity, so choose a few and get in the habit of using them, whatever they are.


As an indie developer, one of the best things you can do is to find like-minded developers that will provide encouragement and motivation while pursuing a commitment. A great collection of indie iOS developers have helped me stay on track, most of them are either developers associated with iDevBlogADay, or those I have met through the 360iDev conferences. I am writing this from the lobby during the pre-conference day of 360iDev in Austin, and I am really look forward to the conference.

Also, here is a little more information about me, Doug Sjoquist, and how I came to my current place in life. You should follow me on twitter and subscribe to my blog. Have a great day!