Make a Copy of the OSX Lion Installer BEFORE You Run It!

If you’re planning on downloading OSX Lion from the Mac App Store and installing it on multiple Macs, heed my warning to make a copy of the .dmg file before you actually install it. I learned the hard way this morning that once the install is complete, it deletes the installer. That’s a 4GB file, by the way. And it’s not in the trash can; it’s completely gone. If you fail to make a copy of it, as I did, your only option, apparently, is to re-download it on your other Macs. Which is fine, unless you are a Comcast customer with a bandwidth cap and a draconian exceed-the-cap-twice-in-six-months-and-we-cut-you-off-completely plan. I accidentally exceeded the cap last month for the first time, so I’m extremely conscious about my usage now. I’m pissed that I need to re-download a 4GB file.

Steve, you have failed me. It is asinine to automatically delete a file so big without asking me. I understand that some people are short on disk space, and may not want that big file hanging around, but for those of us who have lots of space available, let us decide whether to delete it or not.

Posted in mac | Tagged , , , , | 1 Comment

Google Chrome Sync Not Working? Try This

I use Google Chrome exclusively as my browser on both Mac and Windows, and I pretty much love everything about it. One of the things I love most about it is the ability to sync most of your settings between machines. This includes bookmarks, apps, themes, passwords, etc.

But the last three times I’ve done an install of Chrome on a machine (my friend’s loaned MacBook, my new MacBook Pro, and a Windows7 VM), when I entered my email address and password, I was told by Chrome that syncing was not available on my Google Apps account. Hmmmmm….

I don’t have an @gmail.com Google account, I have my own domain and a Google Apps account. While Google is trying to make Apps accounts and regular Gmail account identical, there are still some differences (like no profiles…). This can be frustrating, and I assumed that somehow my existing machines had been grandfathered in, but new ones were being excluded. (Also, both the Google Voice and GV Mobile+ apps on my iPhone failed to let me login, complaining about my email address or password being wrong.)

Then yesterday I noticed a comment on a forum (somewhere) suggesting a password mismatch between Google services might be to blame. I decided to give it a shot, so I went into my Google account settings and changed my password. Then I tried to enable sync on my MacBook Pro. BLAMMO! It worked. Then I enabled it on the Windows7 VM. Worked there, too. Then I tried to login using both the Google Voice and GV Mobile+ apps on my iPhone and both now allow me to login.

So, if you are having problems with a Google service or app, such as being told it’s not enabled for your apps account, or getting login failures, try changing your password.

Posted in general | Tagged , , , | 6 Comments

GV Places 1.1 Now Available In the App Store

After sitting in the to-be-reviewed queue at Apple for a week, I’m happy to announce that version 1.1 of GV Places is now available for purchase. The full list of changes is here.

Posted in iphone | Tagged , , , , , , | Comments Off

GV Places 1.1 Submitted To App Store

Yesterday, I submitted version 1.1 of GV Places to the App Store for review. I am hopeful that it won’t take as long to get through this time, but I’m not holding my breath.

The biggest news is that I dropped the iOS target version, so now people with Verizon iPhones can run it. I had hoped that the app store would not let someone download an app that they couldn’t run, but based on the 1-star review I got from a Verizon owner, that may not be the case. Here are the release notes

  • Should now work on Verizon iPhones.
  • Fixed a sorting/display bug that occurred when a place was autoswitched. The next time the app was run, the list would not be sorted properly.
  • Improved the region detection on iPhone 4. This should properly handle overlapping regions, which worked fine on the 3GS, but not so much on the iPhone 4.
  • Fixed a couple of memory leaks.
  • Note that when autoswitching is turned on, the app is not constantly running, looking for location changes. On the iPhone 4, it uses the region monitoring API, which means it tells the OS the regions it is interested in, and then goes to sleep. Whenever the phone enters one of those regions, the OS will wake the app up, telling it that it entered that region. This uses no extra battery on my iPhone 4, that I could tell. On the 3GS, it uses the significant location change monitoring API. With this API, the app tells the OS it is interested in significant location changes (this is mostly when cell towers change), and then goes to sleep. When one of these events occurs, the OS wakes the app up, telling it that a significant location change has occurred. The app then gets the current location and sees if it is within one of your places. If it is, it switches to that place. This is not as accurate as on the iPhone 4, but it’s all the 3GS has. This would probably use up a bit more battery than on the iPhone 4, because it has to do more work, but I didn’t notice any significant battery degradation on my 3GS.
  • Also note that autoswitching of places is NOT supported on the iPhone 3G, because neither of the APIs I described above were available on the 3G. Everything else works on the 3G.

Posted in iphone | Tagged , , , , , , | 2 Comments

Downgrading Your iPhone From iOS5 to iOS4.3.3: It Ain’t Easy

Like lots of other iPhone owners, I was excited about the announcement on Monday of iOS5, and all the new features. I don’t like to wait and since it isn’t going to be released until September, I had to get it somehow. Since I’m an iOS developer, I was able to download a developer seed of iOS5 and install it on my iPhone 3GS. I did so Tuesday morning.

