The Design Sprint – Our Experience

The sprint

The past two weeks we have worked on a prototype for a customer in the financial world. They approached us with an idea for an app. Because it wasn’t clear enough what the potential app would be about, we’ve chosen a design sprint to collaborate with the customer and find out what the app should be about.

A design sprint consists of five stages:

Schermafbeelding 2016-06-13 om 12.04.04.png

We have used these stages in iterations of 3 days:

Day 1: Empathize

  • In this stage we made sure there was a clear understanding of the content ahead.

Day 1: Define:

  • With the information gathered during the first hour(s), we went ahead and started to define the customer profiles of their users

Day 1: Ideate:

  • Knowing the content and the users of the new app, we started with ideas that could lead to an app. Everyone was drawing their ideas as simple as possible on a piece of paper. Afterwards, dot-voting would make sure the best ideas were chosen for further analysis.

Day 2: Prototype:

  • In the previous stages we gathered information and ideas we used as input for the prototype. The first prototype was created as a clickable PDF. However, we soon found out that users got stuck on trivial stuff like static content and missing animations. By creating a simple app we gave users the idea that they where using an actual app. That helped a lot to get better feedback on the content.

Day 3: Testing:

  • We used usability tests to evaluate if the features in the prototype matched our expectations. We gathered around 4 to 6 users each testing day so we had enough information and input for the following iteration.

 

Our experience

To be honest we were a bit skeptical at first, but in the end we couldn’t have chosen a better approach. Because of the short iteration we were forced to be creative and concise at the same time. This resulted in a satisfied customer who knows their target audience and has an idea of what the actual app could be.

We encourage those that want to create a great prototype with well thought out content within a short amount of time to use a Design Sprint. We’re sure you will love it!

For more information about Design Sprints check out Google Ventures.

Advertisements

Monitoring Github projects using GHTorrent and R

GHTorrent

GHTorrent monitors the Github public event time line. For each event, it retrieves its contents and their dependencies, exhaustively. It then stores the raw JSON responses to a MongoDB database, while also extracting their structure in a MySQL database. The database currently stores 7.994.119 Github projects with information about commits, watchers, pull requests and issues. Because it contains so much information, running heavy queries can be rather slow. However, running queries for just one project is done pretty fast. The full schema of the MySQL database is shown below.

GHTorrent relational schema

 

The MySQL client can be found here

Screen Shot 2014-06-17 at 10.54.49

R

R is a free software programming language and software environment for statistical computing and graphics. The R language is perfect for doing statistics and data analysis. I prefer using RStudio as IDE, which provides a bit more functionality than the R IDE that comes with installing R. For example, it can show the data in a nice table. The stackoverflow community is extensive, so questions are easily answered by going to stackoverflow or googling.

Example

Screen Shot 2014-06-17 at 11.16.14

Example query to get all the projects from ItudeMobile, with the language

​SELECT p.id, p.name, p.language FROM projects p, users u WHERE u.id = p.owner_id AND u.login = "ItudeMobile";​

Example R code to put the languages in a graph.


require("ggplot2")
setwd("/Users/Cindy/Documents")

information <- read.csv(“IMLanguages.csv”)
colnames(information) <- c(“id”,”name”,”language”)

languageCount <- as.data.frame(table(factor(information$language)))

