Erfahrungsbericht: Leben und Arbeiten mit einer Smartwatch

Veröffentlicht am 4. Mai 2015

Apple Watch by Pandyland
„Apple Watch“ by Pandyland

Smartwatches werden in meiner Filterblase überwiegend belächelt. Es reicht nicht einmal für die übliche Technikfeindlichkeit im Stile von das braucht doch kein Mensch und OMG WTF BND NSA Überwachung!!11 – es werden einfach nur Witze gemacht. Demnach dürften diese Dinger wirklich komplett egal sein, oder? Trotzdem kam mir vor kurzem die Idee, dass für mich ein solches Teil wirklich nützlich sein könnte. Und so habe ich mir eine Smartwatch geklickt und bin damit ein paar Tage durch die Gegend gewandet. Dieser Artikel ist weniger ein Tech-Review als vielmehr eine Erfahrungsbericht zum Konzept Smartwatch an sich. Es geht hier zwar um Android-Hardware, aber die Erkenntnisse sollten 1:1 auf das Apple-Universum übertragbar sein.

Motivation

Der eigentliche Anlass für die Anschaffung der Smartwatch war mein zunehmend nicht mehr zu gebrauchenes Galaxy S2. Das Telefon ist schlicht, flexibel, robust, konnte zweimal problemlos in Eigenregie repariert werden und hat mir jahrelang treu gedient. Allerdings ist es mittlerweile selbst für ruckelfreien Internetkonsum zu schwach, der Lack des Metallrahmens ist nur noch in Spuren nachweisbar und auch der Ersatzakku des Ersatzakkus ist am Ende. Ein neues Telefon sollte her, am besten ein 1:1-Ersatz mit mehr Power. Sowas scheint aber nicht angeboten zu werden. Heutzutage ist meist ist der Akku fest eingebaut und die Bildschirme haben Flächen, die man am besten in Vielfachen des Saarlandes angibt – einhändige Bedienung ausgeschlossen. Mir war nicht danach, dafür 500 Euro und mehr auf den Tisch zu legen.

Doch auch nach Monaten der Wartezeit kam kein mir genehmes Telefon auf den Markt. Und so kam ich auf die Idee, dass sich die zwei Hauptpunkte meines Anforderungskatalogs eventuell auch anders als über ein zu 100% passendes Telefon erfüllen lassen könnten:

  1. Ursprüngliche Anforderung: Auswechselbarer Akku!
    Motivation: Nicht 500 Euro für ein Telefon bezahlen, das am Ende wegen seines Akkus in den Müll wandert, obwohl der Rest noch funktioniert.
    Alternativlösung: Weniger teures Telefon kaufen, bei dem mir die frühzeitige Verschrottung nicht so sehr schmerzt.
  2. Ursprüngliche Anforderung: Kleines Telefon für einhändige Bedienung!
    Motivation: Unterwegs, d.h. zu Fuß mit Gepäck in der Hand müssen Navigation, Gate-Check, E-Mail-Empfang und dergleichen bequem möglich sein.
    Alternativlösung: „Normales“ großes Telefon anschaffen und mit dem durch den Billigkauf gesparten Geld einen Second Screen für das Telefon, also eine Smartwatch finanzieren.
Meine LG G Watch R
Meine LG G Watch R mit Woto Watch Face

Diesen Plan habe ich in der Tat umgesetzt. Günstige Riesen-Telefone bekommt man heutzutage direkt vom chinesischen Hersteller, die durch die Umgehung von Zwischenhändlern wie Samsung und Apple billiger verkaufen können. In meinem Fall ist es das monströse OnePlus One geworden. Das Telefon ist nicht die ober-absolute Crème de la Crème, aber einem 350-Euro-Gaul (und das ist schon die teuerste Variante) schaut man nicht so genau ins Maul. Dazu habe ich nach dem Studium einiger Uhr-Reviews eine LG G Watch R (Amazon-Link) für rund 200 € geklickt.

Erfahrungsbericht

