Archive for the ‘iPhone’ Category


August 31, 2010

Well, it’s been a busy few months. I’ve gotten a new job, as a iPhone developer at Loopt here in Mountain View. Which is quite a change from being a compiler developer at Synopsys! I’ll write some thoughts on that, hopefully tying in with the whole recent discussion on ageism in Silicon Valley.

I also had a very successful reading of my full-length play, Enlightenment, at Foothill College, in June. My writing has taken somewhat of a back seat to finding a new job for the better part of a year, so I’m hoping that I can get back to it.  But I am sending material out: I submitted entries to contests at the Marin Theatre and Playground SF.


Retweets ThrededTweet-style

March 24, 2010

So here’s what I settled on for representing new-style retweets in ThrededTweet. Guess which is the retweet:

I didn’t make that hard, did I?  Here’s what it looks like when you look at a retweet directly:

I like this because the addition of the picture gives an instant visual clue that this is a retweet (there is no picture there, normally). Clicking on the user icon at the bottom would open up @rschu’s user information, not @dane’s, so you can look at his tweets directly, or start following him, if you wish.

This will all be in ThrededTweet 1.3.0, which I uploaded to the App Store for approval tonight. Apple has really sped up approval times, so hopefully it will be available later this week.

Retweet Conundrum

February 28, 2010

On Twitter, “to retweet” originally meant to repost a tweet, prefixed with “RT @<username>”. And ThrededTweet supports this type of retweeting.

But Twitter then introduced a new type of retweeting, where you can’t change the original tweet, and it appears as part of your stream, but with the original user’s name next to it.  I’m adding support for this type of retweeting in the next release.

But I want to keep support for old-style retweeting, which means I’ve run into a conundrum:  when a user of ThrededTweet wants to retweet, they tap the right-most button under the tweet in question and select “Retweet” from a list that includes a couple of other choices.  What do I add to this for “new-style” retweeting?  In my current development sandbox, the buttons are labels “Retweet (old-style)” and “Retweet to Friends”. I’m not sure that’s clear, but I’m also not sure how to improve it.

“Retweet (old-style)” vs “Retweet (RT-style)” vs “Retweet (editable)”?

“Retweet (new-style)” vs “Retweet to Friends” vs “Retweet As Is”? Alas, I can’t include the funky retweet icon.

Decisions, decision…

The UI Implications of Having a Big Finger

January 30, 2010

Among the settings that a user of my Twitter app, ThrededTweet, can adjust are the number of tweets that should be loaded at one time, and the time interval that should pass between reloads.  For the former, the allowed values are between 20 and 200, while for the latter it’s between 0 and 60 minutes.  These values are adjusted with a slider on the “Settings” page.

Currently (version 1.1.2 and earlier), the sliders behave in a purely linear manner. That is, the distance you have to slide the slider is the same to go from 5 minutes to 6 minutes, as it is to go from 55 minutes to 56 minutes. While this works well in the iPhone simulator, where user interface elements are manipulated with a mouse, on an actual iPhone I’ve discovered that it’s a different story. I’m 6’5″, with hands to match, and I’ve found it difficult to exercise the fine amount of control needed to hit a value precisely. If I want to reload every 5 minutes, sometimes I’ll end up with 4 minutes or 6 minutes.

In version 1.2.0, the sliders are still there, but after having a realization about usage, I’ve modified how they’re handled in a way that improves usability quite a bit. The realization is that, most of the time, people will be more concerned about hitting small values precisely than they will about hitting large values. Many people will want to select between a reload every minute vs. every two minutes, while few if any will be concerned about accurately selecting between 55 minutes and 56 minutes.

So as of 1.2.0, slider values are interpreted with an exponential function, rather than a linear function. This gives a lot more sensitivity for small values, at the cost of sensitivity for large values.

If we assume that a slider all the way left has value 0.0, and one all the way to the right has value 1.0, then the reload time can be defined like so:

reloadTime = 10^sliderValue * 6.666666 – 6.666666

For sliderValue=0, this gives a reload time of 0 minutes, while for sliderValue=1, this gives 60 minutes. In Objective-C, this is:

    int reloadTime = round(pow(10.0,reloadTimeSlider.value)*6.6666666-6.6666666);

Going the other way:

    reloadTimeSlider.value = log10((reloadTime+6.6666666)/6.6666666);

For the number of tweets to load, since the range is between 10^0*20 and 10^1*20 (20-200), the formula is simpler:

    int numTweetsToLoad = round(pow(10.0,feedCountSlider.value)*20.0);
    feedCountSlider.value = log10(numTweetsToLoad/20.0);

After making this change, I’ve found these sliders much easier to manipulate accurately on the actual phone.

Handling Ampersand Codes in ThrededTweet

December 21, 2009

One of the architectural issues I’ve been having with ThrededTweet is handling HTML ampersand codes, such as &amp; , &caret; , etc. ThrededTweet uses a UIWebView instance to display whole tweets, and that handles ampersand codes automatically. But the summaries of tweets that are displayed, such as on the main Feed page, use a UILabel.

For release 1.0.0, I manually added handling of what I assumed were common cases, but then immediately found an example of a tweet with an M-dash (&mdash;), which I didn’t handle. Version 1.0.1 expanded the set of ampersand codes that are handled, but as you can probably guess, as soon as 1.0.1 came out, I found example of another code that wasn’t handled. So I needed a comprehensive solution.

For verson  1.0.2, I decided to use a program called gperf to create code to automatically handle all ampersand codes. gperf is the GNU perfect hash function generator:

For a given list of strings, [gperf] produces a hash function and hash table, in form of C or C++ code, for looking up a value depending on the input string. The hash function is perfect, which means that the hash table has no collisions, and the hash table lookup needs a single string comparison only.

The first step was to get a list of all HTML ampersand codes, along with their corresponding Unicode code points, which is available on the “List of XML and HTML character entity reference” page on Wikipedia. I cut-and-pasted the code list, separated out the parts I wanted with a one-line Perl script, and stored the results in a file called codelist:


The default behavior of gperf is to create a function that just verifies whether or not a given string is in the hash table, but I needed it to return the Unicode code point as well. So I added the definition of the struct that would be stored in the hash table at the start of the codelist file:

struct code { char *name, int val; };

I then fed this to gperf (the “-t” means that I’m providing my own struct definition):

gperf –t codelist >amp.c

That created a file I could import into Xcode. The important function is that file is:

struct code *
in_word_set (str, len)
register const char *str;
register unsigned int len;

Feed it a string, and its length, and it will return the instance of “code” that corresponds to that string, or NULL if none was found.  If the pointer was not NULL, I still needed to compare code->str to the string I was looking for, in order to validate that we found the correct entry. Note that, for this case, the only reason that it would not match is there was a garbage ampersand code (e.g. “&iowfdna;”).

I then did some cleanup. “in_word_set()” became “is_amp_code()”, and I changed the function to something more modern than ye olde K&R style generated by gperf:

struct AmpCode *
is_amp_code (const char* str, unsigned int len)

The structure definition changed from this:

struct code { char *name, int val; };

to this:

typedef struct AmpCode { char *name, int val; } AmpCode_t;

Finally, “amp.c” became “Amp.m” (perhaps not strictly necessary), and I created an “Amp.h” that contained the struct definition and the prototype for is_amp_code().

I then imported Amp.m and Amp.h into Xcode, removed most of my old ampersand-code parsing code (keeping the part that found substrings that started with “&” and ended with “;”), and put a call to is_amp_code() in its place.

Voila! An ampersand-parser that handled anything I threw at it. If you were following my Twitter test account, you would have seen a string of tweets with all sorts of random ampersand codes, some legal, some not.