Think, Think, Think…

Filed in iDevBlogADay, Miscellaneous | Comments Off on Think, Think, Think… |

Think, Think, Think...

Think, Think, Think…

One of my favorite shows to watch with my young children was Winnie The Pooh — perhaps because I had good memories of watching the classic TV specials from when I was a child.

I loved the simple, happy nature of Pooh, but one downside of being stuffed with fluff is that it can be hard to think. Pooh occasionally worked very hard at it, with very limited results. I’m pretty sure my head isn’t stuffed with fluff, but some days my thinking doesn’t seem to get me any farther than Pooh’s did.

Lost in Thought — An Incredible, Productive Day

In developing software, my primary tool is my mind. Languages, frameworks, IDE’s, and editors all are important — but without the right mind to use them, and the right frame of mind, they are worthless.

My family can tell you that watching me work some days is incredibly boring. Much of those days is spent staring at the screen, at some scribbles on notepaper, or blankly into space. Those are often the days where I make the most progress.

My most productive days are when I’m so deep in thought that I don’t even remember to eat. I love those days. It’s like I can see the entire program as a single entity in my mind–I can turn it over and around, zoom in and out, pull one part out, graft something new in–it’s a incredible feeling. I wish they happened more often!

Holding it in your head

Paul Graham describes that feeling as “Holding a Program in One’s Head“. He writes:

They do more in their heads: they try to understand a problem space well enough that they can walk around it the way you can walk around the memory of the house you grew up in. At its best programming is the same. You hold the whole program in your head, and you can manipulate it at will.

He goes on to list ways to help load the entire program into your head. I may quibble about some items, but the point is valid. In order to get to that incredible, lost in the world of my program point more often, I need to figure out deliberate steps that move me away from Pooh-thinking and into that magical place.

From Pooh to TRON

There are a number of tactics I use to de-fluff my mind and achieve TRON-ness with my program, but none of them work every time, and each of them are subject to exceptions.

Working at a consistent level

  • I try to stay at a consistent level of abstraction as long as possible, switching costs between working on high-level designs and low-level implementation details can be high.
  • Rather than switching back and forth between competing projects throughout the day, I try very hard to spend most of the day on a single project — even if it is not the exact same task.

Managing distractions

  • Some interruptions are predictable, so preempt them and deal with them before they attack. (If you work at home, this may mean keeping up properly with your share of household duties before you begin.)
  • Have a notebook or software tool that allows you to quickly record any unrelated items demanding attention. Do not do any real thinking about it, simply record it. Once recorded, dismiss the thought and go back to work, those items are attacks on your concentration — do not give ground. (This only works if you have a reliable system for addressing those items, otherwise your mind will not let go.)
  • After you finish a session, deal with the items you recorded appropriately if necessary. That way you train yourself to trust that you really will “deal with that later”.
  • Schedule times or days where coworkers or family know you need to be left alone, in cooperation with them of course! On-going communication is key.
  • If twitter, facebook, news readers, or email keep pulling you away — just STOP IT.

Achieving Flow quickly

  • When you finish a session, or are interrupted, record what you are thinking or doing so that you don’t lose all your context. (See the excellent advice in the post “the interruptible programmer“.)
  • Use music, headphones if necessary. I listen to a lot of different kinds of music, but my “flow” music tends to fade into the background quickly and support my thinking, rather than require me to pay attention to it directly. For me, that usually means minimal or no lyrics, but everyone is different in that regard.
  • If you are actively working on code, then leave it in a mildly broken state. Put some notes directly in the source file where you left off so it won’t compile, add a failing unit test, something to draw your attention back to the point you left.

Manage your expectations

I don’t believe it is possible to be so consistent at your work, that you never suffer from Pooh-thinking days. So don’t set your expectations so high that your disappointment becomes a serious distraction all by itself.

You goal should be improvement, and perhaps even that “perfect” day — but don’t let the fluffy-head days get you down. There’s a good chance tomorrow will be a better day.


