Friday, August 31, 2012

RubyMotion : Gems Are Not Being Compiled / Built / Included

I was working on the most basic of apps, really nothing complicated at all, and trying to include BubbleWrap.  But the first time I tried to use anything (in this case, Device.screen.width) I was getting a name error - as if BW was not included.

I had  require 'bubble-wrap' in my Rakefile. I'd done a gem install bubble-wrap.  That wasn't it.  What appeared to be happening was that over in build/iPhoneSimulator-5.1-Development/objs there should have been a /Users/dmorin/.rvm/... directory where my required gems were getting copied, and that directory didn't exist.

I double checked everything, I ran "rake clean", I could not for the life of me make it include that directory.  I even created a brand new empty motion directory and included bubble-wrap in it so that this was literally the single line change I made from default -- and it compiled.  Go figure.

Finally, I found it.  I had been modifying some sample code that I found online, and it was this line:


app.files = Dir.glob(File.join(app.project_dir,'app/lib/**/*.rb'))|

Dir.glob(File.join(app.project_dir, 'app/**/*.rb'))

I'd seen something like that trick before, and it seemed like something I understood - basically saying that you're going to put some common code into a /lib subdirectory, so compile that first in order to make it available to your primary code.

But that's not quite accurate.  I think there was a mistake in the code that I copied, because what this does is to make app.files *only* point the files in your app/ and app/lib directory - completing removing any gems from the filepath.  You can check this with rake config - performing this command on a brand new directory will return all of your gem paths (whether it's .rvm or not), but doing so in the directory where the above line is included in the Rakefile?  Shows all my app/ code, but no gems.

In my case it turns out I don't need that line at all, so I've removed it.  Soon as I did that, my gems were included.  If you do need to manipulate app.files and the way things are included, you'll want to append or otherwise manipulate the existing list, not just replace it with a plain old equals!




Friday, August 10, 2012

Rails MVC vs iOS MVC

If your primary experience with Model View Controller (MVC) has been via Ruby on Rails, and then you switch over to iOS (iPhone / iPad) programming, see that it also supports MVC and think, "Oh, cool, I already know that!"  Not so fast.

I am not expert at either of these technologies, but let me put it in the best terms I can.  In the Rails world, the controller is primarily associated with manipulating the model.  You have a Person object, you have a PersonController.  That PersonController has actions like index (show a list of Person objects), show (a single Person), edit/update, create/save, destroy and so on.  Things that you can do with that object.  Each action, in general, has a view.  To the point where the default behavior of an action called "foo" on the PersonController is to assume that there is a file called foo in the /views/person directory.

In iOS world, each controller handles a single view.  I'm still trying to get my head around it.  I keep thinking of the View as an entirely separate object that I instantiate and "connect" to the controller in some way, such that the controller's only real job is to take in some user input, manipulate some stuff, and then let the next view do its thing.

Not really.  In fact, the controller can go ahead and just instantiate a UIView object and start populating it.  There' a method called viewDidLoad, that gets called when the view is all loaded.  Fair enough.  Where is that method?  Is there a didLoad() method on UIView?  Nope!  It's on the controller.  So it's practically hard coded in the framework that a controller deals with "the view" and you don't get to trick it into managing many views.

I don't yet fully get it.

UPDATE - As I do more googling on stuff like "switch UIView" I'm learning some techniques for how to manage multiple views inside a controller.  It's not quite the same thing as having a specific view associated with a specific action like Rails does, but it's inaccurate to say that a controller can only handle a single view at a time. It's more like, "The controller has a pointer to a view.  You are free to swap out and/or otherwise regenerate that view according to whatever rules you like."  So I don't think I have to have a PeopleIndexController and a PeopleShowController and a PeopleEditController...

Monday, July 16, 2012

Speeding Up the Stanford iPhone / iPad / iOS Development Course

I've known for years that I should learn iOS and Objective-C programming. I've just never found the time and/or patience to do it.  I'm a full time Ruby on Rails developer with a bunch of years of Java before that, so I feel relatively confident in my ability to pick up a new platform/language, but I found that there were a number of key differences between that world and the world of Objective-C that merely picking up a book on the subject and banging on it for a few hours a night wasn't working for me.

What is the greatest resource for learning iOS programming?  Everybody points to the Stanford iPad and iPhone Development Course.  Tens of thousands of people have gone through the course, and most rave about it.   I like the idea, a lot.  My biggest problems with it are two-fold.  First, it's a video long video course - almost 20 hour-long episodes.  I don't have the attention span for that, honestly.  Second and perhaps related to the first, it is impossible for all learners to get the same amount out of a single course.  Someone who has never touched Smalltalk, for example, will take longer to grap the idea of message passing than someone who knows Smalltalk.  That means that a lesson on messages will be the kind of thing that some folks want to just fast forward past.  But then if you FF too far you may miss important things.

This is why I've never done the Stanford courses, and instead tried to wing it with heavy Googling and lots of time on Stack Overflow.

