Connecting to a headless Raspberry Pi w. VNC

Rather than dedicate a keyboard, mouse and display to my Raspberry Pi I'd prefer to access it over the network. ssh access is usually good enough, but sometimes I'd also like to use its graphical desktop, via VNC.

This post at My Raspberry Pi Experience provides all the required info in one place. Many thanks!

To recap the article: with the Pi connected to my network, and with its IP address reserved on the router, log in via ssh. Then install tightvncserver:

$ sudo apt-get install tightvncserver

Create a script, somewhere on the path, to start the VNC server manually:

#!/bin/bash
# start_vnc_server
# Starts a VNC server listening on port 1, with a 16-bit pixel depth.
vncserver :1 -geometry 1024x768 -depth 16
Run the script (natch).
When you're done, either unplug the Pi or shut down the server. If you're as forgetful as I am, you'll need a script for that, too:
#!/bin/bash
# stop_vnc_server
vncserver -kill :1

I use Jolly's Fast VNC as my vnc client. The Pi's server doesn't seem to advertise its presence via ZeroConf/Bonjour, but it's pretty easy to configure:

Pasted Image 3 8 14 12 23 PM 5

And there it is:

Pasted Image 3 8 14 12 42 PM 2

Coincidentally, it's curious that all of my iOS devices show up in the server list. Someday when time is free I should investigate how to view them via VNC...

Mavericks, OS X Server, and CalDAV

Well, that's inconvenient. I didn't set up an email address for my local sync user. Pasted Image 11 5 13 1 24 PM 3

Happily, changing account type to Manual allows one to specify a username and a server address.

Pasted Image 11 5 13 1 26 PM 2

Now to follow Jay's advice from Setting up your own sync server: Export existing iCloud-synced calendars one by one, then import them into the new local server.

Mavericks, OS X Server, and local sync accounts

I've installed OS X Server under OS X 10.9. Among other uses, I wanted to use it for local sync of contacts and calendars, in place of iCloud.

For the most part I've followed the beautifully clear instructions posted at securityspread.com (Setting up your own sync server). Everything has worked as documented, right up to the point in Configuring OS X to connect and sync with the server where Jay writes

[...]select ‘All on My Mac’ (this is where all the originals should be), select all of your contacts and drag them to ‘All OS X Server’.
Whenever I would drag to 'All OS X Server', the green "+" badge would not appear on the drag icon. I could not drop my local contacts onto the "All OS X Server" group.

Eventually it occurred to me to try to set up a CardDav account – the approach described in the section on configuring an iOS client. So, instead of adding a new OS X Server account, I'm doing as follows:

In System Preferences > Internet Accounts, select "Add Other Account...". Then instead of selecting "Add an OS X Server account", select "Add a CardDAV account".

Add A CardDAV account 8

In the resulting sheet, enter the account information much as you would have done when adding an OS X Server account.

Pasted Image 11 5 13 1 00 PM 5

Go ahead and create the account. You may get a warning about being unable to verify the identity of the server, if you're using a self-signed certificate like I am. If this happens you can click "Show Certificate" and, opening the Trust section, explicitly trust the certificate.

Pasted Image 11 5 13 1 04 PM 2

Click Continue to add the account.

With the new account in place, quit System Preferences. Launch Contacts. You should see a new group with the local name of your server. Better yet, you should be able to drag contacts from "All on my Mac" and drop them onto your new server account.

I haven't gotten around to trying a similar workaround for the OS X Server Calendar service. Here's hoping it works just as well.

OS X Server.app and pre-existing PostgreSQL Installations

This one is for everybody doesn't like to read documentation. (Or, at least, for me.)

I recently got a copy of OS X Server, hoping to use it to set up an Xcode CI server. From past projects I had PostgreSQL 8.4 running on the localhost, listening on port 5432.

When I first launched Server.app it would display a setup dialog. Then it would hang for about an hour saying that it was "Preparing Services". Finally it would say that an error had occurred. Thereafter the app would respond very sluggishly to almost every user interaction.

