Trying out Android Studio

logo.gif

Note: this post assumes you have an existing knowledge of Android development, probably using Eclipse. 

The first time you download Android Studio, before you head straight into creating or importing your first project, start by checking for updates. In my case I downloaded Android Studio 0.2.0 from the developer site, but 0.2.6 was available. Definitely update to the latest version!

One of the big fundamental differences between Android Studio and Eclipse + ADT is that you will now be using Gradle for your build system rather than Ant. I'm no expert on build systems, but I do appreciate good build tools (like Rake) and hopefully Gradle. I've only done 20 minutes worth of Googling Ant vs Gradle, so feel free to do the same. Or, if you want just think of Gradle as a more flexible version of Ant with superior certificate signing and command line build tools. Also, its integration with Jenkins is solid, if CI is your sort thing.

configuration.png

With Android Studio updated and a little knowledge of Gradle under your belt, create a new Android project. (The new project wizard is so straight forward my mom could do it.) You'll notice that the project structure is mostly familiar in terms of java packages containing your source code and your res folder containing layout files and image assets. Good, right? One major difference, however, is that you no longer live within a workspace. Each Android Studio instance now belongs to its own project. I haven't gotten used to the multiple projects with dependencies workflow yet, but I trust it will be eons more logical than it is in Eclipse. Okay. now for another new feature look at the top bar towards your configurations (upper right). This is something new. Here you can setup build configurations with specific application/target combinations. It's an easy way to switch between multiple emulators and devices.

Couple other things to point out in Android Studio. The undo functionality is really smart. In addition to all the things you would expect, it can undo file deletions, creations, and its memory is very impressive. Another small thing that makes you happy is that Android Studio will replace @string/label references with the actual string in manifest and layout files. Hover over it to see the code and click to access it. Another cool thing in layout files is that missing files or resources will show up as red! This is huge! For me anyway I would run the my app on the device and only then find out that I had typed in the image name incorrectly. This has the potential to be a major timesaver.

Keyboard shortcuts rock. Far and away my favorite shortcut in Eclipse is cmd+D (or ctrl+D) to delete line. I miss it every day in Xcode. Here are a few tips and tricks I've discovered so far:

  • cmd+backspace - delete line (a little different, but I could get used to it)
  • cmd+d - duplicate line
  • cmd+o - quickly jump to any class in the project
  • cmd++ - fold code
  • cmd+- - expand code
  • ctrl+spacebar - code completion
  • ctrl+r - build and run (using last selected configuration)
keyboardshortcuts.png

It's not all peaches and cream though. Even with just a few hours under my belt, there are already a couple things that slowed me down which I'd like to see improved:

  • When adding a new activity, double click does not move to the next screen (currently you must to click next)
  • Also in the new activity wizard, changing the activity name does not automatically update the layout name (even eclipse did this!)
  • Creating a new activity defaults to a vanilla package (rather than the currently selected package)
  • Double clicking a "error: gradle: no resource found that matches [filename]" doesn't link to the place where the invalid resource is being referenced
  • The Android emulator hasn't changed a bit

Android Studio is still not a perfect solution, but neither is Eclipse. Overall it feels like a solid start and if its progression is anything like the progression of Android (oh boy the dark days of Froyo), it's only going to improve significantly over the next couple years.

Growing Pains is Making a Comeback

If you know me personally, you probably knew that I worked on an app called Growing Pains for last year's BYU Mobile App Competition. It's a photo journal designed to help you easily capture photos of your growing child. The interface is designed to allow you to quickly browse through and see your child's growth over various time periods (ideal for newborns and toddlers -- or puppies). While Growing Pains was a success in the competition, winning over $2000 value in awards and placing 5th overall, unfortunately it has not yet seen the light of day.

A partner on the project and I have been talking recently about bringing it back to life, and last week while at Cocoa Camp Apple challenged us to bring our own ideas to work on, so I did just that. On Monday of last week I ctrl+shift+N'ed a new project in Xcode and started clean. Did this for several reasons, firstly, because Cocoa Touch changes so much from year to year that I'm sure our existing code base would require some amount of updating to get in line with the latest conventions and best practices. Secondly, and the bigger reason, is that while SDK changes have been semi-significant, changes to iOS design patterns have been EXTREMELY significant. Take the example below.

