Comicblendr “Secret” Features

I’ve been a bit slack about updating this space lately, but Comicblendr (and the associated iPad version, Comicblendr HD) has been through several rounds of updates to fix bugs and introduce a number of user-requested features. Many of these new features are immediately apparent, such as the inclusion of “alt” text for comics that support it. Some aren’t so obvious, however, so let this serve as a brief user-guide for these “hidden” Comicblendr features.

Jump Forward/Back
The navigation controls in Comicblendr aren’t just limited to “previous”, “next”, “first”, and “last”. The application also supports skipping forwards and backwards by an arbitrary number of strips. To use this feature, tap and hold the “previous” button (if you want to skip backwards) or the “next” button (if you want to skip forwards) until the “skip” dialog appears. This will allow you to enter an arbitrary number of strips to jump forwards/backwards by. Note that while you can enter any desired number, you will likely get the best results if you constrain yourself to values of 10 or fewer.

Swipe to Change Comic
When reading a comic you can swipe left or right using two fingers to jump to the previous/next comic in the comics list. For instance, if you have both “QuestionableContent” and “Xkcd” enabled in the settings section then when reading QuestionableContent strips you can swipe left across the comic viewing area (with two fingers) at any time to start reading Xkcd.

Double-tap for Full-screen
When reading a comic you can double-tap anywhere in the viewing area to enter/exit full-screen mode. This feature is currently only available in the iPhone version, but will be making an appearance in the iPad version shortly.

Note that full-screen mode is not available in “Lite” versions of Comicblendr.

Posted in Uncategorized | Leave a comment

Webcomix – Now on your iPhone!

Except it’s actually called Comicblendr. Someone else beat me to the “Webcomix” name in the app store. But their app kind of sucks, and Comicblendr doesn’t, so there should be no confusing the two.

In any event, the experiment that began so long ago has finally yielded an app, vindicating my original performance-oriented, client-agnostic design. Building the app was, in fact, a breeze, taking not more than a week’s worth of actual effort. And that’s even including the time spent doing things that I have no innate talent for, such as creating graphic resources and the like. I can only blame myself and chronic procrastination for it taking so long to come up with an app.

I invite you to give it a try; all things being equal I think Webcomix works better as a native iPhone app than it does as a webapp. If nothing else it’s certainly a lot of fun:

Comicblendr - More fun than Sony Playcubes tied to snapping turtles.

If you reply to this post with a comment I will gladly provide you with a promotional code good for a free copy of the app (until I run out of codes). All I ask in return is that you give it a positive review in iTunes. Assuming, of course, that you think it deserves one.

Do also note that if you have an innate talent for graphic design and would like to make a contribution to Comicblendr, you are welcome to do so. There is, in fact, an ongoing contest to find some better icon and splash-screen artwork. Full details are available on the app’s Facebook page.

You can find Comicblendr on iTunes at the following URL:
http://itunes.apple.com/app/id477119612

Update
A brief user-guide for Comicblendr is available here. This guide discusses some “hidden” features that aren’t immediately obvious within the app.

Posted in banter, software | Tagged , , | 15 Comments

[iOS] Jira Mobile Connect

Not long ago Atlassian released version 1.0 (now up to 1.0.7) of their Jira Mobile Connect plugin. This is a plugin for Jira (obviously) that aims to simplify testing, error-reporting, and feedback collection/management for iOS applications. Assuming that you are doing iOS software development and have a Jira server instance running (which you really should if you are doing any nontrivial amount of development work of any variety) then using this plugin in your apps is really a no-brainer. Jira Mobile Connect includes a number of very cool features, such as the ability for users to attach annotated screenshots/images to their feedback reports, to record audio to attach with their feedback, and even to chat back and forth with the developer(s) working on their issue/ticket . And of course it does basic crash logging and reporting, as well.

Previously if you wanted a free/open-source crash reporting framework for iOS your options were basically limited to QuincyKit, which is a serviceable but basic solution. Sadly, the backing architecture used by the QuincyKit server is not well designed and scales very poorly with the number of crash reports in the system. Once you have around 5,000 you’ll notice the server slowing down significantly, and go much beyond 10,000 that and the system grinds to an unusable halt. With a day or so of database and code refactoring, these scalability issues can be resolved, creating a system performant enough to track millions of error logs or more. But that’s a subject for another time. The point for today is that despite its basic level of functionality and flawed server architecture, there are a few key areas in which QuincyKit blows the default implementation of Jira Mobile Connect out of the water:

  1. Automatic grouping of crash reports.
  2. Automatic symbolication of error logs.