Für mich und meine Luxusprobleme funktioniert die Kombination aus Riesentelefon und Hilfscomputer am Handgelenk ganz hervorragend. Wenn ich entspannt im Zug sitze, habe ich ein größeres Telefon, woran man sich sehr schnell gewöhnt. Viele lästige Zwischendurch-Am-Handy-Herumfummel-Momente werden hingegen durch die Uhr abgefangen:

  • Nachricht geht ein? Auf der Uhr kann man schnell eine Notification-Vorsortierung vornehmen und entscheiden, ob man das Telefon in der Hand nehmen muss oder nicht. Wurde ein Tweet gefavt? Zur Kenntnis nehmen und nichts weiter tun. Eine E-Mail berichtet, dass auf einer relevanten Github-Issue ein „+1“-Kommentar eingegangen ist? Direkt von der Uhr aus die E-Mail löschen. Eine SMS der Airline berichtet, dass dein Flug gestrichen wurde? Jetzt ist es vielleicht der Moment gekommen, zum Telefon zu greifen und nachzuforschen. Ansonsten kann der Klotz in der Tasche liegen bleiben und Mainframe spielen. Welche Apps Benachrichtigungen an die Uhr durchreichen können, ist frei konfigurierbar.
  • Für Navigation in einer fremden Stadt braucht man eigentlich keine computergestützte Karte – es reicht, wenn man gesagt bekommt, wann man links abbiegen muss. Ein entsprechendes Vibrations-Signal reicht da eigentlich und ein entsprechender Pfeil passt auch bequem auf das Smartwatch-Display. Praktisch ist dabei auch, dass der Blick auf die Uhr nicht so sehr ablenkt, dass man dabei je gegen einen Laternenpfahl laufen könnte.
  • Ein Timer oder Alarm lässt sich schnell direkt an der Uhr einstellen und hat den großen Vorteil, wirklich nur am eigenen Handgelenk stattzufinden. Niemand bekommt (anders als beim laut summenden Telefon) mit, dass man gerade an etwas erinnert wird, d.h. niemand fühlt sich genötigt, mitten im Satz ein Gespräch abzubrechen. Ich nutze diese Funktion vor allem, um mich bei Schulungen an Pausen erinnern zu lassen. Der Alarm geht 15 Minuten vor der Pause los, so dass bequem noch das aktuelle Thema zu Ende bringen kann.
  • Eingeschränkt nützlich scheint mir die Uhr auch für das Lesen von Notizen geeignet zu sein. Normalerweise bin ich in Sachen Notizen, Einkaufszetteln und Todo-Listen ganz klar im Papier-Camp, da sich Kugelschreiber und Papier einfach schneller bedienen lassen als irgendwelche Apps oder Gadgets. Aber um sich an einem fremden Bahnhof oder auf einem Flughafen daran zu erinnern, wo man eigentlich nochmal hin wollte, scheint mir die Uhr eine handliche Alternative zu sein. Die meisten Apps sind nicht besonders gut darin, Text auf dem winzigen Display darzustellen, aber mit Google Keep klappt es ganz passabel.
  • Auch Mediensteuerung und Lautstärkeregelung funktionieren recht komfortabel.

Die Uhr ist also eine hübsche Ergänzung wenn es darum geht, Internet-Informationsfluss vorzufiltern, sich an Dinge erinnern zu lassen oder sich zurechtzufinden – jeweils ohne an einem unhandlichen Telefon herumzufummeln.

Beklagen kann ich allerhöchstens ein paar technische Details der LG G Watch R und von Android Wear, Googles Smartwatch-App für Telefone. Die Uhr wie das Telefon jeden Abend aufzuladen ist kein Problem und der Akku hält bei moderater Benutzung auch zwei Tage und mehr. Wenn es überhaupt ein Strom-Problem gibt, dann noch am ehesten auf Seiten des ständig mit Bluetooth funkenden Telefons. Die LG G Watch R braucht ein spezielles Ladegerät und möchte man davon mehr als ein besitzen (weil man wie ich stets eins im Koffer liegen haben möchte), ist man auf windige eBay-Händler angewiesen. Kabelloses Laden oder USB wäre angenehmer. Ein Helligkeitssensor wäre eine sinnvolle Erweiterung der Hardware gewesen, denn ohne einen solchen Sensor ist die Display-Helligkeit nur fest einzustellen. Dank des starken Akkus ist das kein großes Problem, denn nichts spricht dagegen, die Helligkeit einfach voll aufzudrehen. Auch ohne einen platzhungrigen USB-Anschluss ist die Uhr für meinen persönlichen Geschmack recht groß. Gemessen an anderen Herrenarmbanduhren ist sie das zwar nicht, aber ich bin eben eine halbe Portion und da wirkt das Gerät schon ein wenig klotzig. Und das Lederarmband finde ich recht langweilig, sollte sich aber vom Fachmann ohne weiteres ersetzen lassen. Wirklich gravierende Nachteile sehen anders aus, so dass ich mit dem Kauf der Uhr ganz zufrieden bin. Ärgerlicher ist die in vielerlei Hinsicht hakelige um umständliche Android-Wear-Software, aber so ist das eben bei Android – und nach dem erstmaligen Einrichten ist das auch egal.