You've probably seen and heard all about iOS 7, so I'll save my personal thoughts on the change for another discussion, the important points to note are the focus on simplicity, utility, and depth. With the greater population generally familiar with smartphones, as an app designer & developer I can now eliminate the use of some of the more cutesy effects that previously communicated "tap here", "I am a menu", "this is a button", and so on. Apple has also stressed depth in the new design, despite it looking more flat than before. By adding blurs, realistic motion effects, and new levels of perspective, iOS 7 is inherently more realistic than before, albeit far less skeuomorphic.

Growing Pains is now undergoing its own transformation from the old world to the new. Here are a few of the design concepts for the new UI, shown alongside the original designs. Please feel free to jump in if you have any thoughts or suggestions. These designs are being iterated on almost daily at this point.

 

What do you think? Are there any elements of the old design that you like better, or feel are missing in the new versions? Is it any more or less intuitive than before?

Maybe Microsoft is doing it right. Or maybe they're not.

Dell Venue Pro, running Windows Phone 7.5

Since I first began seeing concepts of Windows 8 I kept thinking, huh, maybe Microsoft is onto something here. Despite being both an Android and an iOS fanatic, I have been impressed with the Windows Phone OS since trying out Windows Phone 7.5 from Dec 2011 - March 2012 on an extra Dell Venue Pro my dad had available. The hardware was...a brick... to put it nicely, but the OS itself was excellent. 

Over the last 18 months I've found myself continuously (and to my friends' amusement) defending Windows Phone as a viable mobile operating system, and, as an extension, defending Windows 8. I've gushed over the Lumia 920, HTC 8X, and now the Lumia 1020. I almost bought all three of these devices on numerous occasions (just ask Dru). While I maintain that Windows Phone is a great OS, I'm coming to terms with the idea that maybe Microsoft isn't doing it right and that they did in fact jump the gun on the idea of the convergence of the desktop and the mobile experience. Since MS's release of Windows 8 there's been talks of how revolutionary and visionary it is. Ahead of its time. Some referred to it as showing that Microsoft had not only caught up to Apple and Google, but far surpassed their ability to deliver innovative products that end users didn't even know they wanted until they tried it (take the iPad for example).

Well, after a year of saying to myself, yeah, maybe they did get it right, maybe Windows 8 isn't as radical as all the critics say, maybe we will all be using touchscreen desktop computers in a couple years, I'm now saying maybe not

The truth is that the people don't want the same experience on a tablet as they have on their desktop or laptop. Sure, they like familiarity, but at the core a user's interaction with a tablet and user's interaction with a desktop computer is just different. And people are fine with that. The design of an application on the desktop environment is (and should be) vastly different than the tablet and the phone representations of that same application. Probably one of the best examples of this is the Day One app for iPhone, iPad, and Mac. Ask any active Day One user if they'd like to combine either the iPhone and iPad experience or the iPad and Mac and they'd look at you like you were crazy.

Day One for iPhone, iPad, and Mac

Further evidence that people just don't want to merge desktop computing and mobile computing... look at this Acer commercial comparing their 8" Windows tablet to the iPad mini. This is my opinion, and I bet some Windows 8 fans view this commercial as a win for Acer and Windows 8 Pro, but firstly, who wants to play Halo on a tablet (not that they even look like they're actually playing...)? Don't get me wrong, I love iPad games... Plants vs. Zombies vasebreaker endless mode... that'll keep me busy for HOURS. But I don't really care for the idea of getting a dumbed down PC gaming experience on my iPad. Maybe if the entire game was reimagined for iPad, and it really was just a distant relative of Halo, but the ability to run full-fledged PC games on a tablet just doesn't do much for me. Okay, next flaw in the video, of all the things you can do on a tablet, why show someone accepting changes to a Word doc? I mean, seriously, of all the things I've used a tablet for (thinking my Kindle Fire, Nexus 7, and iPad), I have never once wanted to accept changes to a reviewed Word doc. And if I did, I wouldn't want to be using the traditional Word app to do it (see all those tiny touchpoints?!).