ps showed a few Python processes, all of them trying to connect to a PostgreSQL server. Eventually I remembered my ancient PostgreSQL server.

I exited Server.app, ignoring its warning that it was busy, and moved it to the Trash. A few seconds later an alert appeared recognizing the trashing of the app and reporting that it had been uninstalled (or words to that effect).

With that done, I stopped my postgresql installation via launchctl. Then I moved /Library/Server to /Library/Server.save/, put back Server.app from the Trash, and launched it again.

Things went much better this time.

I should probably have completely removed my postgres installation just to make sure that OS X Server didn't find it by mistake. One step at a time...

Xcode 5 - a profusion of provisioning profiles

When I upgraded to Xcode 5 I was very disturbed to discover that all of my old provisioning profiles, many of which I'd long since deleted from the app store, were suddenly re-appearing. I couldn't make them go away. All of them showed in the provisioning portal as "managed by Xcode 5".

And those old profiles were updated to include every device that I'd registered in the portal. Egad!

It seemed almost as if Xcode 5 were using Spotlight to find .mobileprovision files no matter where they might be hiding, and to bring them back to life.

I'm not sure I've fixed the problem, but so far this procedure appears to have worked:

  1. In Xcode 5's Organizer, review all provisioning profiles installed on your development devices. Delete those you no longer want.
  2. Quit Xcode 5.
  3. Using spotlight search, find all .mobileprovision files on the development machine.
  4. Trash every old .mobileprovision file.
  5. Empty the trash.
  6. Using Safari, login to the developer portal. Delete every provisioning profile that you don't want to keep.
  7. Restart Xcode 5.
  8. Open preferences.
  9. Open each of your Apple IDs, and View Details.
  10. Refresh the Provisioning Profiles.

iOS 6, initially hidden status bars, and UITabBar clipping

My app has a tab bar as its main view. Its status bar is hidden at app launch, via an Info.plist entry:

    <key>UIStatusBarHidden</key>
    <true/>

When the app finishes launching, the app delegate makes the status bar visible.

    [application setStatusBarHidden:NO withAnimation:UIStatusBarAnimationFade];

Unfortunately, this causes the content of the tab bar's current view to extend under the status bar.

Extending under status bar

And there it stays until the app is rotated.

I tried to fix this by resetting the main window frame as soon as the status bar was made visible:

    self.window.frame = [[UIScreen mainScreen] applicationFrame];

This worked, but only until the app was rotated. If the app was initially in portrait orientation, then rotating to landscape and back to portrait caused the tab bar's view to shift downward 20 pixels -- the status bar height -- so the bottom of the tab bar was clipped.

Clipped tab bar

Happily, a discussion on Stack Overflow triggered a head smack: I was changing the frame too soon. I should have been subclassing UITabBarController, overriding viewDidAppear:, and adjusting the view's frame there:

- (void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];
    self.view.frame = [[UIScreen mainScreen] applicationFrame];
}

Problem solved. Thanks again, Stack Overflow.

Singletons and dispatch_once

Cocoa Samurai: Singletons: You're doing them wrong:

"If you must use singletons, use dispatch_once()"

In short: dispatch_once is thread-safe.

"Invalid use of NULL Value", MySQL and RoR Migrations

Today I was working with a Ruby on Rails application, configured to use MySQL 5.6.10, that kept failing to perform a column-modifying migration:

class SomeModel < ActiveRecord::Migration
 def up
   change_column(:some_models, :some_value, :integer, default: 0, null: false)
 end

def down end end

The error message, from the Mysql12 adapter, was "Invalid use of NULL value".

Using the test database I could change the schema manually, from the MySQL prompt. But I couldn't do so in the development database. As is typical, the test database held no records. That should have been my clue.

Eventually I realized that in the development database the "some_models" table contained many records, at least some of which held NULLs for "some_value".

After performing a manual update:

update some_models set some_value = 0 where some_value is null;

I was able to run the migration.

[Edited 20130822 for typos]

Hover on Multi-touch Devices: Samsung Launches The Galaxy S4

In August, 2010, I wrote,

it seems likely that "hover-free Mobile Safari" will become a historical anomaly.

