Tuesday, July 24, 2012

Android-App: Anrufweiterleitung


Anrufweiterleitung - einfach und unkompliziert Anrufe auf ein anderes Handy oder eine Festnetz-Nummer weiterleiten und wieder ändern.
Viele Unternehmen müssen auch außerhalb der üblichen Bürozeiten eine ständige Erreichbarkeit für den Kunden sicher stellen. Häufig wird deshalb mit Rufumleitungen auf Handys gearbeitet, so z.B. auch in der ambulanten Pflege. Hier übernehmen einzelne Mitarbeiter außerhalb der Bürozeiten, die sogenannte Rufbereitschaft. Kunden können dann auf einer Notfallnummer anrufen und die Mitarbeiterin, die in der Rufbereitschaft ist, nimmt das Telefonat auf ihrem Handy entgegen und kümmert sich um die Bearbeitung der Anfrage. Die Notfallnummer ist entweder auf ein speziell dafür vorgesehen Rufbereitschafts-Handy geschaltet oder die Nummer wird weitergeleitet auf das jeweilige Handy der Mitarbeiterin.
All diese Fälle unterstützt die App Anrufweiterleitung, indem schnell auf die letzte gespeicherte Rufnummer, einer Nummer aus dem Adressbuch oder auf eine neue Nummer Anrufe weitergeleitet werden. Und mit einem einzigen Klick ist die Weiterleitung wieder ausgeschaltet.
Und für den privaten Einsatz? Lässt sich die App genauso einfach uns sicher einsetzen wir im geschäftlichen Bereich.
Hinweis: die App zeigt immer zuverlässig an, ob weitergeleitet wird oder nicht. Auch wenn die Weiterleitung über eine andere App oder direkt über das Handy-Menü ein- bzw. ausgeschaltet wird. Das gibt die nötige Sicherheit, wenn im geschäftlich aber auch im privaten Bereich die Erreichbarkeit sicher gestellt sein muss.

Sunday, June 3, 2012

UIs for Hierachical iPad Apps


If you're in a hurry: tl;dr version

At factis research we developed FRLayeredNavigationController, a view controller compositor which enables you to develop -- as we think -- great iPad apps. Influenced by the UI of the Twitter and Soundcloud iPad apps we designed a new navigation concept for our product Checkpad MED. Since we love open source software and know what we owe the community we'll again try to give something back: FRLayeredNavigationController gives iPad developers a simple drop-in replacement for UINavigationController for great UIs. This screencast shows a very simplistic app made with FRLayeredNavigationController.

Full-blown post

Motivation

The Apple iPad is a great mobile device which is due to its big screen capable of displaying a lot of content at the same time. This capability makes the iPad a great device for apps with complex, structured data. A question Apple leaves to its developers is how to guide the users through deeply hierachical content.

On the iPhone the usual way is to use UINavigationControllers. Because of the small screen, UINavigationControllers are great on the iPhone, only the currently most relevant information is displayed. The sole trace of the navigation path from app start to the current content is the title of the second-to-last view controller in the back button at the upper left side of the screen.

On the iPad UINavigationControllers alone are fine, too, when all your view controllers really have an iPad-screenful of content. But, most apps have some kind of low-content view controllers which are primararilly made to bring the users to the actual content, stepping through several layers of the hierarchy. Often, these controllers are simple UITableViews which look bad when they are displayed fullscreen on the iPad. To solve this problem, Apple gave us UISplitViewController: the navigation-only part on the smaller left side (or even in a UIPopoverController) and the content right next to the navigation in a somewhat bigger frame. This concept works great and looks good as demonstrated at least by the iPad Settings and Mail apps. Compare them to their iPhone counterparts and you will see how nicely they work on these very different devices with minor changes only.

UISplitViewControllers work great when your content hierarchy's depth is two: One navigation layer and one content layer. Three layers is still okay, since you can use a UINavigationController inside the left or right side of the UISplitViewController. But if the depth of your content hierarchy exceeds three, it does not fit nicely in the UISplitviewController somehow, you have to go other ways.

At factis research we particularily liked the Twitter and Soundcloud iPad apps and decided to go a similar path with our product Checkpad MED. We called our solution FRLayeredNavigationController because it enables developers to build schrieblesque apps with multiple hierarchy layers.