It was painfully slow on the 3GS. Granted this is just beta 1, and it will probably improve before it launches, but it was nearly unusable.

So today, I went out and bought an iPhone 4. I had been wanting one for a long time anyway, and my contract was up in February so I’ve been able to get a subsidized price since then… Anyway, I bought a 4, and was not planning on putting iOS5 on it just yet. But when I attached it to iTunes and tried to restore my last 3GS backup to it, iTunes wouldn’t let me because the backup was of iOS5 and the iPhone 4 was running 4.3.3. So, against my better judgment, I installed iOS5 on it.

Big mistake.

While speed was no longer an issue, bugginess was. Lots of 3rd-party apps just seemed to not work right, and even some features of iOS were a bit squirrelly. A downgrade was in order. But, as the release notes tell you, you can’t downgrade.

Well, you can, but it’s a major pain in the butt. Below is a list of what I did to restore mine. But first, please be aware that your mileage may vary, use at your own risk, by reading this, you agree that I am not liable for any damage to your iPhone, iTunes, data, computer, house, car, cat, dog or anything else.

(This is in list form, but it’s not an instruction list, per se. It’s a list of what I did, thus the verbs are in the past tense.)

  1. Restored the entire ~/Library/Application Support/MobileSync/Backup directory from Monday, before I did the upgrade of the 3GS, using Time Machine. (On Windows, the directory is C:\Users\<UserName>\AppData\Roaming\Apple Computer\MobileSync\Backup)
  2. Downloaded the iOS 4.3.3 software image from links here (the links go to Apple) http://osxdaily.com/2011/05/04/ios-4-3-3-download/
  3. Launched iTunes, but hit the little ‘X’ button in the top area to stop it from syncing.
  4. Selected the iPhone 4 in the Devices section, then pressed Option while clicking on the “Check for Update” button. This popped up a dialog to find the .ipsw file that I had downloaded. I navigated to where I had saved it, and selected it.
  5. iTunes started to restore it, then barfed with one of those “unknown” errors. It did leave the iPhone in recovery mode.
  6. Out of paranoia, I shut down iTunes, deleted the partial backup that it had tried to do, thus leaving the Backup directory as it was on Monday.
  7. Started iTunes.
  8. iTunes popped up a dialog saying that the phone was in recovery mode and did I want to restore it. I said “yes.”
  9. It then showed me the EULA for 4.3.3, re-downloaded the .ipsw, then started the restore.
  10. Ten minutes later, it rebooted and showed up in iTunes, with iTunes asking if I wanted to restore it from one of my backups.
  11. I selected the 3GS backup and off it went.
  12. When the phone rebooted, iTunes started re-syncing it.
  13. Half an hour more, and it was done restoring all my data and settings. Then it started restoring 4,500 songs, which takes about 3 hours.

So, that’s it. All in all, it took me about 2 hours, start to finish. If you don’t have a backup of the Backup directory, you’re screwed.

I use pre-release software all the time, but this is the first time I’ve really, truly, gotten burned by it. I have now learned my lesson, and will at least wait for the release of iOS5… beta… 3 before trying again. :-)

Posted in iphone | Tagged , , , , , , , | 7 Comments

GV Places Is Now In the iTunes App Store


I am pleased to announce that my first iPhone app, called GV Places, is now available in the iTunes App Store. If you have an iPhone (preferably a 3GS or 4) and a Google Voice account, you might like it.

What it does is lets you create geographical areas that will enable or disable your Google Voice callback numbers, in various combinations. For example, I have three places that I use: Home, Office and Georgia. For the Home place, I have a region that fits snugly around my house, maybe .25 mile in each directory. For this place, I have my house line, my Skype-In number and my Google Talk IM enabled. My cell phone is disabled, because AT&T coverage here stinks.

For the Office place, I have a 2 mile-ish area around my office. Enabled numbers are my cell phone, my Skype-In and my Google Talk IM. My home number is disabled, naturally, because I don’t want calls ringing at home when I’m not there.

Finally, the Georgia place covers the entire state, plus some bits of the adjoining states. For this place, I have my cell phone enabled, and nothing else. This makes sense because I am most likely not at home, or my office, if this place is active.

Once you have defined your places, and associated phones with them, there are two ways to activate a place: manual and automatic. Manual mode means you go to the main Places screen and tap on the one you want to activate. Automatic mode only works on iPhone 3GS and 4, and uses the location awareness features of the phone to automatically switch places for you as you move around. When Automatic mode is enabled, even if GV Places is not running, iOS will notify it when you enter one of your places and it will then activate that place for you. Automatic mode works best on an iPhone 4, though if you are in a good coverage area, it works pretty well on a 3GS. (This is a hardware limitation of the 3GS.)

Here’s the Settings screen where you provide your Google Voice email address and password (which is stored in the Keychain for security purposes). If you have a Google Voice account that ends in @gmail.com, then you can leave the Hosted Apps account switch turned off. If you know that you have a hosted apps account, turn this on.