Today, I found a better answer.  Playback the Stanford courses at double speed.  How?  Harder than it looks, actually, if you've got the latest of everything on your machine. Turns out you have to go back in time a bit.  [ Note that I am running a Mac with Lion installed.  Your mileage on Windows may vary.]


  1. Download Quicktime Player 7.  This advice comes straight from discussions on the Apple.com website, by the way.
  2. Find your video in iTunes, select Show in Finder.
  3. Right-click (or ctrl-click or whatever) on your video, go to Open With... and pick QuickTime Player 7.   Note that you did not upgrade QuickTime in the first step, and it will not become the default player. You deliberately installed a previous version.  You may have to find it under "Other" the first time you do an Open With, but in my experience once you've done that the first time it will show up as an option the next time.
  4. Got it open in QTPlayer 7?  Good.  Now go to Window -> Show A/V Controls.  This is the part that you needed QT7 for, because they've taken it out in later versions.
  5. In the lower right corner there's a slider for Playback Speed.  Pick a speed.  I'm running them at 2x, and I find it the right combination of understandable while causing me to yell "Faster, talk faster!" at the screen like I do at 1x.
Now I feel like I'm getting somewhere.  If you've got two monitors, that's even better - put the video up on a second screen, and then go about your business doing whatever other tasks are important while you half-listen to the lecture (just like most of us developers do in staff meetings when we bring the laptop, am I right?)  When it gets to something that seems interesting, pay more attention to the video.

I learned this trick this morning, and blew through the first lesson (the one that I would have been most likely to scream "Talk faster!" at) while doing other things.  Now I'm halfway through lesson 2 and into stuff that's more interesting to me, but still only at that "Confirm and clarify stuff that I'd already experienced" sort of phase (remember, I've been banging around on all this stuff by myself for a long time).  Eventually I'll get to the "Entirely new to me" stuff and, if necessary, I can bring the speed back down to 1x.

But probably not 1x. ;)






Tuesday, June 19, 2012

How To Hard Reboot / Factory Reset Your Verizon Droid Incredible 2

I have a Droid Incredible 2 from Verizon.  Had it coming up on 2 years.  This past Father's Day it stopped powering on.  Very weird circumstance, it rebooted itself while in camera, then acted flaky, then when I put it on the charger....nothing.  Stopped responding in any way to any sort of stimulus.  No lights, no nothing.  When I'd first plug it in there'd be a little red charging light, but that would go off in 5 seconds.  Left it on over night, nothing.  Popped the battery, still nothing.

Having tried everything and now bracing myself for the worst (a dead phone), I call Verizon tech support, who quickly moves me along past all the above steps to "Ok let's do a factory reset on the phone."


  1. Hold down the Volume Down key.
  2. Press and hold the Power key for 3-5 seconds.
  3. You should now get a boot screen.  (The hacker/geek in me squealed with glee when I saw this come up).
  4. One option is Factory Reset, which if you've never done one I'll warn you wipes your entire phone as if it's brand new, and you'll be tasked with setting up your Google accounts and such al over again, not to mention the havoc it will wreak on your various installed apps.
  5. Another option, however, is Fast Boot.
I asked the tech person, "Since I know what a factory reset will do, can I try Fast Boot?  Worst case it does nothing, and I repeat this process and select the reset."

"Sure, sounds good," she tells me.  "All we really have is directions for how to reset it."

Wonderful.  I hit the Reboot and thank her for her time.

A few minutes later (the I2 has a very long boot time, you ever notice that?)  I have my phone back!  Yay.

Documenting here because I did go googling for how to hard reboot my phone, and could not find easy instructions to do so.  Maybe the next guy to come along looking for it will land here.  Hold down Volume Down + Power, get boot screen, pick Fast Reboot.



Zazzle on Rails

I have merchandise on the Zazzle store.  I also have sites that I manage, and I would like to advertise my merchandise on my sites under my own control.  Zazzle offers a handful of banner options, but I wasn't really finding the level of control that I wanted.  So I've set about writing my own.

Zazzle does offer a PHP front end if you want to host your own store.  However I'm a Rails guy and would much prefer to work in that language.  From what I can tell, there is no Zazzle gem.  Yet.

What they do offer is a simple enough RSS feed that will allow you to easily pull the relevant info on your products, in a variety of ways.  You can customize the call to grab newest items, or most popular, via search terms or by searching for specific product types only.  In my case, and since I have less than 100 items in the store,  I can just go ahead and grab all of them:

@feed = Feedzirra::Feed.fetch_and_parse("http://feed.zazzle.com/ShakespeareGeek/feed?st=date_created&pg=1&ps=100")


You'll get back the item URL, description, and even a pre-made

complete with image that you can just go ahead and drop right on your page, if you like.


Now it's really up to you what you do next.  I actually use this call to go ahead and seed a local database of Product objects, which I'm then tagging and categorizing as I see fit.  Since I know when I create new products, I can manually go in and update my database to stay in sync.

I wrote up a simple banner script for now that just goes in and says "Get me 3 random products," and then I display the supplied HTML that came with the RSS feed.  Later, depending on the context of the page, I'll be able to say "Get me 3 random Hamlet products" or "Get me 3 t-shirts" or possibly even change what and how I'm displaying the items.