How does it work?

The basic idea is not to completely hide a view controller when a new view controller is being shown.  FRLayeredNavigationController still shows some pixels of the view controllers the user passed through until reaching the currently active one. This will give the user a good idea of where (s)he currently is in the navigation hierarchy. If the user should need more information of these partly covered view controllers, (s)he can always reveal the covered pixels by intuitive pan gestures. The user will think of a stack of paper and has similar interaction options. Probably you get a better idea when looking at these screenshots:

regular view
after revealing more information in the level-2 view controller (the "Teams" view controller) by swiping  to the right
Also watch these two iPad screencasts to get the idea: http://youtu.be/v_tXD_mL05E and http://youtu.be/q66HX2td_uc .

Technically, it uses view controller composition as introduced in iOS 5. It manages multiple "Layers" which are UIViewControllers you provide. The moving of the layers is triggered by a UIPanGestureRecognizer and some logic when to move which layer. It looks and feels very nice due to the nice iOS animation support.

Can I use FRLayeredViewController, too?

Sure, it's open sourced and available at GitHub! If you have any problems, feel free to contact us.

What is the API like?

Have a look at the API documentation, it's quite similar to UINavigationController's API from Apple.

Say, you have a UIViewController and you're using UINavigationController from Apple. To show a new layer to the user, you would do:

[self.navigationController pushViewController:test animated:YES];

with FRLayeredNavigationController it's quite similar:

[self.layeredNavigationController pushViewController:test
                                           inFrontOf:self
                                        maximumWidth:NO
                                            animated:YES];

The maximumWidth parameter is how you tell FRLayeredNavigationController whether the new view controller is content (give it the maximal width still available) or not.

Just as UINavigationController, it also supports UIBarItems and a configurable title view. For example, a UIViewController which has been pushed onto a FRLayeredNavigationController could have the following viewWillAppear method to add a back button on the upper left corner:

- (void)viewWillAppear:(BOOL)animated
{
    self.layeredNavigationItem.leftBarButtonItem =
        [[UIBarButtonItem alloc]
         initWithImage:[UIImage imageNamed:@"back-button.png"]
                 style:UIBarButtonItemStylePlain
                target:self
                action:@selector(backButtonClicked)];

    self.layeredNavigationItem.leftBarButtonItem.style =
        UIBarButtonItemStyleBordered;
}

Have a look at FRLayeredNavigationController and FRLayeredNavigationItem to see what's possible with FRLayeredNavigationController.

How can I embed FRLayeredViewController in my project?

It's explained step-by-step in the README file and in this screencast.



Thursday, December 1, 2011

A rant about Scala vs. Haskell

After two weeks of non-stop Scala programming I now feel comfortable working with implicits, abstract member types, path-dependent types, variance annotations, existential types and everything else. We even used the CPS transformation plugin as a Cont-Monad replacement, already.

Scala's type system is powerful but also complex right from the start. With Haskell you can use most basic libraries without enabling GADTs, RankNTypes, OverlappingInstances and TypeFamilies or having to learn about them. And you can take your time to learn all these concepts. The containers API is really simple compared to Scala's collections API. On the other hand in Haskell you have to learn about monads quite early. (Oh, I miss this warm fuzzy feeling in Scala!)

We're using Scala for integration with existing Java code and libraries and that's working really well. As a "stand alone" language I still prefer Haskell and I doubt that's going to change with more Scala experience. For me as a functional programmer subtyping doesn't add much more than Java compatibilty. Maybe I have to change but IMHO it makes API design and the type system too complex. I'm still overwhelmed by the "default" design possibilities: type parameters or abstract member types? Sealed case classes or open subtyping? Implicit parameters and conversions (aka type classes) offer even more design choices! Maybe I'm just more experienced with Haskell but mostly I just decide between "data" and "class" and with higher-order functions that's enough 95% of the time. For the missing 5% we have extensions (and FlexibleX + Rank2Types + TypeFamilies + ExistentialQuantification is enough for me).

Often people complain about GHC's error messages but they're really great compared to scalac's. I also miss STM. Actors are nice, but using react doesn't feel natural and we can't just use "receive" with thousands of threads "without thinking" just like in Haskell. (We're now using react with the CPS transform plugin to hide the fact that internally everything is implemented using continuations.)