Braucht man sowas?

Wäre auch Otto Normalverbraucher mit der Anschaffung eines vergleichbaren Geräts gut beraten? Da bin ich mir nicht so sicher. Ich bin ein effizienzvernarrter Nerd mit zu vielen Internetkontakten, der ständig unterwegs ist und das Glück hat, mal eben 200 Euro übrig zu haben. Bei einer Smartwatch handelt es sich um einen Hilfscomputer am Handgelenk, was mit einer herkömmlichen Armbanduhr meiner Meinung nach noch weniger gemeinsam hat, als ein Telefon mit einem verkabelten Wählscheiben-Telefon.

Ein Smartphone ist nicht in erster Linie ein Ersatz für ein altmodisches Kabel-Telefon oder 90er-Jahre-Handy. Es stellt vielmehr einen tragbaren Internetanschluss dar, mit dem sein Besitzer jederzeit mit Freunden oder der Arbeit in Kontakt bleiben kann. Das kann für so ziemlich Jedermann ein Gewinn sein. Den Hilfscomputer hingegen kann man meiner Meinung nach vor allem dafür gebrauchen, zu viel Internet etwas besser zu managen. Die Navigations-Funktion ist ein höchstens ein hübsches Extra und den ganzen Fitness-Krempel kann ich nicht wirklich einschätzen, da sowas bei mir immer noch mit Stift und Papier bzw. Excel-Tabellen erfasst wird. Als wirkliches Must-Have-Killerfeature erscheint mir das aber auch nicht. Die Kehrseite einer Smartwatch ist, dass sie mit der normalen Armbanduhr durchaus ein vorhandenes Accessoire vom Handgelenk verdrängt. Letztere ist oft ein Schmuckstück und ggf. Statussymbol, das seinen Wert über Jahre behält oder gar noch steigert. Der Hilfscomputer ist ein rapide veraltendes Stück Kunststoff und/oder Blech. Das sollte man nicht verwechseln und man sollte sich genau überlegen, ob man für sowas die mehreren hundert Euro wirklich übrig hat.

Fazit: die Smartwatch macht meinen persönlichen Alltag ein klein wenig effizienter und das ist mir die 200 Euro wert gewesen. Sich vor dem Kauf eines solchen Gerätes gründlich zu überlegen, was damit anzustellen gedenkt, ist aber keine schlechte Idee. Es geht bei diesen Geräten nicht um Armbanduhren (denn Armbanduhren sind die im Vergleich zu Smartwatches besseren Armbanduhren) sondern um Miniatur-Hilfscomputer der allerersten Generation.

ECMAScript 6: Symbols

Veröffentlicht am 20. April 2015

Ein Wiedergänger unter den JavaScript-Patterns ist die Idee, man könnte doch die Prototypen von Built-Ins (z.B. Function, Array) und Host Objects (wie Element.prototype) erweitern, um Library-Funktionalität direkt an Objekte anzubauen. Macht man das, handelt man sich mehrere mögliche Probleme ein. Möglicherweise gibt es (jetzt oder in Zukunft) anderen Code im Projekt, der sich darauf verlässt, dass Objekte nur exakt jene Eigenschaften haben, die der Standard vorgibt. Oder möglicherweise gibt es (jetzt oder in Zukunft) Code im Projekt, der eine genau gleich benannte Erweiterung in die gleichen Objekte einbauen möchte. Oder möglicherweise programmiert eine halbwegs erfolgreiche Library und belegt damit in Zukunft einen Eigenschafts-Namen, den zukünftige ECMAScript-Standards gern benutzt hätten. Letzteres ist in ES6 passiert – dort sollte Array.prototype.contains() eingeführt werden, doch weil Mootools diesen Namen einst besetzt hat, musste die Funktion für ES6 in Array.prototype.includes() umbenannt werden.