I don't know whether or not their implementation is any good, but Samsung is bringing hover to multi-touch devices. Fun times:

Samsung Launches The Galaxy S4:

  • Air View: Hover with fingers to get a preview of content
  • Air Gesture: Wave your hand to change music, take a call, scroll a web page

SQL 2008 R2 - Uninstall of SQL fails with error about RsFx Driver or Common Files still being installed

I've been trying to re-install a stack of MS SQL Server installations, from 2005 to 2012, with no luck. "Uninstall" of MS SQL Server 2008 kept failing because "the following products are installed:"

Microsoft SQL Server 2008 R2 RsFx Driver

Of course the RsFx (Report Streaming?) driver showed up nowhere in the list of installed programs.

This post solved my problem:

SQL 2008 R2 – Uninstall of SQL fails with error about RsFx Driver or Common Files still being installed:

"Option B – Get the product GUID (Identifying number) from WMI using WMIC and uninstall using MSIEXEC /X {GUID} "

I had trouble reading the text describing the actual shell commands to use, because it rendered white-on-white in my browsers (Safari, Google Chrome). Happily it was easy enough to just select the region with the mouse and paste into a plaintext text editor buffer :)

Climate Predictions: Worst-Case May Be Most Accurate, Study Finds

Here's more about the research predicting "higher end" temperature increases.

Climate Predictions: Worst-Case May Be Most Accurate, Study Finds:

"Hovering several thousand feet above Earth's surface, in the troposphere—the part of the atmosphere where clouds can form—dry zones play a primary role in the future climate.

The scientists compared the observed relative humidity in the dry zones to 16 different climate models used in the most recent study by the Intergovernmental Panel on Climate Change.

Since we don't have good ways to observe or predict how clouds will form, focus instead on relative humidity, which we can observe. How well do the climate models predict the relative humidity data that has actually been observed?

Fasullo and Trenberth found that the three models that best matched the humidity observations were the same ones that predict the hottest future, with temperatures increasing 8 degrees F before century's end. The least accurate models overpredicted relative humidity and projected lower increases in temperature.

Fasullo used the analogy of an eye: 'The dry zones are like the iris of the climate system. With warming, the iris dilates, decreasing cloud cover and allowing in more heat.' Models that don't provide for that expansion of the dry zone fail to accurately depict observed data, he explained."

The article ends with a small equivocation:

Karen Shell, a climate scientist from Oregon State University who was not involved in the research […]: "It's a promising technique. It's one study, but if this relationship holds up, it implies the climate sensitivity is on the higher end of the range."

Climate science is Nate Silver and U.S. politics is Karl Rove | Grist

Climate science is Nate Silver and U.S. politics is Karl Rove | Grist:

"Empiricism won. It didn’t win because it’s a truer faith or a superior ideology. It won because it works. It is the best way humans have figured out to set aside their prejudices, their perceptual limitations, their cognitive shortcomings, and get a clear view of what’s to come."

Let’s be clear about this.... There are serious scientists who doubt that human civilization can endure at all in the face of 7.2 degrees. And we are headed for 10.8.

…on the biggest, most pressing risk facing the country, those involved in U.S. politics might as well be witch doctors. Or worse, Karl Rove.

It’s not a wise approach, because in the climate race, losses are permanent and irreversible. There will be no recount.

For more than 20 years I've been hearing that our response to climate change needs to take into account the health of the economy. OK. How healthy will our economy be when we can't keep factories cool, or grow enough food to keep its employees from starving?

iOS 6 and un-syncable Safari bookmarks

