Wednesday, October 28, 2015

Learning a Whole New Tech Stack for Liftium, a Beautifully Simple Weightlifting App for Android

If you follow me on anything, you've been subject to multiple shameless plugs of Liftium for Android, a weightlifting tracking app. You'll have to forgive me for being a bit excited. I talked for years about publishing something to an app store, finally getting serious about learning iOS development starting almost two years ago. About a year ago, I had nearly finished a patient/ provider secure messaging app for iOS when the plug was pulled on the project. Go figure that after spending so much time on iOS, my first app is a collaboration on a project first targeting Android.

Lookin' good, Liftium!


It's been a thrill working on it and releasing, and since I (very infrequently) share technical bits here, I figured I'd describe some of the tools and how I learned to really enjoy working with them.

For my day job, a little over a year ago I become a full-time, full-stack web developer. I had worked on web services before, and even spent some time on an MVC app, but I had spent the vast majority of my career a) not doing full-time development, and b) most development I did in Windows client apps using a very vanilla Visual Studio configuration. I didn't have time to learn how a bunch of different technologies could work together, because my job didn't offer much time to research the right solution to the problem. If it wasn't first-party, strongly-typed, and it didn't work just by hitting a "play" button, I was afraid of it.

A big part of embracing development on Liftium was embracing a diverse technology stack that isn't available in shrink-wrap:

  • Cordova for taking a web app and compiling it into an Android APK
  • Angular.js as an MVVM-design-pattern-enforcing framework, providing guardrails around otherwise wild and messy HTML and JavaScript.
  • Grunt for "compiling" the web app, allowing us to use intermediate languages that make web technologies easier to implement, like SASS for CSS.
  • SQLite/ Persistence.js for storage. In this case, native database capabilities are exposed to our web app via a Cordova plugin, and wrapped with a nice API that tracks changes we make to objects and persists them to the database.
When doing, say, native iOS development, a lot of these things are right there in the base package. Apple gives you Core Data for persistence, Apple enforces that you'll use "the" MVC framework, Apple has ways of styling things. It's easier to get the base Apple package working because it's already there. But, even though I used to disdain un-opinionated frameworks because to me no opinion meant no guidance on how to make it work, I came to really enjoy what this toolset became, which was more like an un-opinionated federation of opinionated frameworks.

