Setting Up a CentOS VM in VirtualBox

July 28, 2011

I’ve been trying to set up a CentOS VM in VirtualBox, and had a lot more trouble than I’ve had with other Linux distros. The prebuilt image I tried from virtualboxes.org had issues with the networking adapter and keyboard layout. Trying the minimal or network installer had the same problems.

I was eventually able to solve it by installing from the Live CD disk image.


Script to Clear Dropbox Cache

June 16, 2011

I store an encrypted sparseimage file on my Dropbox for security. As of a few weeks ago, I started getting a problem where my hard drive space was filling up quickly. It turns out that Dropbox was storing multiple copies of it in a folder called “.dropbox.cache”. According to the forums, this is a bug that was fixed years ago, but it seems to have come back.

I’ve reached out to Dropbox for a fix, but, until then, here’s an AppleScript you can run to clear the cache. It quits Dropbox first for safety, clears the cache, then reopens Dropbox. I saved it as an application and put it in my dock so I can run it in one click any time I’m running low on hard drive space.

WARNING: I don’t provide any warranty for this code. It deletes files off of your hard drive without warning. It shouldn’t cause any problem, but if it does, I can’t take any responsibility for it. Understand the code and use it with caution.


tell application "Dropbox"
quit
end tell
do shell script "rm -fr ~/Dropbox/.dropbox.cache/*"
tell application "Finder"
open application file "Dropbox.app" of folder "Applications" of startup disk
end tell


Setting up a PayPal Sandbox Account

March 29, 2011

I’m trying to get my webapp set up to accept payments via PayPal. Trying to get it set up was a bit overwhelming, just because of all the PayPal options out there. So here’s a quick walkthrough on how to set up a sandbox account for Website Payments Standard, the simplest way to just add a single Buy Now button to your web site.

Note: you do not need to have a real PayPal Business account set up in order to set up a sandbox account. They’re totally separate.

  1. Go to developer.paypal.com.
  2. Click “Sign Up Now”, and fill in your information to register. This creates a developer account. You can use this to create multiple test accounts. For example, if you wanted to test a setup where you’re paid via bank account, and another setup where you’re paid via credit card, you could set up one test account for each. You sign into developer.paypal.com with your developer account, and you will sign into http://www.sandbox.paypal.com with your test accounts.
  3. Once you’re logged in to developer.paypal.com under your new developer account, click “Create a preconfigured account”.
  4. Choose the “Seller” account type, then enter any other information you’d like.
  5. Once that account is created, go to the Test Accounts tab. This will list your sandbox accounts, showing the e-mail address login for each.
  6. Click “Enter Sandbox Test Site” to be sent to www.sandbox.paypal.com (or you could just go there manually).
  7. Sign in using your test account.
  8. When you’re logged in here, a warning: make sure the address of the site always says http://www.sandbox.paypal.com. I clicked a certain link and was incorrectly sent to the production PayPal site, so that could have been unfortunate.
  9. On the top tab bar, click “Products & Services.”
  10. Then click “Get Paid” on the bar below that.
  11. Scroll down to find the “Add Payment Buttons” link and click it.
  12. Click the “Setting Up” tab in the middle of the page.
  13. Choose the style of button you want, and click it.
  14. Make sure you’re still on http://www.sandbox.paypal.com–if not, go there and start over.
  15. Follow the instructions on the screen to customize your button. In particular, under Step 3 you may want to enter a success and cancel URL to send users to, so they can get back to your app and so your app gets information about the purchase.
  16. Click “Create Button” and you’ll be given the code for your button. That’s it!

When you’re ready to create your real business account, it’s easy: just go to paypal.com, click Sign Up, choose Business account, create it, then start at step 9 above and go through the same steps to create the production version of your button.


Returning Grails Validation Errors for Ajax Calls

January 6, 2011

I’m using Grails to create a REST service, and its built-in JSON formatting makes receiving and returning objects easy. When I get validation errors, I’d like to return the errors in JSON in a format that’s easy to use by my client. With a web client, Grails (and most other validation frameworks) by default outputs a list of human-friendly error messages. Ideally, what I’d like to return from my REST service is a list of strings, where each string is one field error.

Incidentally, REST’s HTTP status codes make it easy to distinguish when I’m returning objects vs. error messages. If I return a 200 or 201 status code, it’s success, and my client should expect an object from my data model back. If I return a 500 status code, my client should expect a list of error strings back.

It took me a little poking around in javadocs and Grails source to figure it out, but here’s the syntax that will work:


