A Couple of iOS 7.1 UI Development Surprises (not the good kind)

Custom Track and Progress Images for UIProgressView broken

If you set trackImage and progressImage in UISliders, you’ll find these have broken in iOS 7.1.  They will be ignored and you will get the standard slider (at the standard 2 pixel height) instead.

Accessibility Bold Text affects images drawn with UIImageRenderingModeAlwaysTemplate

We are using ‘template’ images (UIImageRenderingModeAlwaysTemplate) for all of our buttons, so that iOS draws them using the shape of the image and a tint color.  However, in iOS 7.1, if the user turns on Bold Text under Accessibility, then all images drawn with the template rendering mode will have their pixels expanded to simulate a bold look.  For example, here is an image of a UIImageView and UIButton that use UIImageRenderingModeAlwaysTemplate with Bold Text turned off:

normalAnd here is the same app with Bold Text turned on:

bold

 

So, if you plan on using template images, be aware that they might be affected by accessibility settings.

 

NSURL fileURLWithPath changes behavior in iOS 7

Another interesting issue found today.  NSURL fileURLWithPath has changed behavior in iOS 7.

Before iOS 7 it would return a fileURL with file://localhost prepended to the path passed in (so passing in “/var/test” would return “file://localhost/var/test”)

In iOS 7 it returns file:// (so passing in “/var/test” would return “file:///var/test”)

 

UITableView Color Changes in iOS 7

Before iOS 7, the default background color for a UITableView was clearColor, and UITableViewCells by default took on the UITableView’s background color, so there was virtually no work setting up our tables in iOS 6.

When you switch to Xcode 5, your tables will default to the new iOS 7 behavior.  UITableView’s have a white background color by default, so you must change it to clearColor either in Interface Builder or programmatically.

More importantly, UITableViewCell’s no longer pick up the background color of the UITableView and are white by default. Setting the backgroundColor in InterfaceBuilder for a UITableViewCell has no effect (to my surprise I guess this has always been the case).

So, the “correct” way (based on Apple’s documentation in UITableViewCell) to set the UITableViewCell’s backgroundColor is to do it in the UITableViewDelegate willDisplayCell method, as shown here:

 

- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
    cell.backgroundColor = [UIColor clearColor];
}

Also, be sure your UITableViewCell’s contentView.backgroundColor is also set to clearColor (this can be done in Interface Builder).

 

I have found though that I can set the backgroundColor when I deque the cells in cellForRowAtIndexPath, but I’m not 100% sure this will work in all cases.

 


					

Nostalgia for the Amiga

I just finished reading the current set of articles on ARS Technica about the history of the Amiga computer (http://arstechnica.com/gadgets/2007/07/a-history-of-the-amiga-part-1/).  It brought back great memories for me.  I was a Commodore fanatic from the time I got my Vic 20 at age 15, and the Amiga really was something unique and ahead of its time.  While I’ve long since lost my religious devotion to the Amiga, it still holds many fond memories for me, and was the foundation for my career in video software engineering.

While finishing my degree, I worked for Armadillo Brothers, a local computer chain that sold Amiga computers.  Many of the customers we sold to used the Amiga for video, and I ended up creating tools for them to do more with it.  One tool I created was a sing-along titler used by Living Scriptures for some of their animated videos (I didn’t have a good sense of the value of what I had created, and sold it to them for $30).  I loved creating software for the Amiga, it was so far ahead of its time in many of its operating system design concepts, and much of what I learned there has served me well in creating software throughout my career.

After college, my friend and colleague from Armadillo Brothers, Steve Gregerson, contacted me with his idea for Hollywood FX, so over 6 months in the basement of my first house, I created the software for Hollywood FX.  We released Hollywood FX a few months after Commodore went out of business, yet it still sold well enough to establish our business and become the foundation for the PC and Mac versions. It didn’t have any rendering code of its own.  It used AREXX to control Newtek’s Lightwave to render 3D transitions with multiple inputs.  AREXX also controlled separate frame store devices (ADPro and Video Toaster Flyer) to pull frames one at a time to use for texture mapping, and to write the resulting frames back out to the device.  A 1 second transition could easily take all day to render, but the quality was great, and it was a relatively inexpensive product for creating amazing 3D effects.

The Amiga version led to the creation of the Windows and Mac versions of Hollywood FX (which had their own OpenGL-based rendering engine), which led to Pinnacle’s purchase of Hollywood FX, and my 13 years at Pinnacle, Avid and Corel, where I’ve built and rebuilt FX and video editing technologies, worked with an amazing group of people, and led the development of Pinnacle Studio for iPad which I’m happy to be working on every day now as part of my new company, Luma Touch.

 

My Keys For Successful Scrum: The Story of Poe

One of my main reasons for starting this blog was to share some of the stories from the development of Avid Studio/Pinnacle Studio for iPad, codenamed Poe. It was the first development where we really used Scrum, and it ended up being a very successful product, and an incredible learning experience. There are a lot of stories and thoughts to share from this development.  In this blog entry I want to share what I think are some of the key elements to successful Scrum, many of which are ignored by other Scrum teams I’ve seen.

Background

Early in 2011, after the release of Pinnacle Studio 14, the Pinnacle team at Avid went through a major upheaval (a nice way of saying 2/3 of the team was laid-off).  While that was an incredible blow to the team, it was also a chance to reorganize and try something new.  Toby Youngberg, the remaining engineer in my small office had just finished an iOS game on the side, and we discussed some ideas for video on the iPhone and iPad. This led to my proposal for a new video product on iOS, which would soon morph into Poe, a powerful video editor on the iPad.

For Poe, we were able to put together a small but really unique core team.  There were three full-time engineers: Toby Youngberg and myself in Salt Lake City and Oleg Tsaregorodtsev in Mountain View.  We also had Ray Johnson in Mountain View part-time, who helped with automation, localization, and so much more as usual). We had two QA engineers, Eddie Kestermont (who we nominated as ScrumMaster) and Eduardo Urrutia, and finally Terri Morgan in Seattle who was both product owner and designer (and had the distinct honor of having to prepare much of the material to satisfy the old product lifecycle process that Avid still held onto, hiding much of the tedious work from the rest of the team).