An obvious draw of Cordova is the ability to write cross-platform code. But, once you get there, the choices can be liberating, if you get over the initial feeling that they're bewildering. The web doesn't favor a particular MVC framework. I was lucky to not be struck by analysis paralysis, as my partner had already chosen Angular. But having gotten under the hood, I can appreciate how the app might work with React or Ember, and I think I could have been happy in any number of frameworks, because one nice thing about web development is, given some guardrails, JavaScript is really enjoyable to write. I wish I could write native iOS code in JavaScript (React Native is like this, but it's still young). 

I feel so bogged down opening XCode after having experienced writing a similarly-equipped client app in JavaScript. JavaScript is just so... light and fluffy. There's such little syntax to learn. I just need a text editor to write it. Once I took 15 minutes to learn promises and prototypical inheritance and such, I was off to the races. I no longer am afraid of code littered with anonymous functions. I'm kind of sad when it isn't, frankly. Compare this to how I feel when writing Objective-C block syntax. I will never, ever memorize block syntax, even if I become a full-time iOS dev someday. Even if I am writing Swift. I think Swift's block syntax replacement might be even more difficult to understand than Objective-C's.

So, the first big takeaway- you can write real client software in JavaScript, with less effort and head-scratching than the languages that you're "supposed" to do this stuff with, and it's a lot of fun. It's not that I hate Objective-C in comparison- I still like to brag to C# devs that I use pointers in off-hours- but I feel confident and capable in JavaScript, something I couldn't imagine a few years ago.

The second part is what you get when you make all these little pieces fit together. If you code regularly in an environment where everything is there for you in the IDE or someone else has put a nice API around the external dependencies and you just don't have to think about how they integrate, I recommend stuff like this. Try using SASS instead of CSS and having it build on the fly with Grunt of Gulp or Webpack. Integrate a 3rd party web service into something. Mix native and web. It's frustrating at first- it can be really, really frustrating the first time you try it and nothing fits together and everything is throwing cryptic errors on the command line. But out of these ashes come superpowers. Anything you integrate that actually works brings you closer to a place where you could write an API linking assembly code to a pizza. Going from being able to construct a clever algorithm to someone who could lay plumbing where none existed previously has been a game changer for me. It's absolutely changed what kinds of problems I feel confident taking on and the results when I do take on those hard problems that I previously thought were impossible.



Monday, May 4, 2015

Blue Ocean or Red? The Personal Finance Market and Another Way

I have a budgeting system that's worked pretty well for a few years and I think it's been improving. It started as one Google spreadsheet with one page born out of desperation, when we kept hitting the bottom of the barrel on our checking account. This sheet just gave me a general idea of how cash flow would look for the month- would I have enough in our checking account or not? Later I took all of the "set in stone" expenses from that sheet, combined them with the typical set in stone stuff on our credit cards, took the difference between that and our monthly income, and that became a monthly budget for everything else. The last two years have been just keeping an eye on what comes out of that last number and otherwise just copying over the columns month to month on everything else.

I was really excited when I heard about You Need a Budget (YNAB), as it seemed to encode into software what I thought was the most distinctive feature of my spreadsheet system- the separate budgets/ accounts, or, as I called them, "pots," for different types of spending. Like, say, allocating $100/ month to home improvement or a vacation fund. When the app went on sale at the end of 2014, I scooped it up and coded as much of my system in it as I could.

So far, it's working, and it isn't. The pots are mostly fine- I like that money rolls over into the next month but it shows how we're performing against what's currently in the pot. Entry is quick and easy and works well on computers and phones. But now I see what really was distinctive about my system. It wasn't the pots, but the handwaving I did over most of the budget. YNAB allows transactions to be automated, but I don't want to think at all about my monthly mortgage payment, other than initially subtracting it from what money I actually have to work with. If I want to get that same sense of cash flow, I need to time up these automated transactions exactly and add in my previous credit card balances. I can't really do my monthly divvy up on the quarterly water bill. I need to add credit card payments in the same place where I put the spending transactions I care about.  I've taken to just paying attention to the pots and ignoring the checking account and total values, because they look nasty and I'm not sure I trust them, and event less sure I care about them.

So, for now I think I'm keeping YNAB for entering transactions we track in detail and I'll continue with at least my monthly cash flow model. The whole ordeal has me wondering about the value of a different kind of budgeting app. The value of a budgeting app like YNAB or Mint or Quicken that strives to keep your entire financial picture by either pulling in your accounts or having you enter everything is just that- you give it everything, it should provide a perfectly picture of expenses and cash flow. But the cost is high- entering everything isn't easy, and pouring over a computer's interpretation of your credit card statement is tedious.

I want an app that just lets me hand-wave over the parts of my budget that I'm not concerned about. The mortgage payment will not change all year, nor will city taxes. I can estimate the electric bill for the year and come within $100, so I don't care about that, either. Assume that my salary is constant for the year. Ah, this is where YNAB really gets me- I can't really project anything, because I can't count on a paycheck until I get it. I get the idea that people shouldn't spend cash that isn't there, particularly for those who may have overspent or have an unstable income- key audiences for finance tracking apps. But I'm responsible enough to revise the equation if I lose my job. If I can assume I'm going to be gainfully employed for the year, I can do things like preallocate for big expenditure so I am underspending before then, and see how cash flow is affected when I will take the hit.

My working theory is that there's generally only about 25% of your budget (stuff after fixed bills, taxes, regular savings, etc.) that is really worth tracking for anyone who is not in a desperate situation cash-flow-wise. Tracking 25% should take me 1/4 of the work of tracking 100%, right? So, given an alter ego with 40 extra hours a week, I'd like to make that app. Financial tracking for lazy people who don't urgently need a financial tracking app. Probably not the best idea because it seems like there are already plenty of such apps that are well-geared towards the people who need or want them the most, but maybe it isn't a terrible idea because perhaps there are others like me who want to a bit of control without all the extra work.

Sunday, January 11, 2015

A messaging app where you talk to yourself

One silly idea I've been playing with lately is what I call "Introvert Chat." The idea started when I was working on a real two-way iOS messaging app that used the excellent JSQMessagesViewController, and I was trying to think of other contexts for using the control. When you write a messaging app with such a control, obviously you accept input from the user and wait for new messages from a server for the other half of the conversation, with your app processing the output of each source in a similar way, just plopping it on a different half of the screen. Around the same time, I had read something about the deep internal conversation that introverts have with themselves at the expense of talking to others (I am personally familiar with this), and then I thought, "what if both sides of the conversation accepted input from the keyboard?"

So, it was the pairing of a technical possibility with a practical reality that is actually quite productive. The conversations inside of our heads are at least as important as those that happen with our mouths. In fact, a conversation with yourself is an oft-used writing technique (I've always enjoyed Terry Pluto's columns where he asks himself questions and answers them). The app can add something to these conversations that perhaps the average general-purpose note-taking app cannot- the guardrails of an internal conversation. As my data "schema" has sorted itself out so far, Introvert Chat enforces organization of answers under questions. The questions generally go in chronological order, but you can tap on a question to bring it to the front, and your next answer will go under that question.

The other part of the schema is topics- just as one can switch to a different question in the conversation view, one can flip between different topics- essentially other conversations with yourself. In fact, one of my next moves is to ditch the menu drawer setup and just go with a simple messaging UI a lot like Apple's texting/ iMessage app.

Tap on the "Ask" button to type out a question, then the app switches to "answer mode," waiting for your answers. Tap on a question that's already on the screen to add to it.


Tap on a question in the drawer menu to open the current topic on that question, tap a topic to switch to a different conversation with yourself.


A big part of this app is making something that I would consider using. For me, that means it syncs to the cloud so it's saved safely and is accessible from other devices. At the moment, the Evernote API looks like a great way to do this. I don't think it makes sense to sync changes in Evernote back to Introvert Chat, but formatting Introvert Chats into Evernotes for reading later makes sense.

There's a whole additional level of smarts that is needed to make this really useful- a lot of our internal conversations don't start with a question. Or maybe they start with one question and the dialog just goes on, but still has logical subdivisions that aren't necessary "the" question. This could be a whole new level of the data hierarchy, or perhaps the app could just "ask" a question at the right time. In my daily standup example above, perhaps Introvert Chat just adds the day heading automatically and I start typing under that day.

At a level beyond that, perhaps Introvert Chat could initiate conversations by asking a question out of the blue at the right time. Ask me once a week to describe a good book I'm reading, or a new app idea, or ask me what's one thing I love about my wife.

Thursday, October 9, 2014

The new celebrity obsession

One app idea that keeps kicking around in my head is what I call "You v. Ben."  From time to time, Ben Franklin's daily routine pops up on a productivity website, or even as clickbait elsewhere.  His charting of virtues (same link) also comes up from time-to-time.  Long story short, he was one of the most successful americans and obviously very disciplined, so who wouldn't want to be more like Ben?

Franklin not only left us his routine, he wrote it down in the form of an interactive chart.  It was kind of like an early form of gamification.  So that's the idea behind the app- turn Ben Franklin's routine and principles into a game.  Someone already did this with his thirteen virtues chart, but it's just the virtues chart.  I think the chart itself could use an update to make it easier to keep up to date, and his schedule could be included, and perhaps some of his other life experiences or principles could be incorporated.  For instance, he avoided meat in order to save money to buy books.  Maybe there's a meat-avoidance component, or just a thrift component.  Or a reading component.  He also gave away a lot of his inventions.  So maybe you get points for "open sourcing" your ideas.

Speaking of points, that's the big point- turn these charts and virtues and other things into questions and turn the answers of those questions into a score- a number that says not how good or bad or virtuous or punctual or whatever you are, but how much like Ben Franklin you are.  I'm reading his biography right now to see what other bits I can find that might not be as obvious.

Not sure if I'll make this, but it's the best idea I have at the moment, I think.  I wouldn't expect it to make a million, let alone a thousand or perhaps even a hundred dollars.  But at the outset it sounds like something a person or two might consider spending 99 cents on if it's good.  In the broader sense, I wonder if there could be legs to the general idea of gamifying the ideas of great thinkers and doers.  There's the trend of desire for self-improvement (look at all the couch-to-5k apps on the top charts), and there's the sense of nostalgia (maybe towards the 70's or 80's now, but why not the 1770's or 80's?), and then of course, the obsession with celebrity.  Top app seller Kim Kardashian and Ben Franklin aren't quite comparable, but maybe our nostalgic and celebrity-obsessed culture will manifest itself some strange way that will make this a great idea.

Monday, July 28, 2014

Feel free to shamelessly copy: Catholic tech handout

A few months ago, I gave a short talk before our parish's RCIA class about good resources for Catholics in social media, the web, and on smartphones and tablets.  It boiled down to a few different types of resources:

  • Who to follow on social media sites and what communities to join
  • What "read-only" resources to check out
  • Recommended Catholic-specific apps and recommended "secular" apps that that can help in practicing one's religion (reading eBooks, note taking, pod catching, etc.)
It was a lot of fun to do.  One of my favorite small touches of it (not sure if anybody used it, but if one person did it was worth it) was to compress everything into a one page document that could also be accessed via a web browser.  That way, folks took something home with them from the meeting and could go somewhere where they could click links in order to access the resources of which I spoke.  Much cleaner than trying to put all those URL's on the page, and much more precise than asking folks to just google anything they were interested in.  I could see doing this for just about any talk given where there are recommended online resources to check out (which is just about any topic I think!).

I didn't even really need to make a web page for this.  I just wrote a Google doc and then used the "Publish to the Web" feature in the File menu to make the web page.  From there on out, any update I made to the doc replicated to the public web page within a few minutes.

Feel free to use this or adapt it to your own parish or diocese. Here's the read-only web version and here's the Google doc.

Sunday, July 13, 2014

Rebuilding the laser scanner with iOS AV Foundation framework

At my day job, we have all of these splendid rugged PDA's with laser barcode scanners built-in. Fastest scanners in the West... great experience... until you look at the screen. Yeah, these things are running Windows Mobile. Sadly, though Android is finally becoming more popular, most of these devices still run some flavor of Windows CE. Scanner sleds are available for the iPhone and iPad, but they're expensive. I've never tried one and I'm not all that sure how well they integrate.

The processors on these modern devices are spectacular and there's camera optimizations and all that which make taking pictures literally a snap, so why not use that? There's plenty of scanner apps out there and some that integrate scanning into forms (I remember trying FormMobi and being pretty impressed with the results). Most apps take scanning to the full screen- like you hit the scan button, it goes to a full screen camera window, and then when you hit the barcode it takes you back to the data entry screen or wherever. I was curious as to how fast and how well things would work if the scanner's "laser" was in a peripheral view, like a separate window that represented looking over the screen of one of these ancient Windows Mobile rugged PDA's to see the red of the laser hitting the paper.

I'm quite indebted to Torrey Betts for providing a great code example of how to get started with using Apple's AV Foundation framework for reading barcodes. The framework is not quite as fancy as the Red Laser SDK, but I'm not quite ready to spend a few thousand on this. Anyway, I started with almost all of his code. I created my view on more storyboard with a child view within the top half. That would be the view for the camera output. Then a label to show what was last scanned, a text view for the scanning history (could be a table view or a whole entry form someday), and a button that would become the scanner trigger. I'm sure there's better ways to do this, but I got scanner trigger-like behavior by showing the camera view on the "touch down" event for the button, and removing the view upon "touch up inside" or "touch up outside". The result was that the user would push down the button and the scanning/ camera view would appear, and when they removed their finger from the button, the view would disappear. Additionally, whenever the view registers a valid barcode, the view disappears, requiring another press down of the Scan button. Thus, it's just like the trigger on my old rugged PDA.

 Here's all the special sauce I added:
     // if it found a barcode  
     if (detectionString != nil)  
     {  
       //update the label and history  
       self.lastScannedLabel.text = detectionString;  
       NSString *updatedHistory = [detectionString copy];  
       updatedHistory= [updatedHistory stringByAppendingString:@"\n"];  
       self.historyTextView.text = [updatedHistory stringByAppendingString:self.historyTextView.text];  
       //remove the barcode view  
       [_session stopRunning];  
       [self.prevLayer removeFromSuperlayer];  
       highlightViewRect = CGRectZero;  
       break;  
     }  
     else  
       self.lastScannedLabel.text = @"(none)";  
   }  
   _highlightView.frame = highlightViewRect;  
 }  
 //start scanning when the Scan button is pushed down (touch down)  
 - (IBAction)startScanning:(id)sender {  
   if(![self.session isRunning])  
   {  
     [self.barcodeScanAreaView.layer addSublayer:_prevLayer];  
     [_session startRunning];  
     [self.barcodeScanAreaView bringSubviewToFront:_highlightView]; //isn't necessary at this point because the line gets removed before anyone sees it. Could be useful if there was a delay before shutting down the view and recording the scan  
   }  
 }  
 //stop scanning when the button is pushed up (inside button) (touch up inside)  
 - (IBAction)stopScanning:(id)sender {  
   if([self.session isRunning])  
   {  
     [_session stopRunning]; //this makes the camera stop streaming to the screen.  
     [self.prevLayer removeFromSuperlayer]; //this makes the view containing the camera image go blank  
   }  
 }  
 //stop scanning when the button is pushed up (outside button) (touch up outside)  
 - (IBAction)stopScanning_Outside:(id)sender {  
   if([self.session isRunning])  
   {  
     [_session stopRunning];  
     [self.prevLayer removeFromSuperlayer];  
   }  
 }  