We all need the support of others to do our best. Find other like-minded developers that will provide encouragement and motivation through local user groups, regular conferences or meetups. This post is part of iDevBlogADay which has really helped me stay on track with my writing and my iOS projects.

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!

Open Source iOS CoverFlow Implementations

Filed in iDevBlogADay, iOS Development | Comments Off on Open Source iOS CoverFlow Implementations |

For my personal iOS development, I have a technical experiment and exploration todo list. It includes techniques I need to get better at, open source packages to investigate, that sort of thing.

I try to keep the items on the list small enough to do enough prototyping in a single evening to satisfy my curiosity. That way I am willing to move on during my next exploration session. The point is not usually proficiency, but enough familiarity to decide if the technique or framework merits further study. I often keep the code around as a reference, but it is definitely throwaway code, so it’s in a separate folder than “real” code.

One of the items on my list was to find and investigate CoverFlow clone examples floating around the intertubes. I found several that were based on Apple’s private APIs or were old enough that I was not interested. But, I did find two that I spent some time investigating.

OpenFlow, a CoverFlow clone developed during iPhoneDevCamp

The first was OpenFlow by Alex Fajkowski, released at iPhoneDevCamp in August, 2009. It is hosted on GitHub, but it does not look like it has been updated since then.

There is sample code included with the OpenFlow download, but it does not have a simple, quick-start example to get an initial feel for the package. Fortunately, others have written posts with some simple examples, two I looked at were:

A simple example by Julios Barros’ (@juliobarros).

And another simple example, but with more pictures and step-by-step details.

I liked OpenFlow well enough, but the current implementation did not allow for flicking through multiple covers. It behaves a little more like iTunes on the mac, not like browsing albums on the iPhone iPod app. Fortunately, my other “find” did have better flicking behavior, with tweakable momentum settings.

FlowCover, an easy to use OpenGL ES based CoverFlow clone

My other “find”, FlowCover by William Woody is essentially one OpenGL ES class with a simple helper class for data caching.

I like simple. Since I am likely to tweak the behavior of whatever I find, the simpler and cleaner the starting point — the better.

I added the two classes to my prototyping base project, and I was off and running. FlowCover works pretty much as expected, behaving smoothly and simply. The only change I made to FlowCover.m was to allow for different scaling when in landscape and portrait modes. Other than that, it worked just as I wanted.

Conclusion

If you are interested in adding some Cover Flow type behavior to your app, I recommend checking out both projects.

OpenFlow is based on UIKit, and has more features than FlowCover.

FlowCover is based on OpenGL ES, has few features, but behaves a little more like I expected Cover Flow on an iPhone to behave.

Either is a good choice, but my needs are simple enough right now that I think I will be using FlowCover.


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!

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!

Adding subgestures to iOS gesture recognition

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

I want users of my photo application to feel like they are physically manipulating their old stack of photos. To do that well, it needs the ability to respond to multiple simultaneous touches and movements in a consistent and coherent manner. UIGestureRecognizer provides an interpretive layer that I like, but it is designed around UIEvent and handles touches in sets.

UIGestureRecognizer’s multitouch recognition is elegant, but not exactly what I want. I hope to develop a set of classes for subgesture recognition that follows that style for individual touches, interpreting the user’s intent for each touch independent of other touches. For example, one touch may be interpreted as a pause or hold gesture, while simultaneously another touch is recognized as a single tap, and yet another as a swipe, all without regard to the UIEvent or when other touches began, moved or ended.

Multitouch Events and UIGestureRecognizer

In The Joy of Gesture Recognizers in iOS, I gave a quick overview of UIGestureRecognizer. It is an interpretive layer that takes the raw data of touches, applies some internal rules, and produces a higher level answer when it “recognizes” the user’s intent.

UIGestureRecognizer happens within the context of a single UIEvent. In all iOS touch handling, when the first touch is made, a UIEvent is created. As long as there is at least one touch still active, the UIEvent instance stays the same, and all touch events reference that same instance. Instances of UIGestureRecognizer use that behavior to decide between competing possible gestures. A single UIEvent instance may contain multiple touches but is usually interpreted as a single gesture. (The framework does support other options.)

