Introducing Powergremlin

powergremlin-banner

Introduction

Using power effeciently is essential to making a successful app. Not only is it rude to drain your users’ batteries but if their phones run out of battery quickly they physically can’t use your app. Sadly, the built-in Instruments energy diagnostics are fairly limited. You can see which major power draws (GPS, screen, cell radio, etc) are currently on but there’s no way to see how much current the device is currently drawing. This is the crucial piece of information because ultimately you want to be able to answer two basic questions:

  1. How long will the battery last when running my app?
  2. How much is the battery life extended when I perform a particular optimization?

Powergremlin leverages private APIs to measure the battery’s current capacity over time and determine current draw. Using this information you can easily answer these questions.

Note: Powergremlin only works with iOS 6 and below

Read on

Mac Apps We Like

Here are some apps for OSX that help some of us at Palomino Labs work better, faster, and more efficiently:

TotalFinder ($18, 14-day free trial)

Say goodbye to multiple Finder windows! TotalFinder lets you have consolidate them into one window with Chrome-like tabs. It also brings a bunch of other improvements like Dual Mode which makes working with two directories at once a cinch.

totalfinder


Moom ($10, 100 free uses)

Moom brings Windows 7-style window pinning to Mac, and one-ups it by allowing you to customize everything about it. Easily resize and position windows to pre-defined sections of your screen by snapping it to the edges, or using a handy keyboard shortcut.

Read on

Side-Scrolling Parallax Background Effect Using Only CSS3

View Demo

The parallax effect, or using multiple moving images to give the illusion of depth, is increasingly being used on sites across the web. So its worth exploring how we can create this effect using CSS, without the need for any JavaScript.

Let’s start out with this:

.bg {
  position:absolute;
  top:0;
  bottom:0;
  left:0;
  right:0;
  background:url('front.png') 0 0, url('middle.png') 40% 0, url('back.png') 80% 0, #000;
}

<div class="bg"></div>

This styles the element to stretch to the size of the first non statically-positioned parent element, and layers three different background images on top of each other. Note that the x-positioning of each image is offset a certain percentage, so as the element size changes the images move disproportionately to each other, creating that sweet depth effect.

parallax

Now to get them moving we have a number of options. First option is to use the transition declaration, and add it to the .bg class. Vendor prefixes are still needed for some browser versions— check out Can I Use for the latest details on which browsers support CSS transitions.

Read on

Tips for an Effective App Store Listing

So you’ve just finished building your amazing new iOS application. You’ve spent countless hours making sure it’s the best Facebook-integrated location-based to-do list with slick bird-flinging action, and you may be excited to finally get it listed in the App Store. But you’ve got a little more work and careful consideration to do before you submit your app for approval, because you need keywords, a good description, and some screenshots for your App Store listing. So here are some quick tips and best practices to help you out.

appstore-1

App Store Optimization is becoming as sexy and lucrative as traditional SEO. While Apple constantly tweaks the App Store search engine, the name and keywords of your app are the two fields Apple seems to regard the most important when it comes to search (others include number of downloads and ratings; the description of the app is mostly disregarded). Although Apple doesn’t encourage you to do so, the app name in the App Store can be different than the name that shows up on the home screen under your icon (the two have to be “similar” though, and Apple’s approval team gets to decide what that means); you may want to take advantage of that to include additional terms you don’t put in your keywords.

Speaking of keywords, you’re allowed 100 characters worth, separated by commas (to make the most of that limitation don’t put a space after each comma). Think about what keywords best describe your app, but don’t be too broad as you’re likely to be drowned out by the thousands of other apps with that keyword. Nor should you be too specific–make sure it’s something people actually would search for. Don’t include your app name and company name as part of the keywords, since you’re already searchable by those terms. And if your app is free, the keyword “free” is automatically associated with your app, so don’t include it in your list. Apple also doesn’t let you use keywords that are irrelevant, offensive, and refer to other apps, products, or trademarks. In the latest search update, plural forms of keywords seem to be handled similarly to singular forms, and similarly, using phrases as keywords offers no advantage–use “peanut,almond,butter” rather than “peanut butter,almond butter”.

Read on

Enabling Web Inspector in QtWebKit