Dieses Problem kann man schrittweise abschwächen; macht man die neu an das Objekt gebaute Eigenschaft non-enumerable, taucht sie z.B. nicht mehr in for-in-Schleifen auf und reduziert damit etwas ihr eigenes Kollisionspotenzial. Aber eine wirklich halbwegs saubere Lösung gibt es erst mit den in ECMAScript 6 eingeführten Symbols.

In Variablen gespeicherte Strings kann man bekanntlich als Eigenschaftsnamen für Objekte einsetzen:

// Das ging schon immer
var o = {};
var x = 'Foo';
o[x] = 42;

// Das ist neu in ES6
var p = {
  [x]: 42
};

In ECMAScript 6 gibt es eine spezielle Art von Objekten, die anstelle von Strings als Eigenschaftsnamen verwendet werden können. Diese Objekte heißen Symbols und können genau wie die Strings im obrigen Beispiel benutzt werden:

var o = {};
var x = Symbol();
o[x] = 42;

var p = {
  [x]: 42
};

Symbols funktionieren auf den ersten Blick also wie Strings, haben aber mehrere entscheidende Unterschiede. So sind Symbols sind per Definition einzigartig. Code, der keinen Zugriff auf ein Symbol hat, kann die damit gesetzten Werte nicht ohne weiteres auslesen:

var o = (function(){
  var x = Symbol();  
  return {
    [x]: 42
  };
})();

// Wie soll man an den Wert kommen?

// Das funktioniert nicht, Symbols are einzigartig
var x = Symbol();
console.log(o[x]); // undefined

Symbols sind außerdem immer non-enumerable und tauchen daher nicht in for-in-Schleifen auf. Sie verweigern sich auch jedem Versuch, sie in einen String zu verwandeln um irgendwie an den „wahren Wert“ hinter einem Symbol zu kommen oder es zu klonen. Symbols selbst sind der einzig wahre Wert und sie sind per Definition einzigartig.

Symbols kann man für viele nützliche Dinge gebrauchen. Die ECMAScript-Spezifikationen nutzen Symbols extensiv für den internen Aufbau der Sprache. Was den Hausgebrauch angeht sind Symbols super, um „private“ Instanzvariablen auf Objekten unterzubringen, ohne diese selbst in Closures zu platzieren:

// Keine Chance, die 42 zu überschreiben!
var o = (function(){
  var x = Symbol();  
  return {
    [x]: 42,
    getX: function(){
      return this[x];
    }
  };
})();

Aber auch öffentliche Symbols können nützlich sein. So könnte eine Library ein öffentliches Symbol anbieten, das Nutzer der Library nutzen können, um bestimmte Funktionen gezielt zu überschreiben. Theoretisch könnte diese Rolle auch ein String übernehmen, aber diese String-Eigenschaft wäre (wenn ich explizit anders definiert) in for-in-Schleifen sichtbar und sie würde bis in alle Ewigkeit eben jenen String-Namen als Objekt-Eigenschaft belegen und ggf. so manches Problem hervorrufen – man denke nur an __proto__. Symbols sind hier die sauberere Variante.

Symbols sind freilich nicht völlig privat: mit Object.getOwnPropertySymbols() kann man sich die Liste aller Symbol-Eigenschaften auf einem Objekt ausgeben lassen und darüber iterieren:

var o = (function(){
  var x = Symbol();  
  return {
    [x]: 42,
    getX: function(){
      return this[x];
    }
  };
})();

Object.getOwnPropertySymbols(o).forEach(function(sym){
  console.log(o[sym]); // > 42
});

Dass diese Funktion existiert, ist recht sinnvoll. Wer einen komplett privaten Wert haben möchte, hat ja bereits mit Closures das passende Werkzeug an der Hand. Symbols sind geheim genug für den Alltagsgebrauch und Object.getOwnPropertySymbols() macht das Debuggen und Testen von Objekten um einiges einfacher.