Shortly after iOS 6 was released I upgraded my iPhone. About the same time I set up iClouds backups of Safari bookmarks. Within days (hours? It's all a blur) I discovered that I could no longer sync Safari bookmarks via iTunes. Worse, I could no longer edit them on my iPhone.

The problem proved to be a corrupt schema in Mobile Safari's bookmarks database.

Here's the quick repair procedure. It does not require you to restore your phone to factory settings. (It should go without saying, but: do this at your own risk!)

  1. Buy iBackupBot — it will save a lot of hassle in editing your phone backups
  2. Export Library/Safari/Bookmarks.db
  3. Using sqlite3 /path/to/exported/Bookmarks.db, run the following commands on your exported bookmarks database to re-create missing tables and indices
    CREATE TABLE bookmark_title_words (id INTEGER PRIMARY KEY, bookmark_id INTEGER NOT NULL CONSTRAINT fk_bookmark_id REFERENCES bookmarks(id) ON DELETE CASCADE, word TEXT, word_index INTEGER);
    CREATE INDEX title_bookmark_id_index ON bookmark_title_words(bookmark_id);
    CREATE INDEX title_word_index ON bookmark_title_words(word);
    
  4. Re-import the modified Library/Safari/Bookmarks.db
  5. Use iTunes to "Restore from backup…"

Note that the last step should read "Use iBackupBot to restore the bookmarks file to your iPhone." I haven't yet tried doing that. I didn't even know iBackupBot could restore individual files until after my problem had been solved. Ah, ignorance :)

Also note that the exact set of required schema restoration commands may vary from one phone to another. These were the bits which were missing on my phone.

I learned a lot of interesting trivia while bumbling along toward this solution. Writer's block permitting, I'll try to summarize it in subsequent posts. Meanwhile, here are some links which helped me find a solution. Thanks to all for sharing!

Google Go: Interfaces, not Inheritance

This item showed up on today's "4 Short Links" by Nat Torkington, on O'Reilly Radar. I was struck by Nat's chosen excerpt:

What matters isn't the ancestor relations between things but what they can do for you. That, of course, is where interfaces come into Go. But they're part of a bigger picture, the true Go philosophy. If C++ and Java are about type hierarchies and the taxonomy of types, Go is about composition.

Setting Go aside for a moment, that first sentence captures one of Python's most useful traits: duck typing. Or, I don't care who your parents are. Can you do this job?

In any case, Rob Pike's post is thoughtful and well written, and its treatment of "programming in the large" makes me want to go play with Go.

command center: Less is exponentially more:

" Less is exponentially more

[…]

I was asked a few weeks ago, "What was the biggest surprise you encountered rolling out Go?" I knew the answer instantly: Although we expected C++ programmers to see Go as an alternative, instead most Go programmers come from languages like Python and Ruby. Very few come from C++.

[…]

Python and Ruby programmers come to Go because they don't have to surrender much expressiveness, but gain performance and get to play with concurrency.

Mike Pirnat: Configuring Wordpress SSL Login and Admin on Webfaction

It has been bothering me that my Wordpress installation on webfaction wasn't using SSL for admin. Mike Pirnat explains how to fix this, concisely and clearly. Thank you!

Mike Pirnat: Configuring Wordpress SSL Login and Admin on Webfaction

Placeholder text in UITextView

For a recent iPhone app I wanted a multi-line editable text field, in which I could display placeholder text so my user would know what to do with the field.

Placeholder text is a common affordance provided by several UI classes such as UITextField. But UITextView in iOS 4 does not support placeholder text.

A web search turned up several implementations. Some of these seemed too complex, and some failed to provide the behavior I wanted:

  • If the view is empty, show the placeholder.
  • Whenever the view is the first responder, hide the placeholder.

Here's my implementation. It's very basic. For example it doesn't let you customize the color of the placeholder text; and the placeholder is always centered vertically within the bounds of the text view. But it does provide the behaviors listed above.

PlaceholderTextView.h

#import <UIKit/UIKit.h>
@interface PlaceholderTextView : UITextView {
    UILabel *placeholderLabel;
    NSString *placeholderText;
}
@property (nonatomic, retain) NSString *placeholderText; @end

PlaceholderTextView.m