If you have any experience whatsoever with supporting multiple high-volume iOS applications you will instantly realize that these are features that you want. They might even be features that you want more than annotated screenshots, audio feedback, user chat, or seamless integration with Jira and all the awesomeness that Jira brings. In short, Jira Mobile Connect’s lack of support for these two key features may cause serious developers to pass it over in favor of other solutions.

Without grouping every single crash will be creating a new ticket in Jira that you need to track and resolve. Multiple instances of the same crash will have to be manually flagged as duplicates within Jira. And without symbolication trying to actually map back from an error log to the line of code that caused it is an exercise in futility, or at best, tedium.

In any case, rather than abandon the excellent potential shown by Jira Mobile Connect I decided that instead I would attempt to patch it up and add the missing features myself. It’s all open-source code, after-all, and if the tangled mess of PHP that is QuincyKit server can provide these features then they can’t be that difficult to implement. Unfortunately I had to change too many files in too many different places to show the code here, but if you want the short version of it I was able to implement both grouping and symbolication, and you’re welcome to view the complete diffs on bitbucket:

https://bitbucket.org/aroth_iapps/jiraconnect-ios-iapps/compare/..atlassian/jiraconnect-ios (client/native iOS code)
https://bitbucket.org/aroth_iapps/jiraconnect-jiraplugin-iapps/compare/..atlassian/jiraconnect-jiraplugin (server/Java code)

One interesting side-effect of adding groups was that it became possible for multiple client UID’s to be associated with a single Jira ticket. This had an important implication for feedback notifications/chat in that the reference implementation allowed only a single UID to be associated with each Jira ticket. Since the UID is used for determining what notifications/updates to send to the native client, this restricted update notifications to a single user per ticket. Not too useful if you have a common crash that thousands of users have experienced. The implementation above extends the data model to allow multiple UID’s to be stored against a single Jira ticket, allowing each UID to be updated when new feedback is posted by the developer on a ticket. In essence, implementing grouping also required the implementation of group feedback/chat.

There is one caveat with my server implementation, in that it assumes the existence of the ‘symbolicatecrash‘ utility on the system’s runtime PATH. This means that it will only work if your Jira server is hosted on a Mac, with the proper XCode developer tools installed (and with your application’s .app and .dSYM files copied to the local filesystem). This is of course a requirement regardless if you want automatic symbolication to work on any sort of system; somewhere there needs to be a Mac with ‘symbolicatecrash‘ available. In any case, it is a fairly simple matter to either turn this off or otherwise make it more intelligent, if your Jira server is incapable of running ‘symbolicatecrash‘.

Also note that the native iOS code has been restructured to build a universal iOS framework as opposed to an architecture-specific static library. This is done using Karl Stenerud’s excellent XCode4 Project Template. You will need to install this template in order to actually build the modified code. Or you can just refactor it back to build a static library again, but why would you want to do that?

When using the iOS framework, be aware that you will need to set the ‘-all_load‘ linker flag and also include all the images and nibs in the framework’s ‘/Resources‘ folder as part of your build. You will probably also want to include the ‘JMCLocalizable.strings‘ file in the same folder as well, to provide proper text and labels on Jira Mobile Connect’s UI elements.

Regardless, if you do a lot of iOS development and are already using Jira (like you should be) then I encourage you to check this out. This is the Jira Mobile Connect plugin, now with automatic grouping and error log symbolication.

Posted in banter, coding, software | Tagged , , , | Leave a comment

[JavaScript] Creating an Animated Hurricane Tracker

Here’s a fun little diversion I came up with when the news was all abuzz with information about Hurricane Irene. Now I use Wikipedia almost exclusively for keeping track of this sort of thing as I find that it consistently provides the most up to date data in the cleanest and most easy to digest format, but I also noticed a large volume of comments on other news sites complaining about the accuracy of hurricane forecasting. And this got me to wondering, just how accurate are the historical forecasts when overlaid with the actual storm track?

Well Wikipedia doesn’t provide this information directly, but interestingly enough Wikipedia does in fact keep all the historical data necessary to answer this question. Thanks to Chrome’s awesome JavaScript console (and the fact that Wikipedia uses jQuery on all of its pages) it is a very simple matter to extract this historical information in a format that is easy to work with later. The following code will do the trick:

var result = [];
jQuery.each($(".filehistory a[href$=5day.gif]"), function(){
    result.push(this.href)
});
result;

This simply constructs an array containing the URL’s of every historical forecast/storm track graphic (ordered by date from newest to oldest) and outputs it to the console. We can then copy/paste the console output to wherever we like, such as jsFiddle for instance. Combine this with some basic HTML structure:

<div class="title">
    Hurricane Irene Animated Forecast Map
</div>
<img id="display" src="http://fcf.teambeachbody.com/fcf/images/spinner5.gif" />
<div id="status">
    (<span id="numLoaded"></span> of <span id="total"></span> frames loaded)
</div>

…and some simple JavaScript to handle the actual rendering:

document.getElementById("numLoaded").innerHTML = "0";
document.getElementById("total").innerHTML = data.length;

//preload all the images so that they are cached for the animation
window.imagesLoaded = 0;
for (var index = data.length - 1; index >= 0; index--) {
    var node = document.createElement("img");
    node.style.display = "none";
    document.body.appendChild(node);
    $(node).bind('load', function() {
        window.imagesLoaded++;
    });
    $(node).attr('src', data[index]);
    //node.src = data[index];
}

//run the animation
window.currentImage = data.length - 1;
window.updateAnimation = function() {
    if (window.imagesLoaded < data.length) {
        //keep waiting
        document.getElementById("numLoaded").innerHTML = window.imagesLoaded;
        return;
    }
    $("#status").hide();
    document.getElementById("display").src = data[currentImage];
    currentImage--;
    if (currentImage < 0) {
        currentImage = data.length - 1;
    }
};

setInterval(updateAnimation, 200);

…and you get an animated map of the entire forecast history, including the actual storm track. The result looks something like this:

Not too bad for a few dozen lines of code and about 30 minutes worth of effort. You can also access a full-scale, editable version of this animated storm history here.

So what does this say about the accuracy of the hurricane forecasting for Irene? Personally I think it shows that the forecasts are pretty damn accurate. In fact, if you focus just on the solid white portion of the predicted storm track it appears that the storm never deviates from its forecast path. It’s only when looking at the dashed white portion of the forecast that any significant deviation can be noted. And the dashed white portion indicates forecasts that are more than 72 hours in the future.

Of course we should always be working to improve our ability to predict and forecast these things, but I have to think that being able to accurately predict a storm’s movement for up to 72 hours into the future is adequate for most purposes.

Posted in coding, javascript | Tagged , , | Leave a comment

Fixing Copyright

You don’t have to look very far to see that copyright is in a pretty sad state nowadays. There are lawsuits flying left and right, sometimes even targeting children and deceased people. Companies attempt to scare, coerce, and bully citizens into paying thousands of dollars for a few dozen or few hundred dollars worth of content, and the courts are imposing even more ridiculous verdicts amounting to costs of several thousand dollars per song. There’s even been pressure for governments to turn into copyright police or worse.

While the most active arena for this ridiculosity would appear to be the music industry, the movie and software industries are not far behind, and with the growing popularity of e-book readers books and printed-media are bound to follow shortly. The core issue behind all of this nonsense is the same no matter the context, and it is that content owners feel compelled to continue enforcing a copyright model that came into existence well before the Internet, while simultaneously resisting any and all attempts to change, reform, or modernize the underlying model to bring it up to speed with the technology of today. The original creators of copyright law did not envision a world in which any piece of information could be replicated and distributed anywhere on the globe instantly at almost zero cost. They did not stop to consider the social implications of such a technology, nor what it would mean for content creators, owners, and distributors.

For our less technologically adept visitors I’d like to digress into a bit of an example. Consider the web browser that you are using to view this website. It has created, without any explicit consent from myself, and quite possibly without your knowledge, at least one copy of all the content that you see on this page. It holds this copy in memory and uses it as its internal representation of the website state. Also, unless you have disabled your browser’s cache, then it has very likely created a second copy of all the content on this page, this time stored on your computer’s HDD. While the first copy will disappear as soon as you leave the page, this second copy may stick around on your computer for weeks, months, or even years. And if you want to get technical, there is a third copy of this website that is stored in your computer’s video framebuffer while you are reading it/displaying it on the screen. So by simply accessing this website, you have caused up to three copies to come into existence. And I could assert, under current copyright law, that each one of those copies has been produced illegally. And if we use the benchmark figure of $2250 per illicit copy, you will see that you now owe me $6750 for your browser’s misbehavior. So you see how ridiculous it can get when every copy that gets produced is treated as if it is some tangible thing that must be tracked and paid for. Or if you don’t then please mail me my $6750 (cash only, please, no personal checks).

