Hello, I'm Steven Veltema: a programmer, founder of Labosu K.K., maker, and longtime resident of Japan.

Keep Map Target While Zooming To Show All Markers

Recently an app I develop needed to keep the map center while zooming in/out to show all markers dropped on the map. It's not a particularly difficult thing to do, but it took a moments thought. The example is for Android, but it works the same way on iOS etc.

3d Printed iPhone6+ clamp

I've been dying to try out the new time lapse photography on my 6+, but I haven't had a great way to attach the larger iPhone to a camera stand. I could order up one from Amazon or something, but this is something that just screams for 3d printing.

Camera clamp rhino screenshot

I whipped up a quick clamp design that would fit the large phone and subtracted a hex hole for the mounting nut. One printout, some hot glue, and a few rubber bands later I had a camera mount.

Camera clamp photo The first version is fine for my purposes but the tolerances on the slider should be tighter, the edges in the band groves should be rounded to prevent band wear, and the whole thing could be slimmed down a bit to use less materiel.

Shapeoko2 T-slot Clamps

Now that my Shapeoko has a nice t-slot aluminum bed, I needed some work holding clamps. The great thing about CNC machines and 3d printers is that you can often make parts to improve your machines with the machines themselves.

For any CNC work, it is a must to keep the workpiece held firmly while milling. There are many ways to do this with bolts, tape, metal clamps etc. The slots in the t-slot bed can be positioned inconviently for a particular piece and tape can come undone partway through milling not to mention the occasional tape residue left on the bed. Premade clamps are availaible or printable out of plastic, but I wanted to make at least part of something for the machine with the machine itself.

Inventables has created a cam tool specifically for use with the Shapeoko called Easel that's simple to use. Upload a SVG file, set up the materiel, arrange the parts layout, connect and mill. The CAM functionality of Easel is minimal, no tab support etc, but it works well for more simple jobs and has very easy to follow instructions. Files can be shared with links or published to Inventables.

Creating the cut file was a simple matter of taking a very nice existing clamp design from thingiverse, cleaning up the 2d data, and modifying the design and material settings to match the 9mm MDF I had at hand.

Easel screenshot

For some reason, Easel marked several areas in red that might be problematic, but after checking the tool paths and the design this was a false warning and I milled the pieces anyway. Milling the clamps (link) was a smooth and trouble-free process. The only quibble I had about Easel besides the lack of tab support was that the tool paths were not optimised very well and resulted in significant wasted movement. Some of that could possible be improved by altering the design, but still the milling took much longer than otherwise necessary.

cut out clamps After cutting, glue the halves together, clamp and let them dry. Next, drill a hole and cut off a short piece (roughly 18mm) of 20mm dowelling. When the glue has dried, add a bolt, washers, a wing nut, and an insertion nut for the t-slots and the clamps will be ready to go. Wooden clamps are great if you happen to make a mistake and run the tool through one, destroying the clamp but saving the end mill (hopefully).

assembled clamps

BOM

Laser Cut Snowflakes

Paul Kaplan from Inventables made this great snowflake generator tool that outputs SVG. I figured this would be an easy project for newcomers to my weekly FabFriday events at Fablab Oita. It's quite easy if you are familiar with Illustrator (or similar vector tools), but if not then you may need a little help.

Snowflake Generator First go to Paul's great snowflake generator tool and design a snowflake. At this stage it's ok to have narrow points within reason but very small details may become lost. After you are satisfied with the design, download the SVG snowflake file

Next open the SVG in Illustrator or a similar vector image editing program. I'm still getting by with and old Japanese version of CS3 that amazingly still runs on Yosemite. The first step is to select the object and increase the line width. snowflake in Illustrator Some detail will end up getting lost, so only do this if you have narrow weak points in the design and increase the line width as little as possible and still maintain structural integrity. Illustrator line with settings Next in the line window, round off the corners and edges. snowflake in Illustrator Select the snowflake again, and outline the object paths to fix the new thicker object outlines. Finally, select the snowflake and use the pathfinder merge tool to clean up all of the interior lines. Final snowflake design From here, you can add a hole to hang the snowflake or cut out the design as is.

cutting the snowflake

The whole process is quick, easy, and fun to watch. Adding a colourful ribbon and a little white makes a nice ornament.

Snowflake ornament

Shapeoko2 aluminum bed

So, this summer I purchased and assembled a Shapeoko2 because CNC machines are really cool. From the perspective of a professional, the whole kit is full of compromises like the delrin wheels, the fake Dremel hand tool, and the Arduino controller. Most of these compromises are fine for an entry level desktop CNC that machine that is not in heavy use and used with only lighter materials. After my first project, it was pretty obvious that the worst compromise was the stock MDF bed (followed closely by the fake Dremel). The MDF bed may be cheap, easy, and relatively light but the two panels of the bed flexed under the slightest pressure and were nowhere near strong or stiff enough to provide a stable cutting platform. One post in the Shapeoko forums showed a particularly nice aluminium bed with extrusions (HFSQN4-15250-500) from Misumi that happened to be sized perfectly to fit the stock Shapeoko. Luckily, Misumi is a Japanese company and I quickly placed an order for the extrusions and corresponding nuts for the T-slots.

Shapeoko2 with aluminum bed and bracket