Next is the App Settings section, where you can tweak a few points of how the app works. By default, when you tap on a place to activate it, GV Places will prompt you to make sure that’s really what you want to do. If this annoys you, you can turn it off here.

Automatic place activation is controlled by the next option. This is disabled by default, but can easily be turn on here. Note that you must have an iPhone 3GS or iPhone 4 to use automatic place activation.

The final option here is only useful if automatic place activation is enabled. If “Notify on automatic activation” is turned on, then a notification will appear on your phone when GV Places automatically activates a place. If you don’t like this, you can easily turn it off.

Next is the Place Editor. This is where you define your places using the map. When you create a place, it starts out centered on your current location. You can use your fingers to drag the map around, and pinch to zoom, just like on the built-in Maps app. When you tap Save, the place will encompass everything that is shown on the map. Once you have the map how you’d like it, be sure to give the place a meaningful name. Finally, tap the button at the bottom of the screen. If you are just creating a place, it will say “Select Phones.” After that, it will indicate how many phones you have selected.

This is the screen where you select which of your phones you want associated with this place. Just tap the ones you want to place a checkmark next to it. Tap again to remove the checkmark. Those that are checked will be enabled for this place.

Finally, we come to the main Places screen. This shows each of the places you have defined, sorted by what I call their “snugness.” What this means is that the place that fits the most closely around your current location will be on top. The farther down the list you go, the less snug the place fits. Places that don’t encompass your current location at all will still show, but they will appear toward the end of the list, sorted by how close they are to your current location. Your currently-selected place will show in blue letters.

Snugness is neat because if you have overlapping regions, the region that fits most snugly will sort higher in the list. In my example, if I’m in my house, the Home place will sort higher than the Georgia place, because Home fits more snugly around my house than Georgia does.

Tap a row to activate that place. If you want to edit a place, tap the blue disclosure icon on the right-hand side of its row. To add a new place, tap the + icon at the bottom right. To get to the settings page, tap Settings.

I have a wiki setup for it, which current just has mostly this same information, at https://bitbucket.org/joeygibson/gvplaces/wiki/Home. If you buy it and find a bug, you can report it at https://bitbucket.org/joeygibson/gvplaces/issues.

If you’re just dying to own a copy of your very own, you can buy it for $1.99 in the app store.

Posted in iphone | Tagged , , , , , , | 1 Comment