UPDATE: I hadn't done my research on Halo Spartan Assault, and it looks like it very much is  the Halo experience reimagined for touch. That's cool. What I was trying to get at is the idea of playing traditional PC games on a tablet running Windows 8 Pro.

What I'm getting at (and have probably repeated 20 times by now) is that I no longer believe that we are heading in the direction of an integrated desktop and mobile computing environment. Those who never got on the Windows 8 bandwagon are probably thinking, yeah, knew that all along. But for those who have seriously entertained the idea of everything converging into a single, universal experience, either the timing is wrong or the implementation is wrong. Either way, maybe Microsoft isn't doing it right after all.

Configuring Xcode and Bamboo CI Server

NOTE: This document was written with respect to Bamboo 4.4 and version 1.8 of the Xcode plugin. I'll update it to Bamboo 5 and v 2.1 soon.

Here's the process, from top to bottom, including my little discoveries along the way.

Install the Bamboo iOS, Cocoa and Xcode plugin

  • First off, note that Bamboo has its own marketplace (as opposed to one for your JIRA instance). In order to do this, you need to be an administrator in Bamboo (but not JIRA).
  • Navigate to Administration -> Plugins -> Find New Add-ons. Search Xcode and install the plugin. No additional configuration or plugin management needed here. This simply enables a few features like support for adding the iOS SDKs and Xcode tasks, which you'll get to later.

Creating a remote agent in Bamboo

  • From the Administration tab, go to Agents and select install remote agent. You can install it wherever you'd like... I wouldn't recommend your downloads folder though. I put mine in /Documents/dev/bamboo-agent-home.
  • If you have problems running your remote agent to the tune "Could not load properties", you may need to explicitly set your port number or open a port on your firewall. This Atlassian Support Q&A was helpful for addressing this issue.
  • For more information see the Remote Agent Installation Guide.

Configuring Capabilities for your Remote Agent

  • Agents use capabilities for two purposes, (1) to tell the agent what it can do, and (2) in order for jobs to identify which agents can run which build plans.
  • Regarding point 1, you will now create two capabilities that will allow you to build you project for iPhone and for the simulator.
    • From the Agents screen, select your remote agent
    • Select Add Capability
    • Select Xcode SDK as the compatability type
    • Enter Simulator - iOS 6.1 as the SDK Name
    • Enter iphonesimulator6.1 as the SDK Label. ****This part is what took so much time to figure out. In a couple of the blog posts out there it recommends using the command 

     

  • Regarding point 2, this is important because if you don't specify capabilities, your build plans will try to run on all agent that meet their basic requirements. In our case, our web team's build plan's requirements weren't set to the appropriate capabilities, so whenever a build occurred and the OSX remote agent was running, it would try to run on both agents, causing it to fail immediately on our remote agent. Note that custom capabilities are often used to control which jobs will be built by which agents, the most common one I've seen being an isLocal flag, which only allows the local agent to run the build plan.
  • For more information see Agents and capabilities.

Connecting to your GIT repository

  • After you have configured your remote agent, create your plan. This part is fairly straightforward, which the exception of connecting to your GIT repo, which can be tricky.
  • In our case, a user named 'fisheye' has already been setup with the appropriate permissions and keys on neptune. Unless something has changed, don't worry about generating new ssh keys for yourself and putting them up on neptune. Have Jacob login and upload the private key for this user.
  • Note that the repository URL should include ".git" at the end, i.e. ssh://something@path.com/home/git/myapp.git

