Jan 22

Für mich persönlich stellt JavaScript seit einiger Zeit immer wieder eine große Herausforderung dar. Insbesondere seit in Titanium Appcelerator das JSCommon Framework zum Einsatz kommen darf und soll. Meine erste iPad-App soll nun endlich fertig werden und ich stand vor der Herausforderung innerhalb einer Klasse setInterval für periodische Aufgaben benutzen zu wollen. Jede Klassen-Instanz sollte natürlich seinen eigenen Timer benutzen. Hier ist meine Lösung – runtergekocht auf eine Minimal-App bestehend aus der obligatorischen app.js und dem Module processingQueue.js:

Als Screenshots:

app.js - titanium appcelerator

Die eigentliche OOP-Klasse

 

Und hier nochmal als Quelltext zum rauskopieren :-)

Die Datei app.js instanziert zwei Objekte der Klasse processingQueue

  1. // App.js
  2. var pq = require('modules/processingQueue');
  3.  
  4. Ti.API.info("Erstelle PQ1:");
  5. PQ1 = new pq.processingQueue(200, "-Eins");
  6. Ti.API.info("Erstelle PQ2:");
  7. PQ2 = new pq.processingQueue(500, "#Zwei");

 

Das JSCommon Module processingQueue implementiert die gleichnamig Klasse, die ein Timer-Objekt initialisiert:

  1. // JavaScript Object Class processin Queue using JSCommon Modules
  2.  
  3. // Constructor:
  4. function processingQueue(timerInterval, theName) {
  5. this.myName = theName;
  6.  
  7. if(!(this.queueTimerHandle)) {
  8. var holder = this;
  9. this.queueTimerHandle = setInterval( function() {
  10. holder.applicationQueueProcessing(holder);
  11. }, timerInterval);
  12. }
  13. };
  14.  
  15. // This function is called timer based
  16. processingQueue.prototype.applicationQueueProcessing = function(me) {
  17. Ti.API.info("Processing Queue Name:" + me.myName);
  18. }
  19.  
  20. exports.processingQueue = processingQueue;

Ich hoffes es hilft jemandem…

Oct 04

Regelmäßig sieht man in den letzten Monaten einschlägige Fachzeitschriften, die Artikel über Appcelerator bringen – teilweise sogar auf der Titelseite. Dort wird dann auf wenigen Seiten beschrieben, wie einfach es doch sei mit diesem Tool Crossplattform-Entwicklung für mobile Endgeräte (vornehmlich solche mit iOS und Android) zu betreiben.

Nachdem ich nun einige Wochen mit der Appcelerator-gestützten Entwicklung einer iPad-App verbracht habe, kann ich nur sagen: Es stimmt – ist aber nur die halbe Wahrheit. Denn so lange man nur nette kleine Demo-Projekte umsetzt ist alles “Heile”. Natürlich vermisst man hier auch schon Einiges. So ist beispielsweise die Dokumentation eine einzige Katastrophe. Aber da hilft einem die rege Community gerne weiter. Und ein Workaround lässt sich auch oft genug finden.

Sehr besorgt wird man dann, wenn man sich anschaut wie lange manche Bugs schon bekannt sind und nicht gefixt werden. Im sogenannten “Forum” von Titanium werden solche Probleme von offizieller Seite zumeist auch ignoriert. Man kann zwar im Bug-Tracking-System ein Ticket eröffnen. Aber mangels einer öffentlichen Roadmap und Feedback, ist danach völlig unklar was mit diesem Bug geschieht und wann man mit einer Auslieferung des Bugfix rechnen darf.

So kann man natürlich keine kommerzielle Produkte erstellen bei denen der Kunde mit einer Deadline winkt. Folgerichtig, gibt es auch immer mehr Entwickler, die Appcelerator wieder den Rücken kehren und zurück gehen zur “echten” nativen Entwicklung mit Xcode oder Java.

Eine aktuelle und sehr interessante Diskussion zu dem Thema gibt es in Andrea Dalleras Blogbeitrag “Why you should stay away from Appcelerator’s Titanium”. Natürlich gibt es dort auch positive Stimmen, die auf die Vorteile von Appcelerator verweisen (zu recht!). Die Mehrzahl der Kommentatoren unterstützt aber sehr Kenntnisreich die Aussage von Andreas Beitrag.

Wie häufig in diesen Fällen zu beobachten, wird gerne auf alternative Programmiertechniken verwiesen, die die bekannten Memory-Probleme umgehen sollen. Sicher werde ich diese ausprobieren. Frustrierend und verwunderlich nur, dass die offiziellen Best-Practice-Beispiele, andere Vorgehensweisen propagieren.

