01 January 2015

Continous Integration for Localization

Some time ago I wrote an article about why we even should use CI for a one man project. Today was one of these days I’m really happy that I use it even for Localization. I was working on a new feature of PlusPoints. When I thought the work was done, I commited and pushed to github. A few minutes later jenkins reported a failure in my PlusPoints_Test job. When looking into the logs I saw these lines:

Checking Localizations
+ php checker.php check:strings-folder application/Resources/en.lproj/ application/Resources/de.lproj/ application/Resources/fr.lproj/
File "application/Resources/de.lproj/Localizable.strings" has missing keys:
 - grade.rounded
 - grade.rounded.prefix
File "application/Resources/fr.lproj/Localizable.strings" has missing keys:
 - grade.rounded
 - grade.rounded.prefix
File "application/Resources/de.lproj/SMSettings.strings" has missing keys:
 - grade.rounded
File "application/Resources/fr.lproj/SMSettings.strings" has missing keys:
 - grade.rounded
Build step 'Execute shell' marked build as failure

I had to smile. This message was generated by a small tool I wrote some time ago: LocalizationChecker. It is a small PHP CLI application which is based on the Console component of Symfony. It does nothing else then check if all translation files are available in all languages. Then it checks if all files contain all entries from a base localization (usually english).

In the above log, one can easily see that I forgot a few keys in the german and french translations. I’m quite sure that I would have forgotten to add them if I didn’t have Jenkins setup to perform these checks on every commit.

27 December 2014

FidelisFactory @ SRG Hackdays

At friday, 12. September at 9 AM the SRG SSR Hackdays took place for the first time. Roman and me joined for this 28 hour hacking marathon.

After short presentations of the idea, the hacking began. We joined Martin and Beat to start our crowd connect four game.

Usage

Cool atmosphere and awesome catering

As the hackathon was organized by the SRG SSR, the swiss broadcasting company, we were located inside a television studio which is usually used to make TV shows. You had absolutely no idea wheter it was 2 PM or 2 AM. The perfect atmosphere for hacking.

Everytime the organizer anounced food, it took only 2 minutes until the room was empty. That’s not because we were tired of hacking, it was because of the food. The catering was just awesome. There was food and drinks the whole day. It was like a luxury hotel.

To get some impressions from the hackathon, check out this short video of the whole 28 hours.

Telegame - Connect Four for the Crowd

Originally, we wanted to create an interactive television guide for the Samsung Galaxy Gear 2. We received 2 of these watches some time ago from Samsung Switzerland to develop apps for them. We changes our mind in the same second as Martin presented his crowd teletext game idea. So we joined him.

Check out this short interview with Martin where he explains the idea behind the game.

The result is the following teletext page, which was available on SRFInfo on page 595 during the hackathon.

Usage

People could join the game by opening the IP address on the teletext page. After choosing a side, they could participate in every round. After 30 seconds, the column with the most votes is chosen and a cross or a circle, (depending on which team’s turn it was), is inserted at that position.

If you are intersted in the the source code of the game, check out Roman’s Github account. He will opensource the code within the next few days. The project contains also an emulator which looks like the teletext on a tv. So you can play, even if the API for publishing something on the teletext is not available for public. (The picture above is actually taken from the emulator and not the real teletext.)

Thank you

Thank you SRG for this hackathon. We really enjoyed it, even if the second day after only 3 hours of sleep was very hard. We would really like to join the SRG SSR Hackdays next year again!

19 August 2014

Jenkins for solo developers

I asked myself many times if it is worth to use Jenkins for hobby projects like PlusPoints. But once you start using it, you won’t miss it. I promise.

I assume you already know what Jenkins is. If not, just have a look at its logo. Jenkins is your personal assistent for all sort of task. They don’t even have to do something with software development. It can do all sort of repetitive tasks for you!

Unit Testing

I know you hear it again and again. But I’ll repeat it too:

Unit test every project. Also simple projects. They can and will grow. At that point you’ll be happy to have automated tests

Unit testing is fun. Believe me. When you are at a point where you have the first small test suite, it makes you happy see all tests pass. Also if a test is failing it makes me smile. I can think that this bug would have gone into production without the tests.

Deploying

Espacially if you are running websites or webapplications, you need to update them from time to time. The process may look something like this:

  • Prepare project (remove unneeded files, generate sitemaps…)
  • Open FileZilla and try to find the FTP password
  • Backup current application and database
  • Upload everything
  • Open your browser and check if everything works as expected

It was for me the same until I started using Jenkins. It took me a few hours to set it up. But now I save a few minutes every time when I deploy a new version of a webapplication. The deployment process now looks like this:

Jenkins performs all the actions described above. The best thing: It will never forget a step. Especially if you didn’t deploy for some time you may have forgotten what you need to do. Jenkins won’t forget. Just press “Build now” and a new version is deployed. At the end of the post I have a short list of useful resources if you want to deploy an application with Jenkins.

Get project insight

It’s important to now details about your project. But this gets harder when the projects grows. Jenkins can help. There are tons of plugins available for all sort of things (Jenkins Plugin list).

Even if you don’t need all this information, it can still be very interesting to watch a project grow. Have a look at the graphs above from the development of PlusPoints. In my opinion, these beautiful graphs are reason enough to install some of these plugins. 😃

Wrapping up

Unit testing should be reason enough to use Jenkins. You may forget to run the tests from time to time before commiting. But Jenkins will tell if something bad happened. This is another level of security you add to avoid such situations.

Maybe you ask yourself where you should run Jenkins. On a server? On your local development machine? On a Raspberry Pi? If you ask me, it doesn’t matter as long as Jenkins is running. I have it running on my local development machine. It’s always running, and most of the jobs are started by polling a git repository somewhere. And if there’s a new commit, it’ll build, test or deploy it!

Useful resources

The following contains some useful resources for specific topics with Jenkins.

Deployment

Statistics

If you have some other useful links, which you would like to see listed right here, just write me an email.

20 June 2014

PlusPoints 2.0.0 released

A few week ago we were looking for beta testers. Now we are one step further. Last monday, June the 10th, PlusPoints was released on the Appstore and is now available for download.

We really have to say Thanks to our testers. We got very valuable Feedback and could get the best out of it, resulting in awesome new features and many bugfixes.

I don’t want to cover the new features in this post. If you are interested in what’s new, head over to this blogpost about the main features we added in Version 2.0.0.

Technical Aspects

I would like to talk about some technical features which are behind PlusPoints.

Objective-C + C++ = Objective-C++

We get more and more user feedback asking for an Android version of PlusPoints. As my partner Luis explained in a blogpost, we currently don’t have the time and experience to write and maintain a PlusPoints for Android.

But anyway we try to be prepared for the future. This is way I did some testing with C++ and Objective-C++, which makes it possible to share code between iOS and Android. It is possible to write a pure C++ library and use it on both platforms.

For example the “Weight parser” is written in pure C++. I then wrote a small Objective-C wrapper around it. As an example, I published the code on Github. Check it out if you are interested in how to mix Objective-C and C++.

In a next step it would be possible to use this C++ in an Android project by using the Native Development Kit (NDK). I already did some tests with JNI Bindings and the NDK for another project. Perhaps we will use this in the near future for Android versions of our applications…

KIF Integration Tests

When I write code, I do as much Test Driven Development (TDD) as possible. With PlusPoints I did even more. When the UI became stable, I started to write some integration tests which test default UI behaviour like adding and removing semesters adds/removes cells from the UITableView. For running the tests I use the KIF framework. You don’t have to worry about all the interactions with the views itself. You write the UI tests as you would write a normal unit test. That’s it.

It was the first time I wrote integration tests for iOS, and it was completely worth the effort. I wouldn’t do it for all of our apps, but as we plan to release frequent updates for PlusPoints, it’s important to not break the UI. And finally it is really fun seeing the simulator starting up and running all these UI tests. :-D

Continuous Integration (CI)

This post is more focused on the parts inside PlusPoints. But the most important part outside is CI which I also make use of as a solo developer. Explaining the benefits of this would be too much for this post, so the next post will only be about why you should use CI as solo developer. So stay tuned!

27 April 2014

We want you!

PlusPoints 2 is in its final phase. Most of the features are ready and Polished. But there is still the one and other bug. This is the reason why we need you! We need you to test our application.

If you are interested in participating as a tester, head over to the blogpost on fidelisfactory.ch which describes what you need to do.

Use your chance right now to get an early preview of PlusPoints 2!

Become Tester

10 April 2014

Samsung Smart TV Hackathon

I have been eagerly waiting for the last weekend. The reason was the Samsung Smart TV Hackathon. Roman Brunner and myself signed up a long time ago. Originally the hackathon was planned for february. But they couldn’t find enough participants for that date. So it was postponed and took place last weekend.

On Friday 6 PM the whole thing started. 6 Teams with up to 5 people were ready to start working on their projects. After a short introduction we could get our hands on the Smart TVs. The goal was to build an application running on a Smart TV. It didn’t matter what, but it had to work (and look beautiful).

Usage

The timeframe was 40 hours until the project presentations took place on sunday 11 AM. At this point we already knew that this amount of time would not be enough to make our application ready for sale. We decided to only implement the core features and fake everything else. As I mentioned before, finally it needs to look pretty. 😃

