17 Nov 2015
I'm a huge fan of Sean Rose. He is a forward-thinking mind in the world of product/platforms and is currently helping Slack on their mission to reinvent team messaging. One of his tweets made me think quite a bit about the value of conferences.
I had recently been lucky enough to attend Swift Summit, a conference for Swift developers in San Francisco. It was honestly one of the best decisions I've made as a young iOS developer. I wanted to offer a perspective on conferences that Sean's tweet misses.
Humanizing Your Heroes
A quote I used to swear by is "keep working until your heroes become your peers." I've have since modified my mindset towards this idea. Your heroes are really no different than you are. They may have a years of experience under their belts, but life is isn't about Y-intercepts. It's all about your slope. Conferences help remind me of this.
At Swift Summit, I met so many people I look up to including Chris Eidhohf, Felix Krause, Sam Soffes, and Grant Paul. A few of us even got sushi together! It was like a Swift developer's dream come true!
Meeting Chris, Felix, Sam, and Grant in person humanized my mental notion of them. Instead of only interacting with them on Twitter, I got to hear about their unfiltered day-to-day lives, fun hobbies, and work ethic. Ryan Hoover recently relayed this idea in his post about the value of Product Hunt LIVE Chats.
"Sometimes we’re given a chance to connect with our seemingly unreachable heroes thanks to the Internet, and recognize that they’re human, too."
- Ryan Hoover
Today most digital communities coalesce around forums, subreddits, private Slack rooms, and ad hoc Twitter circles. No matter how intimate these places are, nothing beats nerding out with a venue full of like-minded people. Every so often at Swift Summit, I'd look around and soak in the fact that I'm amongst a portion of the world's Swift community and that I belong! This helps remedy the occasional loneliness that creeps up with being buried in Xcode all day.
These are just a few of the reasons I love attending conferences in person. While events like Swift Summit do a great job making all of the videos accessible to those who cannot attend, I wish there was a way to lower cost as a barrier (potentially with attendee sponsorships). More frequent, local meet ups are also a way to tackle this :)
16 Nov 2015
For the past few weeks, I've been running a small project called Public Extension. Each weekday1, I come up with a handy Swift extension (to the Standard Library, UIKit, etc.) and tweet it out for everyone to follow along!
One particular extension has been on the back of my mind for a few days now. Public Extension #9 (initial draft below)
The goal was to make class registration for
UITableViewCells safer by avoiding a
Stringly-based API that requires code to be updated in multiple places, when reuse identifiers change. To tackle this, I took the following approach:
- Define a
Reusable protocol that requires classes to have a static
- Wrap the traditional
registerClass(_:forCellReuseIdentifier:) to accept a
Reusable.Type metatype, which hides the previously-needed
- In my initial extension, I omitted the wrapper for
dequeueReusableCellWithIdentifier(_:forIndexPath:), but we'll discuss these soon!
Note: This approach only works in code. Setting reuse identifiers in Storyboards requires you to manually enter a
Before diving in and refining the above approach, let's take a step back and define what
CustomCell.self mean in the snippet above. They're making use of Swift's Metatype Type.
Swift Metatype Type
In The Swift Programming Language book, the metatype type is defined as follows:
"A metatype type refers to the type of any type, including class types, structure types, enumeration types, and protocol types."
This is exactly what we need. Since our
Resuable protocol defines
reuseIdentifier as a static member, we can access it from the metatype of any class that conforms to it! To access a type as a value, we can use a postfix
self expression (i.e.
.self). For example, in our
CustomCell class above,
CustomCell.Type not an instance of
Refining the Approach
Now that we've gone over metatypes, let's make our approach to safe cell reuse better! We'll keep the same
Reusable protocol but redefine our
UITableView extension as follows:
While we could have used Swift's error handling, cell misconfiguration is tricky to recover from. If misconfigured, it might be misleading to return a plain
UITableViewCell. So, it's probably better to lean towards a
fatalError to catch these issues during development.
Note that the return types for the
dequeueReusable overloads are non-optional. This is really handy because we no longer have to deal with awkward casts in
tableView(_:cellForRowAtIndexPath:). Here is how the call site might look:
We can apply this same pattern to
UICollectionView as well:
A Note on Cell Subclassing
One of my friends, Hans, brought up a potential gotcha with regard to subclassing cells that implement
static keyword in Swift translates to
class final2, meaning that the property is attached to a class but cannot be overridden. However, when defining
Reusable, we have to use the
static keyword (even though we have the explicit
class requirement on the protocol) because the class keyword is only allowed within
class definitions. To allow for subclassing of cells that conform to
Reusable, we can define
reuseIdentifier as a computed3
It's a little awkward that we can conform to a protocol (constrained to
class) with a static requirement using a
class var. Would love it if Chris Lattner or Joe Groff could chime in on this!
So, there we have it! We've abstracted away a
Stringly-based API for cell reuse in table and collection views. Now, if we ever need to change reuse identifiers, all we have to do is update the the cell definition. This benefits from code locality. I had also thought about an
enum-based approach, but this would move reuse identifiers farther away from cell definitions, as
enums can't be defined across multiple files. However, the
enum approach has one advantage, which is guaranteeing unique reuse identifiers.
Hope this pattern is useful! If you have any feedback or suggestions, I'd love to hear from you!
1: Took a break between November 4th through 16th for job interviews :)
2: In the case of classes
class properties aren't supported yet.
24 Oct 2015
A mechanism for handling change is to focus on the constants in life. Let's take a physical example of stretching your quadricep, while standing on one leg. To keep your balance, it is helpful to focus on a single point in front of you. I have begun to notice this anchor pattern sprinkled throughout life.
Difficult Decisions in the Workplace
When faced with a challenging decision at work, the core values upon which the company is built can help you reach the right choice. Care deeply about your users? Go with the option that puts them first instead of alternatives that increase runway at their inconvenience.
A technique in meditation is to focus on one’s breath because it remains constant throughout the session. I try to imagine my mind as a highway, with each thought being a vehicle driving along it. Attempting to control a passing thought is like stopping traffic, which runs the risk of getting "hit." Instead, I find it helpful to take a step back, label the thought for what it is (worry, stress, feeling), and return to my breath as an anchor.
At its core, boredom is a dissatisfaction with the current state (surroundings, people, etc.), wishing to be in a more interesting one. Once I started viewing boredom through this lens, it became easier to address. When my mind wanders, I try to acknowledge the presence of boredom and return to the current state as a point of focus. If you want to learn more about this method, it is called mental noting.
Handling Habit Streaks
When I first got into habit formation, I used to focus on keeping 'streaks.' This is known as the "Seinfeld Strategy," where the fear of breaking a streak is supposed to motivate you to keep a habit. However, I found a big flaw with this approach. Breaking a streak can be tough to handle emotionally. Take exercise as an example. If I made it into the gym 20 days last month, it is tempting to focus on the days I missed going to the gym. To avoid this mental trap, I remind myself of the underlying goal that has not changed. My desire to build a better self. These goals serve as an anchor to handle the variability of life that may interrupt daily habits.
It is fascinating how sometimes the best way to handle change is to focus on what stays the same. Notice this pattern in your life? I would love to know!