Learn all the things

Simon Goudie's blog

VPS – an education in servers

You can get Virtual Private Servers for $15/year. A YEAR! Sure, they’ve got less RAM than my couch, but $15 is a pretty small price to pay for a new playground. I signed up for SpotVPS‘ offering (affiliate link!), which is a VPS with 128MB RAM (256MB burstable), 10GB storage and 500GB of bandwidth.

It’s dead easy to set up, you just specify which OS you want loaded on your virtual server, then away you go. There’s next to nothing by way of support, so it is a bit daunting to be left with the barebones of a server and not much else. I initially SSHed in and had a look around, realising that I should get a better feel for the OS. I initially opted for an Ubuntu install, as I had had a bit of practice on the desktop; however, this seemed to use too much memory, so I switched for CentOS. I don’t know a whole lot about CentOS, but it turns out to be an offshoot of Red Hat Enterprise that is very stable, but not necessarily on the latest versions. The book ‘The Definitive Guide to CentOS‘ is a pretty easy read and was really helpful in getting a handle on what was going on and before too long I had user accounts set up and some idea about using Yum to install packages.

After this orientation, I was able to install and setup:

  • Webmin, to make server management much easier
  • PHP, mySQL and configure the existing Apache install
  • proFTP
  • update DNS settings to route a spare domain name (simon4.com)
  • and, finally, WordPress.

Having WordPress up and running was the first achievement I was aiming for, as a way to prove that I could setup and configure a server with the necessary requirements. With WordPress running, a lot of other common web hosting tasks would be possible, so I’m pretty happy with hitting this target.

So, lessons learned from a bargain-basement VPS setup?

  • Firstly, 128MB of RAM is nothing! Even now, the server typically idles at around 180MB being used after a reset, frequently maxing out and throwing strange errors in the SSH session. Moving up to 512MB (1024MB burstable) is only $50/year, and I’ll probably make this change if I continue to use the server.
  • Second, a VPS is a great test environment. If things go horribly wrong, then it is just a button press to restore the SOE or change to a new OS.
  • Third, Linux should not be feared. I don’t have a great deal of experience with Linux systems, but there is plenty of documentation and Googling for answers is a a great way to get a feel for the system and the esoteric corners that you need to explore. If something isn’t working, you just start at the bottom and work backwards to find what’s broken!
  • Fourth, setting up a server is a great way to see just how transparent the structure of the web really is. You get to see every cog and play with every setting. You quickly realise, just like learning HTML, that the every web site is based on the same common technical elements.
  • Lastly, the command line is woefully underrated. Being able to administer whole servers from a CLI shows the real power of the interface. SSH out is blocked at work, but I had the exact same abilities with a Prompt session running on my iPhone over 3G. I really look forward to developing some more bash and scripting skills to exploit the command line.

All in all, I was pretty happy with what I was able to put together for $15 and half a weekend’s worth of effort and research. I’ve now got my own platform to experiment with, break and repair with full control (as opposed to having to fill out tickets for a hosting company to action when changing MX records – also a project that was accomplished on the weekend).

Editing in Vim

On the path to becoming a real geek, the command line is pretty key. I’ve never been scared of the DOS prompt in Windows, but haven’t had much exposure to the terminal in OSX or Linus until recently. As part of coming to terms with working from the keyboard, I decided to tackle one of the seminal text editors – either emacs or vi.

I ended up choosing Vim as it seemed to fit my style of working a bit better, purely personal preference. Perhaps a lot of the decision had to do with already being used to the idea of using j/k to move p and down in other programs, like Reeder and the Google apps. So I picked Vim and got to work. I had the typical initial shock of modal editing, that is, one mode for entering text and another mode for everything else, but soon began to see the logic and the power in it. I worked through the built-in tutorial, then found a few more resources to work through online (I think that this article by Steve Losh made a lot of things click in to place).