Technologies

We could choose between 2 technologies. There was a rich Javascript API which gives us access to many of the core features of the Smart TV. But there’s also a more low level C API which you can use if you want to do more performant stuff or if you just need to be closer to the hardware.

We decided to build a web application using HTML5, CSS3 and Javascript. Because the TV uses the V8 Javascript Engine internally we get enough power to build a reach user expirience.

Broadcaster vs Smart TV

During the contest many different additional ideas arised. Imagine an application that displays additional statistics on your TV screen while watching the UEFA Champions League final or an “Ad Blocker” to get rid of the endless advertising interruptions. Sadly these ideas cannot become reality. As we were told by the Samsung engineers, this is not allowed in europe. The broadcasters don’t want anything on the screen while watching their channel. The situation looks completely different in the US or asia, where these things are allowed. In my opinion these features would make it worth buying a Smart TV.

The result of 40 hours

I can’t say I had slept enough in the last two nights, but it was enough for our presentation on sunday. Around 10:30 we “finished” the work on our application and started to prepare the short presentation.

Usage

I was very excited to present our result, but also to see the other applications. The applications where spread over many different areas. Starting from easy photo displays up to a Social TV application which allow people to watch the same movie on multiple TVs while chatting over their smartphones.

When the presentation finished it took around half an hour for the jury to decide who should win. We didn’t really hope to win something as we just participated for fun. That’s why we have not been very surprised when the german team with their social TV application won the first prize: (not) surprisingly a Samsung Smart TV. But we have really been surprised when Christoph Burgdorfer, one of the organizers, revealed the second team: Us with our application “Tournaments on TV”.

We are very proud of this result and happy with our prizes. For the second place we got a Galaxy Tab 3 and a Galaxy Note 3.

Are Smart TVs smart?

It wouldn’t have been a hackathon if there was no fun. So we also needed to play a little bit with these TVs. I was really impressed by the gesture control. When I started playing with an EyeToy for PlayStation 2 a few years back. It was just a toy and half of the time it didn’t work. But during this weekend I realized, that gesture control is still a toy, but works 99% of the time. It is very accurate and most of the time much faster then controlling the TV with a remote control.

Usage

On the other hand, the voice control didn’t convince me. For simple commands like “Up” and “Down” it worked pretty well. But from time to time the TV did crazy things, like starting Twitter and searching for random things. I’m sorry Samsung, but Siri is quite a bit ahead of you…

But the major drawback on TVs is still the keyboard. As soon as you have applications on your TV you need some sort of keyboard to enter text. E.g. for your Facebook and Youtube accounts. The only way to insert something is to use your remote (or your hand via gesture control) to select single characters on that ugly keyboard. After no more than 2 words you get annoyed.

Overall I think, Samsung’s Smart TVs did a huge step forward during the last 2-3 years, but there are still a few problems that need to be solved (e.g. text entry with “non-ugly” keyboards).

Thank you Samsung

…for this awesome event. Special thanks to Daniel Schwarzl and Christoph Burgdorfer, the main organizers. But also the technical stuff, who helped us with the TVs and its sometimes tricky API.

I really enjoyed this weekend and I already look forward for the next Hackathon which I will join for sure!

If you want to have look at the application we made during the hackathon, checkout the backend and the frontend repositories on GitHub.

14 February 2014

PlusPoints - 30'000 Downloads

Our application “Grade Calculator - PlusPoints” reached 30’000 downloads. I’m really proud! But I have another really impressive number to present: 1’000’000 Sessions! Our app has been used over 1 million times. To be exact, at the time of writing it has been used 1’088’734 times.

A brief history

On January the 1th 2010 an app called “PlusPointsPro” launched on the appstore. It was the first application by FidelisFactory that wasn’t available for free. We hoped, it would give us a small amount of money for all the expenses we had by the time. But that was just a dream. During the time it was available, we earned only 50$.

We realized that students just don’t have money and don’t want to spend money on an application to track their grades. So we decided to give the application away for free.

When the app became available for free, as you can imagine, we got more downloads. All students with iPhones and iPods at my school used it by the time and we received a lot of feedback.

We added features like templates, import/export and “Pluspunkte” (A special system to count the grades). On May 25th the application received it’s last update to version 1.6.0.

Students as customers

As I mentioned before, students are not the best customers if you want money for your application. But there are some other interesting phenomena you can see in the usage and downloads data. Take a look at the statistics of the downloads and sessions between the 1st September 2013 and the 1st February 2014.

Downloads

Usage

Sessions

Usage

You can see that Students don’t (like to) work on weekends and holidays. Both, the downloads and sessions, collapse during the weekends and holidays.