Current intellectual-property laws were designed for an analog world in which a copy of something always had a 1:1 mapping back to some tangible item in the physical world, and in which the distribution of an illicit copy robbed the content creator not just of the effort they put into creating their intellectual property, but also of part of the capital which they had invested in creating and distributing legitimate physical copies of their work. We no longer live in such a world, however. The cost of creating and distributing copies of a work is now essentially nil (unless you happen to be one of the few holdouts who still insist on distributing physical media), and we should be loathe to apply a model designed for an analog world to today’s digital context. Unfortunately that’s exactly what we’ve done, and it has lead directly to the aforementioned ridiculous outcome(s).

So it should be clear that something needs to be changed. But what? My suggestion is that the whole issue of copyright as it pertains (or rather, should pertain) to digital content can be understood through two competing concerns:

  • The social benefits of a world in which every person has instant and unrestricted access to every piece of information, media, and digital content ever created are far too great to be ignored or repressed.
  • The people who invest their time and effort into creating a piece of intellectual-property deserve compensation for their efforts in an amount that is proportional to the popularity of the content they produce.

Given the first point, it should be clear that the days in which people pay for this-or-that specific bit of content in individual transactions are rapidly coming to a close. There is simply no excuse for not allowing everyone to have access to everything, when the net social benefits of the proposition are considered.

We’ve all seen movies or read books that depict a sci-fi future world in which anyone can sit down at a public (or private) terminal and pull up any bit of content they desire, from music to movies to television shows and beyond. We are at the tipping point of making such a world a reality, but first we have to let go of the antiquated idea that each person should pay individually for exactly the content that they access or consume. Such a model made sense in a world of tangible things, of which only a finite number of copies may be created, and where each copy carries a very real cost associated with its production, distribution, and stocking. But we are rapidly leaving that world behind, and this model no longer makes sense.

Now it’s easy to just say that everyone should get all of this for free, but that would be ignoring the second point. The individuals who spend their time creating the content that the rest of us consume deserve fair compensation for their efforts. Without that, there would simply be no incentive for people to continue to create music, art, movies, and the like (the cliche of the “starving artist” notwithstanding). The content creators (and owners, though I really wish artists would wake up and realize that they no longer need to sign their lives away to large media corporations in order to be successful) should be able to profit from their work, particularly if their work becomes widely popular. So where does that leave us? We could say that each individual who wants access to a particular piece of content must purchase it directly, but that gets us nowhere, it’s just the same broken status quo that we have today. And that’s not good enough.

What I think we need, and where I think we need to get to is, in essence, an Internet tax (to use the most easily comprehensible if not the most strictly accurate of terms). Basically, there should be some reasonable monthly fee that is assessed against each ISP in terms of dollars per connected user. This fee would of course be passed on from the ISP’s to their customers, so the cost of Internet access would increase slightly. All proceeds from this monthly “tax” would go into a fund that is distributed (again monthly) to intellectual-property creators/owners, based upon the relative popularity of their content during that month. This of course requires a way of determining a rough estimate of how many times a given piece of content is accessed, but given that the RIAA and MPAA and others seem to have no trouble coming up with estimates of how much money they are “losing” to piracy I have to believe that doing so is entirely possible. Either that or these media companies are guilty of blowing smoke up our collective asses.

If this all sounds a little far-fetched to you (or if you’ve experienced the typical “no new taxes” reflex), consider that there are already a number of opt-in services that are essentially following this model. Services such as Spotify, Rhapsody, Google Music, and even Netflix all collect a monthly subscription in exchange for unlimited access to any content you want. Internally these companies are simply pooling their monthly subscription revenues, paying a portion of it out to their content providers as royalties (almost certainly based upon how many times each piece of content was accessed, as in “based upon the relative popularity” of content), using the rest to cover operating expenses, and keeping whatever is left over as profit.

There are limits to these services, of course, the biggest one being that you only get access to content owned/created by groups that have explicitly signed agreements with these companies. If you happen to want something that is created by an artist or owned by a company who doesn’t want to play along with the service provider, then you are out of luck.

Thus my proposal is to simply take a model which has already proven popular and successful, centralize it, and remove the ability of everyone on both sides to opt out. Every individual with an Internet connection has to “subscribe” and no artist or company may opt out of the system, and that is the trade-off. Everybody pays, and everybody gets equal and unrestricted access to everything. Governments can stop playing copyright police, media companies can stop lawyering everybody to death, the courts can stop levying massive fines against normal citizens who haven’t done anything that the rest of us haven’t done and continue to do every single day, artists can continue to earn a living by producing popular works of art, and everyone can enjoy the collective creative output of the human race without restriction or fear of reprisal.