The whole thing is quite hastily-made, but I was quite encouraged that I could get that far in about an hour.  And the camera view appears and disappears quite quickly, even on my "old" iPhone 5C.  These rugged PDA's days are numbered...

Here's the git repo if you'd like to take a peek.

Tuesday, July 1, 2014

Throwback Tuesday: Screen scraping the hard way

The much-more-precise Beautiful Soup code I posted reminded me of when I used to screen scrape without really having any idea how. I'm sure HTML tree parsers existed back in 2003, but I had just learned regular expressions in my college courses, and of course I was determined to use them. My friend had just started an online book selling business, so I wrote him some apps to screen scrape from Amazon to pull bulk pricing information.
 my $connection = Win32::Internet->new();  
 my $amazon = $connection->FetchURL($amazonBook{"url"} . $amazonBook{"isbn"} . "/");  
 //...  
 if($amazon =~/<title>\s*Amazon\.com: (.*): Books.*<\/title>/)  
      {  
           $amazonBook{"title"} = $1;        
      }  
      elsif($amazon =~/<title>\s*Amazon\.ca: Books: (.*).*<\/title>/)  
      {  
           $amazonBook{"title"} = $1;        
      }  
      elsif($amazon =~/<title>\s*Amazon\.ca: (.*): Books.*<\/title>/)  
      {  
           $amazonBook{"title"} = $1;        
      }  
      elsif($amazon =~/<title>\s*Amazon\.com: (.*): Books.*<\/title>/)  
      {  
           $amazonBook{"title"} = $1;        
      }  
      else  
      {  
           $amazonBook{"status"} = "PARSE ERROR: title";  
           $amazonBook{"error"} = "PARSE ERROR: title";  
      }  
 //...  
 if($amazon=~/<span class="price">(.*)<\/span>/)  
      {  
           $amazonBook{"price"} = $1;        
      }  
      elsif($amazon=~/<span class=price><b>CDN\$ (.*)<\/b><\/span>/)  
      {  
           $amazonBook{"price"} = $1;        
      }  
      #if($amazonBook{"price"} =~/<font color=\#990000>CDN\$ (.*)<\/font>/)  
      #{  
      #     $amazonBook{"price"} = $1;  
      #}  
      #elsif($amazonBook{"price"} =~ /\$(.*)/)  
      #{  
      #     $amazonBook{"price"} = $1;  
      #}  

So clumsy in comparison! Every time Amazon made the price bold or not bold, it'd break the whole program, so by the end of it all I had 4-5 different regular expressions for each piece of data that needed to be scraped, depending upon the whims of Amazon. I love in particular the one that looks for a particular font color in order to find the price. I'm positive regular expressions can be done much better than I did, but, still, using classes to drill down to a small subset of HTML and then drilling down by elements seems like a much better way to go.