For the class I needed a meaningful example application. My idea was to build an application that manages one or more counters. The first things I needed were a description for the idea and a graphic designer to assist with turning that idea into something interesting and fun to build. I wrote up an App Definition Statement to describe the application and searched on behance.net to hire a graphic designer for the project.
Apple recommends that you create what they refer to as an App Definition Statement to describe each new app you want to build. As described in the iOS Human Interface Guidelines, “An app definition statement is a concise, concrete declaration of an app’s main purpose and its intended audience. Create an app definition statement early in your development effort to help you turn an idea and a list of features into a coherent product that people want to own. Throughout development, use the definition statement to decide if potential features and behaviors make sense.”
The application will let the user easily perform manual counting of many different things. There are apps like this in the store already so its not an original idea. The idea is easy for developers to understand and most of their focus will be on learning iOS development.
The goal is to teach the students to work through the whole process of building an iOS application. They will be exposed to the process of building something that follows the graphical and interaction design as spec’d by a professional designer. I’m not just trying to teach the students to build “programmer interfaces” in iOS applications. I want to show them how to build beautiful and functional applications. By the end of the class the students will have an app that they can show their friends and be proud of having built.
The application will have an overview screen where you can see all of your counters in a colorful display. Perhaps something similar to Static or StatNut. Counters could be grouped together and assigned a group name. Each group could have a separate overview screen where the individual counter names and values are summarized. Swipe left/right on overview screens to get at different sets of counters. Tap on a counter’s “tile” to open up the details of that counter.
Counters would have a name, type and be assigned a color. Depending on the type there might be other properties too.
Counting up or down might be done using a gesture (swipe up/down) and also by tapping on a + or - button. Switching between counters might be handled by swiping left/ right. It might be fun to include some sound effects that play on increment, decrement, reset and when a major boundary is crosses (every 10 counts, for example). The counters are all stored in the user’s iCloud account so they sync between iOS devices.
This is an integer counter. It has a starting value and a step increment. The counter can be reset manually.
This is an integer counter, like the simple counter. The difference is you also set a goal and the counter displays how close to the goal you are. It might be used to track how many times you went to the gym this month. This counter type might auto-reset on a specific date, or might reset manually.
This counter tracks how much time has elapsed. It is basically a stop watch with a name. The timer can only be started, stopped and reset. When stopped the timer can be started again to continue measuring time. This might be used to measure the number of minutes a player is on the field in a youth soccer game. One counter can be setup for each of the players on the team.
Youth soccer coach could setup counters to track game play. - One elapsed time counter for each player on the team. - One simple counter for team goal count. - One simple counter for opponent goal count. - A way to reset the group of counters should be provided to make it easy to “zero out” before a game. - When a player is on the field start his/her elapsed time counter. - When a player is taken off the field stop his/her elapsed time counter. - When a goal is scored increment the team goal count for the scoring team
]]>The focus is on helping you develop practical skills building mobile applications for iOS by building a real application over a weekend. At iOS Weekend you won’t get bogged down in mindless study of API calls or every little detail of Objective-C. What you will do is build a real application from start to finish. By the time you leave Sunday evening you will have an app running on your phone that you can be proud of.
This course is an introduction to iOS development. You will learn how to build applications using Xcode, iOS and the UIKit framework. You will have a better appreciation of how developers build iOS applications, having built one yourself once you complete the class. The full process for turning ideas into mobile applications sold through the Apple iTunes Store will be discussed.
You will build an iPhone application called “Count’em UP” over the course of 2 1/2 days. The class is 100% hands-on development with class size kept to a minimum so there will be plenty of one-on-one assistance as you work through the class exercises. Using guided demonstrations and a mix of follow-along exercises and hands-on experimentation you will see “Count’em UP” come to life.
You will receive a complete design specification for the application on the first day of the class. This will include some user stories, wireframe models from a graphic designer, pixel-perfect Photoshop files, all design elements (icons, font, color and animation specifications) and an object-model diagram to get you started. Here’s a short video illustrating what you can expect. (http://files.iosweekend.com/movies/Counters_revisions.mp4)
This course will be valuable if you are a …
Hope to see you there!
]]>Here is some information about the modem, as reported by accessing the web interface to the modem.
Standard Specification Compliant DOCSIS 3.0 Hardware Version 1 Software Version SBG6580-3.1.0.0-GA-07-180-NOSH Cable Modem MAC Address ff:ff:ff:ff:ff:ff Cable Modem Serial Number 324369118008466559530006 CM certificate Installed
Looking in the logs of my gateway device I noticed a number of critical error messages. Below is an excerpt of the logs currently on my device. One of the errors that comes up repeatedly is a T3 time-out. If you run google searches on this you will learn that many Comcast subscribers (and other cable providers too) see this error in conjunction with intermittent disconnects from their service.
I have reproduced the log of errors from the modem at the bottom of this post.
After a lot of reading of forum posts on http://forums.comcast.com I have learned that many people have similar issues.
What all of these have in common is that after repeated suggestions from Comcast that it was a modem issue or an in-house wiring issue, and after customers in some cases spent money to swap out hardware, none of that helped to resolve the issue. The issue is most likely something upstream of the house, but other possibilities exist too.
Some have suggested that the firmware on this model is very old (and riddled with bugs) and that Motorola has made a number of updates to the firmware. You can read an interesting thread about trying to get the firmware upgraded here.
I found references to the following firmware versions being available from Motorola to the carriers.
Every networking device except a basic switch or hub has firmware in it that can be field upgraded. Most knowledgable customers are aware of this and have probably done at least one firmware upgrade of a networking device. The Motorola SURFboard 6580 is no different. The firmware can be upgraded. The problem is, Motorola will not provide the firmware to end consumers. Here is a support document from Motorola about their cable modems and the policies about firmware upgrades. To quote,
We apologize about the inconvenience, but your Motorola modem does not support manual upgrades. Motorola is not allowed to control the upgrades of DOCSIS devices, per the standards specification. Any firmware or software changes must be implemented via the cable network. Your cable provider can update the firmware based on what they have approved for their network distribution. Because of that Motorola is not capable of installing firmware for cable modems. Please contact the cable operator to obtain information on upgrading firmware on the cable modem.
Repeated calls to Comcast Customer Service (1-800-XFINITY / 1-800-934-6489) got me no where. I spent approximately two hours on the phone with them. I was disconnected three times, had it suggested to me that the problem was the modem multiple times and was offered the option of paying them for Signature Support, but at no time were they able to actually provide me with updated firmware for the modem.
In summary, they were no help what so ever.
After reading about lack of firmware upgrades and my experience with their customer service folks I began to question whether
I wonder how many Comcast subscribers have similar problems with intermittent connection loss and just live with it. A survey of forum posts on their own site seems to indicate that the issues are wide spread.
This is truly a terrible situation. Customers purchase devices that Comcast recommends and then when something goes wrong with the service they place all of the blame on the in-house equipment and offer no support what so ever. The cable service providers have things structured such that consumers cannot get support for the devices from the manufacturers because that is the “service agreement” between the manufacturers and cable providers. Customers get squeezed in the middle without any recourse.
According to another site there are known problems with the Motorola SURFboard, especially with VOIP. I suspect these problems could be addressed with a firmware update, but we have already established that Comcast is in no mood to provide the necessary updates.
As a last-ditch effort I am now going to place the SURFboard SBG6580 into bridge mode and use a separate router. I found instructions for doing this on Anthony Volodkin’s blog, here. I will use my Apple AirPort Extreme (which Apple happily provides firmware updates for) as my router.
In a few days/weeks I will post a follow-up to let people know if this solved the intermittent connection loss problems.
TLV-11 - unrecognized OID;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:01:5c:24:f1:45;CM-QOS=1.1;CM-VER=3.0; Resetting the cable modem due to docsDevResetNow Started Unicast Maintenance Ranging - No Response received - T3 time-out;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:01:5c:24:f1:45;CM-QOS=1.1;CM-VER=3.0; Started Unicast Maintenance Ranging - No Response received - T3 time-out;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:01:5c:24:f1:45;CM-QOS=1.1;CM-VER=3.0; Received Response to Broadcast Maintenance Request, But no Unicast Maintenance opportunities received - T4 time out;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:01:5c:24:f1:45;CM-QOS=1.1;CM-VER=3.0; No Maintenance Broadcasts for Ranging opportunities received - T2 time-out;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:01:5c:24:f1:45;CM-QOS=1.1;CM-VER=3.0; No Ranging Response received - T3 time-out REG RSP not received;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:01:5c:24:f1:45;CM-QOS=1.1;CM-VER=3.0; No Maintenance Broadcasts for Ranging opportunities received - T2 time-out;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:01:5c:24:f1:45;CM-QOS=1.0;CM-VER=3.0; No Ranging Response received - T3 time-out SYNC Timing Synchronization failure - Failed to acquire FEC framing;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:00:00:00:00:00;CM-QOS=1.0;CM-VER=3.0; SYNC Timing Synchronization failure - Failed to acquire QAM/QPSK symbol timing;;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:00:00:00:00:00;CM-QOS=1.0;CM-VER=3.0; SYNC Timing Synchronization failure - Failed to acquire FEC framing;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:00:00:00:00:00;CM-QOS=1.0;CM-VER=3.0; SYNC Timing Synchronization failure - Failed to acquire QAM/QPSK symbol timing;;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:00:00:00:00:00;CM-QOS=1.0;CM-VER=3.0; SYNC Timing Synchronization failure - Failed to acquire FEC framing;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:00:00:00:00:00;CM-QOS=1.0;CM-VER=3.0; SYNC Timing Synchronization failure - Failed to acquire QAM/QPSK symbol timing;;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:00:00:00:00:00;CM-QOS=1.0;CM-VER=3.0; SYNC Timing Synchronization failure - Failed to acquire FEC framing;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:00:00:00:00:00;CM-QOS=1.0;CM-VER=3.0; SYNC Timing Synchronization failure - Failed to acquire QAM/QPSK symbol timing;;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:00:00:00:00:00;CM-QOS=1.0;CM-VER=3.0; SYNC Timing Synchronization failure - Failed to acquire FEC framing;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:00:00:00:00:00;CM-QOS=1.0;CM-VER=3.0; SYNC Timing Synchronization failure - Failed to acquire QAM/QPSK symbol timing;;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:00:00:00:00:00;CM-QOS=1.0;CM-VER=3.0; SYNC Timing Synchronization failure - Failed to acquire FEC framing;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:00:00:00:00:00;CM-QOS=1.0;CM-VER=3.0; SYNC Timing Synchronization failure - Failed to acquire QAM/QPSK symbol timing;;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:00:00:00:00:00;CM-QOS=1.0;CM-VER=3.0; SYNC Timing Synchronization failure - Failed to acquire FEC framing;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:00:00:00:00:00;CM-QOS=1.0;CM-VER=3.0; No Maintenance Broadcasts for Ranging opportunities received - T2 time-out;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:01:5c:24:f1:45;CM-QOS=1.0;CM-VER=3.0; No Ranging Response received - T3 time-out No Maintenance Broadcasts for Ranging opportunities received - T2 time-out;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:01:5c:24:f1:45;CM-QOS=1.0;CM-VER=3.0; No Ranging Response received - T3 time-out No Maintenance Broadcasts for Ranging opportunities received - T2 time-out;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:01:5c:24:f1:45;CM-QOS=1.0;CM-VER=3.0; No Ranging Response received - T3 time-out SYNC Timing Synchronization failure - Failed to acquire FEC framing;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:00:00:00:00:00;CM-QOS=1.0;CM-VER=3.0; SYNC Timing Synchronization failure - Failed to acquire QAM/QPSK symbol timing;;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:00:00:00:00:00;CM-QOS=1.0;CM-VER=3.0; SYNC Timing Synchronization failure - Failed to acquire FEC framing;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:00:00:00:00:00;CM-QOS=1.0;CM-VER=3.0; SYNC Timing Synchronization failure - Failed to acquire QAM/QPSK symbol timing;;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:00:00:00:00:00;CM-QOS=1.0;CM-VER=3.0; SYNC Timing Synchronization failure - Failed to acquire FEC framing;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:00:00:00:00:00;CM-QOS=1.0;CM-VER=3.0; SYNC Timing Synchronization failure - Failed to acquire QAM/QPSK symbol timing;;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:00:00:00:00:00;CM-QOS=1.0;CM-VER=3.0; SYNC Timing Synchronization failure - Failed to acquire FEC framing;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:00:00:00:00:00;CM-QOS=1.0;CM-VER=3.0; SYNC Timing Synchronization failure - Failed to acquire QAM/QPSK symbol timing;;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:00:00:00:00:00;CM-QOS=1.0;CM-VER=3.0; SYNC Timing Synchronization failure - Failed to acquire FEC framing;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:00:00:00:00:00;CM-QOS=1.0;CM-VER=3.0; SYNC Timing Synchronization failure - Failed to acquire QAM/QPSK symbol timing;;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:00:00:00:00:00;CM-QOS=1.0;CM-VER=3.0; SYNC Timing Synchronization failure - Failed to acquire FEC framing;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:00:00:00:00:00;CM-QOS=1.0;CM-VER=3.0; SYNC Timing Synchronization failure - Failed to acquire QAM/QPSK symbol timing;;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:00:00:00:00:00;CM-QOS=1.0;CM-VER=3.0; SYNC Timing Synchronization failure - Failed to acquire FEC framing;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:00:00:00:00:00;CM-QOS=1.0;CM-VER=3.0; SYNC Timing Synchronization failure - Failed to acquire QAM/QPSK symbol timing;;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:00:00:00:00:00;CM-QOS=1.0;CM-VER=3.0; SYNC Timing Synchronization failure - Failed to acquire FEC framing;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:00:00:00:00:00;CM-QOS=1.0;CM-VER=3.0; SYNC Timing Synchronization failure - Failed to acquire QAM/QPSK symbol timing;;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:00:00:00:00:00;CM-QOS=1.0;CM-VER=3.0; SYNC Timing Synchronization failure - Failed to acquire FEC framing;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:00:00:00:00:00;CM-QOS=1.0;CM-VER=3.0; SYNC Timing Synchronization failure - Failed to acquire QAM/QPSK symbol timing;;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:00:00:00:00:00;CM-QOS=1.0;CM-VER=3.0; SYNC Timing Synchronization failure - Failed to acquire FEC framing;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:00:00:00:00:00;CM-QOS=1.0;CM-VER=3.0; SYNC Timing Synchronization failure - Failed to acquire QAM/QPSK symbol timing;;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:00:00:00:00:00;CM-QOS=1.0;CM-VER=3.0; SYNC Timing Synchronization failure - Failed to acquire FEC framing;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:00:00:00:00:00;CM-QOS=1.0;CM-VER=3.0; SYNC Timing Synchronization failure - Failed to acquire QAM/QPSK symbol timing;;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:00:00:00:00:00;CM-QOS=1.0;CM-VER=3.0; SYNC Timing Synchronization failure - Failed to acquire FEC framing;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:00:00:00:00:00;CM-QOS=1.0;CM-VER=3.0; SYNC Timing Synchronization failure - Failed to acquire QAM/QPSK symbol timing;;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:00:00:00:00:00;CM-QOS=1.0;CM-VER=3.0; SYNC Timing Synchronization failure - Failed to acquire FEC framing;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:00:00:00:00:00;CM-QOS=1.0;CM-VER=3.0; SYNC Timing Synchronization failure - Failed to acquire QAM/QPSK symbol timing;;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:00:00:00:00:00;CM-QOS=1.0;CM-VER=3.0; SYNC Timing Synchronization failure - Failed to acquire FEC framing;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:00:00:00:00:00;CM-QOS=1.0;CM-VER=3.0; SYNC Timing Synchronization failure - Failed to acquire QAM/QPSK symbol timing;;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:00:00:00:00:00;CM-QOS=1.0;CM-VER=3.0; SYNC Timing Synchronization failure - Failed to acquire FEC framing;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:00:00:00:00:00;CM-QOS=1.0;CM-VER=3.0; SYNC Timing Synchronization failure - Failed to acquire QAM/QPSK symbol timing;;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:00:00:00:00:00;CM-QOS=1.0;CM-VER=3.0; SYNC Timing Synchronization failure - Failed to acquire FEC framing;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:00:00:00:00:00;CM-QOS=1.0;CM-VER=3.0; SYNC Timing Synchronization failure - Failed to acquire QAM/QPSK symbol timing;;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:00:00:00:00:00;CM-QOS=1.0;CM-VER=3.0; SYNC Timing Synchronization failure - Failed to acquire FEC framing;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:00:00:00:00:00;CM-QOS=1.0;CM-VER=3.0; SYNC Timing Synchronization failure - Failed to acquire QAM/QPSK symbol timing;;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:00:00:00:00:00;CM-QOS=1.0;CM-VER=3.0; SYNC Timing Synchronization failure - Failed to acquire FEC framing;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:00:00:00:00:00;CM-QOS=1.0;CM-VER=3.0; SYNC Timing Synchronization failure - Failed to acquire QAM/QPSK symbol timing;;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:00:00:00:00:00;CM-QOS=1.0;CM-VER=3.0; SYNC Timing Synchronization failure - Failed to acquire FEC framing;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:00:00:00:00:00;CM-QOS=1.0;CM-VER=3.0; SYNC Timing Synchronization failure - Failed to acquire QAM/QPSK symbol timing;;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:00:00:00:00:00;CM-QOS=1.0;CM-VER=3.0; SYNC Timing Synchronization failure - Failed to acquire FEC framing;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:00:00:00:00:00;CM-QOS=1.0;CM-VER=3.0; SYNC Timing Synchronization failure - Failed to acquire QAM/QPSK symbol timing;;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:00:00:00:00:00;CM-QOS=1.0;CM-VER=3.0; SYNC Timing Synchronization failure - Failed to acquire FEC framing;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:00:00:00:00:00;CM-QOS=1.0;CM-VER=3.0; SYNC Timing Synchronization failure - Failed to acquire QAM/QPSK symbol timing;;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:00:00:00:00:00;CM-QOS=1.0;CM-VER=3.0; SYNC Timing Synchronization failure - Failed to acquire FEC framing;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:00:00:00:00:00;CM-QOS=1.0;CM-VER=3.0; SYNC Timing Synchronization failure - Failed to acquire QAM/QPSK symbol timing;;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:00:00:00:00:00;CM-QOS=1.0;CM-VER=3.0; SYNC Timing Synchronization failure - Failed to acquire QAM/QPSK symbol timing;;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:00:00:00:00:00;CM-QOS=1.0;CM-VER=3.0; SYNC Timing Synchronization failure - Failed to acquire FEC framing;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:00:00:00:00:00;CM-QOS=1.0;CM-VER=3.0; SYNC Timing Synchronization failure - Failed to acquire FEC framing;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:00:00:00:00:00;CM-QOS=1.0;CM-VER=3.0; Received Response to Broadcast Maintenance Request, But no Unicast Maintenance opportunities received - T4 time out;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:01:5c:24:f1:45;CM-QOS=1.1;CM-VER=3.0; Received Response to Broadcast Maintenance Request, But no Unicast Maintenance opportunities received - T4 time out;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:01:5c:24:f1:45;CM-QOS=1.1;CM-VER=3.0; SYNC Timing Synchronization failure - Failed to receive MAC SYNC frame within time-out period;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:01:5c:24:f1:45;CM-QOS=1.1;CM-VER=3.0; Started Unicast Maintenance Ranging - No Response received - T3 time-out;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:01:5c:24:f1:45;CM-QOS=1.1;CM-VER=3.0; Started Unicast Maintenance Ranging - No Response received - T3 time-out;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:01:5c:24:f1:45;CM-QOS=1.1;CM-VER=3.0; Started Unicast Maintenance Ranging - No Response received - T3 time-out;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:01:5c:24:f1:45;CM-QOS=1.1;CM-VER=3.0; Started Unicast Maintenance Ranging - No Response received - T3 time-out;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:01:5c:24:f1:45;CM-QOS=1.1;CM-VER=3.0; Started Unicast Maintenance Ranging - No Response received - T3 time-out;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:01:5c:24:f1:45;CM-QOS=1.1;CM-VER=3.0; Started Unicast Maintenance Ranging - No Response received - T3 time-out;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:01:5c:24:f1:45;CM-QOS=1.1;CM-VER=3.0; Started Unicast Maintenance Ranging - No Response received - T3 time-out;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:01:5c:24:f1:45;CM-QOS=1.1;CM-VER=3.0; Started Unicast Maintenance Ranging - No Response received - T3 time-out;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:01:5c:24:f1:45;CM-QOS=1.1;CM-VER=3.0; Started Unicast Maintenance Ranging - No Response received - T3 time-out;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:01:5c:24:f1:45;CM-QOS=1.1;CM-VER=3.0; Started Unicast Maintenance Ranging - No Response received - T3 time-out;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:01:5c:24:f1:45;CM-QOS=1.1;CM-VER=3.0; Started Unicast Maintenance Ranging - No Response received - T3 time-out;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:01:5c:24:f1:45;CM-QOS=1.1;CM-VER=3.0; Started Unicast Maintenance Ranging - No Response received - T3 time-out;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:01:5c:24:f1:45;CM-QOS=1.1;CM-VER=3.0; Started Unicast Maintenance Ranging - No Response received - T3 time-out;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:01:5c:24:f1:45;CM-QOS=1.1;CM-VER=3.0; Started Unicast Maintenance Ranging - No Response received - T3 time-out;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:01:5c:24:f1:45;CM-QOS=1.1;CM-VER=3.0; Started Unicast Maintenance Ranging - No Response received - T3 time-out;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:01:5c:24:f1:45;CM-QOS=1.1;CM-VER=3.0; Received Response to Broadcast Maintenance Request, But no Unicast Maintenance opportunities received - T4 time out;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:01:5c:24:f1:45;CM-QOS=1.1;CM-VER=3.0; No Maintenance Broadcasts for Ranging opportunities received - T2 time-out;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:01:5c:24:f1:45;CM-QOS=1.1;CM-VER=3.0; No Ranging Response received - T3 time-out No Ranging Response received - T3 time-out No Maintenance Broadcasts for Ranging opportunities received - T2 time-out;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:01:5c:24:f1:45;CM-QOS=1.0;CM-VER=3.0; No Ranging Response received - T3 time-out]]>
Syslog is controlled by a plist file found in the launch daemons directory. The full path to the file is:
/System/Library/LaunchDaemons/com.apple.syslogd.plist
You need to edit this file to add a network listener. The plist is stored in a binary format so you need to use the plutil to convert it to XML using this command:
$ pushd /System/Library/LaunchDaemons $ sudo plutil -convert xml1 /System/Library/LaunchDaemons/com.apple.syslogd.plist $ sudo vim /System/Library/LaunchDaemons/com.apple.syslogd.plist $ sudo plutil -convert binary1 /System/Library/LaunchDaemons/com.apple.syslogd.plist $ sudo launchctl unload /System/Library/LaunchDaemons/com.apple.syslogd.plist $ sudo launchctl load /System/Library/LaunchDaemons/com.apple.syslogd.plist
Here is a complete example of the modified plist file. The new key is the NetworkListener. Be sure you add it nested inside the Sockets key or it will not work.
Once you have updated the plist the next step is to update the configuration of your AirPort Extreme. Under Applications => Utilities open the AirPort Utility and connect to your AirPort Extreme. On the Advanced tab select the “Logging & Statistics” panel. Enter the IP address of your Mac OS X Lion Server in “Syslog Destination Address:” and select “6 – Informational” for the “Syslog Level:”. You can see a screenshot of the AirPort Utility settings below. Update the settings on the AirPort Extreme.
Now, you probably want to verify that the logging is actually happening. Open Console.app on your server and look at “All Messages”. While looking at the logs go to another machine (I used my MacBook Air with a wireless connection to the AirPort Extreme) and open System Preferences and then Network. Select your network adapter and ask for it to renew the DHCP lease. You should see some activity in the log.
Another way to verify the logging is to turn wifi off on your laptop. You should see a message like this:
8/9/11 8:43:09.000 AM 80211: Disassociated with station 60:33:4b:2c:de:c0
When you turn wifi back on you will see something similar to this:
8/9/11 8:43:10.000 AM 80211: Rotated TKIP group key. 8/9/11 8:43:21.000 AM 80211: Associated with station 60:33:4b:2c:de:c0 8/9/11 8:43:21.000 AM 80211: Authenticating station 60:33:4b:2c:de:c0 to RADIUS. 8/9/11 8:43:21.000 AM 80211: Installed unicast CCMP key for supplicant 60:33:4b:2c:de:c0 8/9/11 8:43:21.000 AM natpmp: Binding added for udp, 173.164.164.17:32770 to 10.0.1.104:4500 with lifetime 7200 8/9/11 8:43:21.000 AM natpmp: Binding added for udp, 173.164.164.17:32771 to 10.0.1.104:5353 with lifetime 7200
That’s it. You now have syslog data being captured on your Mac OS X Lion server from your AirPort Extreme base station!
]]>$ curl -O ftp://ftp.cwru.edu/pub/bash/readline-6.0.tar.gz $ tar xvf readline-6.0.tar.gz $ cd readline-6.0 $ ./config && make && sudo make install $ cd .. $ rm -rf $HOME/.rvm $ bash < <(curl -s https://rvm.beginrescueend.com/install/rvm) $ rvm install 1.8.7 -C --with-arch=x86_64, --with-readline-dir=/usr/local $ rvm system $ rvm gemset export system.gems $ rvm 1.8.7 $ rvm gemset import system $ rvm --default 1.8.7
The following pages were helpful in figuring this out.
]]>Download the Ubuntu 11.04 Server .ISO file from http://www.ubuntu.com. I first tried the 64-bit version but it seems that VirtualBox has trouble with it. The 32-bit version worked just fine, and for the sort of development tasks I am planning it will be okay so I didn’t look any further into why the 64-bit version failed to install.
Create a new virtual machine. I called mine “ubuntu-11.04″. This one will be used as a basis for other machines I clone. I went with 512MB of RAM and 40GB of hard drive space, making sure that the hard drive was configured to grow dynamically. I accepted all of the default settings during the installation process. I did not install any additional packages at this stage. Since I plan on using Vagrant (http://vagrantup.com) to manage my virtual machines I chose to name this machine ubuntu and gave it a user name of “Vagrant Manager” with a login of “vagrant” and a password of “vagrant”.
Shutdown the virtual machine and then create a snapshot (I called mine “Fresh Install”).
You are now ready to create a clone of this machine and start playing around. Right-click on the virtual machine you just created and select “Clone…” from the context menu. Give your new virtual machine a unique name and be sure to check the “Reinitialize the MAC address of all network cards” option. I assigned the name “vagrant-ubuntu-natty” since that is in keeping with the conventions mentioned on the Vagrant site. I choose to only clone the current machine state.
Boot up the new virtual machine once the clone operation completes. Log in using vagrant/vagrant. You will now need to correct issues with the ethernet drivers. Basically, when you asked VirtualBox to reinitialize the MAC addresses it caused the operating system to no longer recognize the virtual ethernet adapter hardware. The steps to correct this are:
sudo rm /etc/udev/rules.d/70-persistent-net.rules
sudo service udev restart
sudo shutdown -r now
By running these three commands your virtual machine will be reconfigured to now recognize the new virtual ethernet adapters with their reinitialized MAC addresses.
Now you can proceed to install the VirtualBox Guest Additions software. Start by updating the Ubuntu software using these commands:
sudo apt-get update
sudo apt-get -y upgrade
sudo apt-get -y install linux-headers-$(uname -r)
sudo apt-get -y install dkms
sudo shutdown -r now
At this point you are actually ready to do the installation of the Guest Additions. From the Devices menu in VirtualBox select the “Install Guest Additions…” menu item. This will “insert” the CD containing the guest additions software into the virtual machine.Now, from your virtual machine run the following commands.
sudo mkdir /tmp/cdrom
sudo mount /dev/cdrom /tmp/cdrom
cd /tmp/cdrom
sudo ./VBoxLinuxAdditions.run
Note, the installation of the Window System drivers will fail. This is okay; remember, we are running the server variant of Ubuntu and don’t have any of the windowing system components installed.
Now change the hostname for the system so it can be used as a Vagrant base box.
sudo hostname vagrant-ubuntu-natty.vagrantup.com
Edit the /etc/hosts file and change the second line where localhost is defined. Set the fully qualified domain name for the host and the short name for the host.
Edit the /etc/hostname file and replace “ubuntu” with “vagrant-ubuntu-natty”.
Edit the /etc/resolv.conf file and replace the domain and search values with “vagrantup.com”.
Reboot the machine once more using
sudo shutdown -r now
It is now time to setup the rest of the required software on the guest in order for it to be used as a Vagrant base box.
Start by editing /etc/sudoers using
sudo vim /etc/sudoers
Add or change the line giving sudo access to administrators to read as follows:
%admin ALL=NOPASSWD: ALL
Add the following line right after the “Defaults env_reset” line:
Defaults env_keep="SSH_AUTH_SOCK"
Run the command:
sudo /etc/init.d/sudo restart
Now setup the software Vagrant relies upon to provide all it’s goodness.
sudo apt-get install -y ruby-dev
sudo apt-get install -y rubygems
sudo apt-get install -y puppet
sudo apt-get install -y chef
sudo gem install chef
sudo apt-get install -y openssh-server openssh-client
When installing the chef package (above) you will be prompted for the URL of the Chef server. Just press enter here and ignore that step. We are only interested in chef-solo, and this URL is only used by chef-client. The package installer will go ahead and configure the chef client to run automatically. We now need to disable this by running the following command:
sudo /usr/sbin/update-rc.d chef-client disable
Edit the file /etc/ssh/sshd_config and add the following line (case matters here):
UseDNS no
Configure a secure key pair for our new Vagrant base box by running the following command on the host system.
ssh-keygen -P "" -t rsa -C "Some meaningful comment" -f ./vagrant-id_rsa
This command will create two files in the local directory called vagrant-id_rsa and vagrant-id_rsa.pub. You will need to copy vagrant-id_rsa.pub into the ~/.ssh/authorized_keys file on the guest system. To do this you will need to setup port forwarding between the host and guest. The first step is to learn what the IP address of the host and guest systems are. Use the following command to view the network adapters that are configured on each system:
ifconfig
Run this on both the host and guest. Once you know both IP addresses you need to add a port forwarding rule in Virtual Box for the SSH port. This is done by selecting the “Settings…” menu item from the “Machine” menu. Once you have the settings dialog box open select the “Network” button and then open the “Advanced” section. You will see a button labeled “Port Forwarding”. Press it to open the port forwarding rule editor. Here you need to create a rule as follows:
Name: SSH
Protocol: TCP
Host IP: <fill in host IP address from ifconfig>
Host Port: 9999
Guest IP: <fill in guest IP address from ifconfig>
Guest Port: 22
Close the panel and dismiss the settings dialog box. You should now have a port open between the host and the guest for SSH/SCP. To verify this, enter the following command in a terminal window on the host system.
ssh -p 9999 vagrant@<host ip address>
When prompted for a password enter “vagrant”. You should now be in an ssh session on the guest system. If this worked you are ready to propogate the public key generated earlier. You can exit out of the SSH session now by typing exit in the guest. Back on the host type the following command to copy the public key.
cat vagrant-id_rsa.pub | ssh -p 9999 vagrant@<host ip address> 'sh -c "cat - >>~/.ssh/authorized_keys"'
You will be prompted for the guest password. Type “vagrant” again. You will now want to test that the key propogated successfully. On the host system enter the following commands.
ssh-add ./vagrant-id_rsa
ssh -p 9999 vagrant@<host ip address>
If everything worked in the earlier steps you should be in an SSH session on the guest without the need to enter your password!
As a final step before packaging a vagrant base box you should clean things up in the guest by running the following commands:
sudo apt-get clean
sudo apt-get autoclean
You are now ready to package the vagrant base box. Back on the host system in a terminal window first create a Vagrantfile that points to the SSH private key. Here is an example of what it might look like if you decide to copy your key (generated earlier). Call this file Vagrantfile.pkg.
Vagrant::Config.run do |config|
config.ssh.private_key_path = "lcl-vagrant-id_rsa"
end
Now invoke this command in the terminal window to create the package.
vagrant package --base vagrant-ubuntu-natty --include lcl-vagrant-id_rsa --vagrantfile Vagrantfile.pkg
The packaging takes a little while. Once it completes you should test the base box using these steps:
mv package.box vagrant-ubuntu-natty.box
vagrant box add lclbase32 vagrant-ubuntu-natty.box
mkdir test_environment
cd test_environment
vagrant init lclbase32
vagrant up
vagrant ssh
If all went well you are now finished with building a Vagrant base box. Congratulations!
]]>Boot up, open terminal window and run the following commands in order to configure network. (Updates the MAC address for the virtual network adapter.)
# rm -fr /etc/udev/rules.d/70-persistent-net.rules # shutdown -r now
Packages to install…
sudo apt-get install vim sudo apt-get install build-essential sudo apt-get install curl sudo apt-get install zlib1g-dev sudo apt-get install libssl-dev sudo apt-get install libreadline5-dev sudo apt-get install sqlite3 libsqlite3-dev sqlite3-doc sudo apt-get install libxml2 libxml2-dev libxslt1-dev sudo apt-get install libyaml-dev sudo apt-get install postgresql-8.4 postgresql-client postgresql-client-8.4 postgresql-doc-8.4 sudo apt-get install postgresql-server-dev-8.4 sudo apt-get install pgadmin3 sudo apt-get install libcurl4-openssl-dev sudo apt-get install git-arch git-doc git-csv git-svn git-email git-daemon-run git-gui gitk gitweb sudo apt-get install ssh subversion libgssapi-perl libio-socket-inet6-perl rssh molly-guard sudo apt-get install openssh-blacklist openssh-blacklist-extra socklog-run sudo apt-get install rdist makejail subversion-tools db4.8-util sudo apt-get install autoconf autoconf2.13 autoconf-archive gnu-standards autoconf-doc libtool gettext gettext-doc libtool-doc sudo apt-get install ruby sudo apt-get install ruby1.8 ruby1.8-dev rubygems1.8 ruby1.8-examples ri1.8 rubygems-doc graphviz graphviz-doc sudo apt-get install flex bison bison-doc
Setting up RVM
# System Wide RVM Installation bash < <( curl -L http://bit.ly/rvm-install-system-wide ) # Setup of user defaults edit /etc/adduser.conf - enable the EXTRA_GROUPS stuff and make sure the user is added to the 'rvm' group edit /etc/skel/.bashrc to add the necessary RVM initialization stuff sudo su - rvm install ruby-1.9.2-p0 rvm install ruby-1.9.2-head
(notes on config of Postgres on Ubuntu https://help.ubuntu.com/community/PostgreSQL)
curl ftp://ftp.ruby-lang.org:21//pub/ruby/1.9/ruby-1.9.2-p0.tar.gz > ruby-1.9.2-p0.tar.gz tar xvf ruby-1.9.2-p0.tar.gz cd ruby-1.9.2-p0 ./configure --prefix=/usr/local/ror --enable-shared make make test sudo make install
Create a file called /usr/local/ror/ror_env.sh. Add the following to it:
export PATH=/usr/local/ror/bin:$PATH
Run the command
sudo ln -s /usr/local/ror/ror_env.sh /etc/profile.d/ror_env.sh
Log out / Log in
Open a terminal window
$ which ruby /usr/local/ror/bin/ruby $ which gem /usr/local/ror/bin/gem
sudo su - gem update --system gem install rails -v 3.0.3 gem install sqlite3-ruby gem install pg gem install passenger
passenger-install-nginx-module --prefix=/usr/local/ror --auto-download --auto]]>
I tend to write down a lot of notes as I learn a new technology or tool. The migration to git is no different. What is different is how GitHub (the hosted git solution I am using) makes it possible to record just about anything in what they call a gist. This is turning out to be a very useful tool for me. It is a great place to store little bits of code or notes.
]]>I wrote the following script to handle installation of MongoDB. I decided to grab the pre-built version of MongoDB from the project site and then place the files under the /usr/local/ror directory tree.
#!/bin/bash # Get and extract a copy of Mongodb curl http://fastdl.mongodb.org/osx/mongodb-osx-x86_64-1.6.4.tgz > mongodb-osx-x86_64-1.6.4.tgz tar xvf mongodb-osx-x86_64-1.6.4.tgz curl http://downloads.mongodb.org/docs/mongodb-docs-2010-09-23.pdf > mongodb-docs-2010-09-23.pdf # Move files into final locations ( cd mongodb-osx-x86_64-1.6.4 sudo cp -R * /usr/local/ror sudo chmod a+r /usr/local/ror/GNU* /usr/local/ror/README* /usr/local/ror/THIRD* sudo gem install mongo ) ( sudo cp mongodb-docs-2010-09-23.pdf /usr/local/ror/share/doc/mongodb.pdf sudo chmod a+r /usr/local/ror/share/doc/mongodb.pdf )
Download the script tarball (mongodb.sh.tar), extract it into a folder like /tmp and then run sh ./mongodb.sh. This will download the MongoDB binaries and place everything in the /usr/local/ror tree.
One final step. Since you are running on a Mac you might want to check out a cool MongoDB client called MongoHub. You can learn more and download it from the official site.
]]>You should download and install the Mac version of PostgreSQL 9.0 from the folks at EnterpriseDB. You will need to register on the site in order to do the download. Be sure to download PostgreSQL 9.0.1, not one of their Plus packages. It is a nicely packaged installer for the freely available version of Postgres.
Once you install this software you should have a file called pg_env.sh in the /Library/PostgreSQL/9.0/ directory. This file should be added to your /etc/profile. Here is an example of what mine looks like:
# System-wide .profile for sh(1) # This has to be set to something in order for path_helper (below) # to update it with paths found in the /etc/manpaths.d directory. MANPATH=/usr/local/share/man; export MANPATH # Setup the PostgreSQL environment. . /Library/PostgreSQL/9.0/pg_env.sh if [ -x /usr/libexec/path_helper ]; then eval `/usr/libexec/path_helper -s` fi if [ "${BASH-no}" != "no" ]; then [ -r /etc/bashrc ] && . /etc/bashrc fi
Be sure to log out and log back in before continuing with these instructions. This is important to make sure your PostgreSQL environment variables are set properly.
One of my goals with this setup is to keep everything independent of the default tools that ship with Snow Leopard. To do this I decided that all of my Ruby on Rails setup will be located in the /usr/local/ror directory tree. Here is a script I developed to setup my Ruby on Rails development environment.
#!/bin/bash # Get and extract a copy of LibYAML curl http://pyyaml.org/download/libyaml/yaml-0.1.3.tar.gz > yaml-0.1.3.tar.gz tar xvf yaml-0.1.3.tar.gz # Build LibYAML ( cd yaml-0.1.3 ./configure make sudo make install ) # Get and extract a copy of Ruby 1.9.2 curl ftp://ftp.ruby-lang.org:21//pub/ruby/1.9/ruby-1.9.2-p0.tar.gz > ruby-1.9.2-p0.tar.gz tar xvf ruby-1.9.2-p0.tar.gz # Build Ruby 1.9.2 ( cd ruby-1.9.2-p0 ./configure --prefix=/usr/local/ror --with-arch=x86_64 --enable-shared make make test sudo make install ) # Update Ruby Gems sudo gem update --system # Install Gems sudo gem install rails sudo gem install sqlite3-ruby sudo gem install pg sudo gem install passenger # Configure Passenger for Nginx (downloads Nginx and PCRE automatically) sudo passenger-install-nginx-module --prefix=/usr/local/ror --auto-download --auto
Download the script, un-tar it and place it in any directory you want. I call the script doit.sh, but you can name it anything you like. Run the script using the command shown below.
$ sh ./doit.sh
Once the script completes you need to add /usr/local/ror/bin to your path. I did this by editing my /etc/paths file. Here is a copy of the file on my machine:
usr/local/ror/bin /usr/local/bin /usr/bin /bin /usr/sbin /sbin
One more logout/login and you are done. Have fun playing with Ruby on Rails on your Mac!
]]>A few episodes ago Alex Lindsay mentioned that his company was going to be hosting a one week Commuter iOS Class at their San Francisco offices so their team could come up to speed developing applications for iOS devices. The class would be taught by the folks from Big Nerd Ranch. Usually the BNR folks teach classes from their monastery at a secret location just outside Atlanta, Georgia. Having them venture out to San Francisco; wow, what an opportunity. Oh, did I mention that Alex Lindsay also announced that there were a limited number of spots open to the unwashed masses to attend and the class would be held from 2:00 p.m. until 10:00 p.m. each day so folks could continue to do at least part of their day jobs.
All in all this just sounded too good to pass up so I fired off an e-mail to the folks at BNR to let them know I wanted to attend. My fingers were crossed because I know how quickly their classes fill up. Needless to say I wouldn’t be writing this post if I didn’t get in.
So, I’m off to the Pixel Corps offices later this month to soak up some more iOS goodness. Hope to see a few of you there too.
BTW: Here is a link to the course description for anyone curious.
]]>My MacBook Pro is running Snow Leopard. I am planning to host my projects on Google App Engine and it requires Python 2.5. Snow Leopard ships with Python 2.6 as the default. You can switch to Python 2.5 using a few simple commands, as follows:
$ defaults write com.apple.versioner.python Version 2.5 $ sudo defaults write /Library/Preferences/com.apple.versioner.python Version 2.5
After issuing these commands you should logout and login, launch a Terminal window and issue the command
$ python --version
It should report Python 2.5.4 as the result. If it still says Python 2.6.1 then your change did not take effect. To troubleshoot the problem start with man python. It includes information on how to switch the default version of Python on your system.
Google App Engine expects that the ssl module is installed. This is so it can verify the identity of the GAE servers when trying to deploy your projects. Install it like this:
$ curl http://pypi.python.org/packages/source/s/ssl/ssl-1.15.tar.gz --output ssl-1.15.tar.gz $ tar xvf ssl-1.15.tar.gz $ cd ssl-1.15 $ sudo python setup.py install
If you want to use the GAE image manipulation classes while running on the local development server you will need to install PIL using the following command.
$ sudo easy_install pil
The following will be necessary for building some other python libraries later in the process.
$ sudo easy_install docutils
The following modules are necessary if you choose to install IPython (see next section). If you are planning on skipping the IPython installation these can be skipped as well.
$ sudo easy_install readline $ sudo easy_install nose $ sudo easy_install pexpect
The IPython interactive interpreter is a good addition to your Python development environment. It does not come pre-installed on Snow Leopard. You can download the latest stable version using this command:
$ curl http://ipython.scipy.org/dist/0.10/ipython-0.10.tar.gz --output ipython-0.10.tar.gz $ tar -xzf ipython-0.10.tar.gz $ cd ipython $ sudo python setup.py install
The Google App Engine SDK for Python is available at http://code.google.com/appengine/downloads.html. As of this writing you can use the following command to grab the latest version:
$ curl http://googleappengine.googlecode.com/files/GoogleAppEngineLauncher-1.3.7.dmg --output GoogleAppEngineLauncher-1.3.7.dmg
Once you download the dmg file open it in Finder and run the installer. It will place all of the necessary files on your machine. Once complete locate the GoogleAppEngineLauncher.app icon in Finder and double-click on it. This application provides a nice UI for managing your GAE projects.
I am planning on managing the source code for my projects with git and will store my master repositories on http://github.com. Apple does not include a copy of git on the machine by default. An installer is available at http://help.github.com/mac-git-installation/. While you are at it also create an account on github if you don’t already have one. It is useful for social coding in the wider open-source community.
Some of the Django open source software I plan on using is maintained using a distributed source control management tool called Mercurial. An installer for this is available at http://mercurial.selenic.com. Download and install the software.
$ curl http://mercurial.selenic.com/release/mercurial-1.6.3.tar.gz --output mercurial-1.6.3.tar.gz $ tar xvf mercurial-1.6.3.tar.gz $ cd mercurial-1.6.3 $ make PREFIX=/System/Library/Frameworks/Python.framework/Versions/2.5 all $ sudo make PREFIX=/System/Library/Frameworks/Python.framework/Versions/2.5 install $ hg version
I plan on implementing my web applications on top of the Django framework. Some modifications are required in order for this framework to run properly on GAE since Google uses Big Table for data storage instead of a relational database. Everything necessary to get Django working in GAE is included as part of the Django-nonrel project. Specific instructions for GAE are available at http://www.allbuttonspressed.com/projects/djangoappengine.
Use the commands listed below to install copies of all the necessary components onto your machine. Everything will be stored in a folder called DjangoStuff under your home directory.
$ mkdir $HOME/DjangoStuff $ cd $HOME/DjangoStuff $ hg clone https://bitbucket.org/wkornewald/django-nonrel $ hg clone https://bitbucket.org/wkornewald/djangoappengine $ hg clone https://bitbucket.org/wkornewald/djangotoolbox $ hg clone https://bitbucket.org/wkornewald/django-dbindexer $ hg clone https://bitbucket.org/wkornewald/django-testapp
Now, pick another folder where you want to setup a practice application. I am calling mine cs-practice since this is also the name of my Google App Engine application.
Use the following commands to configure the practice application for Django-nonrel development.
$ mkdir $HOME/cs-practice $ cd $HOME/cs-practice $ ln -s $HOME/DjangoStuff/django-nonrel/django django $ ln -s $HOME/DjangoStuff/djangoappengine djangoappengine $ ln -s $HOME/DjangoStuff/djangotoolbox/djangotoolbox djangotoolbox $ ln -s $HOME/DjangoStuff/django-dbindexer/dbindexer dbindexer $ cp -r $HOME/DjangoStuff/django-testapp/* .
Once you have the practice folder setup you need to edit the app.yaml file and change the application name to reflect the Google App Engine application name you selected when registering on http://appengine.google.com.
]]>Earlier this year, in April the event organizers held a special iPadDevCamp. That was my first exposure to this great event format. You can read more about that experience over on the Powered By AMP blog. For that event I was on a team with some co-workers from Auctiva. We built a prototype of an e-commerce sales management tool for AMP sellers.
This time I’m attending solo, without a cadre of other Auctiva designers and developers. I want to explore developing location-aware applications for the iPhone and put together a basic idea for an app. It is called Meet4Drinks, and you can read more about it at http://www.meet4drinks.net.
If it sounds like something you would enjoy, it’s not too late to register today. The event starts tomorrow (Friday) evening and goes through Sunday evening. Visit http://www.iosdevcamp.org to register.
Look for updates on Meet4Drinks next week, once my head is back above water after the event. Hope to see you there.
]]>Now it has been a couple weeks and I have the machine back and Apple didn’t find anything wrong. In fact, they say the bluetooth works fine. I turned everything on and it works fine here too. I had a hunch that this might be the case. Last week my 13″ MBP had the exact same issue. No bluetooth devices would work with it. In this case a full reboot did correct the problem.
So, what bluetooth devices do I have, and which one is misbehaving and causing all of these problems? I don’t know for sure, but I suspect either the new iPhone 4 or the Plantronics Bluetooth Headset I have. The Apple Bluetooth Keyboard and Magic Mouse seem to be working fine. I have noticed other issues with the bluetooth on the iPhone 4 when it syncs with the Alpine IWA-505 head unit in my truck so my money is on the iPhone 4 being the cause in all of these bluetooth problems. Time will tell.
]]>The Bluetooth: Not Available message in the system tray is not a good sign. Next I opened up Console.app to see if there were any indications of what the root cause for this behavior was. It appears there is truly something wrong with the Bluetooth Module. Here is what it showed:
A visit to the support forums at Apple led me to an idea to reset the SMC on the iMac. I tried that and still nothing. At this point I’m not a happy camper. It is looking like the Bluetooth Module in my iMac has given up the ghost.
Next step, the iPhone Apple AppStore application to make a Genius Bar appointment.
If you have read this far then you might be wondering why I’m telling you all of this. The reason is simple. Without a USB keyboard and mouse laying around somewhere none of the troubleshooting above would have been possible. Having a wireless bluetooth keyboard and mouse ship by default with the iMac is a really odd choice on Apple’s part.
Thankfully I have a keyboard and mouse from the Xserve in my garage. In case you forgot what these old fashion beasts look like, here’s a picture of the dynamic duo that saved my bacon tonight!
For years I have been developing Windows applications on my MacBook Pro. When other developers ask me why my response is usually something like “The best windows development system I have is my MacBook Pro.” It is fast, the hardware build quality is excellent and best of all, with Parallels Desktop I can have the best of both worlds.
This weekend I saw a tweet from the folks over at Parallels that was part of their promotion to get people to upgrade to Windows 7. It was a contest to win a copy of Windows 7. Guess what – yup, I won! Check it out over on the Parallels Consumer Tech Blog.
Don’t forget to send your own tweet to @ParallelsMac to enter.
]]>The end result is that my garage is always full of books that either describe out of date technology or are still current but not relavent for the projects I am working on at the moment. Worst still, the books I am currently using usually end up weighing many pounds and take up a lot of room.
The difference between carrying around a bunch of paper books and an e-book reader is huge. This stack of books weighs in at 31.8 lbs. Compare that with an iPad that has most of the same books loaded onto it and weights just 1.8 lbs. I know which one I am going to be carrying in my backpack.
Early last year when Amazon released the Kindle2 I purchased one hoping to get rid of this problem by switching to e-books instead of paper books. I did a survey of the technical e-books available and it looked promising. Most of the books I was either currently using or would likely be interested in were now available from Amazon in an e-book version. Amazon made it possible for the Kindle to also read the mobi format so that meant I could also get books from The Pragmatic Programmer and O’Reilly.
You know what they say about the best laid plans and all that. The Kindle worked as advertised. I switched almost exclusively to e-books on the Kindle. The problem was, many of these technical books include figures or illustrations that are in color and the Kindle did an awfull job of displaying them. To make matters worse, you couldn’t change the orientation of the Kindle (no landscape mode) so images that didn’t scale well could not be viewed by rotating the device. This was almost enough for me to go back to paper books.
Flash forward about a year and the rumors were flying about Apple building a tablet/slate of some sort. Would it be a book reader, a netbook computer, a movie viewer or what? No one knew for sure but everyone was speculating. Then the announcement came that Apple would hold a special event to announce “Something they have been working on”. My Kindle2 went up on craigslist that day (about a week before the special event was held) and I sold it the next day. I love craigslist; it just works! The ironic part is I sold it to a software engineer who works for Apple.
We all know what happened next. Steve told us all what we needed (an iPad) and when we would be giving him our money. I listened, reserved one for pickup on the release day and the rest is history. Apple ships the iPad with an e-book reader called iBooks and they have an on-line bookstore where you can purchase e-books. Amazon shipped a Kindle reader for the iPad that uses wifi to sync with the Kindle on-line bookstore.
Here is a picture of my new 1.8 lb iPad that makes an excellent technical book reader.
All of my existing Kindle books transfered over to the iPad without any trouble. The Pragmatic Programmer books I had were all in the mobi format which the Kindle software on the iPad cannot read. No problem – I just downloaded the epub format of the same books from the Pragmatic Programmer on-line bookstore.
Publishers sell their e-books in one or more of the following formats:
As an aside, everyone should make their e-books available like the folks at PragProg do. When you buy a book from them you get it in three formats (PDF, mobi and epub). This means you can read your book on basically any electronic device of your choosing. O’Reilly is almost as good.
To round things out here are a couple pictures of the user interface of iBooks and Kindle Reader for iPad.
This first two images are of the iBooks software. The image on the left illustrates the support for color and the nice page turn animations help you forget that this is not paper after a while. As is typical of most Apple user interfaces, this one has excellent usability. On the right you have a look at the search feature as implemented in the iBooks application. I have found that it works well, but is a bit slow. I would like to see Apple improve on the performance in an update.
The next image is of the Amazon Kindle for iPad software. Here I am showing you what the controls are like for selecting a font size and adjusting the background color and brightness. As I mentioned earlier, the main thing missing from the Kindle software is a search feature.
I would really like to have all my e-books in a single reader. Being forced to keep some in iBooks and others in the Kindle application really sucks, but I’m not holding my breath for a solution anytime soon.
Technical books are often used as references. Neither of the e-book reading applications do a good job with letting you keep multiple books open and rapidly switch between them. It would really improve the usefulness of the applications if you could keep more than one book open and use a multi-touch gesture to switch between them.
If you don’t have an iPad yet, run (don’t walk) to your nearest Apple store and pick one up. You won’t regret it.
]]>The folks over at Big Nerd Ranch are really busy these days. In addition to building a new learning center it looks like they are writing no less than three new books to be released this year. If you have ever read through Cocoa Programming for Mac OS X by Aaron Hillegass or had the fortune to attend one of his classes then you already know that these new books will likely become a core part of your programming library in the future.
The first new title is iPhone Programming: The Big Nerd Ranch Guide, written by Joe Conway and Aaron Hillegass. According to Amazon this book will be available for purchase on May 4th in paper form and May 6th for the Kindle. You can pre-order it now.
The second new book is titled More Cocoa Programming for Mac OS X: The Big Nerd Ranch Guide and is being written by Aaron Hillegass and Juan Pablo Claude. According to Amazon’s web site this book will be available in mid-July, 2010. At this point it appears the book will only be available in print form. Hopefully this will change and a Kindle version will be made available.
The third new book will be titled Objective-C Programming: The Big Nerd Ranch Guide and is being written by Aaron Hillegass and Mark Fenoglio. Amazon pegs the release of this book sometime in December, 2010. Cover art for this book has not been released yet.
]]>