Kickstarter’s Terms of Use states that it is a platform “where Project Creators run campaigns to fund creative projects by offering rewards to raise money from Backers.” In many ways this has similarities to investing in the stock market, where one puts up money with the hope of getting a reward - more money. When you do get more money in the market, you pay taxes on it. When you get a reward on Kickstarter, the Terms of Use makes no reference of any such tax liability. In the Kickstarter case, how much an individual might pay in the unlikely event that doing so would make them a good citizen is incredibly unclear, as the “value” of the product often cannot be easily determined.
Kickstarter is also like the stock market in that you could wake up one morning and realize you’ve lost all of your investment. In the stock market, at least you would be able to deduct a capital loss on your taxes, while with a Kickstarter project you are left to kick yourself for backing the project, and to fight for something from the project creator(s). I believe it is fair not to tax the rewards on Kickstarter if you don’t get to also deduct the losses.
That being said, there was a quote that made the rounds recently on Twitter stating the Kickstarter was the QVC for hipsters. I’d link to it to give out proper credit but I’m sure I’d be breaking some sort of Twitter usage policy. The Kickstarter platform is certainly becoming a more popular and more efficient way to launch innovative products. Success on Kickstarter provides a company great momentum from which they can grow their business. Project creators can explore and refine several product strategies at a low cost through Kickstarter projects. In many ways, the 5% fee that Kickstarter charges is a huge bargain for project creators who run their projects the right way.
If you are someone like me who craves the latest, cool technology - a hipster if you will - then Kickstarter can become a alluring ‘shopping’ destination. The Kickstarter terms state that it exists for funding ‘creative projects’, but it is becoming more and more of a place to buy products. Every product is “creative” I guess, right? If it becomes a place ‘shoppers’ shop for products, you can be sure ‘producers’ will find ways to put more products on it. In life everything chases money. Kickstarter reviews projects before allowing them online, but it doesn’t seem to be doing alot to limit products from being sold under what often seems like the guise of “investment”. I say this because I can assure you that many people don’t look at this like an investment - they are looking at what they are “pledging” as a purchase of a product. Kickstarter can word it however they want, but that’s how many “pledgers” look at it.
As more and more ‘business’ gets conducted on Kickstarter, I believe it will come under regulatory scrutiny. There has not been a public marketplace to date that I’m aware of that hasn’t in time fallen under regulatory scrutiny. You could say that selling new products on Amazon and eBay is a pretty wide open marketplace, but I would retort that those marketplaces are indeed under scrutiny. As I said, money chases money, and when money and products change hands in a very public fashion and aren’t taxed or regulated, that doesn’t last forever.
I’ve backed two Kickstarter projects personally SmartThings and SlimWallet - both great looking projects - and if those projects go well I’m certainly likely to press my luck and invest in more projects that I find appealing. Like any market, blow ups and the regulators will come a calling. I’m going to enjoy the marketplace before outside forces try and ruin it. And I’m going to try and “invest” carefully - and so should you. Often Wall Street is considered a “legal casino” and be assured that Kickstarter is also a casino - an online, hipster casino. As in all casinos, the house has the advantage, so in time you will lose. Place your bets carefully.
I spoke this evening at OJUG about automated testing of mobile web applications on mobile devices with Geb and Spock. The source code that I demoed during the talk is on GitHub.
With the original forked application, different Grails layouts were used for the mobile version (which leverages JQuery Mobile) of the app vs. the non-mobile version. As can be found in many similar web applications, the mobile version acts as a slimmed down version of the desktop application, with limited functionality and different urls to access certain pages. This creates challenges when writing functional tests for the application - even with great frameworks such as Geb and Spock. While one way to address these challenges is to build the application differently so as to not encounter them, in reality that may not be in the developer’s complete control. And even when it is, it likely is not a viable solution for removing all “challenges” that will come about when trying to create functional tests around a mobile web application. It’s just not an area that is refined to that level yet. For my forked ‘flashcards’ app, I addressed some of the challenges, but left many in place. With that as a baseline, I did, as part of my talk, give a few examples of ways to address these challenges using Geb and Spock that I’d like to share.
One challenge I referenced above is with the URL that you ‘drive’ to using WebDriver is typically defined statically as a url property in your Geb Page Object. But what if you want to use the same page object but have a different url for your mobile version? And what if you want to define a different at condition when you have arrived at the page for mobile? Define mobileUrl and mobileAt properties of course - which I do in this base page class.
You’ll notice that this page also builds the entire url to use and determines whether we need to use an ip address or can just use localhost. This allows Geb to communicate with my mobile browser in both emulator and on-device scenarios. I find this to be easier than port forwarding scenarios, which is the other known strategy for finding mobile browser instances that are not located on the same ip address as the running application.
Another issue that I have run into that I’ve addressed through a base Spock ‘Spec’ class is wanting to know when I’m testing via a mobile device. I find this useful as it allows me the option of having ‘switch’ logic in my Geb code, if I so choose, to do something different if I’m running on a mobile device vs. if I’m not - similar to withMobileDevice from the Spring Mobile Grails Plugin.
An example base specification for this might look like:
With this ‘isMobile’ @Shared property, I can now execute logic specific to mobile or non-mobile devices in specifications that extend this MobileSpec class. You’ll see in my LessonsSpec class that I do switch ‘setup’ logic for my tests where I need to bootstrap some data. With the desktop application, I can do this by uploading a file. On a mobile web application - especially iOS - good luck uploading a file on a mobile web application. With my ‘isMobile’ switch, I can choose to manually ‘seed’ an in-memory H2 database with data when on a mobile device, vs. actually uploading the data through the browser when on the desktop device. While this creates some undesirable complexity in the code, it does allow for re-usability of the Spec class between mobile and desktop versions. In the end, it’s the developer’s choice and the one chosen in this particular test isn’t intended to be correct for this use case or any other - it’s more intended to demonstrate capabilities.
In the end, hopefully this sample application and the pulled out examples above will help drive discussion about what we can do to make testing functionality of both mobile and web applications easier and more pain free. While the tools, like Geb and Spock, that we have at our disposal currently can be used pretty cleverly, trying to test mobile and web versions of applications functionally side-by-side can be challenging. As the source code in the sample application alludes to, the styling applied by JQuery Mobile, Bootstrap, JQuery UI and other frameworks makes defining selectors to get at DOM content challenging, and makes creating pages and specifications that can be used for both versions a somewhat foolhardy endeavor (though my sample forked application tries). Couple this with running these tests on mobile emulators and mobile devices (instead of simply spoofing user-agent strings to act like mobile device), and developers and test builders are created with an array of challenges. Limiting these challenges going forward will allow us to help the clients we work for create better quality, tested desktop and mobile web applications in the years ahead.
All kinds of talk lately about hash-bang URLs (http://url#fragment) and how they will lead to the end of civilization (seemingly) this coming December. I was one of the guilty parties, implementing hash-bangs in a heavy AJAX mobile application I’ve been working on, even though nearly (if not) all of the browsers the users would have would support HTML5 PushState. I did this being aware of the burdgeoning holy war, and had always intended to convert. It actually fits more cleanly into the conventions of the Grails back-end for the application - i.e., http://url/fragment - and it’s HTML5, the future - plus all the other reasons those articles allude to (however opinionated or valid they might actually be). Nevertheless, my two-staged approach was more a matter of already knowing how to do the hash-bang approach and needing to understand better the pushState approach prior to implementing it.
Much of the mobile webapp in question is built upon Backbone.js (which is AWESOME) - and I find it can often take a bit of investigative work (blog/documentation/source code reading + experimentation) to figure out exactly how to do something ‘well’. It’s really pretty simple to switch between a ‘hashbang’ approach and a pushState approach with backbone.js - but it didn’t always seem that way. First some setup then some key takeaways:
Typically at some point in your backbone.js MVC workflow you are updating the state of your models and/or collections on the front-end through communicating with the server. As a result, backbone.js will fire a corresponding add, remove or reset event, which you as the event-informed developer will hook into and bind your own JS function(s) against. If you wish to update the browser url - such that it is bookmarkable and works as a state in your browser’s history - you’ll typically do this here.
So there’s your background. Now let’s look at the two scaled down versions of common backbone.js use cases and discuss the subtle different of approach - first hashbang:
then HTML5 pushState:
They look pretty similar. Note that with the pushState version we have a $.mobile.pushStateEnabled = false;. That’s so if our project has JQuery Mobile that it plays nicely. There’s the whole {pushState:true} option declaration when starting the backbone history, but that’s pretty evident/expected. Notice with the router that the pushState version has the /contextPath before the :toDoId while the hashbang version just has the :toDoId. Backbone’s history functionality has the concept of a ‘root’ url - where presumably one could set the contextPath and all url’s in your backbone implementation would be based off of that, but I found in practice that my url’s at best weren’t consistent on when they did or didn’t use that root definition. So I’d almost recommend seeing if a root url works for you (especially if you have no contextPath) but having this as your fallback. I almost found it clearer to define the full context path where needed - as opposed to having a root path used in Backbone history - and ensuring it would work there - and then leveraging a context path elsewhere - vs. just being explicit across the few areas where url’s exist in one’s backbone app. Nevertheless, I could imagine this ‘base root context path’ being configured as a global variable (or in general be configurable) for some apps where the contextPath could change based on environment (helping bring consistency to your url syntax across your backbone.js layer), but for my use case I haven’t crossed that bridge yet.
This in general seems pretty sensible, but the trigger scenario is significant here (and is noted in the backbone docs) - so that my loadTodo router method gets called. With the hashbang approach, the hashchange event was just being picked up and the router method was getting called by backbone. I believe there’s something I could be doing where the router function in question could automatically be called in both scenarios - but it’s good to know that if the router method isn’t getting called that this option is the cure. It’s much more elegant at least than the manual calls to the router method that you see in some online examples.
Other than that, you’re really set. Regardless of implementation, the “requirement” is that the url’s you “save” should be bookmarkable - i.e., not broken at least and should presumably show the same state of the app that the user sees when the url is initially presented. That makes them also convenient to use as the identifiers in your history, as in the end you are manipulating the browser’s ‘back’ history state, should your user use the browser’s back button in your javascript heavy application. And even though in practice backbone.js is most ideal in SPA (single page architecture) applications, even in those applications, being able to return to previous view states is often a requirement. One trick in restoring these ‘states’ is often the models you need to re-render those states are in the backbone collections you already have locally, so you may just be able to grab the right models (based on one or more identifiers in the url) and re-render the view. There’s also the option that you’ve chosen to cache an HTML5 page in the DOM and can simply transition to that page in your UI upon navigating to particular points in your Backbone.js history.
So while this code hopefully helps provide some examples for the UI prospective, don’t forget the back-end piece of ensuring that the url’s you are saving can be returned to and provide valid results.
I’ve been meaning to get back into blogging for a while. Blogging seems like the 2006 thing to do, right? Nevertheless, I really enjoy the technologies I get to work with on an almost daily basis - namely iOS, Grails and various mobile frameworks (JQuery Mobile, Backbone.js, underscore.js, etc.), and hopefully I run across a few things that might be of use to some other people. At least I’d like to use this blog to help give an outlet to that illusion. Having a blog also lets me rant about things and have it stored online for an indeterminate amount of time - who doesn’t like having their words haunt them for years on end?
So with all that being said, I’ve had a long list of weak excuses why I hadn’t gotten a blog going, and high on the list was pretty things like
Need to figure out where to host it
Need to figure out what software to use
Need to figure out what styling to use
Well I’ve read enough to determine that Octopress is the developer’s Wordpress (I probably first noted it being used on Matt Gemmell’s blog, and his post his experiences blogging with Octopress). I also determined GitHub is as good of a place as any to host one, for starters at least - and works well with Git-hosted Octopress. Octopress’s default theme (which this blog uses) provides good enough styling for a developer-centric blog in my opinion - for the time being at least.
For now I’m using Mouapp for my Markdown editor - recommended by @zanthrash - while I thought I liked the idea of posting to Octopress from MarsEdit, I actually like the raw markdown editing better and being able to see the markup in the same window, vs. building html formatted posts. Plus it isn’t that hard to create a new post in Mao, save it to my local blog posts folder, and do a rake generate and deploy - and have it pushed to my github pages repo see it live online - immediately. I’m sure this will be a process that will scriptable to make it even easier to do with future posts.
A couple things I did note during the process - which probably are obvious to many but weren’t initially to me
To ensure that individual blog pages get generated properly you must have the markdown section rake’s new_post command generates at the top of your markdown file
Strings should be in quotes in your Octopress _config.yml file, or you’ll likely get parse errors
If anyone has tips to make the use of these technologies even better going forward please pass them along.