response.status = 500
render myGormObject.errors.allErrors.collect {
    message(error:it,encodeAs:'HTML')
} as JSON

iOS Monospace Font Bug – A JavaScript Fix

December 20, 2010

After struggling through trying to find solutions for the iOS monospace font problem, I was able to cobble together a JavaScript fix.

To summarize the problem: in fixed-width fonts on iOS, spaces, question marks, and hyphens/dashes all display wider than letters, numbers, and other symbols. Replacing the dashes with –es fixed them, but there was no HTML entity fix for question marks or spaces (all the special spaces display either wider or narrower than regular characters).

I was experimenting with different ways to try to get the characters the same width, and I was going to try wrapping the “bad” characters in a span so I could style them differently. What I found was that characters wrapped in a span display at a different width than either the “normal” or “bad” characters not in a span, so it didn’t serve my purpose. But, I also noticed that (almost) all characters (both “normal” and “bad”) displayed at the same width when they were placed into spans!

Incidentally, spaces still didn’t display at the right width, nor did any of the special space HTML entities. (It seemed inconsistent–spaces seemed OK on iPad, but not on iPhone.) The best solution I’ve found so far (and it’s not a good one for the sake of copy-pasting text) is to replace the spaces with an underscore, and style the spaces to be non-visible.

So a solution would go through my code to output, take all the text (non-HTML) characters, and wrap each of them in a span. This was easier on the client-side than the server-side, because the browser has already parsed my document into DOM objects, so it’s easy to tell what’s plain text characters.

The JavaScript function I wrote takes a node, and iterates through its child hierarchy. Whenever it finds a text node, it splits it into characters, wraps each in a span, performs the extra steps I described above for spaces, and then inserts these spans into the DOM in place of the original text node.

Another limitation of this setup is that it can’t be used for editing text in textareas–it can only be used for displaying text.

Note: this has been tested very little! No warranty it won’t erase all your data. If you find cases where it doesn’t work, and you can make it better, let me know and I’ll post the updated version here.

Download the source, or check out an example of it in action, which allows you to see the text before and after the fix is applied.


Monospace Fonts on iOS

December 20, 2010

Today I just had what might be my biggest disappointment of the year: monospace fonts are not monospaced on iOS. Specifically, the hyphen and question mark are wider than other characters in Courier New on iOS. Of course, this completely messes up any kind of monospace-based layout you might want to do.

Here are the alternatives I’ve investigated that didn’t work:

  1. Leaving the programming industry. Unfortunately, I’m not smart enough to do anything else. On to more reasonable alternatives.
  2. Tried other installed fonts. Courier is supported, but has the same problem. Monaco isn’t supported. And that’s all the built-in font options.
  3. Web fonts. I searched through the Google Font Directory and found “Droid Sans Mono.” If that had worked, man, what a slap in the face, huh? Unfortunately, it exhibited the same problem.

Here are options that could or did work:

  1. In app store apps, custom views to lay out text. If you draw one character at a time, you can make sure they’re placed properly. Unfortunately, if you need to use this for an editor (as I do), that would mean re-implementing a ton of functionality.
  2. On the web, replace dashes with HTML entities. This works for webapps and UIWebViews. If you replace all dashes/hyphens with –, you will see an identical (in Courier New) looking dash, that is spaced properly. This works for displaying text, but wouldn’t work for editors, which are just displaying bare characters and not interpreting HTML entities. Also, this doesn’t solve the question mark problem.

Does anyone else have any suggestions?


Running JUnit 4 Tests in Maven

December 8, 2010

I was trying to convert my JUnit tests to JUnit-4-style annotations, and they would run fine individually in Eclipse, but the Maven Surefire plugin wasn’t running them properly. Seems that it was running them using a JUnit 3 runner, because it detected tests by finding methods with “test” at the start of the method name, but ignored @Test and @Before annotations.

I read a number of articles online about how to fix this, but what they said didn’t work. Eventually, I found that I had to add the following entry exactly (can’t omit junitArtifactName, or add a version number to it).


<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.6</version>
<configuration>
<includes>
<include>**/Test*.java</include>
</includes>
<junitArtifactName>junit:junit</junitArtifactName>
</configuration>
</plugin>
</code>


External CSS and JS in a UIWebView

November 1, 2010

When you’re displaying content in your iPhone app in a UIWebView, it’s helpful to be able to store your JavaScript and CSS in external js and css files. But the way to access these reliably has changed as iOS has matured, and there’s a lot of outdated misinformation about it online. Here’s what worked for me.