The set of possible gestures is limitless, but only a subset are very useful. A simple programming exercise to explore multiple touch events can show some interesting possibilities. For instance, write a simple app that merely prints out individual touches and experiment with adding and removing touches within the same event. You will find that you can end up with five completely different touches than those you began with. Since this is all within the same UIEvent, they could all be used to create a very convoluted recognizer (not recommended.)

Generating Subgestures From Individual Touches

If you need to manage touches individually, you can ignore the UIEvent and track each touch yourself. But this means gesture recognition is all on you and the UIGestureRecognizer related classes will not help. The framework I am developing uses subgesture recognizers to interpret the timing and position of individual touches.

The core class is the custom gesture recognizer, IGIndividualSubgestureRecognizer. It’s primary responsibility is to track individual touches and delegate touch events to it’s list of subgesture recognizer (subclasses of IGSubgestureRecognizer) for subgesture recognition. Once an individual touch’s behavior has been recognized by one of the subgesture recognizers, all others will be cancelled. The current version is limited to recognition within a single UIEvent which means something like a single touch, double tap cannot yet be recognized. I want to add the ability to cross the UIEvent boundary in a future version.

IGIndividualSubgestureRecognizer maps each touch event to an instance of IGTouchInfo. These instances track the time and position of each touch event that subgesture recognizers can use to interpret the behavior. IGSubgestureRecognizer instances maintain the current state of each touch in relationship to itself. Once the touch reaches one of the final states for a particular subgesture recognizer, the controlling class IGIndividualSubgestureRecognizer will no longer pass on further events for that touch to that subgesture recognizer.

So if one IGSubgestureRecognizer instance recognized a subgesture for a given touch, then IGIndividualSubgestureRecognizer would set the state of that touch to cancelled for other IGSubgestureRecognizer instances. Once that happens, no instances would receive further events for that touch since one reached a successful final state, and the others reached a cancelled final state.

Subgesture recognizers inherit from IGSubgestureRecognizer. They only need to override the touch event methods and call the setState:forTouch: method when a gesture is recognized or not.

IGSubgestureRecognizer.h

@protocol IGSubgestureRecognizerDelegate<NSObject>
- (void) subgestureRecognizer:(IGSubgestureRecognizer *) subgestureRecognizer
                     forTouch:(IGTouchInfo *) touchInfo
                 changedState:(UIGestureRecognizerState) state;
@end

@interface IGSubgestureRecognizer :NSObject {
    NSMutableDictionary *touchInfoStateMap;
    IGIndependentGestureRecognizer *independentGestureRecognizer;
    id<IGSubgestureRecognizerDelegate> delegate;
}

- (id) initWithIndependentGestureRecognizer:(IGIndependentGestureRecognizer *) aIndependentGestureRecognizer delegate:(id<IGSubgestureRecognizerDelegate>) aDelegate;

- (UIGestureRecognizerState) stateForTouch:(IGTouchInfo *) touchInfo;
- (void) setState:(UIGestureRecognizerState) state forTouch:(IGTouchInfo *) touchInfo;
- (BOOL) isActive:(IGTouchInfo *) touchInfo;

- (void) reset;
- (void) touchBegan:(IGTouchInfo *) touchInfo;
- (void) touchMoved:(IGTouchInfo *) touchInfo;
- (void) touchEnded:(IGTouchInfo *) touchInfo;
- (void) touchCancelled:(IGTouchInfo *) touchInfo;

@end

IGSGRTap is an example of a simple single tap subgesture recognizer.

IGSGRTap.m

@implementation IGSGRTap

static NSTimeInterval maximumTimeDiff = 0.2;
static CGFloat maximumMovementRange = 5.0;

