ImportError: cannot import name urandom

May 10th, 2012
    import os, sys, imp, types, tempfile, optparse
  File "/usr/lib/python2.7/tempfile.py", line 34, in 
    from random import Random as _Random
  File "/usr/lib/python2.7/random.py", line 47, in 
    from os import urandom as _urandom
ImportError: cannot import name urandom

You’re using a virtualenv, you’re probably on Debian or Ubuntu, and you upgraded python through apt-get.

virtualenv /path/to/your/virtualenvironment

iPhone app for SnapReplay – Release Candidate being tested

May 7th, 2012

After sixteen days of whirlwind development, digging through APIs, bad code examples, bugs in documentation (31 of 33 reported documentation bugs have been fixed), this afternoon I released 0.9.11 of the SnapReplay iPhone app to the beta testers through TestFlightApp.com.

On Friday, we had a pending list of bugs and features which were whittled down this weekend to a set of bugs that were blockers, a set of features that would make version 1.1, and a final set of features that would be used for 1.0. Sitting and looking at a set of features and having to decide which make the cut is not an easy task. Compromises were made based on how useful that feature would be in everyday use and whether it should hold up submission to the App Store.

Over the weekend, Paul and I went through twelve versions of the app, fixing bugs, tweaking features leaving one final feature we felt couldn’t be ignored left. Hours of pouring through documentation, bug reports, code sprinkled throughout the net, resulted in me finally deciding that the feature could wait until morning. I pushed out a last test build which included everything but the last feature for testing and went to sleep for a few hours.

When I woke up, I realized that my approach to the problem was not unique, it had to have been solved previously and then I realized that the examples were deleting from the wrong class and that Apple had a convenience class method to handle this very situation. A few minutes later, that was working.

A few tweaks and 0.9.11 was pushed to TestFlightApp for beta testing.

Phew.

Hopefully this evening I’ll push 1.0.0 and submit it to the App Store.

IPhone app development for SnapReplay retrospective

April 26th, 2012

While the SnapReplay iPhone app isn’t finished, it is mostly feature complete compared to the Android app. The first photo was uploaded last night via iPhone and the first event, Dunsborough Sharks Pre Season Party, with both an iPhone and Android phone was taken.

When was the last time I used Objective C? early to mid ’90s? This was going to be fun.

I had XCode installed but only played with the emulator to see how web pages looked. I didn’t own an iPhone and have used Android as my preferred OS for smartphones.

Comparing the development environment between the two, XCode definitely won this hands down. Within minutes of sitting down, I had my storyboard put in place, pages looked consistent when run through the emulator as buttons were connected. All that was left was to write some of the logic behind the pages… and that is where the problems started.

I can’t say I ever recall Eclipse crashing on me. XCode? After submitting 20-30 crash reports, I just click reopen without sending a bug report. Searching google shows that I’m not the only person experiencing these problems. Assistant mode gets confused which requires you to delete the files, and reimport them – and when it reconnects things, things tend to work as documented.

Since the app is based around the camera, we find that the iPhone Simulator doesn’t handle the camera. Even the Android emulator plays a repeating grid pattern with a bouncing ball to simulate the camera, but, with the iPhone Simulator, you get a blank page, your event fires, but, it isn’t really helpful. So, I purchased an iPhone 3GS for testing.

Objective C is reasonably easy to jump back into, but, Cocoa, Apple’s framework, is a nightmare. I submitted close to thirty documentation fixes, and to Apple’s credit, they are acted upon promptly. Numerous blog posts talk about the problems, API documentation errors and example code that won’t even compile, but, you can see that Apple does handle things pretty quickly when posted on their system rather than a random post on the Internet. While I wasn’t doing anything extremely complex, I did find it frustrating that the two features I needed to access were rife with documentation problems. That aside, a seven day whirlwind of coding resulted in an app that is functional and points out some other issues.

When I chose my smartphone, I chose Android for two reasons. One, I could develop applications for it for myself – of which I’ve done none of the things I envisioned. And two, I felt I needed a keyboard on my phone. I tried TMobile for 47 frustrating hours and got a bill for over $80 for dozens of missed text messages – not delayed, but missed, and several calls that went to voicemail even though I can see their antenna from my backyard. I ended up unlocking a TMobile phone and I run that on AT&T – experiencing the world at 2G speeds. When you iPhone people complain that AT&T has throttled you – that’s the speed I run at, 24×7. :) I have contemplated bringing a Desire Z down from Canada.

However, the Android experience is a bit different than iPhone and it was difficult for Paul, my brave alpha tester, to explain how iPhone apps normally worked. After actually sitting down with an iPhone and working with it, several UI issues cropped up due to me porting Android ‘feel’ to the iPhone. After some rework, I have an app that feels more like an iPhone app but still maintains a fairly good parity with the Android version. There is no substitute for actually using the platform you’re developing for. While I wouldn’t switch to the iPhone, the UI/UX is very nicely done.

TestFlightApp – absolutely invaluable. After getting the app to a point where I felt it was worth sending to Paul to test, a few hoops and stumbles and we’ve got an .ipa that can be deployed. Paul downloads the app and the first test text from a phone is a success. It takes a little time to wire up the SDK from TestFlightApp and navigating their interface is a little cumbersome, but, we are collecting data and getting things working.

    SNAPlib *lib = [[SNAPlib alloc] init];
    [TestFlight takeOff:@"api key"];
    [TestFlight setDeviceIdentifier:[lib get_PhoneID]];