By the way, this assumes you’re programmatically creating the content shown in your UIWebView, so this solution wouldn’t work if you’re accessing external web sites. But if you’re doing that, they’ll probably be referencing external CSS and JS anyway. Also, my app doesn’t need to display images in the UIWebView, so I haven’t looked into a solution for displaying local images.

As of iOS 3.0, it appears that a UIWebView can no longer access local files directly. But you can get around this by reading in the contents of the files and then writing them into the HTML of the page you’re going to display. This means you can still store the CSS and JS in their own files, which is much better for readability.

Here’s the code snippet to pull it in: (you may need to copy-paste to see it all)

// load css styles
NSString *cssPath = [[NSBundle mainBundle] pathForResource:@"MyCSS" 
													ofType:@"css"];
NSData *cssData = [NSData dataWithContentsOfFile:cssPath];  
NSString *cssString = [[NSString alloc] initWithData:cssData
											encoding:NSASCIIStringEncoding];

// load js
NSString *jsPath = [[NSBundle mainBundle] pathForResource:@"MyJS" 
													ofType:@"js"];
NSData *jsData = [NSData dataWithContentsOfFile:jsPath];  
NSString *jsString = [[NSString alloc] initWithData:jsData
											encoding:NSASCIIStringEncoding];

// compose full html page
NSString *pageContent =
[NSString stringWithFormat:@"%@%@%@",
 cssString, jsString, actualPageMarkup];

If you try this, the page should display with your CSS, but the JS won’t work. Why? Because, by default Xcode 3.2 thinks your JS files should be compiled, and it doesn’t know how to do it. Instead, what you want is for Xcode to just include the JS files in your bundle, just like it does with the CSS files. To do this, go under Targets in your left-hand “Groups & Files” sidebar, then under your app, then under “Compile Sources.” You should find all your JS files under there. Drag them under “Copy Bundle Resources” instead, rebuild, and the JS should run just fine.


Stupid Cocoa Bugs: Bad Access

October 27, 2010

That is to say, bugs in my Cocoa code that are stupid–not stupid bugs in Cocoa itself =]

After updating something trivial in my iPhone app, I started getting EXC_BAD_ACCESS crashes on the device–but only when it wasn’t hooked up to the debugger. I found out that the error happened in the dealloc method of one of my UIViewControllers, on a line where I release one of the object’s property objects. I checked all my code and it seemed like I was following standard memory management rules.

The solution ended up being dumb: at some point I had gotten it into my head that I was supposed to call the superclass’s dealloc method, then release the properties:

-(void)dealloc {
    [super dealloc];
    [myProperty release];
}

But, when I looked in the Memory Management Programming Guide, it seems that you’re supposed to release your properties first:

-(void)dealloc {
    [myProperty release];
    [super dealloc];
}

This makes sense, assuming that at some point up the superclass chain the object itself gets released or free’d.

The crazy thing was that I’d used the wrong order for the app for over a week without any crashes. I guess this is part of what a JVM guy like me needs to learn about memory management: the problems don’t always show up reliably or right away.


Different CSS and JS for PC, iPad, and iPhone

October 17, 2010

I’m working on a webapp that will run on PCs, iPad, and iPhone. To get the optimum experience for each, I have some styles and JavaScript that I want to run on each, some that are only for iPad, some only iPhone, and some for a combination of the above. Here’s the patterns I’m using to implement this.

JavaScript is easy: I just use regular user agent detection to determine which platform we’re on.

function iOS() { return null != navigator.userAgent.match(/(iPad|iPhone)/i); }
function iPad() { return null != navigator.userAgent.match(/(iPad)/i); }
function iPhone() { return null != navigator.userAgent.match(/(iPhone)/i); }

CSS is a bit more complicated, but not much. I’ve found recommendations for how to target CSS specifically to iPad and iPhone. But really the iPad one is for all iOS devices, so I end up with an iOS CSS file and an iPhone CSS file:


<link rel="stylesheet" type="text/css" media="only screen and (max-device-width: 1024px)" href="iOS.css" />
<link rel="stylesheet" type="text/css" media="only screen and (max-device-width: 480px)" href="iPhone.css" />

So I put my PC styles in my standard stylesheet. Then, I fill iOS.css with styles that I want on all iOS devices or only on iPad. Then I fill iPhone.css with styles I want only on iPhone; and, if there are any styles in iOS.css that were for iPad only, I overwrite them in iPhone.css. For this to work, I have to list iOS.css before iPhone.css, as I did above.


Follow

Get every new post delivered to your Inbox.

Join 525 other followers