First Rejection of My iPhone App :-(

I submitted my first iPhone app, called GV Places, to the Apple App Store on Monday, May 23. On Friday, May 27, around 9:00 in the morning, it entered the review process. About ten hours later I received the first rejection notice. The reason? I didn’t provide them a demo account to use for testing. I didn’t provide one, because of what my app does.

My app works with Google Voice, so you need a Google Voice account to use it. That’s not something I can just create willy-nilly and provide them for testing. Yes, I could create another account, but to really use it, you have to assign some phones to it, and to do that, Google Voice calls them to verify that they are yours. So I would need to use my own phone lines to set it up. I don’t think I should have to do that. I assumed that the tester would have his own Google Voice account to test with. Just like I would assume that if they test a Facebook app, they use their own Facebook accounts. I said as much in my response to them. I suppose we’ll see what they say.

It was sort of amusing that in the rejection email it said they weren’t able to test “all of the features” without a demo account. That’s funny because you can test any of the features without a Google Voice account.

Posted in iphone | Tagged , , , | Comments Off

O Sears, You Disappoint Me

I just got a cold call from Sears saying that the warranty on my refrigerator is about to expire, and asking me if I wanted to extend it for three more years. I listened to all the things this warranty covers, even though we haven’t had to use the warranty we already had. Then the price: $227.98 for three more years.

I would never make a decision about that much money on the spot, nor would I give out my credit card information to someone who calls out of the blue, claiming to be Sears. So I asked for a number I could call back, once I’ve considered the matter. She got a little cagey, but she gave me the number for customer service. Then she slipped this in, “But I can’t guarantee the price.”

I inquired as to what she meant, and she said, “Well, this is a discounted price, and I can’t guarantee that they will give you the same price.” Ah. I see. It’s the old, “Act now, or we’ll never offer you this price again!” tactic that so many sleazy companies use. My grandfather worked for Sears for 25 years, retiring in 1976. He would be appalled at this. I have to say, it’s very disappointing.

Posted in general | Tagged , , , | Comments Off

Only Three Days Until the “Rapture”…

In case you’ve been living under a rock and haven’t heard, the end of the world begins this Saturday, May 21 at or about 6:00 PM. According to Harold Camping, the resident genius cum prophet at WeCanKnow.com, May 21 is exactly 7,000 years after “Noah’s flood,” and is therefore the day that Christ will return.

According to this news report about a bunch of religious nutbags getting together to wear tacky t-shirts and wail and gnash their teeth about the end of the world, only 200 million Christians will be saved. The other nearly-7-billion people in the world will perish, with wailing and gnashing of teeth. Well, not immediately. The day will begin with “a worldwide earthquake, such as man has never seen,” with death and destruction the order of the day. Then those lucky 200 million will be rescued. The rest will suffer and die until October 21, when a “fireball” will destroy the Earth entirely, putting an end to all that annoying wailing and gnashing of teeth.

So, if you’d like to know what our days will be like after Saturday, be sure to pick up a copy of the pretty-much-unreadable Left Behind series which, I’m told, paints a detailed picture of post-rapture living. (Seriously, I tried to read Left Behind several years ago, because I had several friends say to me, “O! You must read it!” and “O! It’s so detailed!” and “O! It’s so horrifying!” I tried. Really, I did. I made it almost 100 pages into it before I was on the brink of spilling state secrets to the Communists. It was that bad. The characters were 1-dimensional, and I just didn’t give a damn what happened to any of them.)

So, mark your calendars for this Saturday. If you’re still around on Sunday, you’ll know you weren’t one of those who were really “saved.”

Posted in humor | Tagged , , | 2 Comments

Courtesy, In the Midst of War

I’m reading a book called Tybee Island: The Long Branch of the South, by Robert A. Ciucevich, because my wife’s cousin and her husband have a house on Tybee, and we just got back from a lovely beach trip.  This morning I came across something that gave me a chuckle, and I thought I’d share it.

In April of 1862, the Confederate army was shoring up Fort Pulaski to keep the Savannah river open and to repel any river-borne assaults on Savannah. About a mile farther down the mouth of the river, known as Tybee Roads, lies Tybee Island. Here, the Union army was building batteries with which to assault Pulaski. They were also building batteries behind Pulaski, including the introduction of new, and mostly untested, “rifled guns.”

Early on April 10, 1862, the commander of the Union army at Tybee, General David Hunter, dispatched a letter to the commanding officer of Fort Pulaski, Charles Olmstead, demanding his immediate surrender. Here is the text of that letter. Notice how the decorum of the time required it to be so utterly polite.

To the Commanding Officer, Fort Pulaski:

Sir: I hereby demand of you the immediate surrender and restoration of Fort Pulaski to the authority and possession of the United States. This demand is made with a view to avoiding, if possible, the effusion of blood which must result from the bombardment and attack now in readiness to be opened. The number, caliber, and completeness of the batteries surrounding you leave no doubt as to what must result in case of your refusal, and as the defense, however obstinate, must succumb to the assailing force at my disposal, it is hoped that you may see fit to avert the useless waste of life. This communication will be carried to you under a flag of truce by Lieut. J. H. Wilson, United States Army, who is authorized to wait any period not exceeding thirty minutes from delivery for your answer.

I have the honor to be, Sir, very respectfully your most obedient servant,

David Hunter Maj-Gen. Com’g

There’s no record of how close to the thirty minute deadline Olmstead made Wilson wait, but here is Olmstead’s reply:

To Maj-Gen. David Hunter, Commanding on Tybee Island.

Sir: I have to acknowledge receipt of your communication of this date, demanding the unconditional surrender of Fort Pulaski. In reply, I can only say that I am here to defend the Fort, not to surrender it.

I have the honor to be, very respectfully, your obedient Servant,

Chas H. Olmstead, Col. 1st Vol. Regt. Of Georgia, Com’g Post

Shelling began at 8:10 AM. At 2:00 PM the following day, unable to withstand the devastating damage done by the “rifled guns,” Olmstead had no choice but to surrender the fort.

What I thought was particularly interesting about these letter is that while they were pointed and deadly serious, they were coated in 19th Century manners. Compare that to General Anthony McAuliffe‘s response in WWII, when a German commander demanded that US forces surrender the town of Bastogne: “NUTS!

Posted in war | Tagged , , , | Comments Off

Review: Still Waters Restaurant

My friends Tim and Meg told me about a new place in Grayson called Still Waters Restaurant which had, they said, “pretty good bar-b-que.” I decided I needed to check it out, so my wife, Tammy, and I went on Friday night.

For those in the Grayson area, it’s in what used to be the Grayson House restaurant. Parking is in the rear, and as we parked, I was delighted to see a smoker, with smoke billowing out of it. That is a very good sign when you go for BBQ. The smell of the smoke was wonderful, and that smell continued into the house, as we entered the front door.

The restaurant bills itself as “A Chic Bar-b-que Joint,” but I’m not really sure what they are going for with that. The decor is mostly “old house” with various for-sale paintings by, I assume, local artists hanging on the walls. This is not to say that the decor is unappealing; I happen to really like old houses. I just don’t see anything particularly “chic” about it.

The menu is split into two parts: Bar-b-que, and everything else. The non-bar-b-que menu has steaks, fried grouper, grilled salmon, chicken, shrimp and some pasta dishes. There is also an appetizer that sounds heavenly, though we didn’t try it this time. It’s called a “Butty Roll” and this is its description

Smoked Tender Pulled Pork Wrapped in a Tortilla, Deep Fried Golden Brown and served with our Special BBQ Sauce

Oh, yeah. That sounds delicious. Next time, I will have you.

We were there for Q, so we went to the second section of the menu. They have smoked beef brisket (my favorite), pulled pork (my wife’s favorite), ribs, chicken, smoked turkey and house-made sausages. I wish they had a sampler platter, or a “build your own” type of thing, because I would have loved to get some brisket, pork and sausages. Alas, they did not. Tammy got the pulled pork, and I got the brisket. Each comes with two sides; she got potato salad and Brunswick stew, and I got fries and BBQ beans. The price for hers was #13, and for mine was $15.

The food came out pretty quickly, and was absolutely delicious. The only complaints we had were the Brunswick stew had far too much sweet BBQ sauce in it, and was nearly inedible, and that the fries were obviously frozen instead of house-made. Everything else was wonderful. The beans were a perfect balance between BBQ sauce and beans. The brisket was tender and moist, and had the smoke deep into the meat. Tammy’s pulled pork was heavily smoked, juicy and delicious. She also said the potato salad was very good. They have two sauces to choose from; sweet and spicy. I only ate the spicy, but I thought it was a nice spicy sauce, with a bit of a kick, but not mouth-scorching. Tammy said the sweet sauce was good, too.

When they first brought our food out, we were both a bit disappointed at how much was on our plates. But after we finished, we both agreed that the portions were just right; it was the prices that were wrong. For $15, I got three strips of brisket (two of which had significant fat I had to cut off), a decent portion of fries, and a coffee cup (really) of beans. For what I got, I think somewhere in the $10 – $12 range would have been more appropriate. Tammy got a sandwich-sized portion of pork, a large-spoon portion of potato salad and a coffee cup of stew. This really was more of an $8 – $10 meal, instead of the $13 they are charging. Both also came with a piece of Texas toast that had been toasted on the smoker with the smoke flavor deep into it. I do wish they had put a bit of butter on them, because they were a bit dry. The clearly frozen fries also bothered me, given the prices. For that kind of money, I expect house-made fries. It’s not that hard to make them, and they make the meal that much better.

Their dessert menu includes cheesecake, Key lime pie, Oreo cheesecake and something that sounded so good, we just had to try it: Fried Pound Cake. Here’s the description from the menu

Our version of strawberry shortcake, sautéed in butter to golden brown, and served warm with ice cream and strawberry sauce topping

What came out on the plate was an entire segment from a bundt cake pan, probably 4″ x 3″ x 2″; it was a big piece of cake. There was a scoop of vanilla ice cream on the side, a few strawberries, and a drizzle of strawberry sauce on the cake. Was it good? To quote a friend of ours, it “was so good, you want to slap your momma!” And it was. The cake itself was moist and tasty, but where the butter had soaked into it was a little slice of heaven. It was $8, but I would say that was actually a fair price, given how big the piece was, and how unbelievably good it was. The vanilla ice cream was just standard, but it was fine. This dish alone is reason to eat here again.

We left full and happy, both agreeing that we would come back. I do hope they will adjust their prices down to more accurately reflect the portion sizes. For flavor, I’d give them 4.5 stars out of 5 (I take off a half for the stew). Price-wise, it’s more of a 3.

Posted in food | Tagged , , , , , , | 3 Comments

Jon Stewart Shows Hannity’s Hypocrisy Over Common’s Trip to the White House

There is much wailing and gnashing of teeth in conservative circles over the fact that a rapper called Common has been invited to the White House for some sort of poetry event. Never mind that Common has won two Grammys and has been on Sesame Street. I’m not a hip-hop fan by any stretch, and I had never heard of Common before the shrill cries from Fox about his White House visit, so it was news to me.

Anyway, you have to watch this. Once again, Jon Stewart shows what a toad Sean Hannity is. Be sure to watch both parts. Part 1 gives you background info on the situation. Part 2 is the skewering of Hannity. And it’s a beautiful thing.

Here’s part 2

Posted in politics | Tagged , , , | Comments Off

GVoice: An Open Source Objective-C Google Voice Library

05/12/2011 Note: I failed to mention that the library, as it currently stands, builds for iOS only. I’m sure it could be rejiggered to work with OSX, because I don’t think I used any iOS specific features. All the project files would need to be changed, and I’m not sure what’s involved with that.

I am please to announce my free and open source Objective-C library for working with Google Voice. It’s called GVoice and you can find it here. It’s BSD licensed, which means you can use it for anything you want, both commercial and free/opensource.

It’s quite easy to use, and this example should help:

// USERNAME, PASSWORD, SOURCE and ACCOUNT_TYPE should be replaced with proper
// values.
self.voice = [[GVoice alloc] initWithUser: USERNAME password: PASSWORD source: SOURCE
accountType: ACCOUNT_TYPE];

// This causes some logging to happen.
self.voice.logToConsole = YES;

BOOL res = [self.voice login];

if (!res) {
// error handling
}

// Assuming you have a phone whose id is 23, this would cause Google Voice
// to route calls to it.
res = [self.voice enablePhone: 23]

if (!res) {
// error handling
}

// Send an SMS. Replace TEXT_PHONE_NUMBER with a proper 10-digit phone number
// capable of receiving SMS messages
res = [self.voice sendSmsText: @"Testing 1, 2, 3" toNumber: TEXT_PHONE_NUMBER];

if (!res) {
// error handling
}

On line 3, we create an instance of GVoice, passing in the email address and password from the user. The third field, source, is a field required by Google to identify where the connection is coming from. It’s free-form, but they suggest a reverse_domain_name-app-version approach, , something like com.joeygibson-GVTest-1.0, for example. The fourth parameter is what sort of account you’re trying to connect to, and there are two choices: GOOGLE and HOSTED. (This is an enum that also has a value of HOSTED_OR_GOOGLE, but I would suggest letting your user decide which account they have. It will save you problems later.)

Line 9 is where the actual login happens. If you get back a YES, all is well. If not, you can look at the GVoice object’s errorDescription property.

Line 17 demonstrates using one of the features of the library: enabling a phone. You pass the phone’s Id, which is obtained through another part of the API, and GV will then ring that number when a call comes in. You can also disable phones in the same fashion.

Line 25 shows how to send an SMS message from the GV account to the specified mobile phone.

There are many features that are fully formed, though some are still not as polished as I’d like. Two things still remain to be done: handling redirects and CAPTCHAs. After a certain number of failed logins, a URL will be returned that leads to a CAPTCHA image. To login after than you need to send a response to the CAPTCHA, but none of that is implemented in the library yet. Similarly, sometimes requests can be redirected by Google, but the library doesn’t handle those either. I’ve never seen either of these cases occur, but they could.

There is a full test suite included, which provides many more examples of how to use it. Before trying to compile it, you need to copy a file in the GVTests directory called GVCredentials-Sample.h to GVCredentials.h, replacing the dummy values with proper values. After that, you should be able to compile it and run the tests.

Full API documentation is available in the doc/ directory.

I wrote this library to use with my own iPhone app, which is currently in final testing before submission to the app store. I thought it would be useful for other people, so that’s why it’s free. If you’d like to use it, please do. If you’d like to improve it, let me know, and I can give you access to the repo.

It’s hosted on Bitbucket: https://bitbucket.org/joeygibson/gvoice.

Posted in iphone | Tagged , , , | Comments Off

Current Events In the Fifth Grade

I don’t know what made me think of this, but this morning while driving to the office, I remembered something from the fifth grade. It was 1980, and every Friday, we were supposed to bring in a news story, either from a newspaper, or that we’d seen on the news, for Current Events. We had to get up in front of the class and either read or summarize our story. This was right in the middle of the Iran Hostage Crisis, so any time someone forgot to bring in a story, they would walk to the front of class and announce, “The hostages have been in Iran for 332 days,” and then take their seat. (Obviously, the number of days changed.) I went to school in Georgia, and so Iran was pronounced as eye-RAN, instead of its proper pronunciation. I remember some Current Events days, we would have five or six kids reporting on the plight of the hostages, because they all forgot to bring in a story.

The teacher really should have only allowed one person to pull this trick each week, and give the others no credit, but she didn’t.

Posted in life | Tagged , , , | Comments Off

Dracula vs. Frankenstein: 1971 Bad-Acting Award-Winning Film…

As I was downstairs this morning toasting a sourdough English muffin, I was flipping through the channels on the TV. I noticed a “film” on the MGMHD channel called “Dracula vs. Frankenstein,” from 1971, starring Lon Cheney, Jr, with this horrible description:

Count Dracula forces fun-park operator Dr. Frankenstein to revive his infamous monster.

Oh, yeah. That sounds like a recipe for box-office gold! Given that I had ten minutes or so before my breakfast was ready, and seeing as there was nothing else on, I decided to check it out. I hoped to learn how Dr. Frankenstein had come to such a low station as a “fun-park operator,” and perhaps what his qualifications were for such a position. I also hoped to learn how Count Dracula, who was vanquished in the 1800s was still around to wreak his particular brand of havoc. Alas, I didn’t get answers to either of my questions. Here’s what I did see.

The scene I came into was two hippies, a man and a woman, talking about the kind of crap that movie hippies normally talk about. The hippie man rolls a tire down the alleyway and tells the hippie girl, “Go get it!” as if she were a dog. She scampers down the alley, and stops dead in her tracks. Coming toward her, very slowly, is the local violent biker gang. All three of them. They kind of reminded me of the Black Window gang from Every Which Way But Loose, if you remember them. Anyway, the leader says to the girl, something like, “So… where have… you… been?” in his most menacing-ish voice, and with appropriate pauses for high-school-quality effect. She dreamily replies that “I’ve pulled myself… out… of the… gutter! Why don’t you all… cut out!” The boy hippie sashays to the girl’s side and dramatically intones, “Are you… OK?” She doesn’t reply. Biker gang henchman #1 says, “I don’t think she likes us very much,” or something like that. The leader continues, “Nobody leaves us. I need a new girl… today. So why don’t you… climb on the back of this… bike… and we’ll… cut out…” Oooh, throwing her own words back at her! Such moxie! Such acting chops!

The two henchmen dismount and walk to the hippie man, menacingly, and at this precise moment, a savior arrives! A police car comes slowly down the alley. The henchmen saddle up, smirking menacingly-ish, and the gang then cuts out. Slowly, and with feeling.

The police car passenger door opens, and Sgt. Martin gets out. Hey! It’s Jock Ewing, from Dallas! (Is Miss Ellie in the backseat? No? OK.) Hippie girl #2, who has just arrived, gets up in his face and accuses him of not doing enough to protect the city. He replies that this is “my part of town” and that after so long there, one “learns the games people play” and from this knowledge knows when to “break it up” and when to “walk away.” Kenny Rogers could not have said it any better. He turns to get back in the squad car, then turns and says, very dramatically, “Stay away from the beaches! There’s a maniac on the loose!” He gets back in the car, and I turned off the TV. I did consider recording the rest of it, but then I decided I had much better things to do, regardless of the fact that I didn’t get my questions answered. Ah, well.

Now, perhaps the movie improved as it went on. And perhaps a preposterous-sounding plot was actually well-thought-out and developed. And perhaps the acting in the rest of the film was much better. Yeah, probably not. The things one sees on early morning TV.

Posted in cinema | Tagged | Comments Off

My Grandma’s “Orange Stuff” Recipe

We don’t have a name for this, so we just call it what it looks like. My wife calls this a “congealed salad.” I call it a dessert. We both call it yummy. Here’s what you need.

  • 16oz tub of Cool Whip
  • 16oz tub of small-curd cottage cheese
  • Small package of orange Jell-O
  • Small can of crushed pineapple
  • Small can of Mandarin oranges

And here’s what you do.

  1. Put Cool Whip in large mixing bowl
  2. Mix in the orange Jell-O
  3. Mix in most of the cottage cheese. (Based on how well you like cottage cheese.)
  4. Drain the pineapple and oranges and mix them in

Refrigerate it until it is cold and then wolf it down. I don’t know if my grandma invented this or read it somewhere, but I learned it from her. I make it frequently, since it is so yummy. And the cottage cheese gives you protien! :-)