Before long, I was somewhat competent. At least, I was no longer deleting paragraphs and not knowing why, and I also learned to work out where I was saving the files I was working on – although I did spray test files throughout the file system in learning this. I found a nice theme, Solarized, and worked out how to make Vim behave on the different operating systems. Importantly, I also discovered the power of the .vimrc file and set about putting together a set of options that further enhanced Vim, but without going overboard and copy/pasting dozens of other people’s settings into one ugly file.

While I still don’t need to use Vim for much coding (most of it is in Xcode), I try to use Vim for all my text notes and replaced Notepad with Vim as the default editor on my Windows machine. Vim’s ubiquity means that I can run it on my MacBook, my Windows machines and also on the Ubuntu instances that I’m playing around with. I even put it on my iPhone and iPad, although the utility of this is still questionable! To keep everything in sync, I store my master .vimrc file in a Dropbox folder and then use the ‘source’ command from each machine’s local .vimrc to import these settings. This means that there’s only one .vimrc file to change and all the settings are kept up to date on all machines. Any OS-specific settings also get put in the local file, but there aren’t very many of these. In case anyone is interested, I have added my settings files, including the master .vimrc, to my GitHub profile – these can be found at: https://github.com/simongoudie/dotfiles

Table view

So table views are a bit more trouble than I thought they’d be. As the second view in the tab bar, I want to display a table view with each item in a row. Tapping on a row should go to an item screen with more details and some actions. Currently, the items are added to a mutable array (probably to move to a database when I get around to learning how to implement one). The items are ‘food’ objects with a number of properties, the key one being the name which is in the property ‘food’.

I initially thought that I could create an instance of a table object, pass it the array and tell the table how to arrange the array in rows and columns, as well as what to do when clicked. Not quite so easy. Turns out there’s a whole heap of pieces that need to be implemented to get this working, not many of which are intuitive. First up is making sure the file knows that it’s working on a table, so the .h file needs to include

@interface TrackingTableViewController : UITableViewController

After this, there’s a set of functions that need to be implemented. I found these out through much Googling and trawling Apple documentation, but mostly ended up keeping the bare bones structure of the functions. The fuctions that were basically copypasta included:

- (id)initWithStyle:(UITableViewStyle)style
- (void)viewDidLoad
- (void)viewDidUnload
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView

The prototype functions I left commented out, most of which I believe are editing functions, included:

- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath
- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath

The trickiest part (for now) was to work out how to get the data from the array to the cells. I eventually caught on to how the

tableView:cellForRowAtIndexPath:

was meant to work, in addition to the concept of recycling table cells. I’m still not completely au fait with this concept, but on the face of it, it looks like once a cell is scrolled off screen, it is then reused for the cell coming up on to the screen (rather than generating cells for every row, onscreen or off). With that in mind, the function turned out to look like:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell *cell = [tableView
                             dequeueReusableCellWithIdentifier:@"ReuseCell"];
	TrackingFood *food = [self.tableViewArray objectAtIndex:indexPath.row];
	cell.textLabel.text = food.food;
	cell.detailTextLabel.text = food.reminder;
    return cell;
}

Not to forget setting the number of rows required:

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return [self.tableViewArray count];
}

And there was a table! This was a long time coming in itself, but a problem quickly became apparent – once the table was generated and displayed once, adding new items to the array didn’t show up in the table. Turns out that the table needed to be reloaded. How? Well, it seemed to be linked to the

tableView reloadData

function, but how to call it? On viewDidLoad was the first thought, but again, this only works on the first time the page is created, so no go there. So if viewDidLoad happens on the first visit, what happens when you move to that view after the first time? viewWillAppear, apparently. This seemed to do the trick:

- (void)viewWillAppear:(BOOL)animated
{
    //    [tableView reloadData];
    [self loadArray];
    [self.tableView reloadData];
}

So finally:
- I had a table
- It filled with the array data
- It reloaded that data and updated the display each time it was shown

The next challenge? Creating a new view to display item details for an item selected in the table. More on that soon, but the main problem was how to pass the correct item and its data from the table view to the new item view, particularly when I have no idea what the table is called or how to address it!