- (void)touchEnded:(IGTouchInfo *) touchInfo {
    CGFloat movementRange = [touchInfo movementRange];
    NSTimeInterval timeDiff = [touchInfo timeDifference];

    // a single tap is defined by the maximum time the touch was down,
    // and the maximum range it moved (allow a little shaking, but no real movement)
    if ((timeDiff < maximumTimeDiff) && (movementRange < maximumMovementRange)){
        [self setState:UIGestureRecognizerStateRecognized forTouch:touchInfo];
    } else {
        [self setState:UIGestureRecognizerStateFailed forTouch:touchInfo];
    }
}

- (void)touchCancelled:(IGTouchInfo *) touchInfo {
    [self setState:UIGestureRecognizerStateCancelled forTouch:touchInfo];
}

@end

IGSubgestures Project Will Be Released to GitHub at Some Point

I have the underlying subgesture recognition working, and will be adding recognizers to match these recognizers available in the UIGestureRecognizer family:

  • Single Tap Gestures
  • Swipe Gestures
  • Pan Gestures
  • Long Press Gestures

Once those are working, I want to add things like flick gestures and single touch spin gestures.

I will be posting the code to github at some point, no promises on exactly when, but I do hope to have a version uploaded before November is over. I will write up a new blog post when I publish the code, so if you are interested, either follow me on twitter, or subscribe to my RSS feed. The license will be something very simple so that you will be able to use it in your own code with no worries.

Please let me know what you think on twitter or in the comments below.


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. If you can make it to Austin in November, I highly recommend it for its content, the friendships you’ll develop, and the passion it will bring to your iOS development.

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!

Advice for Indie developers with young families

Filed in iDevBlogADay, Miscellaneous | Comments Off on Advice for Indie developers with young families |

Take advantage of those serendipitous moments

Twelve years ago, I went independent full time with kids aged 11, 10, 8, and 6 (the youngest just stared college this fall.)

One of the great parts was my ability to alter the day’s schedule on very short notice. There are so many cool things you can do that cost very little but help create memories for a lifetime, especially with younger kids. I am very grateful that I was able to take advantage of my independence in many big and small ways.

Sometimes, the best things come together quickly, and as an indie, you are in a position to take advantage IF you are watching for them. A beautiful early spring day becomes an afternoon bike ride with work pushed to later in the evening. A rainy summer afternoon turns into a mudsliding event for you and the kids. When you get stuck on something, sometimes the best antidote is throwing a frisbee around or playing whiffle ball in the back yard. And the sledding hill is great fun on those snow days!

Include family events in your plans and schedule

Trips to special places can be much less crowded during the week, often cheaper as well. Museums on a weekday are wonderful, camping in the middle of the week instead of crowded weekends gives a much more relaxed time.

With a flexible schedule, you may be able to participate in more of your children’s activities. Coaching youth sports becomes easier to schedule, watching ballet practice or attending concerts, especially when you have multiple kids, can be much less stressful. Taking your kids and their friends to a matinee of the latest Pixar event can be a lot of fun (and very noisy!)

Invest time in building relationships with your kids when they are young

The single, best piece of advice I can give you to prepare yourself for adolescence is to develop a solid relationship with each of your children before they reach that stage.

Infants and very young children quickly develop a complete trust in you as parents that will last for their first few years. A key task for you between those early years and adolescence is to take that trust that is given without reservation, and develop it into a trust based on love, knowledge, and real events. Through the elementary years, work towards giving your children reasons to hold onto and build on that trust. You want them to know that even when they don’t agree with you, you always have their best interest at heart.

As they get older, they may not acknowledge that they can trust you, and may even deny it outright, but it will be an undercurrent to their thoughts, and it will certainly be an influence in their life.

Seize the day

Enjoy these days. They can be stressful, tiring, and tons of work, but enjoy the bright spots.

Remember, the best family memories are built through the drip drip drip of many simple events that occur regularly over the years.

I know it’s almost a cliche, but this time will pass incredibly fast. So, seize the day.


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. If you can make it to Austin in November, I highly recommend it for its content, the friendships you’ll develop, and the passion it will bring to your iOS development.

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!