So how much would this actually cost? That I cannot exactly say. But as a baseline most of the aforementioned music services start at around $5 per month. The unlimited-streaming video Netflix package is $8 per month. So that makes $13 per month combined for unlimited music and video. However when participation is compulsory the user-base increases significantly, and the economy of scale starts to come into play. So I would think that in the neighborhood of $10 to $15 per month for complete and unlimited access to all the world’s movies, music, television shows, and books would be adequate. The only question you have to ask yourself is; would I pay $100 to $200 a year for unlimited access to any and all media I happen to want, with the knowledge that my money is going to support the artists who create the content I most enjoy?

I know I certainly would, particularly if it meant that I would never again have to pay for an individual song, album, DVD, or book again, nor worry about corporate goons snooping on my online activities, slapping me with a lawsuit, or trying to subvert the government and turn copyright infringement into a capital offense. There’s a wonderfully bright sci-fi future waiting for us over the next hill, we just have to realize that it no longer makes sense to keep an antiquated copyright model around on life-support, and that reaching the top of the hill will require a small bit of sacrifice from each and every one of us.

I for one am looking forward to that day when anyone anywhere can sit down at an Internet-connected terminal and have free and unfettered access to the collective works of all mankind. And if it costs me $15 a month to make that possible, then so be it.

Posted in banter, editorial | Leave a comment

[JavaScript] Finding Equidistant Lat/Long Coordinates

Here’s a quick one that was inspired by a StackOverflow question and built using the references posted here. It allows you to compute the position of an arbitrary number of points (expressed as latitude/longitude pairs) equidistant from a given centerpoint (using a given radius/distance, of course) on the surface of the Earth. The crux of the code goes like so:

window.pointsAround = function(centerLat, centerLng, radius, numInterpolations) {
    var result = [];

    //do annoying trig maths to work out the delta in latitude between our start and end points
    var targetD = radius;          //km
    var fractionalDistance = (targetD / radiusOfEarth) / 2;
    var sqrtA = Math.sin(fractionalDistance);
    var a = sqrtA * sqrtA;
    var sinHalfDLat = Math.sqrt(a);
    var dLat = Math.asin(sinHalfDLat) * 2;
    var dLatDegrees = degrees(dLat);

    var minLat = centerLat - dLatDegrees;              //furthest valid latitude above the origin
    var maxLat = centerLat + dLatDegrees;            //furthest valid latitude below the origin

    var centerLatRadians = radians(centerLat); 

    //topmost and bottommost points in the circle
    result.push({lat: minLat, lng: centerLng});
    result.push({lat: maxLat, lng: centerLng});

    //step from minLat to maxLat, interpolating coordinates that lie upon the circle
    numInterpolations = numInterpolations ? numInterpolations : 360;
    var step = (maxLat - minLat) / (numInterpolations / 2.0);
    for (var count = 0; count < (numInterpolations / 2) - 1; count++) {
        minLat += step;
        var minLatRadians = radians(minLat);
        dLat = radians(centerLat - minLat);

        //more annoying trig to work out the delta in longitude for our interpolated coordinate
        var dLon = 2 * Math.asin(Math.sqrt((a - (Math.sin(dLat/2) * Math.sin(dLat/2))) / (Math.cos(minLatRadians) * Math.cos(centerLatRadians))));
        var dLonDegrees = degrees(dLon);

        var newLng = centerLng + dLonDegrees;
        var deltaLng = newLng - centerLng;
        result.push({lat: minLat, lng: newLng});
        result.push({lat: minLat, lng: centerLng - deltaLng});
    }

    return result;
};

This code works out the northernmost and southernmost points that are the specified distance away from the given centerpoint. It then steps between the minimum and maximum latitude of these two points, interpolating the appropriate longitudinal value(s) to satisfy the equidistant constraint. The total number of coordinates returned can be controlled using the optional ‘numInterpolations‘ parameter. When not specified a total of 360 points will be returned by default, because that is a nice, round number.

If you use something like the following code to plot some points on a map:

window.map = new GMap2(document.getElementById("mapDiv"));
    var centerPoint = new GLatLng(37.4419, -122.1419);
    map.setCenter(centerPoint, 8);
    map.addControl(new GLargeMapControl3D());
    map.addControl(new GMapTypeControl());

    var marker = new GMarker(centerPoint);
    var markerText = "Center @ 37.4419, -122.1419";
    GEvent.addListener(marker, "click", markerClickHandler(marker, markerText));
    map.addOverlay(marker);

    var points = pointsAround(37.4419, -122.1419, 50);
    for (var index = 0; index < points.length; index++) {
        var point = points[index];
        var latlng = new GLatLng(point.lat, point.lng);
        marker = new GMarker(latlng);
        markerText = "Marker @ " + point.lat + ", " + point.lng;
        GEvent.addListener(marker, "click", markerClickHandler(marker, markerText));
        map.addOverlay(marker);
    }