I don't miss lazyness, yet. I've used call-by-name and lazy vals on some occasions and I think I prefer strict by default with optional lazyness annotations. I just can't think "the lazy way" - even after 18 months of full-time Haskell coding.

I do miss control over side effects. When writing a higher order function I always get scared when I realize that I can only expect the caller to provide a pure function but the function could be doing all sorts of things behind my back!

One thing I'd like as a GHC extensions is explicit dictionary passing. It's nice that implicit parameters can be used implicitly but also explicitly. Of course it's risky, too, because nobody can stop you from using a different Ord instance every time you're inserting into a Set. "unsafeCoerce" seemed so evil - until erasure forced me to use foo.asInstanceOf[...] (Of course an exception is not as bad as a segfault.) Sometimes I know what I want and I'm willing to take the risk. As long as all those features are not enabled by default I think hard enough before enabling {-# LANGUAGE IncoherentInstances #-}.

Scala might be the best way to live between worlds. But you have to understand both worlds and you're still in between. It's not twice as good. If I have to live in OO world I prefer having a functional world in addition so I'd chose Scala over Java at any time. But if I can choose freely I still prefer the pure Haskell world.

Sunday, October 30, 2011

WifiAlive Android App released

WifiAlive is a very simple and low resource application aimed at maintenance of a Wifi connection. A connection is periodically (every 5 seconds) checked by trying to contact the gateway, as well as IP addresses or domain names which you can enter via the UI. WifiAlive tests each of these addresses by icmp and http head. If one of these tests succeeds, Wifi is considered up. If not, Wifi is reset (that is deactivated and activated). After Wifi (re-)activation Android on its own tries to establish a connection to an access point in reach. On a failed connection check, WifiAlive will only wait 20 seconds for a reset, scan and successful connection until the connection is reset again. Considering the time needed for a Wifi reset and a scan to complete, it can be said, that, as soon as a known network is available, there is a worst-case of roughly 30 seconds for the connection to be established. WifiAlive is thus much more simple then many of its competitors. The popular WifiFixer for example conveys about 6000 lines of code whereas WifiAlive has only around 500.

The code of WifiFixer is publicly available on github. I have checked those parts of the code which seemed important in respect of a problem I believed to have with WifiFixer 0.8.0.6. I was rather stunned by the complexity of the program, since I had in mind the solution I have just proposed. WifiFixer almost replaces the Wifi Settings Tab in Android and will continue this approach in upcoming versions. In some cases, settings from the Android Wifi Settings Tab can be overridden, it does its own management of known networks and behind the scenes does scans for networks in reach, matches them to known networks and harbours a small collection of hacks for devices that have to be dealt with in a special way - for example the Google Nexus One. WifiFixer is a great application. It helps many people with their Wifi troubles. But after I had seen its complexity and, in addition, found a bug in its matching of known to found networks on a scan, I decided that this was not the solution to my problem, as, additionally, a lot of code seemed to do things that Android normally does on its own. No offence David, I've learned a lot from looking at your code.

There are other applications, like Advanced Wifi Lock. But I couldn't get access to their code and very often the free (limited) versions did not seem to cover all aspects of Wifi maintenance that I wanted to ensure. Moreover I am already beyond trusting a random application from the market without knowing its code. The Advanced Wifi Lock application (a bare Wifi lock, if it does what the name suggests) does not solve my problems, as it sometimes takes Android a bit too much of time to re-establish a connection when re-entering the area of an access point or on walking from one access point to another. In my experience this could take up to two minutes, which was just too long for my purpose. These experiences may be better on other devices, still it feels very good to know, that as soon as a known network is in reach, there is a rough 30 second worst-case until you have a connection.

On some devices there also seem to be problems with the supplied Wifi drivers. These drivers may enter an undetermined state or cause wpa supplicant to run in endless loops. I have not delved into these problems. But it seemed to me, that, if at all, they can be resolved by doing a Wifi reset.

To sum up, I think that some applications aimed at taking care of your Wifi connection may be too complicated and question is, why such an application should do things like scanning for access points, as Android usually does a pretty good at this. Others may be doing the things I had in mind, yet there was no way for me to be sure.