Allerdings bedeutet die Existenz von Object.getOwnPropertySymbols() auch, dass es eben nicht möglich ist, vorhandene Objekt zu erweitern und dabei jede Chance auf Kollisionen oder Missbrauch auszuschließen. Zwar gibt es nun keinen String-Eigenschaftsnamen mehr, der überschrieben werden könnte, aber mit einem Extra-Symbol wird plötzlich die Iterations-Schleife über das von Object.getOwnPropertySymbols() zurückgegebene Array länger, alte oder neue Symbols stehen nicht mehr an dem Index, an dem sie vorher waren und schon kann wieder eine ganze Menge kaputtgehen.

Und so bleibt es trotz Symbols bei der JavaScript-Grundregel Nummer 1: Prototyp-Objekten, die man nicht selbst gebaut hat, darf man nicht modofizieren, weil man nicht zu 100% ausschließen kann, das die Modifikation jetzt oder in Zukunft fremden Code kaputt macht.

Laut Kompatibilitätstabelle funktionieren Symbols heutzutage in Firefox, Chrome, dem kommenden nächsten Microsoft-Browser und sind hinter einem Flag auch in Node.js verfügbar. Transpiler wie Traceur und Babel versuchen ebenfalls Symbols zu implementieren, schaffen das bisher aber nicht perfekt.

JavaScript: parseInt() vs. parseFloat()

Veröffentlicht am 9. April 2015

An den Tagen, an denen ich mich für ganz besonders lustig halte, verfasse ich manchmal Tweets wie diesen hier:

Wenn Tweets mit Witzen ein bisschen die Runde machen, wird der Tweet-Autor immer zum Empfänger zahlreicher Witz-Erklärungen. Da in diesem Fall aber keine der angebotenen Erklärungen etwas mit der Wahrheit hinter parseFloat() und parseInt() zu tun hatten, fühle ich mich genötigt eine kleine Erklärung des behandelten Phänomens nachzuschieben.

Wie parseFloat() funktioniert

Anders als man vielleicht zunächst glauben würde, haben parseFloat() und parseInt() in ihrer Funktionsweise unter der Haube nur wenig gemein. Die ECMAScript-Spezifikationen beschreiben die Funktion parseFloat() wie folgt:

The parseFloat function produces a Number value dictated by interpretation of the contents of the string argument as a decimal literal.

Der konkrete Algorithmus für die Interpretation des an parseFloat() übergebenen Strings sieht vor, dass, nachdem er um Whitespace am Anfang bereinigt wurde, der String von links nach rechts nach einem StrDecimalLiteral durchsucht wird. Nach dem ersten Zeichen, das nicht in die Definition von StrDecimalLiteral passt, wird die Suche beendet; so ergibt parseFloat(' 42.23€') die Number 42.23. Ein StrDecimalLiteral ist nichts weiter als ein bestimmter Brocken String-Syntax, bestehend aus einem StrUnsignedDecimalLiteral und einem optionalen Vorzeichen. Und da die Definition von StrUnsignedDecimalLiteral neben den Zahlen 0 bis 9, Kommata und Exponenten auch den String Infinity beinhaltet, produziert parseFloat('Infinity') die Number Infinity.

Wie parseInt() funktioniert

Die Kurzbeschreibung von parseInt() liest sich wie folgt:

The parseInt function produces an integer value dictated by interpretation of the contents of the string argument according to the specified radix.

Der Knackpunkt ist „according to the specified radix“. Grundsätzlich macht parseInt() das gleiche wie parseFloat(), nämlich einen String, der mit Zahlzeichen beginnt, ab der ersten Nicht-Zahl (im Falle von parseFloat() auch ab einem eventuellen Komma) abzuschneiden. Aber parseInt() ist in der Lage, Zahlen mit jeder Basis zwischen 2 und 36 zu verarbeiten, wozu ein zweiter Parameter angegeben werden kann. Das Ergebnis von parseInt('FF', 16) ist also 255. Wird der zweite Parameter nicht explizit angegeben, verwendet parseInt() seit ECMAScript 5 immer 10 (falls der zu parsende Input-String nicht gerade mit 0x beginnt). Beim Aufruf von parseInt("Infinity") sucht die Funktion also nach Ziffern von 0 bis 9 am Anfang des Strings (da ja Baisis 10 verwendet wird), findet keine, kann aus dem Eingabestring keine Zahl extrahieren und gibt gezwungenermaßen NaN zurück.