Ich werde jetzt ein wenig nostalgisch, wenn ich an dieser Stelle noch den Vergleich zu anderen Cross-Plattform-Tools ziehe. Allen voran Flash und vor allem Director (früher von Macromedia – heute auch bei Adobe zu einem Dornröschenschlaf verdammt.) Diese Tools hatten auch immer ihre Macken und Probleme. Aber so heftig wie bei Appcelerator war es nie!
(Nach wie vor bleibt es mir ja unverständlich, warum Adobe auf Flash setzt als Basis für seine Mobile-Crossplattform-Strategie) statt auf das wesentlich bessere Director-Tool. Aber hier mag meine Wehmut die Objektivität trüben…

Quintessenz: Titanium Appcelerator ist derzeit noch instabil und kann für die produktive App-Entwicklung nur mit großer Vorsicht verwendet werden. Die Unternehmensstrategie scheint sehr von den Investoren getrieben zu sein, die es (bisher) besser fanden von neuen Features zu lesen als von stabilen Werkzeugen. Mal sehen, ob sich dies bald ändert, wenn immer mehr Entwickler Ihren Frust in Blogbeiträgen kund tun…

Why you should stay away from Appcelerator’s Titanium

Jun 12

Durch einen Kundenauftrag (Entwicklung einer spezifischen Bildverarbeitungssoftware ) wurde ich vor einigen Wochen “genötigt” mich mit der Programmierung auf dem Mac (OS X – 10.6) anzufreunden. Bisher hatte ich mit dem Mac eher etwas distanziertere Erfahrungen noch aus Zeiten der Cross-Plattform CD-ROM-Entwicklung mit Macromedia Director. Aber auch bei aktuellen Webprojekten gilt es natürlich die Mac-User zu berücksichtigen :-) (Und ich möchte hier nicht verschweigen, dass ich meinen APPLE II geliebt habe!)

Also habe ich mir kurzerhand einen Mac angeschafft, Xcode 4 besorgt und losgelegt.

Das erste Hinderniss war, dass es bis dato nur Literatur zu Xcode 3 gibt. Die Oberfläche (und die automatische Codegenerierung) unterscheidet sich an einigen Punkten stark. Also habe ich sowohl mit Fachbüchern (meine persönlichen Buchempfehlungen finden sich ganz unten) als auch mit der Apple-Doku hantiert. Dazu bin ich dankbarer Leser diverser Foren und Mailing-Listen geworden.

Die Besonderheiten von Objective-C selbst (z.B. Methodenaufrufe über die Eckige-Klammer-Schreibweise)  konnten mich nicht so richtig schocken. Wer Lingo und Actionscript 1 gesehen hat, ist “lustige” Sprachen gewohnt ;-)

Anfangs war ich schier erschlagen von den unendlichen Weiten der OS X-API. Es macht das Programmieren eben nicht einfacher, wenn man erst eine halbe Stunde lang Tutorials durcharbeiten muss um rauszufinden, wie man möglichst einfach zwei NSStrings miteinander verkettet.
Das Gefühl, dass alles sehr mühsam und extrem umständlich ist, ist leider bis heute geblieben. Natürlich lese ich auch die Objective-C Propheten, die die Mächtigkeit und Klarheit der API loben.

Ich bin mir sicher, dass man mit Xcode ein tooles Entwicklungstool bekommt (dazu noch fast umsonst). Aber die Lernkurve ist doch sehr lang.
Und für jemanden, bei dem Zeit rar ist (dürfte wohl auf die meisten Freelancer zutreffen), ist diese Lernkurve ein echter Feierabendkiller. Dabei bin ich sogar hochmotiviert und total begeistern mit welchem Speed meine Grafikroutinen dank C-Power rennen.

Aber ich sehe auch einen Bruch in der “Klarheit” von Objective-C. Die Low-Level-Routinen zur Bildmanipulationen “ticken” wieder anders als die High-Level-Klassen. Und der Aufwand um ein simples Bild auf die Benutzeroberfläche zu bringen, ist eigentlich eine Zumutung.
Sehr deutlich wurde mir dies, als ich heute nach Alternativen recherchiert habe und über das Corona SDK stolperte. Dort gibt es einen sehr schönen Code-Vergleich zwischen Corona und Objective-C – der Corona-Code zur Anzeige eines Bild umfasst eine Zeile. Das gleiche Vorhaben in Objective-C benötigt über 200 Zeilen Code.
Sicher – der Vergleich ist ein wenig “aufgebauscht”. Aber er gibt mein Gefühl gut wieder.

corona SDK versus Objective-C - Codevergleich zur Bildanzeige

Und bei all dem Aufwand gilt es noch zu beachten, dass man mit Objective-C eben “nur” für OS X und iOS entwickeln kann. Andere Plattformen bleiben außen vor. Den Luxus kann man sich eigentlich nur leisten, wenn man genug Kunden hat, die genau nur diese Plattformen betrachten. Dann mag sich die Kraft von Xcode und Objective-C voll entfalten können und der Entwicklungsaufwand wird durch absolut native Anwendungen und Apps belohnt. Power Pur!