While this core team was responsible for the majority of the Poe product, it wouldn’t have been successful without a great deal of work from other teams and individuals.  These incredible people who all had a major role in Poe are listed in the Credits of Avid Studio and Pinnacle Studio for iPad.

So, with that basic background, here are the elements of Scrum that I think are most important based on our Poe experience.

1. Kick it off right

Getting a project started right can make a big difference in how it progresses.  The Poe team was lucky enough to come together for a full week of Scrum training with Bob Schatz of Agile Infusion (Avid had a clear mandate to move to Scrum for all development, and with a small remaining team, everyone was able to come together for this training).

This made a big difference in really understanding the foundation and details of Scrum. We had all thought we knew Scrum from previous projects, but we had only been following the basic mechanics, and were missing many of the key features that would bring us the most benefits (which is what this post is all about).

Even more important, on the last day of together, our team sat together in a room and kick-started the project from a Scrum standpoint.  We came up with a team name as well as amusing codenames for each member.  We developed the profile for our primary user, picked our ScrumMaster, and developed our initial backlog.

For our team’s mission statement, we wrote a loveletter to our users, telling them what it was we were trying to create and what we hoped they would get from it.

We created the rules for the team (if you were late or missed a stand-up more than once, you had to dance the Haka for all to see), and created our Definition of Done (see #6).

While we all knew each other well from years of working together, this was an important start to the project, where we all came together both physically and mentally.

By bringing your team together to kick-off a project, and making sure everyone is reasonably on the same page about the goals and rules of the project and team, things will run much more smoothly.

2. Pick the right ScrumMaster

I think a large part of the success of the Poe team was the choice of ScrumMaster: in our case, Eddie Kestermont.  The first time you meet Eddie, you’ll wonder what the hell you’ve gotten yourself into, but you’ll soon realize the intelligence, capability, and warmth behind the bold, big personality. He turned out to be the perfect choice for our team. He was strong enough not to be overriden by a very senior engineering team, and nice enough that when he told you to shut-up, you knew he meant it in the nicest way.  Eddie was also great at removing obstacles the team had in its way, which is a key responsibility for the ScrumMaster.  He also made retrospectives fun with trivia contests for prizes, and did a great job of facilitating planning meetings, stand-ups and retrospectives.

I recommend choosing a ScrumMaster who isn’t an engineer if possible.  In any case, pick someone who the team respects and who is dynamic and strong enough to stand up and remove obstacles both within and outside of the team.

3. Stand up in your stand-ups

I’ve seen so many stand-ups devolve into status meetings or technical discussions.  If your daily stand-ups our taking more than 10 minutes on average, then you either have too large of a team or you’re doing it wrong.  The first step to getting it right is to stand-up in your stand-ups. Many of us worked remotely, but we all stood up even on Skype, which felt a bit silly at first, but it made a difference.  It’s a reminder that you’re there to communicate what you’ve done, what you’re going to do next, and most importantly, are there any obstacles in your way.

Stand-ups will often lead to additional discussions after the stand-up or separate smaller meetings, but keep the stand-up simple, otherwise you’ll find yourself in daily hour-long meetings that you’ll quickly despise. Your ScrumMaster should be integral in keeping the stand-up on target, and in coordinating needed discussions.  You might get annoyed when he or she tells you to take the discussion offline, but you’ll appreciate it when you don’t have to lose time in endless discussions.

4. Communicate!

If you’re lucky enough to have a co-located team, you certainly have the best opportunity for success, but even in that case you need to work hard to make sure everyone communicates.  Often its a matter of personality.  Again, our ScrumMaster served an important role of drawing out quieter teammates to speak their mind.

If you’re geographically separated, make an extra effort to talk.  With Poe we really started using Skype to communicate regularly and less formally with separated teammates.  This face-to-face communication is critical, and much more effective than long email threads. We’d have design discussions where we would often draw something on paper and show it to others.  Remember though to follow-up a Skype discussion with a stored communication (email, Jira, Confluence/Sharepoint, Wiki) so that important decisions aren’t lost.

4. Break down your stories

I still see this as one of the biggest problems with Scrum teams.  I know that I personally had a tendency to  write what I thought was a pretty atomic story, only to realize that it could easily be broken down much further, and there was great advantage in iterative development to breaking it down that way.  For example, after the initial release of Poe, we finally got to Voiceover on our backlog.  Initially it was a single story, something like “As a documentary creator, I want to be able to add voiceovers to my video projects”.

After breaking it down, we had stories like:

  • As a user, I want a clearly understandable button to tap to bring up the UI for voiceover recording
  • As a user, I want a voiceover interface that shows which audio track I’ll be recording on.
  • As a user, I want the voiceover interface to default to the audio track with the most avialable time on it.
  • As a user, I want to be able to select any track to record a voiceover on.
  • Followed by another 20 stories that covered starting recoding, stopping recording, reviewing, keeping, canceling, etc.

When you’re in a sprint planning meeting, take the time to break down your stories to a point where each story is a manageable chunk of a couple of days work at most.  That should be further broken up into tasks that can each be completed in a few hours.  It’s an amazing benefit to productivity.  There were many times when I’d just finished a big story and wasn’t ready to take on a major piece of work.  I could just pick up a small story, maybe a UI element that needed to be added, and knock it off in 1/2 hour.  It would often kick me back into gear when I was drifting.

5. Don’t get locked into specific roles

Engineers on a team have a natural tendency to try tand divvy up stories and tasks at the beginning of a sprint based on their knowledge domains.  I strongly recommend avoiding this.  At least leave the option that different team members may take different roles during a sprint. With Poe, it was somewhat of an advantage that we were all fairly new to the platform, and even Toby who had the most experience still had a great deal to learn for the complexity of the product we were creating.

If your stories are broken up properly (#4), there is more of an opportunity for engineers to cross into new domains without it being too much of a burden on existing experts in that domain, and it will pay off in the long run.

6. Always follow your Definition of Done

Many Scrum teams don’t even have a definition of done, and for many that do, this is is the first thing to get lost, which was our problem with Poe.  The Definition-of-Done defines all the common elements required to consider a story or epic complete.  We had a good initial Definition of Done, including things like:

  • The product must build without any errors or warnings
  • All strings must be added for localization.
  • All automated tests must complete without failure.
  • All bugs reported by QA must be resolved.
  • Must have designer sign-off
Early on, we did well at this, making sure we checked off the Definition-of-Done items for every story, but after hitting a couple of roadblocks on the way that slowed down development, we started skipping some of these steps to try and get the product finished faster.  Within weeks we were seeing more crashes, more bugs that were propogating through the product, and it felt like we were moving towards disaster.  We ended up taking a sprint just to get back to a reasonable level of quality, and tried harder after that to stick to the Definition of Done.  Even after that, we weren’t careful enough to make sure every story really met our definition of done, and we paid the price, spending the first few months after shipping getting stability to a reasonable level.
This may be the hardest rule to follow, but it may be the most important.  You should set a clear Definition-of-Done up front for your project, and you shouldn’t consider a story complete until it’s met that defnition.  It’s much better to ship a high-quality product with features left on the backlog then spending time trying to recover stability in a large code base.

9. Sprint Reviews and Sprint Retrospectives

This is another area that I think many Scrum teams miss out on.  It’s something we did well with Poe, and it paid off. At the end of each sprint we would have a Sprint Review to demonstrate the completed stories from that sprint, and most importantly we would have a user demo to get feedback.  We brought in a variety of different types of users, including: professional editors, people from other divisions at Avid, even friends and family with a passing interesting in video.

Early on, it seemed like it would be silly, when all our app did was launch and display an image of the team, but we were always pleasantly surprised by the user feedback we would get that ultimately shaped a better product. New bugs would appear and things we didn’t notice were major blockers for users.  Try not to guide your users too much, instead give them a task to perform with the product, and let them try and figure out how to use it.  You’ll learn a lot watching a user struggle with something you thought was completely obvious. Don’t dismiss any feedback from your user demos.  Get everything into your backlog. Sometimes it’s the little things that will make the biggest difference.  Finally, reward the users who come in for a demo (in our case it was with a free Avid product, but it could be anything, including a $10 iTunes gift card).

After the Sprint Review, have a Sprint Retrospective with just your Scrum team.  This should be an opportunity to really look at what worked well and what didn’t from a Scrum-process perspective.  Were you overoptimistic about what was brought into the sprint, did you break up stories well, how was communication.  Did you really follow Definition-of-Done.  How did the demo go.  Are your stand-ups getting out of control.  Are there some things you can tweak to make it better.  Are there some major process-wide obstacles that need to be worked.  It’s here where you’re going to tweak and iterate the Scrum process itself to better meet your needs.

10. Don’t be afraid to iterate, which often means throwing hard work away

Scrum is all about iterative development.  Part of that is being willing to throw work away.  Early in the development of the storyboard/timeline concept for Poe, we realized that there were many things that just didn’t feel right about it.  We took one sprint to completely redesign the UX for the timeline.  After that rewrite, we did user reviews and found that our great new design was even worse.  So we threw that away, and wen’t back to a variation of the original design, but with numerous tweaks that came together to make it feel right. There were many other times during development where we went down a path only to find out that it didn’t pay off with the user like we thought it would.  Source control is your friend here.  We found ourselves cherry-picking from some of the dead-end paths we had gone down to more finely tune the final direction we chose.

This doesn’t mean just randomly picking a direction and heading there.  Your team should be making intelligent choices based on their experience, but it’s also easy to get locked into endless discussions about the “right” way to do something.  Sometimes you just need to pick one of the best choices and give it a try, with a willingness to drop it and start over if it doesn’t work.  If you keep things granular enough in your stories, then this usually means a few days work at most.  Hopefully going down that path also helps you learn something important about the right direction to head.

Bonus: Go around, climb-over, dig-under, blast a hole through

If there is one thing that resonated most in our training with Bob Schatz, it was this.  When you hit an obstacle, you need to find a way around it.  During the development of Poe, we ran into some major limitations of the iOS platform for video (which is amazingly powerful, but necessarily limited).  For example, one of the early obstacles was finding out that even though photos could be loaded as AVAssets, they couldn’t actually be used in a video composition.  So we quickly created a simple architecture that would render a photo into a small video clip that could be added to a composition (we realized later that this was exactly what iMovie was doing as well). Some of the obstacles we hit could have derailed the entire product, but we became master ninjas in finding ways to circumvent them.  Sometimes this meant redefining some feature, other times it meant finding some workaround that was “good enough” that would later be iterated into something more elegant.

Whenever you hit an obstacle, take a step back and figure out a way to get around it, over it, under it, or through it.  Talk to your team about the obstacle and listen to their ideas, particularly the non-engineers.  Often your first thought to an idea will be, that’s impossible!  But sometimes those impossible ideas will spark something that will end up being the perfect path.

Conclusion: Have Fun and Iterate Everything

Poe was an incredible experience, both in creating a product that I love, and in gaining a better understanding of the advantages of Scrum (as well as some of the pitfalls). It was also the most fun I’ve had engineering in a long time.

Remember that Scrum itself is something you need to iterate.  If you’re doing the same thing every sprint and every project, then you’re missing the point.  Scrum is a framework that you need to change and adapt constantly.  So keep iterating and have fun.

 

Adding Exception Breakpoints in XCode

I’ve been using XCode for over 2 years now, and had missed one important debugging feature (and my life has been more difficult for having missed it).

In the Breakpoints navigator, you can click on the + (add) button and select “Add Exception Breakpoint”. The dialog that appears will let you select specific breakpoints, classes of exceptions to break on, or let it break on all exceptions.

Without this I was guessing where the error occured. Luckily I was often correct, but what a waste of time.

Instantiate Storyboard ViewControllers Manually

Quote

I’ve started using storyboards in XCode/iOS more frequently, but I really needed something different from the normal segues and connections that Apple provides, and while Apple briefly documents how to do this, I thought I’d share my example.  Here is the view in Interface Builder of the test app that I created:

My initial controller is on the left, and the blue area is simply a UIView that I’ve connected to  a member variable outlet named _parentView.  This is where I want my yellow and pink sub views to appear, each handled by their own controller.  Notice that there is no connection between the storyboards in this case.  The key here is to set the Storyboard ID for yellow and pink View Controllers so I can instantiate them in my code.  If I don’t set a storyboard id for the yellow and pink View Controllers, I’ll get a warning from XCode that they are unreachable. You set the Storyboard ID in the Identity inspector (see the inspector panel on the right in the picture above – make sure ‘Use Storyboard ID’ is checked).

Once I have storyboard IDs set for each of these view controllers, the code is quite simple to instantiate the view controllers and embed them using the parentView as a container.

- (IBAction)showView1:(id)sender 
{
  [self switchViews:@"yellow"];
}

- (IBAction)showView2:(id)sender 
{
  [self switchViews:@"pink"];
}

- (void)switchViews:(NSString*)storyboardId
{
  __block UIViewController *lastController = _childController;

  _childController = (UIViewController*)[self.storyboard instantiateViewControllerWithIdentifier:storyboardId];
  [self addChildViewController:_childController];
  [_parentView addSubview:_childController.view];

  CGRect parentRect = _parentView.bounds;
  parentRect.origin.x += parentRect.size.width;
  _childController.view.frame = parentRect;
  _childController.view.alpha = 0;
  [UIView animateWithDuration:0.5 animations:^{
    _childController.view.frame = _parentView.bounds;
    _childController.view.alpha = 1.0;
  } completion:^(BOOL finished) {
    if (lastController)
    {
      [lastController.view removeFromSuperview];
      [lastController removeFromParentViewController];
    }
  }];
}
The basics in the code above:
- Keep a pointer to the last view controller child
- Use instantiateViewControllerWithIdentifier using the storyboard id you set in interface builder to create and return the view controller.
- Add the new controller as a child controller to the parent
- Add the new controllers view as a subView to the parent
- Then for fun I animate the new controller onscreen
- When the new view is fully animated, then I remove the old view
With this basic flow, you can customize the user interface in just about any way you can imagine.

Welcome to Average Pro

I’ve followed a number of interesting blogs from a wide range of software engineers, and finally decided that I would add my voice. I’ve been lucky enough to have a wide range of experiences in software engineering and business startup, and hope that some of the things I post might be useful to others.

What really inspired me was my wife coming up with the name Average Pro while trying to come up with a company name.  I didn’t think it was right for a company name, but thought it was perfect for my blog.  It’s how I see myself, as an average professional.

So what makes me qualified to share my experiences and thoughts (other than being a living being like anyone else)?  I’ve been writing software for 33 years (since I was 14, I’ll let you do the math).

I started my career after high school working for a hotel software company.  During college I sold Amiga computers and wrote a number of general-purpose and video-related programs (this was before they were called apps of course). After college I worked for a company that created factory and warehouse automation software.

In 1993, I co-founded Hollywood FX, which was a small but profitable company that made 3D video effects plugins for non-linear editing software.  We sold Hollywood FX to Pinnacle Systems in 1999, where we integrated Hollywood FX and our content licensing software into the Pinnacle Studio product line. Pinnacle was purchased by Avid in 2005, and I continued to work there, creating a new 3D video processing engine, a new animation system, Motion Titler, and much more.

In July of 2012, Avid sold its consumer video division to Corel.  I stayed with Corel for 5 months, and decided it was time to move on.  In November 2012, I joined Condition One, an exciting startup that’s created a unique immersive video technology.

During these many years I’ve learned an incredible amount, and found that there is still an incredible amount to learn.  This blog is my effort to share what I’ve learned both in software engineering and business.  I hope you’ll find something of value.