g <- ggplot(languageCount, aes(x=Var1, y = Freq))
g <- g + geom_bar(stat = “identity”) + xlab(“language”) + ylab(“# projects”)
ggsave(filename=”languagePlot.png”, g)

View of the table in RStudio:
Screen Shot 2014-06-17 at 11.28.00

The plot that comes out:
languagePlot

Sources
[1] Gousios, Georgios, and Diomidis Spinellis. “GHTorrent: Github’s data from a firehose.” Mining Software Repositories (MSR), 2012 9th IEEE Working Conference on. IEEE, 2012.

How to debug deep linking in iOS

What is deep linking?

Deep linking basically enables you to open an app from another app or a website while passing on parameters. This mechanism works with custom URL schemes which you can define in the .plist of your app.

Why deep linking?

If you have an app with lookup functionality (e.g. an app for finding song lyrics) you might want to perform a lookup without having to navigate to the designated screen and typing in the query. This can be achieved by opening the following example URL MyAppScheme://myAction=lookup&myQuery=What%20is%20the%20meaning%20of%20life in another app of the browser. In this case the app is programmed to read the ‘myAction’-parameter on startup to determine the action and the ‘myQuery’-parameter for the search query. Often, deep linking doesn’t go as planned and you might need to debug your app.

Why is debugging this difficult?

Deep linking might occur in three kinds of scenarios:

  1. The app hasn’t been installed yet
  2. The app is running in the background (or foreground for that matters)
  3. The app is installed but not running at all

Scenario 1 is irrelevant in this case, so we’ll skip this one. Scenario 2 should be no problem since the app is running on the device (or simulator) while in a debug session. Scenario 3 requires you not to have the app running, but you need the debug session to be able to debug. This is a problem because Xcode starts the app automatically when starting a debug session. Instead of letting Xcode start the app, you want to do it yourself using the deep link URL.

So… tell me how to do this

There is a convenient option which enables you to start a debug session by manually starting the app. To achieve this, go to the ‘Edit scheme’ screen and tick the ‘Wait for MyApp.app to be launched manually’ option on in the ‘Run’ configuration.

Image

Whenever you run the target in Xcode, the app doesn’t automatically starts and the debug session will only start when you manually start the app.

So start kicking some bugs ass!

Dealing with high resolution displays on mobile websites

Mobile devices currently have increasingly higher resolution displays. For example: you have the iPhone retina screens and there are several Android devices with HD and even full HD screens. Since websites usually are created for desktops (with a much smaller amount of pixels per inch), the device pixel ratio was invented. For example: the iPhone 4+ has a device pixel ratio of 2, which means when you specify something to have a width of 200 pixels, it will actually be rendered 400 pixels wide.

However, this also applies to images. With the same retina based iPhone, if you specify an image to be 200 pixels wide, it will actually be rendered 400 pixels wide. This way, your high resolution display isn’t producing any sharper images. Let’s find out a way to fix this:

Option 1: always use higher resolution images

The first option is the simplest one: simply always use a higher resolution image. For example: specify the width and height of the image to 200 pixels, but actually point to an image with a width and height of 400 pixels. As mobile phones usually scale images pretty well, this will also look good on mobile phones without a high resolution display. The downside is obvious though: users without a high resolution display will download a high resolution image they don’t need. Because mobile internet connections often aren’t very fast, this could be an undesirable situation. However, this is a valid option when you are using images with a very low file size (like icons). Also, if the current trend continues, high resolution screens will become the standard which removes the need to make exceptions for low resolution devices.

Option 2: media queries

You can use media queries in order to use different CSS depending on how high resolution your screen is and select the correct image there:
@media (-webkit-min-device-pixel-ratio: 2),(min-resolution: 2dppx)
{
    .testDiv{
        background-image: url("highres.jpg") !important;
        background-size: 100%;
    }
}
@media (-webkit-min-device-pixel-ratio: 1.5),(min-resolution: 1.5dppx)
{
    .testDiv{
        background-image: url("midres.jpg") !important;
        background-size: 100%;
    }
}
.testDiv{
    background-image: url("lowres.jpg");
}
I have tested this with several iPhones and 2 different browsers on an android device. By looking at the access logs, I found out that in all cases only one image was loaded. Therefore I think it is safe to assume that (at least in most cases), only the correct image will be loaded.

Option 3: JavaScript

We could use JavaScript to detect the device pixel ratio by using window.devicePixelRatio and display the correct image accordingly:
<img id="myImage" width="240" height="207" style="display:none" />
<script type="text/javascript">
if(window.devicePixelRatio >= 2)
{
    document.getElementById("myImage").setAttribute("src","highres.jpg");
    document.getElementById("myImage").style.display="inline";
}
else if(window.devicePixelRatio >= 1.5)
{
    document.getElementById("myImage").setAttribute("src","midres.jpg");
    document.getElementById("myImage").style.display="inline";
}
else
{
    document.getElementById("myImage").setAttribute("src","lowres.jpg");
    document.getElementById("myImage").style.display="inline";
}
</script>

<noscript>
    <img src="lowres.jpg" width="240" height="207"/>
</noscript>

Option 4: SVG

SVG was meant to solve any resolution problems as an SVG image can scale to any resolution:
<img src="mysvg.svg" width="150" height="100" />

Unfortunately, while SVG is supported on iOS since day one, it the default browser of android only supports embedding SVG images at Android 3.0 and higher. Also, Internet Explorer 8 and lower doesn’t support SVG as well. In order to support these browsers, we need to provide a fallback which displays a PNG when the browser doesn’t support SVG:

<object data="mysvg.svg" type="image/svg+xml" width="80" height="29">
<img src="lowres.jpg" width="80" height="29" />
</ object>
This has just one problem: if you use a link around your image, the link won’t work with many SVG browsers. A way to use a fallback around this, is to add the following code to your SVG file.
<svg onclick="window.parent.location='/myLinkLocation';"

This works, but you have to be really careful update the URL in the SVG when you are updating the link around it. Combined with the fact that SVG is only usable for vector graphics makes SVG not a viable solution in a lot of cases.

In conclusion

All the solutions described above are valid solutions and you need to decide which one(s) is/are right for you. Please note, that in the examples above, I don’t test for a device pixel ratio higher than 2. This is because a device pixel ratio of 2 means you have the dpi of a retina iPhone, and I don’t believe providing higher resolution images will result in noticeable better looking images, while it does increases the file size. However, which device pixel ratio’s you support is entirely up to you.

Obfuscating for Android with ProGuard

Obfu-what? Right, Obfuscation, in general, describes a practice that is used to intentionally make something more difficult to understand.
The nature of Java (the programming language for Android apps) is that the code is not compiled down to machine code; it is compiled to an intermediate format that is ready to be run on a variety of hardware platforms. While this allows great portability, it also leaves the code for Android apps, as present in the APK (Application PacKage file), available for extraction.
I’m going to describe a way for you to obfuscate your Android code to make it harder for others to reverse engineer. And also why not shrink the size of your Android applications and optimize them to make them run faster at the same time.

Without a doubt, the simplest method to protect an app is to enable the obfuscation in ProGuard. This freely available tool is already built into the Android toolkit.

Obfuscation

By default, compiled bytecode still contains a lot of debugging information: source file names, line numbers, field names, method names, argument names, variable names, etc. This information makes it straightforward to decompile the bytecode and reverse-engineer entire apps. Sometimes, this is not desirable. Obfuscators, such as ProGuard, can remove the debugging information and replace all names by meaningless character sequences, making it much harder to reverse-engineer the code. It further compacts the code as a bonus. The app remains functionally equivalent, except for the class names, method names, and line numbers given in exception stack traces.

Shrinking

Java source code (.java files) is typically compiled to bytecode (.class files). Bytecode is more compact than Java source code, but it may still contain a lot of unused code, especially if it includes program libraries. Shrinking programs such as ProGuard can analyze bytecode and remove unused classes, fields, and methods. The app remains functionally equivalent, including the information given in exception stack traces.

For a realistic example, take the following code:

if(Config.LOGD))
{
 Log.d(TAG, "Some text");
}