Posted in food | Tagged , | 1 Comment

Thomas’ Tales: Walt Disney World, Day One

Note: Today’s post was written by my son, Thomas. He’s eleven and very excited that we are at Walt Disney World. I edited his post, but the text is his.

Hello. I, the blog famous Thomas, will be writing every day until Monday about our trip to the almost as famous as me, Disney World. Now to get started, we rode down here yesterday and unpacked, but that was twenty-four hours ago, so let’s just forget that. Today, we woke up early to see the Magic Kingdom opening show/song , and it was good. After that, we went to Tomorrowland, where we blasted aliens and moved people, and sent my parents into a mountain in space. Then we headed over to Adventureland, where we went to see the tiki birds and rode on boats. One boat ride being a simple tour of the wildlife and the back-side of water (which was amazing), on the other we went through a pirate-infested town that was currently on fire. I don’t know why it was on fire; maybe someone dropped a lantern or something.

Now for the interesting part. When we were on the People Mover,  I couldn’t believe what happened. As we were entering the part where it goes through Space Mountain, the ride came to a non-screeching halt. I don’t know why, but it took FOREVER to get it going again. Luckily, there were no more problems with our visit; so far, that is. Now we are in our room, relaxing.

That’s all, folks, but expect more from me tomorrow, and the next day, and the next day, and so forth.

