Migrated
This blog has been migrated to http://mobilerockstars.tumblr.com. Check it out!
1.47.2
Monterey Bay Aquarium
🪼
will byers stan first human second

Andulka
Cosmic Funnies

Love Begins
AnasAbdin
we're not kids anymore.

titsay
Stranger Things
Lint Roller? I Barely Know Her
Today's Document

Kaledo Art
Claire Keane
almost home
he wasn't even looking at me and he found me
I'd rather be in outer space 🛸
Aqua Utopia|海の底で記憶を紡ぐ

PR's Tumblrdome

No title available
seen from United States

seen from United States
seen from United States
seen from United States

seen from United States

seen from United States

seen from United States

seen from United Kingdom

seen from Singapore

seen from China
seen from United Kingdom

seen from United States

seen from Brazil

seen from United States
seen from Germany

seen from United States
seen from United States

seen from China

seen from United States
seen from United States
@mobilerockstar
Migrated
This blog has been migrated to http://mobilerockstars.tumblr.com. Check it out!
1.47.2
Configuration file to scale iOS Mobile Apps
by de_poon In our team of mobile rockstar engineers, we often ask ourselves this question: How can we scale our ios mobile apps? Lets take a hypothetical situation. Your CEO is very pleased with the first delivery of the company's mobile app. The other country managers come along and want you to build the same app but adjusted for their individual countries. Assuming they want a separate downloadable app, the general requirements are 1. I want some features taken from the main app 2. I do not want some features from the main app 3. I want some features to be modified from my custom app. Sounds familiar? The way to go about is to create a non-binary configuration file that allows us to specifcy what we want in the app.
The most important principle is that no recompilation is needed when we scale our apps. In our team we've chosen to go with PList file as it is easy for developers to create one out of the box in XCode. Here's the steps 1. Create a PList from XCode
2. Set up your features in a .plist
3. Add the plist file into your main bundle. 4. Use the following codes to read the contents of the plist as a NSDictionary
5. In your app features, read the contents off the NSDictionary to determine how your feature should behave. Eg. - Should this feature be turned on? - How should I order by menu items on the side menu? - Should I enable specific UI Animations at a particular screen? To create additional scalable apps, simply create a new project - import your lib.a binaries - import your resource bundle files - add in your configuration plist ... package and deploy your app!!! Considerations 1. Adding your plist directly into your main app bundle is not a secure way to do (So you think you can start working on it? Gotcha...). It is possible for someone to extract the plist from your app and this exposes all sensitive information such as api end points, security tokens, etc. Dont worry, an upcoming post will address this issue. 2. You might want to create your own configurations file manager to generate your plist on the fly. 3. PList is probably not the best way to encapsulate application configuration. You may want to explore other formats. Feel free to buzz us your thoughts on this
Java unit testing in Android
by hidroh
Having spent 1.5 years working on PHP projects with very high test coverage and frequent test runs, it strikes me with great surprise that to achieve the same thing in Android is not as straightforward.
One of the best advantages of having unit tests is that you can get instant feedback on your changes, whether your code does what it's supposed to do, or if it breaks existing behaviour. In an ideal environment, it should take only a few seconds to verify your changes. Sometimes it's too fast that people argue that as disadvantages.
Surprisingly, it is not the case for Android, which was not designed with unit testing in mind. You would need an emulator or a real device to run your tests! Say what? Every test run now adds at least 30 seconds of overhead. Goodbye, all the best TDD!
Of course there are alternative ways to make Android tests run faster, but what if I only need to test my Java logic that has nothing to do with Android? Why do I need a device to test that logic? Sure, one can extract all pure Java code into a library so he can test them, but with product managers chasing after you, it's not always the best choice. But worry no more, with a little bit of customization to Gradle build system for Android, that dream of TDD your Android projects is getting closer.
What you will need
Gradle 1.11 with Android plugin 0.9.0 and Jacoco plugin. Java plugin for Gradle supports unit testing out of the box. Applying Java plugin will give you a test task that you can use to run all the tests. Jacoco plugin complements that by generating code coverage report, without any special setup. It just works!
To do the same thing with Android, you will need to apply Java plugin together with Android plugin. But you will soon realize that it's not possible, they are not compatible. So that leave you with only option of making a test task by yourself. Luckily, it is not that difficult:
Run Java unit tests with Gradle
First, you need to tell Gradle where you put your test code. Define a sourceSet, here we call it unitTest.
sourceSets { unitTest { java.srcDirs = ['test'] resources.srcDirs = ['test'] } }
Then you need to tell Gradle what you need to compile your sourceSet. Ideally test compilation should be separate from production compilation. Here we add a custom configuration called unitTestCompile, which extends from compile, since you obviously need to compile your code to test it! The inclusion of junit is compulsory, while other libraries are needed if you use some Android interfaces, mock classes or parameterize your tests.
configurations { unitTestCompile { extendsFrom compile } } dependencies { compile project(':your-project') compile project(':your-project-dependencies') unitTestCompile 'junit:junit:4+' unitTestCompile 'com.google.android:android:4.1.1.4' unitTestCompile 'org.mockito:mockito-core:1.9.5+' unitTestCompile 'pl.pragmatists:JUnitParams:1.0.2+' }
With everything compiled and ready to run, let's create our own Gradle's test task. Here the trick is to extends the Test class that is readily available in Gradle API, which executes JUnit tests. We call our extended task 'unitTest'. It depends on assemble to make sure that it will run after we have rebuilt everything.
def debugClassesDir = "${buildDir}/classes/debug" task unitTest(type: Test, dependsOn: assemble) { testClassesDir = sourceSets.unitTest.output.classesDir sourceSets.unitTest.compileClasspath += files(debugClassesDir) sourceSets.unitTest.runtimeClasspath += files(debugClassesDir) project.configurations .collectMany { it.allDependencies } .findAll { it instanceof ProjectDependency } .each { dependenciesBuildDir = "${it.dependencyProject.project.buildDir}/classes/debug" sourceSets.unitTest.compileClasspath += files(dependenciesBuildDir) sourceSets.unitTest.runtimeClasspath += files(dependenciesBuildDir) } classpath = sourceSets.unitTest.runtimeClasspath }
When this task is executed, it will need to know where to look for the compiled .class files. The rest of the task code serves this purpose. It instructs Gradle to look for current project's build folder plus all dependencies' build folders. Take note of the first line of task body. It's needed to tell Test class where its code has been compiled into, even though you don't see testClassesDir used anywhere else.
Switch to your console and type `gradle :your-project:unitTest`. Depends on test results, it will pass or fail your build!
Generate code coverage report with Gradle
Now it's important to be able to run tests, but you would have no idea if you manage to cover every execution path without a code coverage report. Luckily, unlike Java plugin, Jacoco plugin works with Android. All you need to do is add the plugin, tell your Test task where to generate jacoco execution data, and customize jacoco to generate a nice HTML report for you.
apply plugin: "jacoco" task unitTest(type: Test, dependsOn: assemble) { ... jacoco { append = false destinationFile = file("${buildDir}/jacoco/jacocoUnitTest.exec") } } task jacocoTestReport(type: JacocoReport, dependsOn: unitTest) { reports { xml.enabled false csv.enabled false html.destination "${buildDir}/jacocoHtml" } classDirectories = fileTree(dir: debugClassesDir) sourceDirectories = files(android.sourceSets.main.java.srcDirs) executionData = files(unitTest.jacoco.destinationFile) }
With everything in place now, you can make unit test a required step of your build (which you should), by having it run while Gradle checks for compilation errors.
check.dependsOn unitTest
Have fun unit testing!
Introductory Post
We are a group of Mobile App Engineers (iOS/Android) who are very committed to technical excellence. This is a blog where we contribute our thoughts and reflect on our decision making steps that we encounter during development.