Ich werde wohl mein Kundenprojekt mit Objective-C zu Ende führen und mir dann mal Corona anschauen :-)
Meine Buchempfehlungen für den Einstieg in die Programmierung unter OS X – man sollte aber noch die aktualisierte Version für Xcode 4 abwarten!

Cocoa Programming for Mac OS X
Cocoa-Programmierung: Der schnelle Einstieg für Entwickler

Oct 09

Bereits seit mehreren Jahren setze ich nun die Kombination Time Machine und Time Capsule erfolgreich und fehlerfrei ein. Bei jedem Backup wurden bisher nur geänderte Dateien erneut gesichert, weshalb die Sicherung von jeweils nur wenigen 100 MB immer recht schnell erledigt war. Plötzlich wollte Time Machine bei jedem Backup mehr als 100 GB sichern und funktionierte somit nicht mehr wie gewünscht bzw. erwartet.

Abhilfe schaffte bei mir das Zurücksetzen der Einstellungen – hierfür bin ich wie folgt vorgegangen:

  1. In den “Systemeinstellungen” von “Time Machine” unter “Volume auswählen” “Ohne” mit “Backup stoppen” auswählen
  2. Löschen der Datei “com.apple.TimeMachine.xxx.plist” unter “Macintosh HD > Benutzer > benutzername > Library > Preferences > ByHost” (“xxx” bzw. “benutzername” sind systemspezifisch) mittels Finder
  3. Bereinigen oder löschen (beim Bereinigen/Löschen können Voreinstellungen von z.B. Parallels verloren gehen, deshalb sollte man diesen Schritt nur ausführen, wenn man weiß, was man macht) der Datei “com.apple.TimeMachine.plist” unter “Macintosh HD > Library > Preferences”
  4. Neustart des Computers
  5. In den “Systemeinstellungen” von “Time Machine” unter “Volume auswählen” wieder das gewünschte Medium mit “Für Backup verwenden” auswählen
Aug 24

Um Git auf Mac OS X zu installieren lädt man sich den passenden Installer und führt die Installation durch. Abschließend muss man zur PATH-Variable in ~/.profile mittels Konsole noch den Pfad von Git (/usr/local/git/bin) hinzufügen. Nach einem Neustart der Konsole steht der Verwendung von Git nichts mehr Wege.

Jul 29

Wenn man Änderungen nicht nur von einer Datei sondern von vielen Dateien und möglicherweise auch mit komplexer Datei- bzw. Ordnerstruktur feststellen möchte um daraus eine Patch-Datei zu erzeugen, so muss man diff rekursiv anwenden um nicht jede geänderte Datei einzeln patchen zu müssen. Hier erkläre ich die übliche – sozusagen zum Standard etablierte – Vorgehensweise um dieses Ziel zu erreichen:

Zuerst vergleicht man also den Ordner mit den Originaldateien rekursiv mit der geänderten Version:

diff -urN original changed > /pfad/zu/changes.patch

Optionen:

-u  -U NUM  --unified[=NUM]  Output NUM (default 3) lines of unified context.
-r  --recursive  Recursively compare any subdirectories found.
-N  --new-file  Treat absent files as empty.

Anschließend kann man auf anderen Installationen die Patch-Datei anwenden (zuerst muss in das Verzeichnis mit den Originaldateien wechseln):

patch -p1 < /pfad/zu/changes.patch

Optionen:

-p NUM  --strip=NUM  Strip NUM leading components from file names.

Da die Patch-Datei im Verzeichnis der Originaldateien aufgerufen wird, mit diff allerdings die übergeordneten Ordner verglichen wurden, muss der Ordnername entfernt werden, dies geschieht mit der Option “-p1″.

Jul 13

Wenn in einem Ordner eine große Anzahl von Dateien liegt, verweigern cp, mv usw. ihren Dienst mit der Meldung:

$ mv *.png ../target/
bash: /bin/mv: Argument list too long

Abhilfe schafft find mit dem Parameter exec:

find . -name "*.png" -exec mv {} ../target/ \;

Der Nachteil der find-Methode mit dem Parameter exec ist, dass für jede Datei der Befehl in exec ausgeführt wird. Performanter ist hingegen xargs, das die übergebene Liste in kleinere Listen aufteilt, sodass diese dann von cp, mv, etc. noch verarbeitet werden können:

find . -name "*.png" | xargs -0 mv -t ../target/
Apr 13

Path Finder von Cocoatech ist ein großartiger Ersatz für den in Mac OS X standardmäßig integrierten Finder. Dank Tabs, Stapel und vielen weiteren hilfreichen und umfangreichen Features erlaubt dieser ein schnelleres, einfacheres und angenehmeres Arbeiten. Ein Großteil der Features wird in einem Screencast vorgestellt, die Möglichkeiten sind aber beinahe unerschöpflich.