The code as shown above is a typical scenario during development. You create code like this to help debug and test your code. Before releasing the final product, though, you set Config.LOGD to false, so it doesn’t execute. The problem is, this code is still in your application. It makes it bigger, and may cause potential security issues by including code which should never be seen by a snooping hacker.

Shrinking the code solves this problem beautifully. The code is completely removed from the final product, leaving the final package safer and smaller.

Optimizing

Apart from removing unused classes, fields, and methods in the shrinking step, ProGuard can also perform optimizations at the bytecode level, inside and across methods.

Proguard

So let’s have a look at the proguard.cfg file. I recommend you open up the sample code, as I will be highlighting the key parts on this page.

Basic template

-dontpreverify
-repackageclasses ''
-allowaccessmodification
-optimizations !code/simplification/arithmetic
-keepattributes *Annotation*

-keep public class * extends android.app.Activity
-keep public class * extends android.app.Application
-keep public class * extends android.app.Service
-keep public class * extends android.content.BroadcastReceiver
-keep public class * extends android.content.ContentProvider

-keep public class * extends android.view.View {
    public (android.content.Context);
    public (android.content.Context, android.util.AttributeSet);
    public (android.content.Context, android.util.AttributeSet, int);
    public void set*(...);
}

-keepclasseswithmembers class * {
    public (android.content.Context, android.util.AttributeSet);
}