Qt embeds a complete WebKit browser that works on Mac OSX and Windows complete with advanced HTML5 features like websockets, the video tag, and local storage. It evens offers a straightforward way of communicating between JavaScript and C++. This makes it easy to embed a website in a larger app (e. g. to implement OAuth in a desktop app) or to build a desktop app entirely in HTML5 (like Adobe AIR but with local storage, websockets, and the video tag).

The only annoyance is that it’s not immediately clear from the documentation how to enable the WebKit Inspector. Fortunately, this is relatively straightforward.

Read on

Custom Task Types With BenchPress

Time being the limited resource that it is, it took a little while to wrap up, but BenchPress is now open source.

BenchPress is intended to be able to be able to represent many different types of payloads via simple JSON configuration, but the project is still new and it doesn’t (yet) have a lot of flexibility in terms of what users can do with the existing task definition language. Fortunately, it’s pretty straightforward to make your own custom task types, so in this post I’ll show how to make a “hello world” custom task type. You can also check out the sample code on GitHub.

BenchPress basics

The basic structure of the JSON you submit to the job controller is simple.

{
    "task": {
        "type": "HELLO-WORLD",
        "config": {
            # whatever you want
        }
    }
}

The config can be any JSON you wamt for your task type. The type is a semi-magical string that is used to identify a few classes that comprise a specific type of task; you’ll see how that string is used later.

TaskFactory and friends

I’ll go from the bottom up to explain the task execution structure. There are two types of nodes in BenchPress: worker and controller. Typically there is only one controller, but theoretically there could be many if you want. A job is submitted to the controller, which splits its sole task among the available workers. Each worker gets its own partition of the overall work.

Fundamentally, the work that a worker does is just a collection of Runnable instances. The Runnables are made on each worker by a TaskFactory instance. This is the relevant method of the TaskFactory interface:

Read on

Using Netflix Curator for Service Discovery

Apache ZooKeeper is a powerful system for managing distributed systems. While ZooKeeper’s power is great, and the developers even provide recipes for common use cases, it is perhaps masked by the extreme flexibility and complexity of the system. Thankfully, the folks at Netflix have implemented many of the aformentioned recipes in their Curator framework. The only lacking bit of Curator is documentation—the wiki has a lot of information, but is inscrutable for a beginner. This post intends to simplify the introduction to using Curator for service discovery.

This is not a cut & paste tutorial for using Curator, but rather a summariztion of how we implemented Curator in BenchPress. While the class names are unchanged, their content is simplified. Pull up the BenchPress code for further detail on employing Curator’s Service Discovery.

To begin with, put some junk in your POM:

<dependency>
    <groupId>com.netflix.curator</groupId>
    <artifactId>curator-framework</artifactId>
    <version>1.1.9</version>
    <exclusions>
        <exclusion>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
        </exclusion>
        <exclusion>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
        </exclusion>
    </exclusions>
</dependency>
<dependency>
    <groupId>com.netflix.curator</groupId>
    <artifactId>curator-x-discovery</artifactId>
    <version>1.1.9</version>
</dependency>

Read on

XPath, Selenium, and Safely Handling Strings

XPath Basics

XPath is a query language that operates on XML documents and offers a reasonably succinct way to find XML nodes. Unfortunately, XPath string literals have an unsophisticated syntax, so there’s a little extra work to be done to handle strings safely. I’ve released an xpath-utils library for Java to do this robustly.

The simple XPath //div will find a div anywhere in the document. You can also use attributes in your XPath. If you have XML like this

<foo>
    <bar attr="baz">asdf</bar>
    <bar attr="quux"></bar>
</foo>

then you could find the second bar tag with /foo/bar[@attr='quux'].

XPath has lots of tutorials, so check those out if you’re curious.

Strings in XPath

XPath is useful when writing Selenium tests. Even though many Selenium selectors are better done with CSS selectors, XPath can express things that CSS cannot, so it’s useful to know how to use it. One common operation in Selenium is using text() to match against text node contents. You could match the first bar node in the above xml with //bar. However, to match against arbitrary strings, it’s important to be able to safely handle them, just like proper XML escaping is important when generating an XML document.

Read on