Another thing you may have noticed immediately is the period during december and january 2014. You can clearly see the christmas holidays. I thought that there’s an impact on the usage of PlusPoints. But when I saw these statistics, I was surprised that the effect was visible like this.

And there will be Version 2.0.0

As you probably already know, we are working on Version 2.0.0 of PlusPoints. There’s still much work to do, but as we can see by now, it will be worth all the effort we put into it.

If you wonder where we get all the data about the usage of our apps from, have a look at Flurry and AppAnnie. Both services are awesome if you want to know whats going on with your apps.

16 January 2014

Core Data Migration Headache

I’m happy as long as CoreData is able to do a light weight migration. But from time to time the schema changes are to big and this is not possible. This happend to me yesterday. And the headache was terrible.

I’m currently working on version 2.0.0 of our lovely PlusPoints application which is used by students all over the world to track their grades in school. As you can imagine the model changes in big parts as we are introducing many new features. There are easy things like adding a new entity or renaming a property but also harder things I didn’t do before with CoreData. PlusPoints was one of our first applications and started back in 2010. So the old model is a bit messed up. For example I have dates stored as NSString (without any validation…).

I played for 2 days with CoreData’s mapping models to do this sort of migrations. I used this tutorial on how to do custom migrations. But when it came to renaming entities, properties and transforming the property type at the same time, the battle against Xcode began. I was not able to get all that things working together. And on the top of it, Xcode crashed about every 10-15 minutes. I needed something else.

So I decided to try a different approach of doing that migration. The Idea is the following: I want a complete new model and just move the data from the old database into the new one. That will make the development of the new version much easier, because I can design the model from ground up without having to think about migrations and renaming. Short: Without the CoreData Headache.

But to get there the way was longer than I thought..

Preparing the old model

I had to rename the classes (not entities!) of the entities that will exist in the new model aswell. The reason for this is, that I can’t have two classes with the same name in one project. I just used the Refactor capability of Xcode to rename Semester to SemesterOld. I also had to change the Class name in the .xcdatamodeld file. The Semester Entity from the old model will use the class SemesterOld from now on.

Setting up the new model

The next step was to setup and design the new model. There’s nothing special about it. I just added another .xcdatamodeld file to the project and created the new model

Migration

The trickiest part was the migration of the data from the old model to the new model. For this task I wrote a small class called Updater. You can find it in this gist.

The idea behind it is easy. When the update method is called 3 things are done:

  • The ‘old’ CoreData stack is created
  • The ‘new’ CoreData stack is created
  • All entities are (manually) transferred from the old stack to the new stack.

To fully understand the code you may have a look at MagicalRecord which makes this code much more readable.

There’s also one other little thing going on in update. If you look at the database paths, you will see that the old is in the Documents folder and the new is in the Library folder. The reason is that I want to clean the Documents folder to use it for iTunes Filesharing.

Setting up the CoreData Stack

It is important that the update method of the Updater class is run before the application does the CoreData setup (usually in the AppDelegate class). Otherwise the application will crash.

Once the update method is run, I had a new Database.sqlite file in the applications’ Library folder as expected. But when I tried to run the application it crashed with the error:

Can't merge models with two different entities named 'Semester'

Why does CoreData try to merge my different .xcdatamodeld files?

Because I told it to do so. My code to create the NSManagedObjectModel in the AppDelegate looks like this:

// Returns the managed object model for the application.
// If the model doesn't already exist, it is created from the application's model.
- (NSManagedObjectModel *)managedObjectModel
{
    if (_managedObjectModel != nil) {
        return _managedObjectModel;
    }
    _managedObjectModel = [NSManagedObjectModel mergedModelFromBundles:nil];
    return _managedObjectModel;
}

Have a look at the line

_managedObjectModel = [NSManagedObjectModel mergedModelFromBundles:nil];

This is what causes the crash. So I told CoreData which model to use with the following 2 lines:

NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"Database2" withExtension:@"momd"];
_managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];

CoreData doesn’t try to merge anything. It uses the new model I just created with the database that contains the migrated data. That’s exactely what I wanted!

Conclusion

I can now go on with the development of PlusPoints with a complete fresh model. I don’t have to worry about light weight migrations and renaming identifiers. The updater class does all that for me. I’m sure this will simplify the development and prevent the one and other NSInternalInconsistencyException.

13 January 2014

Hello World

Every blog needs a “Hello World” post. So this is my post. Have fun with it and let’s get started with more intresting topics…

I have already a few prepared, but not yet ready for publication. So stay tuned. The main topics will be iOS programming and everything about our application developed together with Luis Martins for FidelisFactory.