The Joy of Gesture Recognizers in iOS

Filed in iDevBlogADay | Comments Off on The Joy of Gesture Recognizers in iOS |

Choosing Gestures for an App

Gestures play a role in an iOS app similar to that of game mechanics — they are the primary contact your user has with your app, and it is important to get them right. Choose something cutting edge, and your users may just not get it. Choose to use just the old, basic ones, and your app will probably not be taking full advantage of the iOS environment. Take a standard gesture and give it a different meaning than most apps, and you will most definitely confuse the user.

Your gestures should:

  • Feel natural to your user in the context of your app’s primary purpose (it does have a single, overriding purpose, does it not?)
  • Not violate standard and expected usage if it is a gesture commonly used across apps
  • Be consistent with other gestures used within your app
  • Be as simple as possible and still accomplish their intended goal

I am implementing a simple, continuous photo stream and wanted a set of gestures to easily manage the flow. I needed gestures to manipulate the stream by:

  • Starting it moving,
  • Speeding it up,
  • Slowing it down,
  • Reversing its direction,
  • Temporarily pausing it,
  • Manually moving the stream back and forth while paused.

I decided to use standard swiping gestures to control the direction and speed of the photo stream, and a custom continuous gesture recognizer to implement the pause and manual movements.

The Joy of Gesture Recognizers

Gesture recognizers were introduced in iOS 3.2 for use with the iPad, and later in iOS 4.0 for the iPhone and iPod Touch. If all you need are the built-in gestures (there are six), then you may not have to deal with touch events directly at all.

I am using two instances of UISwipeGestureRecognizer to handle the swipe left and swipe right gestures to control the main flow of the photo stream, but none of the other standard recognizers worked for my pause and move gesture. UIPanGestureRecognizer only takes effect once movement is detected, and I need the pause to be effective on first touch. UILongPressGestureRecognizer handles the pause correctly but fails once movement is detected. The gesture processing allows me to customize how recognizers interact with each other, but not in a way I needed. Fortunately, it is pretty straightforward to add a custom recognizer, so I wrote PauseAndMoveGestureRecognizer.

Multiple Gesture Recognizers

My custom recognizer is a continuous recognizer. That means my app receives events when recognition begins, for each movement, and when the gesture ends. I pause the photo stream when recognition begins (upon first touch), and manually move the stream back and forth depending on the movement events generated while the touch is still active. Upon receiving the gesture end event, I allow the photo stream to continue moving as before.

The swipe gesture recognizers are used to change the speed and direction of the photo stream. For instance, by repeatedly swiping left, you can speed the stream up in that direction. Swiping right would then slow the stream down, and so on.

Conflicts Between Gesture Recognizers

An important issue to consider is what behavior you want when multiple gestures are possible at the same moment. When my photo stream is moving across the screen and I touch the stream, it could either be the beginning of UISwipeGestureRecognizer or PauseAndMoveGestureRecognizer. I initially tried to use a single touch for both types of gestures, but could not find a reliable method to do so because of the interaction between my custom recognizer and the other gestures.

By default, gesture processing will generate multiple gesture events for the same set of touches (assuming they fit the pattern of each.) The simplest example is including both a single tap gesture and a double tap gesture: in order to have a double tap, by definition you will first have a single tap. The default behavior is to send both events so that your app will first receive the single tap event, then the double tap event.

I used a timer ([NSTimer scheduledTimerWithTimeInterval:…]) to set a threshold for the pause, and it worked fine when it was the only recognizer involved, but it did not trigger the “Began” event when the swipe gesture recognizers were also included. I assume I was violating some assumption or restriction of the gesture processing by using my own timer event inside the recognizer. (I ended up doing something slightly different which I like better anyway.)

My next attempt was to call the ‘requireGestureRecognizerToFail’ method on my pauseAndMoveGestureRecognizer instance for each of the swipe gestures. By doing this, when either of the swipe gestures is recognized, the gesture processing will cancel my pauseAndMoveGestureRecognizer. If the gesture processing determines that neither swipe gesture is possible, then processing of my custom recognizer continues.