After installing the extrusions buckled upwards ever so slightly. To eliminate the buckling I made two brackets out of aluminium, tapped holes into the extrusions, and bolted them down to the existing t-slot crosspieces. It's not a permanent solution but for now it's amazing how much the extrusions stiffened up the whole machine and greatly increased the overall precision.

Next on the list, some nice work holding clamps to go with the T-slot extrusions.

Changing UITextField Placeholder Font and Color

There are no settings available in a UITextField to make the placeholder font different (color, smaller, fontface etc) from the font or textColor. You would think that it would be possible with UITextField attributedPlaceholder, but you would be wrong. The way to get around this is to sublclass UITextField and override drawPlaceholderInRect. Occasionally, this will cause placeholder text to be pinned to the top of the UITextField, which can be fixed by vertically centering the draw rect.

Generating strings.xml from JSON at Build in Android Studio

One project that I'm working on right now shares it's assets across several platforms and development teams. The client maintains all of the string data in Excel and generates several simple JSON files from a worksheet. These sheets are then used by other teams for building the web interfaces and by myself for making the iOS and Android apps. Using the raw JSON files on iOS is not a problem because I use a custom cache backed localized string manager and not the Interface Builder localisation tooling or the default NSLocalizedString macro.

In Android, string handling and localisation are highly integrated into the tools making custom solutions more difficult. Additionally, strings in Android projects are defined in a strings.xml file residing in the read-only res folder and thus are not writeable from within the app itself. The only way then to use the standard IDE etc and still use common set of JSON files for localised strings, is to generate a proper strings.xml file from the various JSON files as part of the build process. Since I am developing in Android Studio, this meant fiddling around with embedded build tool, Gradle. Being relatively unfamiliar with both Gradle and Groovy, the language used in the build.gradle file, it took me a bit of fiddling around but I was finally able to generate a proper strings.xml as part of the build.

The localised JSON string file is just a simple map of keys and strings similar to below:

{
"Localize_back_button":"戻る",
"Localize_html_title":"タイトル",
}

The additions to build.gradle file are as follows:

In the new generateStrings task, the JSON file containing the localised string data is read in and a new xml MarkupBuilder is created to receive the new string data. Next we iterate over the JSON map and add the keys and values as string elements to the xml MarkupBuilder, writing the new strings.xml file when finished.

The trick to get this to be run on build, is to insert the new generateStrings task into the build process. This is done by adding the generateStrings task as a dependency to the preBuild task, ensuring that the strings.xml file is recreated before every build.

gradle.projectsEvaluated {
    preBuild.dependsOn('generateStrings')
}

Possible Improvements

  • The strings.xml file is recreated on every build and as such slows down the build process. There should be a way to only regenerate the strings file when the JSON has been altered
  • It may be desirable to not overwrite the file, but read in the current xml file and only add in the changes from the JSON assets. Could lead to a bloated strings file though.

Restart

Restart

with a few posts from the past

NSDateFormatter woes

NSDateFormatter has some really obscure behavior that I'm sure trips up a lot of people. A case in point. I have an app where a date is sent from the server in the format: "yyyy-MM-dd'T'HH:mm:ssZZ". You would expect that the following code would work just fine:

NSDateFormatter dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setTimeStyle:NSDateFormatterFullStyle];
[dateFormatter setDateFormat:@"yyyy-MM-dd'T'HH:mm:ssZZ"];

but you would be wrong. It appears that

  1. for certain locales (say Japan)
  2. when the phone is set to 12 hour mode

The date formatter ignores the date format and inserts its own localized AM/PM string and date string parsing fail. Now in Japan, the standard and thus majority of users use a 24 hour clock, so you will only get intermittent reports of errors/bugs which can be quite frustrating.

To fix this, instead of solely relying on setDateFormat, you need to set the locale. In a rather obscure Q&A, Apple recommends en_US_POSIX.

NSDateFormatter dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setLocale:[[[NSLocale alloc]initWithLocaleIdentifier:@"en_US_POSIX"] autorelease]];
[dateFormatter setTimeStyle:NSDateFormatterFullStyle];
[dateFormatter setDateFormat:@"yyyy-MM-dd'T'HH:mm:ssZZ"];

I'm sure there are many apps, particularly ones developed with only an English speaking user in mind that contain this bug.

Resizing a UIWebView to fit with a fixed width

Formatting ScreenshotUIWebView is great for displaying hightly formated content, but sizing the frame correctly can be tough at times. Recently, I was using a UIWebView to display formated content and I needed to resize it display all of it's contents. The standard way to automatically resize a UIView to fit its contents is to call sizeToFit. Calling sizeToFit on the UIWebView in the -(void)webViewDidFinishLoad:(UIWebView *)webView UIWebViewDelegate method works nicely... almost.

My problem was that I wanted the width to be fixed and change only the height but sizeToFit automatically changes both, causing the content to run off the edge of the screen.

However, there is a neat little trick.

By calling the UIWebView's& stringByEvaluatingJavaScriptFromString method it is possible to interact with the content of the UIWebView. From there it is easy to get the content size and resize the UIWebView's frame accordingly.

- (void)webViewDidFinishLoad:(UIWebView *)webView {
        CGFloat contentHeight = [[webView stringByEvaluatingJavaScriptFromString:
            "document.documentElement.scrollHeight"] floatValue];
        webView.frame = CGRectMake(webView.frame.origin.x, webView.frame.origin.y, 
            webView.frame.size.width, contentHeight);

And away you go.