…you will get a nice circle of points around the hard-coded centerpoint. You can see a working example of this here: http://jsfiddle.net/HmchC/13/.

Posted in coding, javascript | Tagged , , , , | Leave a comment

Natural Scrolling Isn’t

Mac users and other developers such as myself who have no choice but to use a Mac for certain projects will already know what I’m talking about. For everyone else, however, the newest version of OS X includes a most bizarre feature, called “natural scrolling”. Despite its innocuous-sounding name, this feature (which ships enabled by default) breaks the interface to the OS by inverting the direction content scrolls when using the mouse-wheel.

Apple’s explanation (and seemingly, justification) for this atrocity of a feature is that “content should move in the same directions as your finger”. Now that’s all well and good, except for one thing; there is no “finger” when using a mouse. Touch- and mouse-driven are distinct input paradigms.

Apple is correct in that in a touch-driven system content should indeed track in the same direction as the user’s finger moves. If a hypothetical touch-based interface were ever released which scrolled content in the opposite direction of the user’s finger, then people would say that it was broken. And rightly so. Moving content in the same direction as the touch is the intuitive operating mode of a touch interface.

Similarly, moving content in the opposite direction of the scroll (or more accurately, moving the scrollbar in the direction of the scroll) is the intuitive operating mode for a mouse-driven interface. And it follows that Apple’s mouse-driven interface in Lion is just as broken as that hypothetical touch-driven interface would be. By Apple’s logic scrollbars themselves should also be inverted, tracking from the bottom of the scrollbar to the top as the content scrolls from top to bottom. Confused yet? Apple’s blunder here is that they have conflated mouse-driven input with touch-driven input, without bothering to translate properly between the two.

As an interesting aside, a comparable analog to touch-style scrolling does exist in the mouse-driven paradigm; the drag operation. You’ve probably seen it in things like Adobe PDF documents, and it can also be observed on any scrollbar. In the drag operation you choose an anchor-point, and then that anchor point moves in the same direction that you move, and it all intuitively makes sense. The problem with scrolling using a scroll-wheel is that it has no anchor point from the user’s point of view (they have done nothing to nominate one, and the UI does nothing to indicate that one has been chosen). In the mouse-driven paradigm, scrolling is a distinct operation from dragging, and by conflating the two Apple has broken their interface. At least until they start incorporating a touch-screen into every computer they sell.

If Apple’s position is to be taken seriously, then we must accept that the current cursor position must always represent where the user’s “finger” is. There’s one major problem with that, however. With a mouse and cursor, the cursor never leaves the screen. And if the user’s finger is in constant contact with the screen, then why should there be a separate scroll operation at all? It would logically follow (since mouse-driven == touch-driven and cursor == finger in Apple’s world) that since a touch-point exists, and since it is moving, the content (all of it, everywhere) should simply scroll whenever I move the mouse (all the time, everywhere). But of course that is nonsense, and so is Apple’s “natural scrolling” mouse behavior. The mouse cursor is not a finger, it does not represent a finger, and its location is not where your finger is touching. Mouse-driven and touch-driven are different modes of operation, with different intuitive behaviors.

Thankfully, you can turn off “natural” scrolling and rid your OS of its nonsense. I’ll be happy to turn it back on when my mouse is replaced with a touch-screen display, but until that day comes you can forget about it. Apple, please stop trying to convince me that moving my mouse cursor around the screen is supposed to be the same thing as dragging my finger all over a touch screen. It isn’t, and I’m not stupid enough to be convinced that it is.

Posted in banter, operating systems | Tagged , , | 3 Comments

[JavaScript] Naming Your Function ‘$’ is not Clever

The atrocity that is the dollar function dates back at least 2005 and the introduction of the Prototype Framework. Back in those days, ‘$()‘ was simply a shorthand way of saying ‘document.getElementById()‘ without having to type all 24 characters. And don’t get me wrong, aliasing ‘document.getElementById’ to something shorter is not a bad idea, in and of itself. But why should ‘$()‘ be the alias? Such a name gives no clue that the function is looking up a DOM element by its id. Something like ‘findById()‘ (or even ‘$findById()‘ if there are concerns about naming collissions) would have been infinitely more clear, and still a good deal shorter than writing ‘document.getElementById()‘.