Unfortunately, even though my processing continued, the timing of the events was not what I wanted.

My Custom Gesture Recognizer: PauseAndMoveGestureRecognizer

What ended up working the best was making the swipe gestures require two touches, and the pause and move gesture a single touch. I think this will be clearer to users and also removes any delays, however slight, in pausing the stream.

As you can see from the code below, there is not too much to creating a custom recognizer. Right now, I can’t envision gestures I would want that would not be possible using the UIGestureRecognizer classes.

PauseAndMoveGestureRecognizer.h

//
//  PauseAndMoveGestureRecognizer.h
//
//  Created by Douglas Sjoquist on 10/17/10.
//  Copyright 2010 Sunetos, Inc. All rights reserved.
//

#import <UIKit/UIGestureRecognizerSubclass.h>

@interface PauseAndMoveGestureRecognizer : UIGestureRecognizer {
    BOOL pauseStarted;
    NSUInteger numberOfTouchesRequired;
}

@property(nonatomic) NSUInteger numberOfTouchesRequired; // default is 1.

- (void)reset;
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event;
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event;
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event;
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event;

@end

PauseAndMoveGestureRecognizer.m

//
//  PauseAndMoveGestureRecognizer.m
//  BrowsePhotos5
//
//  Created by Douglas Sjoquist on 10/17/10.
//  Copyright 2010 Sunetos, Inc. All rights reserved.
//

#import "PauseAndMoveGestureRecognizer.h"

@implementation PauseAndMoveGestureRecognizer

@synthesize numberOfTouchesRequired;

- (id) initWithTarget:(id)target action:(SEL)action {
    if (self = [super initWithTarget:target action:action]) {
        self.numberOfTouchesRequired = 1;
    }
    return self;
}

- (void)reset {
    [super reset];
}

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    [super touchesBegan:touches withEvent:event];

    if ([touches count] == self.numberOfTouchesRequired) {
        self.state = UIGestureRecognizerStateBegan;
    } else {
        self.state = UIGestureRecognizerStateFailed;
    }
}

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
    [super touchesMoved:touches withEvent:event];

    self.state = UIGestureRecognizerStateChanged;
}

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
    [super touchesEnded:touches withEvent:event];

    self.state = UIGestureRecognizerStateEnded;
}

- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event {
    [super touchesCancelled:touches withEvent:event];

    self.state = UIGestureRecognizerStateCancelled;
}

@end

Update

Gesture recognizers are only doing a few simple things with touch events on your behalf so your view does not need to handle them directly.

When multiple recognizers are in play, the combination can be a little confusing, but the advantage of the recognizers is that each of them is looking for a single pattern of touch events. So although the interaction between recognizers may be complex, the internal behavior of a single recognizer remains relatively simple. As long as the set of touches does not violate what the recognizer expects as part of a gesture, it will remain “Possible”. At some point the recognizer will decide to accept or “Recognize” the gesture, or forget about it and “Fail” (for discrete gestures).

Recognizers still need to decide how to handle complex situations, just like you do with traditional touch event handling. Putting one finger down then another after a slight delay is an example of that–the recognizer will receive multiple ‘touchesBegan’ events with different sets of touches and must decide what to do about it. Well written recognizers will handle it smartly and consistently.

The benefit of using standard recognizers is that it simplifies your code, removing details from the main body of your work so you no longer have to worry about them. Also, by using them, you are simply following the standards for simple gestures that Apple is promoting, so your app will behave more like other apps on the device.

For custom recognizers, there are two benefits. One is that your recognizer only needs to be looking for a single pattern of events, keeping the code tighter and cleaner. Another is that once a recognizer fails or is cancelled, the gesture processing acts as a filter so that no further touch events with that particular set of touches will be sent to your recognizer.


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. If you can make it to Austin in November, I highly recommend it for its content, the friendships you’ll develop, and the passion it will bring to your iOS development.

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!