Posted in general | Comments Off

WCBHM10 & Birmingham’s New Railroad Park

For the third year in a row, I attended WordCamp Birmingham. And for the third year in a row, it’s delivered on great content. My favorite session was one that I almost passed on; Sara Cannon‘s “Beyond the System Font: Advanced Web Typography” sounded like the same talk she delivered last year, but the technology has leaped forward in the past year, so the session was totally new. I will be implementing typekit.com on this blog, very soon. Thanks, Sara.

Yesterday, we were meeting outside at Birmingham’s newest urban project called Railroad Park. It’s a very nice greenspace right in the middle of town, with spacious covered pavilions that we used for shelter from the really hot sun. I walked around the park before heading back to Georgia and took a bunch of photos, the best of which are below.

Posted in life | Tagged , , | 1 Comment

99 Scala Problems #28 – I Like My Solution Better

I’ve been working through this list of 99 Scala Problems, which is modeled after this list of 99 Prolog Problems. As I’ve been going through them, I have been comparing my solutions to those provided (obviously). Sometimes, my solution is more or less the same as the “official” solution. Sometimes, theirs is better. In the case of problem 28, I think mine is far easier to read and understand.

Problem 28 has two parts. The first part reads:

a) We suppose that a list contains elements that are lists themselves. The objective is to sort the elements of the list according to their length. E.g. short lists first, longer lists later, or vice versa.