But sadly, Prototype decided to use ‘$()‘ as the name of their alias. And even worse, other frameworks have followed in this pattern, adding their own dollar functions that have semantics that can be completely different from the original ‘$()‘ introduced by Prototype. Consider jQuery, which introduces its own version of ‘$()‘ which can be used to find (and wrap and clone) elements in the DOM by a number of different criteria, but which sadly fails miserably when given a string containing a literal element id. This creates a lovely situation where now the developer cannot even guess at what ‘$()‘ is actually doing without first checking to see which framework is being used by the code. It also means that any code that was written using Prototype’s ‘$()‘ will be broken by including jQuery (and vice-versa).

“But that’s what ‘jQuery.noConflict()‘ is for”, you say. But you miss the point. It shouldn’t be necessary for ‘jQuery.noConflict()‘ to exist in the first place. If the jQuery developers hadn’t decided that it would be cute to define their own version of ‘$()‘, then jQuery would never conflict with anything except possibly an older version of jQuery. The thing that really baffles me is how so many developers (obviously talented developers, at that, considering the work that goes into something like Prototype or jQuery) can all decide that it is a good idea to try to lay claim to a name that exists in the global scope. Granted JavaScript does not have any concept of a proper namespace, but if jQuery limited itself to only setting properties on an object named “jQuery” and Prototype did the same on an object named “Prototype” and so on, the current JavaScript landscape would look ever so much more sane.

And of course, this says nothing of the ‘$$()‘ and ‘$F()‘ functions that were also introduced by Prototype (and the ‘$E()’ and ‘$ES()’ functions inexplicibly introduced by MooTools) and whose names are so semantically worthless that a developer has no hope of inferring their function without consulting the reference documentation. Which again can only be accomplished after checking the entire codebase to determine which framework it is that is defining these functions with its woefully awful naming convention.

If the developers of Prototype, jQuery, Mootools, and the like wanted to turn JavaScript into an unreadable and unmaintainable mess of a language like Perl, then I applaud them for their efforts. But if not then I call them all out on their atrocious naming convention and design decisions. There is no excuse for this nonsense. If you’re building a JavaScript library or framework, then pick a reasonable “namespace” to use for it. This namespace should be the only thing that you bind in the global scope. Everything else that is part of your library should be bound as a property inside of this namespace. And there should be no automatic creation of shorthand aliases in the global scope.

I don’t think this is too much to ask. And of course, any developer that wants to use a global shorthand alias can always do:

window.$J = jQuery;
window.$P = Prototype.$;  //or:  window.$P = document.getElementById;

It takes all of one line of code to set up an alias. But when you start doing this automatically for everyone that uses your framework you create nothing but problems. Especially when you jump on the bandwagon and choose the same crappy shorthand alias names that other frameworks are already using.

There is absolutely no reason why multiple JavaScript frameworks should all be competing over the same terrible function names. This isn’t a contest to see who can break the most legacy code, or who can come up with the most obtuse API. They do have such contests if you are interested in such a thing, but this is not one of them. The only thing accomplished by parading the dollar sign around as an example of a well-chosen function name is an increased brittleness in the code that glues together the majority of our modern websites. It muddies semantics, and creates cases where completely unrelated libraries are not easily compatible with each other, and where simply importing a new library can cause existing code to break. Even worse, some novice developers get the wrong idea from all those dollar signs flying around think that they need to (or should) prefix all of their function names with “$”. So let’s put this bad practice to bed before it’s too late.

So please, can well all stop writing frameworks that give people the impression that calling a function “$”, “$$”, “$ES”, or “$anything” is a good idea? Is it so difficult to choose a reasonable namespace, minimize the number of things that you declare in the global scope, and allow the developer to define a global shorthand alias for this-or-that utility function if they decide they want to? I think not.

Posted in coding, javascript | Tagged , | Leave a comment

Resurrecting sun.misc.Unsafe

Here’s one that only the hardcore Java hackers will enjoy. Perhaps you are already familiar with sun.misc.Unsafe. This heavily protected internal class provides access to a number of low-level memory operations and system functions that are generally hidden away from user-code executing in the JRE. If you’ve never heard of it before (or even if you have) then I encourage you to read this article to get an idea about the sort of things that can be done using ‘Unsafe‘. Note that we are talking about very low-level operations here. Operations where if you make a mistake, you won’t just get a simple ‘Exception‘ complaining that you did something bad. Instead you’re liable to bring the entire JVM to a crashing halt if you do something wrong (it’s called ‘Unsafe‘ for a reason, after all), so you should proceed only if you’re sure you know what you are doing.

Also note that the method described in the other article for getting your hands on an instance of ‘Unsafe‘ no longer works. Using the latest JDK, the following code will not work (you’ll get compiler errors for even trying to import sun.misc.Unsafe):