Creating Tasks for Your Build Plan

  • Task 1 - Source Code Checkout
    • The first task you'll want to create is Source Code Checkout. Actually, it was probably done automatically. Make sure the repository is set to your project and run your build plan. You should be green.
    • At this point, if you run into a NoClassDefFound error, check out this support Q&A. Basically, the fix is to downgrade your Xcode plugin to v1.8 and try again. You can download it at the link at the top of this post. To install it, within Bamboo go to Administration -> Plugins -> Manage Add-ons -> Upload Add-on. My guess is that the latest version of the plugin targets Bamboo 5.0 and at the time of this posting we are running Bamboo 4.4.4. The plugin says it supports 4.4... but yeah...no dice.
  • Task 2 - Build the Xcode project
    • Next up we want to create a task to build the Xcode project. This is where those iOS SDK capabilities that we setup earlier come back into play. The first thing to keep in mind here is that essentially all this task will do is build your project, the same way you would if you built it from terminal using xcodebuild, e.g. xcodebuild -sdk iphonesimulator6.1 -project PRTablet.xcodeproj -alltargets -configuration Release. 
    • My personal suggestion here is to forget Bamboo for a minute and try building your project from the command line. In our case, command line builds failed with compile errors because the main PRTablet target can't see the RestKit subproject files (despite it building correctly in Xcode). To get around this, you'll want to setup a workspace and scheme rather than an xcodeproj and target, which will build all projects in the same directory, referred to as the workspace build directory. Now, all of these files are visible to each project. Verify it now builds successfully from the command line, e.g. xcodebuild -sdk iphonesimulator6.1 -workspace PRTablet.xcworkspace -scheme PRTablet -configuration Release.
    • Now that you know it will build successfully, create a second task under your build plan. Select Add Task -> Xcode. When you're done, it should look something like below.
    • Save and run your build plan. If you got a "possible compilation error" check the logs. If it's an xcodebuild error: "The workspace does not contain a scheme named," you need to go back into your workspace, go to Manage Schemes... and check the Shared box next to your scheme. Push your code and run your build plan again (Bamboo may even do it automatically this time). You should now be green.
Screen Shot 2013-07-26 at 6.27.42 PM.png
  • Task 2.5 - Unit Tests
    • To run have your agent execute your unit tests, you'll need to check the "Include OCUnit Test results" box above. See the Xcode docmentation. Note: I've been unable to get this working so far, since Bamboo for some reason is unable to see our unit tests. The error message reads "Failing task since test cases were expected but none were found." I found a support Q&A for this problem and added comment asking if anyone has found the fix.
    • UPDATE: Looks like unit tests with a test host cannot be run in the simulator in v1.8 of the app. If you can, upgrade to v2.1. In versions 2.0+ of the plugin, you can use the ios-sim method to run application tests from the command line.

Working (or not) with Git submodules

 A BYU CocoaHeads club member recently posted to our google group that she’s been having problems with Git and submodules. There were some great responses, suggestions, and tips, and this is my take on Git submodules.

I’ve had some frustrations with submodules, git, and team projects. Now, whenever installing a third-party framework that has supports submodule installation I generally tend to skip that part, download the most recent stable source code, put it in my git repo, and install it w/o using any submodules. This also gives me the ability to update to new versions more selectively, which I prefer… one reason being that by default some of those submodules may be pointing at active development branches rather than stable, production quality/tested code. If you simply copy and paste their installation commands, later on you might get some buggy code when you update. Of course if you’re careful and read through the changesets before you update, double check the submodule branch is what you want, etc, submodules can be really helpful. I just got burned a couple times when I was starting out with git and since then my personal git workflow has progressed w/o using them for the most part.

Testing in iOS

I’ve been researching Continuous Integration (CI) and unit testing in iOS lately and learning a lot about testing your application. So far, I’ve learned how to write unit tests in Xcode, some basic guidelines for writing those tests, and experimented with Jenkins CI server to create automated builds, tests, email notifications, and archives. This post is meant to be a collection of my thoughts and takeaways.

Two Types of Unit Tests

The are two main types of unit tests in objective-c, logic tests and application tests. There also two general approaches to unit testing, which happen to correlate: bottom up and top down. In bottom up testing, you look test each method or class individually, entirely independently of each other. In top down testing, you test the functionality of the app as a whole.

Because your logic tests are independent of each other, they can run without needing the context of your application’s controllers or views. Logic tests can only be run on the simulator. Application tests are (appropriately) run in the context of a host app, and can be run either on a device or in the simulator.

Efficiency in Unit Testing

After figuring out a how to create unit tests, run them, and seeing the little green checkboxes telling me they passed my first reaction was to get a little unit-test-happy. I was thinking oh, I can test this, and that, and all of that… Well I’m finding that there’s a balance between efficient, high-quality unit tests and simply testing every single input and output.