#import "PlaceholderTextView.h"
@implementation PlaceholderTextView
@synthesize placeholderText;
- (void)hidePlaceholder { if ([placeholderLabel superview]) { [placeholderLabel removeFromSuperview]; } }
- (void)maybeShowPlaceholder { if ([placeholderText length] > 0) { if (![self hasText] && ![placeholderLabel superview]) { CGRect frame = CGRectMake(0, 0, self.bounds.size.width, self.bounds.size.height); placeholderLabel.frame = frame; placeholderLabel.text = placeholderText; [self addSubview:placeholderLabel]; } } }
- (void)initCommon { if (!placeholderLabel) { [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(beganEditing:) name:UITextViewTextDidBeginEditingNotification object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(endedEditing:) name:UITextViewTextDidEndEditingNotification object:nil]; placeholderLabel = [[UILabel alloc] init]; placeholderLabel.numberOfLines = 0; placeholderLabel.backgroundColor = [UIColor clearColor]; placeholderLabel.textColor = [UIColor lightGrayColor]; placeholderLabel.font = self.font; placeholderLabel.lineBreakMode = UILineBreakModeWordWrap; placeholderLabel.textAlignment = UITextAlignmentCenter; [self maybeShowPlaceholder]; } }
- (void)awakeFromNib { [super awakeFromNib]; [self initCommon]; }
- (id)initWithFrame:(CGRect)frame { self = [super initWithFrame:frame]; if (self) { [self initCommon]; } return self; }
- (id)initWithCoder:(NSCoder *)aDecoder { self = [super initWithCoder:aDecoder]; if (self) { [self initCommon]; } return self; }
- (id)init { self = [super init]; if (self) { [self initCommon]; } return self; }
- (void)dealloc { [[NSNotificationCenter defaultCenter] removeObserver:self]; [placeholderLabel release]; [placeholderText release]; [super dealloc]; }
- (void)setPlaceholderText:(NSString *)newValue { [newValue retain]; NSString *oldValue = placeholderText; placeholderText = newValue; [oldValue release]; [self maybeShowPlaceholder]; }
- (void)beganEditing:(NSNotification *)notification { [self hidePlaceholder]; }
- (void)endedEditing:(NSNotification *)notification { [self maybeShowPlaceholder]; }
@end

VMware Fusion, Ubuntu 11.04 Natty Narwhal and file sharing

Adding images to the iPhone Simulator

Occasionally I need to create an iPhone app which can either take a picture or select one from the user's library. Testing such an app on the iPhone simulator is a pain; the simulator doesn't include a simulated camera, and it doesn't provide a way to sync photos from iTunes.

I keep forgetting how to load images into the simulator's photo library. Here's a method that works well, courtesy of Stack Overflow:

  • Launch the iPhone Simulator.
  • In the simulator, launch Safari.
  • Drag an image from the Finder into the simulator. It should appear in Safari.
  • Click and hold the mouse on the image.
  • An action sheet should appear. Choose 'Save Image'.

To confirm that the image got added you can launch Photos in the simulator. The image should appear in your Saved Photos album.

Mercurial - Abort: path 'foo/' is inside repo 'foo'

A trailing slash can be hard to see.

This morning I tried to commit to a Mercurial repository which contained sub-repositories. One of those subrepos had been added a few days earlier, along with the corresponding .hgsub entry. .hgsub had been committed explicitly, without incident.

$ vi .hgsub
  # add entry for src/baz/foo
$ hg ci -m "Some comment." .hgsub
$
Today, for the first time since adding the subrepo, I tried an hg commit at the top-level of my repository. Mercurial responded with an error message:
$ hg ci -m "Blah."
abort: path 'src/baz/foo/' is inside repo 'src/baz/foo'

Say what?

It took a few minutes of quiet contemplation before I finally saw the problem:

abort: path 'src/baz/foo/' is inside repo 'src/baz/foo'

Once the extraneous slash was removed from .hgsub, everything was fine.

Good on you, Apple

From Engadget:

"In particular, we are relaxing all restrictions on the development tools used to create iOS apps, as long as the resulting apps do not download any code. This should give developers the flexibility they want, while preserving the security we need.
"In addition, for the first time we are publishing the App Store Review Guidelines to help developers understand how we review submitted apps. We hope it will make us more transparent and help our developers create even more successful apps for the App Store."

For older posts please visit the full Desert Moon blog site.