That's, why I wrote WifiAlive. I hope you like it.

Feel Free to browse the code at http://darcs.factisresearch.com/pub/WifiAlive or just install the app from the android market.

Sunday, October 9, 2011

stm-stats: Retry statistics for STM transaction

Two days ago, Stefan Wehr talked at the Haskell in Leipzig workshop about the experiences that factis research had with Haskell when creating real-world applications. When he mentioned that we have code that keeps count of retries of STM transaction, someone from the audience asked us to publish the code. So, after some refactoring to make the interface generally usable, here it is. The stm-stats package provides a few functions (in Control.Concurrent.STM.Stats) that can replace atomically: trackSTM and variants that allow you to name the transaction or have more control about the warnings that will be emitted when the number of retries exceeds a certain value. The following code demonstrates how the module works:
import Control.Concurrent
import Control.Concurrent.STM
import Control.Monad

import Control.Concurrent.STM.Stats

main = do
var <- trackSTM $ newTVar 0
forkIO $ forM_ [1..23] $ \i -> do
    threadDelay (100*1000)
    trackNamedSTM "writer" $ writeTVar var i
putStrLn "Starting reader..."
trackNamedSTM "reader" $ do
    i <- readTVar var
    when (i < 23) retry
putStrLn "Reader finished."
dumpSTMStats
When run, you will see this output:
Starting reader...
STM transaction reader finished after 23 retries
Reader finished.
STM transaction statistics (2011-10-09 16:26:27.226675 UTC):
Transaction     Commits    Retries      Ratio
_anonymous_           1          0       0.00
reader                1         23      23.00
writer               23          0       0.00
PS: As I usually post on my own blog, I should explain why I from now on will also post on the factis research company blog. Factis research relies heavily on Free Software and wants to contribute back to the community where possible. But in the course of every-day work, this sometimes falls by the wayside. Therefore, I was hired to help out as the community interface: My task is identifying, packaging and uploading components of internal code that are of wider interest, following up on user requests and bug reports, and talk about it. This module is the first brought to you by this new strategy, but expect more to come.

Saturday, October 8, 2011

Talk about developing commercial software in Haskell

Yesterday, I gave a talk at the Haskell in Leizpig workshop about our experience in developing commercial software in Haskell. You can find the slides (in german) here. I was really surprised by the large number of attendees (about 50), given that the workshop's language was german (except the very interesting talk by Kevin Hammond).

Saturday, October 1, 2011

New Version of HTF with Diffs, Colors, and Pretty-printing

I've just uploaded version 0.8.1.0 of HTF to hackage. HTF (Haskell Test Framework) allows you to define unit tests, QuickCheck properties, and black box tests in an easy and convenient way. We use HTF at work all the time, where it has proven to be quite valuable for organizing our test suite. An earlier blog post describes HTF in more detail.

The new version comes with some cool new features:

  • Support for diffs and pretty-printing. If an equality assertions fails, you now get a proper diff of the two values involved. If possible, the values are pretty-printed (thanks to Edward Yang and his groom package for inspiration). Here's an example:
    [TEST] Main:diff (TestHTF.hs:68)
    assertEqual failed at TestHTF.hs:68
    * expected:
    PlusExpr
      (PlusExpr
         (MultExpr
            (PlusExpr (Variable "foo")
               (MultExpr (Literal 42) (Variable "bar")))
            (PlusExpr (Literal 1) (Literal 2)))
         (Literal 581))
      (Variable "egg")
    * but got:
    PlusExpr
      (PlusExpr
         (MultExpr
            (PlusExpr (Variable "foo")
               (MultExpr (Literal 42) (Variable "bar")))
            (PlusExpr (Literal 2) (Literal 2)))
         (Literal 581))
      (Variable "egg")
    * diff:
    6c6
    <         (PlusExpr (Literal 1) (Literal 2)))
    ---
    >         (PlusExpr (Literal 2) (Literal 2)))
    *** Failed!
        
  • As you can see from the example above, HTF now supports colored output.
  • There's a new commandline option --quiet which causes HTF to produce output only if absolutely necessary (e.g. for failed test cases).

Just get HTF from hackage, it now also works with GHC 7.0.* and 7.2.1!