private static Unsafe getUnsafeInstance() throws SecurityException, NoSuchFieldException, IllegalArgumentException,
    IllegalAccessException {
    Field theUnsafeInstance = Unsafe.class.getDeclaredField("theUnsafe");
    theUnsafeInstance.setAccessible(true);
    return (Unsafe) theUnsafeInstance.get(Unsafe.class);
 }

Here is a variant that still works:

	public static Object getUnsafe() {
		try {
			Class unsafeClass = Class.forName("sun.misc.Unsafe");
			Field unsafeField = unsafeClass.getDeclaredField("theUnsafe");
			unsafeField.setAccessible(true);
			Object unsafeObj = unsafeField.get(unsafeClass);

			return unsafeObj;
		}
		catch (Exception e) {
			return null;//UNSAFE_ERROR_CODE;
		}
	}

Note that as importing sun.misc.Unsafe now causes a compiler error, it is only possible to return an Object reference to the ‘Unsafe‘ instance. This means that any method that you want to call on it must be done through reflection, which is tedious at best. Luckily, I’ve taken care of this tedious bit for you, and created a wrapper that provides the same public API as sun.misc.Unsafe and uses reflection to delegate method calls to the real ‘Unsafe‘ instance. The source code for this utility is quite long and not very interesting, so I’m not going to post it here. Instead you can use this direct link to download a copy.

Here is a simple example of how to use this class to perform some basic tasks:

		System.out.println("Testing sun.misc.Unsafe...");
		double[] averages = {-777.0, -777.0, -777.0};
		UnsafeUtil util = new UnsafeUtil();
		System.out.println("addressSize=" + util.addressSize() + ", pageSize=" + util.pageSize());

		long memPointer = util.allocateMemory(1024);
		long memPointer2 = util.allocateMemory(1024);
		System.out.println("1K memory blocks at addresses:  " + memPointer + ", " + memPointer2);

		//valid copy
		util.copyMemory(memPointer, memPointer2, 1024);

		//invalid copy
		//util.copyMemory(memPointer, memPointer2, 1024000);

		int result = util.getLoadAverage(averages, 1);
		System.out.println("getLoadAverage:  Result=" + result + ", averages=" + averages[0] + ", " + averages[1] + ", " + averages[2]);

Do note that if you uncomment the “invalid copy” line then running this code will very likely crash your JVM. As noted above, you should use this utility with caution, particularly if you are running it in an environment shared by other Java code.

And why do all this when Sun (now Oracle) clearly does not want people mucking around with this class? Because ultimately power belongs in the hands of developers. All developers, not just the select few chosen to work on privileged system code.

Posted in coding, java | Tagged , | 1 Comment

[Android] Installing Adobe AIR on the Android Emulator

I’ve got no idea why this process is so poorly documented, nor why many of the existing resources describing how to install the AIR runtime on the Android emulator are so needlessly circuitous, pointing you to links on the official Adobe site that have moved or no longer exist.

But suffice to say, if you want to install the Adobe AIR runtime on an emulated Android device for testing or development purposes without having to wade through a ton of fuss and nonsense, you have two basic options. The first is described briefly here, and basically involves installing the latest Flash/Flex/AIR SDK from the official website and then grabbing the AIR runtime package from ‘<AIR_SDK_ROOT>/runtimes/air/android/emulator/Runtime.apk‘. This file is the AIR runtime that must be installed on the emulator for any apps built with Adobe AIR to function. And this method works fine if you don’t mind downloading and installing the entire AIR SDK (90 MB) just to grab this one file.

You other option is to use this direct link to download just the AIR runtime package (6.1 MB). Note that this is version 2.7 of the AIR runtime, and has been tested with an emulator running Android 3.1 only. I cannot vouch for it working with any other configurations.

In either case, once you have gotten a hold of the the runtime .apk file, installing it on your emulator is a relatively simple process. All you need is the ‘adb‘ utility that is included in the “Android SDK Platform Tools” package (note that this package is not the same as the similarly named “Android SDK Tools” package). If you don’t have this package installed yet, then use your Android configuration manager to install it. Then simply navigate to ‘<ANDROID_SDK_ROOT>/platform-tools‘ and run the following command (while your Android emulator is running):

adb install /path/to/your/AIR/runtime.apk

This will install the AIR runtime on your emulated device, and you can now install and run AIR-based Android apps on your emulator. Quite simple, really. Which only doubles my confusion with respect to why this simple process seems to be so poorly documented online.

Posted in coding, configuration | Tagged , , , | 1 Comment