While they suggest that you use the UUID, I ended up writing a library function around the CFUUID which we maintain for persistence. Since I already had this function, I didn’t need to use the phone UUID class which is deprecated and is a blocker for new apps being submitted to the App Store. I haven’t used checkpoints, but, it is immensely easier than having Paul hook up DDMS and send me a chunk of logs.

TestFlightApp wraps exception handling, which put this in the console, making remote debugging a bit easier.

Unacceptable type of value for attribute: property = "event_auth_token"; desired type = NSString; given type = __NSCFNumber; value = 6629.
7 SnapReplay 0x000aabb3 -[srAppDelegate get_from_storage:val_name:def_value:new_value:] + 775
8 SnapReplay 0x000b1bf1 -[SNAPlib set_EventAuthToken:] + 121...

If you develop for iPhones, TestFlightApp is very nice. Thank you to Craig Agranoff for the heads up there.

All in all I found the experience to be quite good. Today marks day 75 since the genesis of SnapReplay and while I wanted to write the iPhone app much sooner, it is close.

With that said, if you have an iPhone or Android phone and would like to help test – even if you only take a few random photos to send to the beta stream, it would be appreciated.

Google Latitude UX adjustments

April 24th, 2012

I use Google Latitude quite a bit with roughly three to four checkins a day. I remember when you could get free things at Arbys with a checkin – though, I never took advantage of that. Even the manager at our local Arbys had no idea it was available, nor did they have a way to track it in their Point of Sale system. Likewise, our local Walgreens didn’t know how to handle a coupon on a phone that they couldn’t collect, though, did offer to give the discount if we bought the product.

However, the one thing that is very annoying is the amount of data that must be transferred for a checkin. I run a T-Mobile phone on AT&T’s network which means I’m limited to 2G which maxes at 512kb/sec. A first checkin after a phone restart will take two or three minutes transferring data.

When I do a checkin, rather than wait for the fine GPS location, I should be presented with a screen using the coarse lookup with all of the checkins that I have been to. That first screen would usually have the place I’m checking into. Granted I could go to a different store or restaurant, 95% of the time, that first list is going to contain a very short list of the places I’m likely to check in to.

While that list is being presented and GPS is getting a better position lock, I could opt for the refresh once I see GPS has locked in, or, hit search. Hitting search while it is loading results takes me into Maps rather than searching checking locations, then I have to go to the location, click on it, then click checkin. Cumbersome on 3G speeds, irritating at 2G speeds.

However, once I have done that, the amount of data for a checkin must be incredible as it will normally take 10-15 seconds to get to the next page that shows the leaderboard. Even at 2G speeds, I can’t imagine how much data needs to be sent that ties up the phone that long. I can upload a 115k image in less time than it takes to get the leaderboard after checking in. I know it isn’t a lookup time problem as both the send/receive data indicators are solid during the leaderboard download.

It has made me seriously consider bringing in an unlocked HTC Desire Z from Canada so I could have a keyboard phone on AT&T. I tried TMobile for 47 hours and missed text messages and several phone calls even though I can see their antenna from my backyard.

Watching several apps, the amount of data transmitted is sometimes quite scary.

A discussion of Web Site Performance – from a design perspective

March 23rd, 2012

One of the things I always run into are clients that want their site to be faster. Often times, I’m told that it is the server or MySQL slowing their site down. Today, I had a conversation with a site owner that was talking about how slow their site was.

“The site loads the first post and sits there for five seconds, then the rest of the page comes in.”

Immediately, I think, <script src=” is likely the problem.

Load the page, yes, pauses… right where the social media buttons are loaded.

Successive reloads are better, but, that one javascript include appears to always be fetched. Turns out, expire time on that javascript is set to a date in the past, therefore, always fetches regardless of modifications. And, that script doesn’t load very quickly, adding to the delay.

Disable the plugin, reload, and the site is fast. The initial reaction is, lets move those includes to async javascript. Social Media buttons don’t need to hold up the pageload – they can be rendered after the site has loaded. It might look a little funny, but, most of the social media buttons are below the fold anyhow, and, we’re trying to get the site to display quickly.

There is a difference between the page being slow and the page rendering slowly. The latter is what most people will see and make a judgement that the site is slow. So, the first thing we need to do is move things to async. As an example, the social media buttons on this site are loaded by my cd34-social plugin.

But, the meat of the conversion to async is here:

<script type="text/javascript">
<!--
var a=["https://apis.google.com/js/plusone.js","http://platform.twitter.com/widgets.js","http://connect.facebook.net/en_US/all.js#xfbml=1"];for(script_index in a){var b=document.createElement("script");b.type="text/javascript";b.async=!0;b.src=a[script_index];var c=document.getElementsByTagName("script")[0];c.parentNode.insertBefore(b,c)};
// -->
</script>

What this code does is load https://apis.google.com/js/plusone.js, http://platform.twitter.com/widgets.js and http://connect.facebook.net/en_US/all.js#xfbml=1 after the page has loaded, and inserts it before itself.

This will make the social buttons load after the page has loaded, but, won’t hold up the page rendering.

However, this isn’t the only issue we’ve run into. The plugin they used, includes its own social media buttons. The plugin should use CSS sprites which are large images that contain a bar or matrix of icons where you use CSS positioning to move that image around and display only a portion of it. This way, you fetch one image rather than the 16 social media buttons and the 16 social media button hover images, and use CSS to move that image around and display the right icon out of the graphic.

Here are a collection of those sprites as used by Google, Facebook, Twitter and Twitter’s Bootstrap template:

With these sprites, you save the overhead of multiple fetches for each icon, and, present a much quicker overall experience for the surfer.

Not everything can be solved with low latency webservers, some performance problems are on the browser/rendering side.