Running the function should look like this:

scala> lsort(List(List("a", "b", "c"), List("d", "e"), List("f", "g", "h"), List("d", "e"), List("i", "j", "k", "l"), List("m", "n"), List("o")))

res0: List[List1] = List(List(o), List(d, e), List(d, e), List(m, n), List(a, b, c), List(f, g, h), List(i, j, k, l))

For this part, my solution was almost identical. Here’s what I came up with:

def lsort[T](ls: List[List[T]]) = {
	ls.sortWith {(a, b) => a.length < b.length}
}

You can see that this function takes a List of type T, and then calls the sortWith method on that list, passing in a function value that sorts the lists based on their length, shortest to longest. The “official” solution was only slightly different:

def lsort[A](ls: List[List[A]]): List[List[A]] =
    ls sort { _.length < _.length }

Here, they used A instead of T, but that doesn’t affect anything, and they specified the return type, while I left mine inferred. Instead of assigning each bucket of the list to a named variable, as I did, they use the underscore placeholder. The two functions are functionally (get it?) identical, but theirs is a bit shorter because they removed the outer braces, and were able to skip the parameter list, since they used the underscores.

Now, the second part is where I diverge from the official solution. Here’s the problem description:

b) Again, we suppose that a list contains elements that are lists themselves. But this time the objective is to sort the elements according to their length frequency; i.e. in the default, sorting is done ascendingly, lists with rare lengths are placed [first], others with a more frequent length come later.