When you test parsing a JSON response from your server, for example, ONE way to do it is to assert that the final property value is equal to the original value in the JSON. There are however, many more ways to test your parsing and relational mapping. You might try testing for valid data using character sets, checking string lengths are greater than zero, or that birthdates are before today’s date. Then, try 4 or 5 different data sets, rather than a single one.

Basically, rather than test for a specific outcome with your logic tests, be a little more broad. Trying to test for a very specific output might be beneficial in some cases, but it can quickly become tedious and time-consuming. Testing for types of data, unsupported input characters, and invalid states can cover more errant cases in less time. Significantly less time.

The Sweet Spot 

 

image-thumb1.png

I found this graphic in a blog post about unit testing best practices  about halfway through my research and was really glad I did. Essentially, unit tests should hit the sweet spot of testing individual units (bottom-up) or testing the entire system (top-down) and not fall into a dirty hybrid that only costs additional time and effort without proving much.

 

RestKit - Load data from local json file

I've found that it can be very helpful to be able to load data locally rather than from a server, especially for testing and for situations where you don't have control over the availability or stability of the server side. This code sample shows how, using RestKit, you can load json directly from a file. If you knew what the expected server response was, but didn't have access to the server, this would allow you to put all the object mappings in place and load your object in without requiring a live server. https://gist.github.com/kyleclegg/5846568

Google Fiber coming to Provo

Our pre-registrations paid off!

Let's go utah... pre-register now. All of you. 1000Mb/sec #googlefiberfiber.google.com/about/

— Kyle Clegg (@kyle_clegg) July 26, 2012

 

gfiber2.png-fileId=19601385.png

The #EpicProvoAnnoucement hashtag on twitter has truly turned out to be epic. Provo is getting Google Fiber and it makes sense for so many reasons:

Screen Shot 2013-04-17 at 2.02.43 PM

Screen Shot 2013-04-17 at 2.02.43 PM

  • Entrepreneurship - Provo is one of the best places for tech startups outside of Silicon Valley -- on the same level as Austin.
  • Infrastructure - There's an existing infrastructure in place, put there by the city of Provo nearly 10 years ago. It failed (IMO) due to the greed of who decided to limit the speeds to near cable-levels and charge only marginally lower than other providers. Stifling innovation in the pursuit of some extra $$s.
  • Data - Genealogy research is huge in Utah, with several large organizations likely to get on board ASAP.
  • Students - Provo is home to a major university in BYU, with another 25,000+ university ten minutes away in UVU.
  • Innovation - Utah IS Silicon Slopes!

Company Culture

This resonates extremely well for me: "There’s still a traditional view out there that agile methods, hacking, open-source and new technologies don’t have a place in serious business. Our view is that all of those wonderful things power people, businesses, and society forward. We’re obsessed with how things work, are inspired by change, and simply love to build stuff. So we hire people and take on projects that let us do just that."

from http://www.controlgroup.com/careers.html

Ditching mySQL

As a java/OO developer first (web later), I got my start with databases by setting up a couple wordpress blogs, mostly simple UI stuff, but configuration and a few other cases got me into phpMyAdmin and MySQL. I wouldn't be surprised if this was the case for hundreds, or thousands of others. I don't -- or didn't -- mind MySQL so much because honestly it got the job done for those simple blogs and it was easy to get going. However I will say that now that I am surrounded by "production-level" projects, i.e. projects at work that affect millions of users and backends for my own mobile apps, I am extremely concerned about the performance, consistency, (over)complexity, and maintenance of my databases. I've gotten familiar with postgres, and while not fully understanding all its benefits over MySQL, it works great, feels sexy, and posts like this have pushed me to make the move.

Also, using frameworks like Ruby on Rails I feel abstracted far enough from the database level that the change really wasn't too difficult. It makes me wish I hadn't used MySQL in the first place, and started with SQLite because of its support on mobile devices, or Postgres.

Mobile App Competition Results

timeline.png

This post is long in the coming... actually should have been written at the end of November.  Brief recap about Growing Pains and how it took home some awesome awards in the BYU Mobile App Competition.  We had big plans for Growing Pains, but at the time of the submission deadline we were probably only 40-50% done with our first iteration feature set. I honestly was not expecting to take home much from the competition.  The one award I was fairly confident about was the best Ruby on Rails backend, mostly because I was guessing that we were one of the only RoR backends.