Ein Infinity-kompatibles parseInt()

Ein parseInt(), das mit Infinity klar kommt, ist einfach zu bauen, wenn man bereit ist sich auf die Basis 10 festzulegen. Das Problem besteht einzig darin, den Sonderfall Infinity abzufangen, bevor das eigentliche parseInt() auf den Plan tritt. Die hierfür scheinbar prädestinierte Funktion isFinite() würde allerdings auch für Eingaben wie "1a" mit false antworten – schließlich ist der String "1a" keine endliche (oder sonst irgendeine) Zahl. Deshalb sollte man den Eingabewert erst mittels parseFloat() in eine JavaScript-Number inklusive Infinity verwandeln, Unendlichkeit ausfiltern und schlussendlich das Ergebnis von parseFloat() in parseInt() hineinfüttern:

function parseIntInfinity(input){
  var number = parseFloat(input);
  if(!isFinite(number)){
    return number;
  }
  return parseInt(number, 10);
}

parseIntInfinity("1"); // > 1
parseIntInfinity("1F"); // > 1
parseIntInfinity("F1"); // > NaN
parseIntInfinity("Infinity"); // > Infinity
parseIntInfinity("-InfinityXXX"); // > -Infinity

Mit einer anderen Basis als 10 würde eine solche Funktion schon etwas schwieriger zu bauen. Je nach Basis könnte der String "Infinity" für eine ganze Reihe von Werten stehen, beginnend bei 1461559270678 (Basis 36) bis runter zu 18 (Basis 19, wo nach dem I abgeschnitten wird). Wie auch immer man Unendlichkeit repräsentieren möchte: mit demString "Infinity" geht es nicht, wenn parseInt() mitspielen soll.

Erklärbär-Termine für April, Mai und Juni 2015

Veröffentlicht am 31. März 2015

Für das nächste Quartal bietet Erklärbär-Tours zwei kleinere Workshops im Rahmen von Konferenzen und zwei große Wechtech-Schulungen an:

  • 26. - 28. Mai in München: Moderne Frontendentwicklung (HTML5, CSS3, JavaScript). HTML5 … und dann? Die Schulung „Moderne Frontendentwicklung“ ist der Nachfolger meiner klassischen HTML5-Schulung und hebt erfahrene Webentwickler auf das nächste Level. Der Kurs behandelt die seit HTML5 neu hinzugekommenen Webstandards (z.B. Web Components), bespricht Tools und Best Practices, gibt Tipps für den Einsatz neuer Features in heutigen Browsern und bietet auch einen Ausblick in die weitere Zukunft der Web-Plattform.
  • 7. Juni in Berlin: Workshop zu Web Components auf der Webinale. Das Webseiten-Modul der Zukunft ist ein selbstdefinierter HTML-Tag und dieser Workshop beantwortet hierzu alle Fragen. Wie funktionieren Web Components? Welche Tools gibt es? In welchen Browsern kann man Web Components bereits einsetzen? In einem großen Praxisteil können die Teilnehmer selbst ein paar eigene Komponenten schreiben.
  • 18. Juni in Nürnberg: Workshop zu Techniken für asynchrones JavaScript. Auf der Developer Week 2015 erkläre ich alles, was es zu asynchronem JavaScript zu wissen gibt. Angefangen von einem Blick unter die Browser-Motorhaube über Alltags-Techniken wie Callbacks und Promises geht es bis hin zu abgefahreneren Techniken wie asynchrone Funktionen und Communicating Sequencial Processes.
  • 24. - 26. Juni in München: JavaScript MasterClass. Meine aktuelle Bestseller-Schulung bringt erfahrenen Entwicklern mit gefährlichem JS-Halbwissen richtiges JavaScript bei. Vom Grundlagen-Crashkurs über OOP und funktionale Techniken bis hin zu spezielleren Themen wie ECMAScript 6, Makros und Metaprogrammierung ist alles dabei.

Termine unpassend, Orte alle zu weit weg und Programme nicht genehm? Ich komme auch gerne mit einem maßgeschneiderten Talk oder Workshop vorbei – mich kann man ganz einfach mieten!