-keepclasseswithmembers class * {
    public (android.content.Context, android.util.AttributeSet, int);
}

-keepclassmembers class * implements android.os.Parcelable {
    static android.os.Parcelable$Creator CREATOR;
}

-keepclassmembers class **.R$* {
    public static ;
}

Fragments

-keep public class * extends android.support.v4.app.Fragment
-keep public class * extends android.app.Fragment

Serializables

-keepnames class * implements java.io.Serializable

-keepclassmembers class * implements java.io.Serializable {
    static final long serialVersionUID;
    private static final java.io.ObjectStreamField[] serialPersistentFields;
    !static !transient ;
    !private ;
    !private ;
    private void writeObject(java.io.ObjectOutputStream);
    private void readObject(java.io.ObjectInputStream);
    java.lang.Object writeReplace();
    java.lang.Object readResolve();
}

Removing Logging

-assumenosideeffects class android.util.Log {
    public static *** e(...);
    public static *** w(...);
    public static *** wtf(...);
    public static *** d(...);
    public static *** v(...);
}

Methods

-keepclasseswithmembernames class * {
    native ;
}
-keepclassmembers class * {
    public void *ButtonClicked(android.view.View);
}

Now that we have added all our Proguard settings, we need to run Proguard during the build fase. I will use Maven to illustrate this.

Within your pom.xml the android-maven-plugin should be defined. To this definition add the proguard setting like:

<plugin>
   <groupId>com.jayway.maven.plugins.android.generation2</groupId>
   <artifactId>android-maven-plugin</artifactId>
   <version>3.0.0</version>
   <extensions>true</extensions>
   <configuration>
       <sdk>
         <platform>15</platform>
       </sdk>
       <dex>
         <jvmArguments>
	   <argument>-Xms256m</argument>
	   <argument>-Xmx512m</argument>
         </jvmArguments>
       </dex>
       <run>
         <debug>true</debug>
       </run>
       <proguard>
         <skip>false</skip>
         <config>proguard.cfg</config>
       </proguard>
   </configuration>
</plugin>

All that is left is to run Maven with

mvn clean install

To check if the app has been obfuscated, install the apk on you Android device and when you run it, you shouldn’t see any logging in logcat.

Sending and Receiving Data SMS messages with Android

The humble short message service (SMS) celebrates its 20th birthday today. Engineer Neil Papworth sent the first SMS to an Orbitel 901 handset via Vodafone UK’s network in 1992: “Merry Christmas.”

It would be safe to say that nearly every mobile phone sold in the past decade has SMS messaging capabilities. So making use of SMS with your Android app can be a great way to handle information when no Data network (3G or WIFI) is available.
In this article, we will take a look at how you can programmatically send and receive SMS messages in your Android applications.
Continue reading

Fun with Android and NFC

So, you probably heard of something called NFC (Near Field Communication), and maybe you have seen the video (as shown below) from the 2012 Google I/O showing you a developers perspective on NFC.

But what you want is a short “How to” on creating an Android NFC application. In this tutorial we’re going to build an app that reads and writes to an NFC tag.
In order to follow along you will need an NFC enabled Android device, such as the Samsung Galaxy Nexus or Samsung Nexus 7. Also, but not mandatory, what you will need is an NFC tag or sticker. Be sure the NFC tag is pre-formatted because a bug in Android 4.0.2 may prevent you from encoding completely blank tags.
Continue reading