My sister Kandace and I were there and were pumped when they announced Growing Pains as a top-16 semifinalist out of 25, with a guaranteed $250 cash prize.  Dru couldn't make it because it was during the day and she would have to miss work.  All 16 semi-finalists gave a 2 minute demo and presentation on their app, which was exciting for me.  I've never made a pitch to 500 people before.

Then the awards... Kandace and I were super stoked when the first award they gave out -- BizVector award for business potential from MokiNetworks -- was given to Growing Pains!  $100 gift card.  Sweet!  Next up the finalists.  Again, the very first app they announced (which just added to the excitement and surprise) was Growing Pains, 5th place with a $1000 cash prize.  Other top apps included a couple games and 2 business productivity apps, with a top cash prize of $3000.  We also won the Ruby on Rails API award, which was a iPad for each team member.  In total we came away with $2100 in awards and prize money, plus a heavy dose of validation and encouragement about our idea and the direction Growing Pains was heading.

finalists.png

We've continued working on Growing Pains and recently started beta testing with couple family members.  If you're interested in giving us some pre-release feedback - let me know!

iOS Final Exam

In 3 hours do: 1) download and parse json for version number and location of zipped sqlite db file 2) if first time or newer version than previously downloaded, download zip using a progress indicator 3) save zip to device documents folder 4) decompress zip file and save 5) delete saved zip file 6) open connection to db, query last updated time and display

Recommended frameworks: afnetworking ziparchive sqlite

and the result.... http://screencast.com/t/UXm4kHuMnuq. i didn't have time to make it look pretty, but I finished all 6 tasks. it took every minute of those 3 hours, but I'm pretty proud of it. :0

Duplicate an SQL Record

When working with SQL databases there are times you want to clone database rows and for whatever reason don't want to write out a ton of INSERT statements.  This would be easily handled by

insert into users select * from user where username="webuser1";

except that this will not handle unique key contraints, i.e. when your ssn or user_id fields must remain unique.  One convenient way to get around the restrictions on unique keys it to create a temporary table, clone the record, change necessary fields, then copy is back to the original table.
CREATE TEMPORARY TABLE users2 ENGINE=MEMORY SELECT * FROM users 
WHERE username="webuser1";
UPDATE users2 SET username=webuser2; ## Change the username to be unique
## Update any other fields that must be unique
INSERT INTO users SELECT * FROM users2;
DROP TABLE users2;

Tablet or Laptop

A past professor recently asked island (the information systems forum/community I participate in) whether he should get a tablet or a laptop for his teenage daughter.  She's been asking for a tablet, and he wants a solution that will work for her for both play and for school and homework.  It's an interesting question and very interesting topic since laptops and tablets are accepted for use in many high schools across the US.  When I was in high school (2001-2005) using a laptop at school wasn't even a consideration.  I wonder what kids will have in 30 years...

Here are my recommendations at around the $300 price:
  1. Nexus 10
  2. iPad 2
  3. Windows Surface (with condition)

The Nexus 10 is going to be pretty ideal for this situation.  I think a high schooler can very reasonably do their studying and homework on a tablet, with the exception of research papers and essays.  For those he or she may need to use the family computer (or at least a keyboard dock), but I wouldn't consider that case enough reasoning to go with a laptop instead of a tablet, especially if they're already wanting a tablet.  I have a Nexus 7 and I really like it for reading and for taking notes.  I love Evernote because it's on every platform I could dream of using (web, iOS, Android, Amazon, OS X, Windows, and even Windows Phone, but not Linux AFAIK).

As another option I think you can get a 16GB iPad 2 in that price range, which would be a great choice as well.  It also wouldn't be brand new, which may or may not be important to a parent.  I know some would rather their teenagers have a older generation version of a project than something fresh off the shelves.
About the Microsoft Surface... if it were 1 year from now, I would recommend getting a used Surface.  It would definitely have all the windows based functionality that someone could need.  However because it just was released Friday and its price point is $499, I don't think it's a good option today.  But it's worth mentioning.