And the expected call and result is

scala> lsortFreq(List(List("a", "b", "c"), List("d", "e"), List("f", "g", "h"), List("d", "e"), List("i", "j", "k", "l"), List("m", "n"), List("o")))

res1: List[List1]  = List(List(i, j, k, l), List(o), List(a, b, c), List(f, g, h), List(d, e), List(d, e), List(m, n))

First, let’s look at what they presented as the solution. It referenced functions from other files, but I have included them all here for easy of viewing.

def lsortFreq[A](ls: List[List[A]]): List[List[A]] = {
    val freqs = Map(encode(ls map { _.length } sort { _ < _ }) map { _.swap }:_*)
    ls sort { (e1, e2) => freqs(e1.length) < freqs(e2.length) }
}

def encode[T](ls: List[T]): List[(Int, T)] = {
	val packedList = pack(ls)
	packedList map {list => (list.length, list.head)}
}

def pack[T](ls: List[T]): List[List[T]] = ls match {
	case Nil => Nil
	case h :: tail => (h :: tail.takeWhile(_ == h)) :: pack(tail.dropWhile(_ == h))
}

I think this is very confusing code. It’s calling the encode function which does run-length encoding of the passed-in thing. It then uses a Map of these encodings to sort the passed-in list. The presence of five underscores in the first line, obscures where those parameters are coming from, and the final underscore is actually part of the _* method of the Array class!

My solution, while being a longer function, is far more readable, in my opinion. And, it’s the same number of lines as the three-method solution. Here it is

def lsortFreq[T](ls: List[List[T]]) = {
	val lengthMap = scala.collection.mutable.Map[Int, Int]()

	for (l <- ls) {
		val len = l.length
		if (!lengthMap.contains(len)) {
			lengthMap(len) = 1
		} else {
			lengthMap(len) += 1
		}
	}

	ls sortWith {(a, b) => lengthMap(a.length) < lengthMap(b.length)}
}

In my function, I created a mutable Map and then iterate over the list, getting each item’s length, and then keep a running tally of how many items had that length. The map has these lengths as its keys, and the number of items with that length as its values. Get it? I then sort the original list by having each item in the comparison lookup how many items share its length, and use that as the sort criterion.

I have no idea which of these solutions is more efficient. For small problems like this, I doubt there’s any measurable difference. But I do believe that my solution is easier to read and understand. So much so, in fact, that I think someone who is not familiar with Scala would be able to easily figure out what it’s doing. I don’t know that the same can be said of the other solution.

I got criticized for promoting terse code in this article, so this is my attempt at balance. :-)

Note: I did change the inputs to these functions from symbols to strings. The code formatter I use on the blog wasn’t colorizing things properly when there were symbols involved.

Posted in java | Tagged , , , | 1 Comment

Two Videos From Lula Lake

As I said earlier today, my buddy Tim and I went hiking on Saturday and ended up spending much time at Lula Lake. You can see pictures from that excursion in the previous entry. (The first of the pictures are from Cloudland Canyon. The pics from Lula Lake begin with the rocks in the river that actually contained water.) Below are two videos of the beauty at Lula Lake. The first I took standing directly next to the cliff edge at the top of the falls. The second was taken from across the lake, looking at the falls and the surrounding cliff. If that place were on my property, I don’t think you could pry me away.


Posted in life | Tagged , , , , , | Comments Off