Note that the URL takes you back to the product page on Zazzle, where your customer would then still have to hit a Buy button.  Not the greatest user experience, but I'm not trying to rebuild the store from scratch, either.  I just wanted a way to display advertisements for my merchandise in my own way.  Your mileage may vary.

When I have time I hope to expand this with more source code and examples about exactly what I'm doing.  At the moment, though, I have no idea if Google will pick up this post and if anybody will ever see it.  So if you did land here because you do want to connect Zazzle and Rails, leave a comment so I'll know whether to keep posting on the subject.




Tuesday, March 20, 2012

Rails Migrations Break Over TIme?

Here's a fun little problem.  I'm sure I'm not the only one to have run into it, but I'll document it for kicks even though I'm not quite sure yet how I'll solve it.

I just inherited a legacy codebase for a Rails 2.3.x project.  So I point to a clean database, run a rake db:create followed by a rake db:migrate, and suddenly I'm getting an error - in this case about the absence of a certain "ambassador" column in my AdminUser object.

Two things are odd.  First, there is a migration to set up that column on that object, we just haven't gotten to it yet.

Second, this migration has nothing to do with that column.

...or does it?

Here's where the time warp comes in.  The original owner of this code set up the AdminUser object, then at some point later decided he needed an ambassador column, so he wrote a migration to add it.  Fair enough.  But then after that he went in and enhanced the create method for AdminUser to say "If your ambassador flag is set, do something different."

Remember that migration that was failing?  That migration tries to insert a new AdminUser (as a mock object).  Before the column is added.

So one migration created the AdminUser object (without the ambassador column).  Next in sequence comes this innocent migration that tries to create a mock AdminUser.  However, the AdminUser can't be created without looking at the ambassador flag - which hasn't been added yet.

Not quite sure how I'm going to solve this one -- probably comment out the ambassador related code long enough to mock the object and let the migrations run.

I just found it interesting.  You inherit a Rails project, you try to run migrations, they break in the middle.  Your first thought is quite possibly, "Oh great, the last guy didn't keep his migrations up, now I have to do everything in SQL."  Maybe not the case!  This appears to be a completely innocent problem that crept in over time, and he would never have noticed it because it's not like he's constantly going back and building his database from scratch like I just did.
 

Tuesday, January 24, 2012

I want to share with you something that I wrote in an email back in 12/2004:

Imagine your favorite book.  The sort of book that you always like to
have a copy of, because there's always something in there worth
revisiting.  Maybe it's the Bible, maybe Shakespeare, maybe the Tao of
Physics.  Or, maybe it just happens to be the text book for a course
you're currently taking.

Now imagine you have a thought on that book.  Maybe it's an idea you
want to scribble down so you don't forget.  Maybe it's a question.
Maybe you just want to talk to somebody about the book, but none of
your friends are into it.  How do  you find a community of people who
are interested in it?

What if that book was really an e-book, and that e-book had a wireless
internet connection?  And, whenever you had such a thought or a
question, with a simple tap of the keys you could connect immediately
to a community of people exactly like you.  I like the notion of a
"deep" book, it feels very alice in wonderland to me.  Because you're
leaving the original intact, and that's key.  You're telling somebody
"Look, we're not gonna get in the way of your enjoyment with this
book.  But when you want us, just look a little deeper."  The book
itself is merely a reader onto the larger, centralized service that
tracks all the comments, questions, and so on.

Right now, the idea would have to take the form of a PC-based reader.
It's really the only technology that can handle it.  But hey, that
could easily mean laptops.  What about PDAs?  Pretty soon.  Need a
better UI.  And before you know it, ebooks really will take off.

How does this fit our model?  Imagine the kind of content that can be
plugged in to that sort of interface.  Who says it has to be a
straight blog/message board?  Maybe you work up a quiz on a certain
subject, and you link it directly into the book.  And charge people
for it.  Not everyone will take it, of course, but some will.  Or
maybe you're the author of another book on the subject.  Maybe you're
teaching a class that uses this text, and you want to leave a message
for your students.    The book itself not only becomes a walking
course on itself, it becomes an infinite number of courses on itself.
By grabbing a "deep" view of Shakespeare you open up the door to
everything you could possibly learn about the subject, all depending
on how you choose to navigate through it.  On your terms and your time
line.  Want to pay for some stuff?  Ok.  But there'll be free stuff as
well.  You pick.

The question, as always, is revenue.  Who pays?  Will readers pay to
be a part of this service?  Probably not 100%.  But they might pay for
certain premium services.  Imagine if J.K. Rowling offered sneak peeks
into her books to premium subscribers?  And what about content
authors?  Do they expect to be paid, or will they pay us to be a part
of the service?  The latter is not so very far fetched.  Because
basically what you're talking about is a built in community support
forum.  All an author needs to do is enable his book to work with this
system and presto, a community might/can/will spring up, and he's
done.    He can even make some money back by offering premium
services, as above.

We've finally reached the point where this is possible.  Check out Subtext for iPad. I hate when this happens.