Web & smart device developer 2017

Page 1

web & mobile

DEVELOPER

Stylesheets optimal organisieren S. 42

Das WebSocket API

im Detail

S. 58

web & mobile

DevOps in der Praxis S. 96

webundmobile.de

DEVELOPER Die Top-Features von Java 9 So nutzen Sie die zentralen Verbesserungen von Java 9 Eine detaillierte Darstellung der neuen Sprachelemente S. 18

Ausgabe

Framework Laravel

Deutschland

14,95 EUR

3/17 CH: 29,90 CHF A, B, NL, L: 16,45 EUR

Carsten Möhrke bietet eine Einführung in das PHP-Framework Laravel S. 87 4 198255 014951

03


Jetzt kostenlos testen: www.internetworld.de/probelesen

Die 14-tägige Fachzeitschrift fßr Digital Professionals! E-Commerce I Online-Marketing I Technik Sichern Sie sich jetzt 4 kostenlose Ausgaben der INTERNET WORLD Business inklusive Business-Newsletter.


EDITORIaL

3/2017

Java 9 im Blickpunkt Java 9 bietet weniger neue Sprachmittel, dafür aber zahlreiche zentrale Verbesserungen und hilfreiche Ergänzungen. Das Motto lautet: Modularität, Portabilität und Produktivität.

J

ava als Plattform und Sprache hat inzwischen mehr als zwei Jahrzehnte auf dem Buckel und kann auf einen nachhaltigen Erfolg zurückblicken. In zahlreichen Marktanalysen zur Verbreitung und Popularität von Programmiersprachen nimmt Java immer noch eine Position an der Spitze ein. Frank Simon hat die neue Version 9 der beliebten Programmiersprache in einem umfangreichen Schwerpunkt ab Seite 18 unter die Lupe genommen.

»Modularität, Portabilität und Produktivität lautet das Motto von Java 9.« Continuous Integration kann bei Softwareprojekten dabei helfen, die Qualität der Software zu steigern: Werden Änderungen in das jeweilige Versionskontrollsystem (Git, Subversion et cetera) committet, so führt das CI-System (Continuous Integration System) automatisch bestimmte Prozesse aus, beispielsweise das Kompilieren von Quelltext, Unit- oder Integrationstests, Tests bezüglich der Code-Qualität, Ermittlung der Testabdeckung oder Ähnliches. Philip Ackermann befasst sich in einem Artikel ab Seite 32 mit diesem Thema. Ursprünglich wurde das PHP-Framework Laravel im Jahr 2011 als eine Alternative zu CodeIgniter entwickelt, inzwischen beschreitet es aber eigene Wege. Die aktuelle Version 5.3 benötigt mindestens PHP 5.6.4 und versteht sich auch gut mit PHP 7. Carsten Möhrke stellt das PHP-Framework in seiner Artikelserie ab Seite 87 vor. Erst durch einen gezielten Einsatz von passenden Bildern wird die Aufmerksamkeit des Betrachters erreicht. Dabei sollten verschiedene Aspekte berücksichtigt werden. So sollte zunächst die Bildfläche so aufgeteilt sein, dass die grundsätzliche Linien-und Flächenführung die Bildaussage unterstützt. Hinzu kommen Überlegungen zur Zielgruppe und welche Grundvoraussetzungen diese zum Thema mitbringt. Davon abhängig ist dann auch der Einsatz von visuellen Schlüsselreizen. Katharina Sckommodau stellt das Prinzip in einem Artikel ab Seite 114 vor.

Tam Hanna zeigt, wie das Framework Mercury JavaScript-Entwicklern die Arbeit erleichtert (S. 48)

Philip Ackermann erläutert, wie man das WebSocket API optimal einsetzen kann (S. 58)

Olena Bochkor erklärt, wie man die Zufriedenheit von Kunden mit digitalen Produkten misst (S. 128) Ihr Max Bold chefredakteur@maxbold.de

www.webundmobile.de 3.2017

3


InHaLT

3/2017

I N H A LT Update Connect 2016 SQL Server für Linux und Visual Studio für Mac Browser-Entwicklung Mozilla baut Multi-Prozess-Technologie in Firefox aus

6

10

Feature ausblick auf Version 9 von Java Die Version 9 von Java bietet weniger neue Sprachmittel, dafür aber zahlreiche zentrale Verbesserungen und hilfreiche Ergänzungen 18

HTML, CSS & JavaScript Continuous Integration mit Jenkins für node.js-Projekte Dieser Artikel zeigt, wie sich das CI-System Jenkins für Node.js-Projekte einsetzen lässt

Java 9 bietet weniger neue Sprachmittel, dafür aber zahlreiche zentrale Verbesserungen und hilfreiche Ergänzungen 18 32

Stylesheets optimal organisieren BEM, OOCSS, SUIT CSS und Co. bieten Strategien für wiederverwendbare Stylesheets 42 JavaScript-Framework Mercury Mit Mercury tritt ein neues JavaScript-Framework an, das Entwicklern die Programmierung von Frontend-Applikationen erleichtern möchte 48 WebSocket aPI Das WebSocket API ermöglicht die bidirektionale Kommunikation zwischen Client und Server 58

Mobile Development add-ins für iOS iMessage programmieren Mit iOS 10 können erstmals Add-ins für die iMessage App entwickelt werden

Eine wichtige Komponente von SMACSS ist die Kategorisierung von CSS-Regeln 42

64

Experten in dieser ausgabe

Exponent – Laufzeitumgebung für native apps Seit geraumer Zeit gibt es ein Spannungsfeld zwischen Webanwendungen und nativen Apps

68

Swift: Properties im Detail Properties sind ein essenzielles Sprachmerkmal von Swift und verfügen über einige Besonderheiten

76

4

Dr. Florence Maurice zeigt, wie man Stylesheets optimal organisiert 42

Johann Baumeister stellt den SQL Server 2016 von Microsoft vor 108

3.2017 www.webundmobile.de


3/2017

InHaLT

Backend Properties sind ein grundlegender Bestandteil von Apples Programmiersprache Swift

PHP-Framework Laravel Der Artikel liefert eine kompakte Einführung in das PHP-Framework Laravel 87

76

DevOps in der Praxis (Teil 2) Microservices und Container-Plattformen haben die Software-Entwicklung um Fähigkeiten zur kontinuierlichen Bereitstellung erweitert

Bild: Amazon

SQL Server 2016 (Teil 1) Nach nur zwei Jahren erneuert Microsoft den SQL Server zur Version 2016

Amazon Pinpoint identifiziert potenzielle Stolperfallen der Usability mobiler Apps

96

96

108

Beyond Dev Grafik für Entwickler Ob nonverbale Kommunikation oder Schlüsselreiz – Bilder, die Geschichten erzählen, sind nicht nur in der Werbung wichtig

114

Smart-TV-applikationen für Fire TV Fire TV von Amazon möchte existierende Fernsehgeräte in Android-basierte Smart TVs umwandeln

118

Per net Promoter Score die Zufriedenheit der Kunden mit digitalen Produkten messen Die beste Werbung geht von zufriedenen Kunden aus. Dies ist bei digitalen Produkten nicht anders als bei herkömmlichen Konsumgütern und Dienstleistungen 128 neue Jobs im Zeichen der Digitalisierung Im Zuge der Digitalisierung sind zahlreiche neue Berufsbilder entstanden: Gefragt sind dabei vor allem Digital-Profis mit wirtschaftlichem Denken 134

Ein in Relation zum Körper großer Kopf sowie große Augen und eine kleine Nase lösen unseren Beschützerinstinkt aus 114

Standards Editorial

Jetzt abonnieren Sichern Sie sich jetzt die web & mobile developer im Jahresabo und profitieren Sie von exklusiven Services und Angeboten für Abonnenten. http://probeabo.webundmobile.de

www.webundmobile.de 3.2017

3

Online-Recht

138

Stellenmarkt für Entwickler

140

Impressum

143

Dienstleisterverzeichnis

145

Vorschau

146

5


aKTUELL

News

NEWS & TRENDS AKTUELLE NEWS FÜR ENTWICKLER

Im Rahmen der Entwicklerkonferenz Connect hat Microsoft neue Produkte für Linux und macOS vorgestellt

IT-Trends zung der CIOs die IT-Budgets bei knapp über der Hälfte dieser Unternehmen weiter steigen könnten. Die Situation bei Energieversorgern ist sehr stabil: Es wird kaum gekürzt, aber auch wenig erhöht. »CIOs sind stärker denn je gefordert, die Digitalisierung des Unternehmens auszubauen. Ein großer Teil des IT-Budgets fließt aber in die Aufrechterhaltung des Tagesgeschäfts. Der Rest reicht nicht aus, um die Neugestaltung des Geschäftsmodells

Connect 2016

SQL Server für Linux und Visual Studio für Mac

Quelle: www.de.capgemini.com

Budget-Prognosen für 2017 Im kommenden Jahr erhöhen voraussichtlich 44,4 Prozent der Unternehmen in der DACH-Region die IT-Budgets, rund 11 Prozent sogar im zweistelligen Bereich. Kürzen müssen 2017 nur noch 16,1 Prozent der CIOs – im Jahr zuvor waren es 21,3 Prozent. Das zeigt ein Vorab-Ergebnis der jährlich im September und Oktober von Capgemini durchgeführten IT-TrendsStudie. Die Gesamt-Ergebnisse werden im Februar 2017 veröffentlicht.

Die Budget-Prognosen im IT-Bereich für 2017 sind erneut optimistisch Der Handel und die Logistikbranche werden 2017 deutlich mehr Geld für ITProjekte ausgeben. Banken und Versicherungen investieren weiterhin auf hohem Niveau. So auch die Industrie, die angesichts der Vorhaben für Industrie 4.0 die IT-Budgets bereits deutlich aufgestockt hatte. Diesen Kurs wird sie, wenn auch etwas moderater, in den kommenden Jahren fortsetzen, sodass laut Einschät-

6

durch IT-Innovation zu unterstützen, weshalb solche Ausgaben zunehmend von den Fachabteilungen übernommen werden«, erklärt Dr. Uwe Dumslaff, Chief Technology Officer bei Capgemini in Deutschland, die Ergebnisse. Die Ausgaben für Updates, Aktualisierungen und Erweiterungen steigen das dritte Jahr in Folge auf jetzt 24,4 Prozent des gesamten ITBudgets. www.de.capgemini.com

Microsoft hat auf der virtuellen Konferenz neue Dienste für die Entwicklung von Cross-Platform-Anwendungen für Windows, iOS und Android präsentiert – auch auf der Basis von Linux: Vorgestellt wurde eine öffentliche Vorschauversion der Linux-Version von SQL Server, die neben Windows-Umgebungen auch Linux-basierte Docker-Container unterstützen soll. Sodann die Preview des Azure App Services für Linux – ebenfalls mit Unterstützung von Containertechnologie und nativem Linux-Support für Node.js und PHP-Stacks. Und die Preview von Visual Studio for Mac. Mit diesem Produkt entwickelt Microsoft das auf mobile Anwendungen spezialisierte Xamarin Studio zu einem vollwertigen Entwicklungswerkzeug für .NET und C# weiter und öffnet die Plattform gleichzeitig für das Mac-Betriebssystem. Im Kern handelt es sich bei Visual Studio for Mac um die Komplementärversion der Win-

dows-Ausgabe. Visual Studio Code ist als Editor integriert. Zudem hat Microsoft die Bedienoberfläche an das AppleBetriebssystem angepasst. Im Rahmen der Konferenz hat Microsoft auch neue Partnerschaften bekanntgegeben. Das Unternehmen tritt der gemeinnützigen Linux Foundation als Platinum-Mitglied bei, um die Zusammenarbeit mit der Open-Source-Community zu intensivieren. Außerdem konnte es Google als Mitglied der unabhängigen .NET-Foundation begrüßen und eine Kooperation mit Samsung bekannt geben, um .NET-Entwickler bei der Entwicklung von Apps für die weltweit mehr als 50 Millionen Samsung-TVs, -Wearables, -Smartphones und -IoT-Geräte zu unterstützen. www.microsoft.com

neuer Git-Client

Tower für Windows 1.0 Nach einer mehrmonatigen Beta-Phase, in der mehrere Tausend Nutzer die Anwendung testen konnten, ist jetzt die Tower-Version 1.0 verfügbar. Um

3.2017 www.webundmobile.de


News

aKTUELL

Zahl des Monats Laut einer Umfrage unter Arbeitnehmern zu ihrem digitalen Arbeitsplatz bemängeln knapp 60 Prozent einen schlechten Datenzugriff von unterwegs, 58 Prozent kritisieren einen zu langsamen IT-Störungsdienst und 55 Prozent erleben die IT der eigenen Firma als zu unflexibel. Quelle: CSC

Open-Data-Gesetz

Der Git-Client Tower ist in der Mac-Version bereits häufig im Einsatz ein Höchstmaß an Performance und Stabilität zu erreichen, wurde die Windows-Version komplett mit nativen Technologien entwickelt. Die Software unterstützt alle Git-Hosting-Plattformen und bietet eine erweiterte Integration für Dienste wie GitHub, Bitbucket, Visual Studio, Perforce, GitLab und Beanstalk. Im Gegensatz zu anderen GitTools setzt Tower weder einen Online-Account noch ein monatliches Abo voraus. Der Client kann für einen Einmalbetrag erworben werden. »Unser wichtigstes Ziel ist es, unseren Nutzern zu helfen, produktiver zu sein. Tower erleichtert nicht nur die Arbeit mit Git, sondern hilft letztlich dabei, besseren Code zu schreiben«, so FournovaCMO Julian Rothkamp. www.git-tower.com

Oracle

Unterstützung der Informatikausbildung in der EU Oracle will im Rahmen eines Dreijahresprogramms insgesamt 1,4 Milliarden US-Dollar in Direkt- und Sachleistungen zur

www.webundmobile.de 3.2017

Unterstützung der InformatikAusbildung in allen Mitgliedsstaaten der Europäischen Union (EU) zur Verfügung stellen. Fast 1000 Bildungseinrichtungen in der EU arbeiten derzeit mit der Oracle Academy zusammen, dem philanthropischen Flagship-Bildungsprogramm von Oracle, das nahezu 3,1 Millionen Studierenden in 110 Ländern eine Informatikausbildung ermöglicht. Im Rahmen der Ankündigung plant die Oracle Akademie, in den kommenden drei Jahren 1000 zusätzliche EU-Pädagogen in CS-, Java- und Database-Anweisungen auszubilden und weitere Studierende in 1000 Bildungseinrichtungen in der EU zu erreichen. »Wir bei Oracle sind stolz, dass wir Studierende aus allen Teilen der Welt für Informatik inspirieren und motivieren können«, erklärte Alison Derbenwick Miller, Vice President der Oracle Academy. »Am Anfang dieses Jahres ist Oracle nennenswerte Verpflichtungen in Zusammenhang mit den Initiativen CS for All und Let Girls Learn des Weißen Hauses ▶ eingegangen. Die heutige

Große Chance auf Innovationen und Wachstum Das Bundesinnenministerium tieren, Unternehmen können hat einen ersten Entwurf für im Umfeld der digitalen ein Open-Data-Gesetz vorgeTransformation neue Wachslegt. Es besagt, dass Behörden tumsfelder erschließen und Daten offen, kostenfrei und die Verwaltung wird auf Basis unter freier Lizenz verfügbar besserer Services und aufbemachen sollen. Das würde reiteter Informationen effizineue Produkte und Dienstenter«, sagt Felix Zimmerleistungen möglich machen. mann, Bereichsleiter Public Mit dem digitalen Staat Sector beim Bitkom. Für die erhalten Unternehmen die Wirtschaft sind vom OpenChance auf mehr InnovatioData-Gesetz erhebliche ponen und zusätzliches Wachssitive Effekte zu erwarten. tum: Der Digitalverband BitDas Innenministerium geht kom begrüßt die Pläne des für die kommenden zehn Bundesinnenministeriums, Jahre von einem volkswirteine Rechtsgrundlage für schaftlichen Potenzial in Open Data zu schaffen. Höhe von bis zu 130 MilliarDaten der Bundesverwalden Euro aus. Nach dem aktung sollen demnach stantuellen Gesetzentwurf werdardmäßig offen, kostenlosi den allerdings nicht alle Daund unter freier Lizenz verten der öffentlichen Hand Daten von Behörden sollen künftig offen, kostenlos und unter freier Lizenz verfügbar sein

Quelle: www.opengovpartnership.org

fügbar sein. Dafür soll das E-Government-Gesetz geändert werden. Das sieht ein aktueller Entwurf des Bundesinnenministers vor. Das Gesetz soll im kommenden Jahr verabschiedet werden. »Das Open-Data-Gesetz ermöglicht neue Produkte und Dienstleistungen. Bürger werden unmittelbar von neuen Apps und Services profi-

zugänglich gemacht. So sind viele Ausnahmen vorgesehen, wann Behörden Daten nicht veröffentlichen müssen – das ist etwa bei Informationen der Fall, die den Datenschutz berühren oder die sicherheitsrelevant sind. Zudem soll es keinen einklagbaren Rechtsanspruch geben. http://opengovpartner ship.org

7


aKTUELL

News

Smarte Unterhaltungselektronik besonders gefragt

Foto: Shutterstock/ Antun Hirsman

Der Markt für sogenannte Smart-Home-Lösungen in Deutschland entwickelte sich laut aktuellen Zahlen aus dem GfK Handelspanel 2016 in Richtung Massenmarkt. Insgesamt stieg der Umsatz in den ersten zehn Monaten des Jahres 2016 um 10 Prozent auf 3,1 Milliarden Euro. Neue Smart-Home-Lösungen von verschiedenen Herstellern unterschiedlichs-

schen Smart-Home-Sensoren und dem Internetrouter. Auch das Umsatzvolumen vernetzter Produkte im Bereich der Haushaltsgroßgeräte hat sich im Vergleich zum Vorjahr auf 145 Millionen Euro verdoppelt. Besonders beliebt bei den Verbrauchern sind Waschmaschinen, die sich vernetzt steuern lassen. Ähnlich verhält sich der Markt für intelligente Haushaltskleingeräte. Das Umsatzvolumen für vernetzte Produkte in diesem Bereich hat sich im Vorjahresvergleich ebenfalls auf 122 Millionen Euro verdoppelt. Vor allem intelligente Lösungen im Bereich der Staubsauger und Espressovollautomaten verzeichneten einen erheblichen Umsatzanstieg auf 9 beziehungsweise 26 Millionen Euro. Auch die klassische Heimautomatisierung mit dem Segment Automation & Security schließt sich dem dynamischen Wachstum der zuvor genannten Warengruppen an. Nach den Warengruppen Smart Entertainment und Communication & Control Devices liegt das Segment mit 0,7 Millionen verkauften Geräten auf Platz 3. Das entspricht im Vergleich zum Vorjahr einem Absatzwachstum von 67 Prozent. Insbesondere das Umsatzwachstum in den Produktkategorien intelligenter Visual Cams beziehungsweise Überwachungskameras sowie LED-Lampen spiegelt die positive Entwicklung wider. Das gesamte Umsatzvolumen in den genannten Produktkategorien beträgt 71 Millionen Euro beziehungsweise 8,6 Millionen Euro. www.gfk.com/de

ter Branchen geben dem Markt in Deutschland Rückenwind. Mit 4,1 Millionen verkauften smarten Produkten im Bereich Entertainment gehört das Segment der vernetzten Unterhaltungselektronik zu den verkaufsstärksten Kategorien. Das Wachstum in diesem Bereich fällt jedoch im Vergleich zum Vorjahr geringer aus. Diese Entwicklung trägt zu einem moderaten Umsatzwachstum im Smart Home Markt von insgesamt 10 Prozent bei. Am zweithäufigsten wurden im Jahr 2016 SmartHome-Lösungen im Bereich Communication & Control Devices verkauft (1,2 Millionen Geräte). Dabei handelt es sich hauptsächlich um smarte Steckdosen sowie Gateways und Smart-HomeSteuerungsboxen. Diese fungieren als Transmitter zwi-

8

Quelle: Oracle

Smart Home

Das philanthropische Flagship-Bildungsprogramm von Oracle, die Oracle Academy, unterstützt weltweit die Ausbildung im Bereich Informatik Ankündigung untermauert die Beibehaltung unserer Dynamik bei weltweiter digitaler Fortbildung und zunehmender Diversität auf den technischen Gebieten.« www.oracle.com

Konzern-Websites

81 Prozent haben SSL-Zertifikate Die Unternehmensberatung Absolit hat die 500 umsatzstärksten deutschen Unternehmen auf 17 Variablen analysiert. Alle haben eine Website und 81 Prozent auch das dafür erforderliche Sicherheits-Zertifikat SSL (Secure Sockets Layer). Grob fahrlässig ist jedoch, dass nur 42 Prozent der Unterneh-

Die Studie untersucht die Digital-Marketing-Aktivitäten der 500 umsatzstärksten deutschen Unternehmen

men diese Technologie auch einsetzen. Wirklich wichtig wird die Verschlüsselung, wenn Kreditkartendaten oder persönliche Informationen über das Web übertragen werden. Nur 39 Prozent bieten eine verschlüsselte Übertragung persönlicher Daten an. Auch die eigene Domain wird mangelhaft gesichert. Spammer missbrauchen oft die Domain bekannter Unternehmen als Absender. Dieser Markendiebstahl durch Fälschen der E-Mail-Absenderadresse kann mit einen SPF-Eintrag (Sender Policy Framework) verhindert werden. Leider haben nur 48 Prozent einen solchen Domain-Schutz. Nur 70 Prozent der Konzerne nutzen ihre Website aktiv zur Neukundengewinnung. Im Mittel haben die Webseiten der Top-500-Unternehmen 40.000 Besucher im Monat. Hier gibt es jedoch starke Branchenunterschiede: Händler haben bis zwei Millionen Besucher und betreiben Leadgenerierung. Banken und Versicherungen haben um die 100.000 Besucher und verzichten zum Teil auf Neukunden. B2B-Unternehmen liegen knapp über zehntausend Besuchern. Eine kostenlose, 38-seitige Kurzversion der Studie kann von der Website des Unternehmens heruntergeladen werden. www.top500-studie.de

3.2017 www.webundmobile.de


Jetzt kostenlos testen!

2x

gratis!

Praxiswissen fĂźr Entwickler! Testen Sie jetzt 2 kostenlose Ausgaben und erhalten Sie exklusiven Zugang zu unserem Archiv.

webundmobile.de/probelesen


aKTUELL

News

Browser-Entwicklung

Logistikbranche

Mozilla baut MultiProzess-Technologie in Firefox aus

Newcomer vielen Logistikern heute noch nicht bekannt sind, verändern sie die Branche bereits mit erheblichen finanziellen Mitteln. Der Analyse der Managementberatung Oliver Wyman zufolge beliefen sich allein die öffentlich bekannten Finanzierungsrunden von LogistikStart-ups in den letzten zehn Jahren auf fast elf Milliarden Euro. Im Schnitt wird alle fünf Tage ein neues LogistikStart-up gegründet. Joris D’Incà, Partner und Logistikexperte bei Oliver Wyman: »Innovative Start-ups sind dabei, das klassische Speditionsgeschäft komplett zu digitalisieren. Sie fragmentieren die bisherigen Supply Chains und revolutionieren durch die Kombination einer bisher nicht gekannten Menge an Daten die Effizienz und Transparenz des Transportgeschäfts. Wenn die etablierten Anbieter nicht rechtzeitig auf die digitalen Geschäftsmodelle reagieren, können die agilen Start-ups schon bald zu einer realistischen Gefahr werden.« www.oliverwyman.com

Mozilla hatte die Multi-Prozess-Technologie erstmals mit der Firefox-Version 48 für einige Nutzer ausgerollt, die keine Browser-Erweiterungen verwenden. Dabei werden Rendering-Prozesse separiert, um die Stabilität und Sicherheit des

Die neue Multi-ProzessTechnologie in Mozilla Firefox soll den Browser stabiler und responsiver machen

www.oliverwyman.com

analyse zur Digitalisierung im Speditionsgeschäft Die Logistikbranche steht vor weitreichenden Veränderungen durch die Digitalisierung des kompletten Speditionsgeschäfts. Ausgerechnet die global führenden deutschen Unternehmen gehen jedoch die Aufgabenstellungen der digitalen Transformation eher zögerlich an. Zu dieser Einschätzung kommt die Managementberatung Oliver Wyman in einer internationalen Marktanalyse: Um langfristig wettbewerbsfähig zu bleiben, sollten die etablierten Logistikdienstleister weitaus stärker als bisher die Zusammenarbeit mit innovativen Startups ihrer Branche suchen. Sie heißen Flexport, UShip, Uber Freight oder Freighthub und sind dabei, die Logistiklandschaft zu revolutionieren. Wurden in den vergangenen Jahren Milliardenbeträge hauptsächlich in Startups aus dem Umfeld der Personenmobilität wie Uber, BlaBlaCar oder Flixbus investiert, steht nun der Logistiksektor auf dem Plan der Investoren. Auch wenn die

Der Großteil der Logistik-Start-ups operiert in Feldern, die skalierbare Plattformen ermöglichen und geringe Fixkosten erfordern

10

Browsers zu erhöhen. Kommt es etwa zu Fehlern beim Laden einer Webseite, stürzt nur der Tab und nicht der gesamte Browser ab. Zudem kann der Rendering-Prozess mit niedrigen Rechten in einer Sandbox ausgeführt werden, wodurch mögliche Schwachstellen nur noch schwer von Angreifern auszunutzen sind. Darüber hinaus verspricht Mozilla signifikante Steigerungen bei der Responsivität des Browsers. In den Versionen 49 und 50 erweiterte Mozilla schrittweise die Nutzergruppe der neuen Funktion. So wurden zunächst Anwender mit Erweiterungen hinzugefügt, deren Kompatibilität zuvor getestet wurde. Mit Version 50 wurde der Nutzerkreis um Anwender mit Erweiterungen ausgebaut, deren Entwickler Support für die Multi-Prozess-Technologie angegeben hatten.

Im kommenden Jahr will Mozilla mit Firefox 51 nochmals die Multi-Prozess-Nutzergruppe ausbauen. Diesmal sollen auch Anwender hinzukommen, deren Erweiterungen nicht explizit den Einsatz von Multi-Prozess ausschließen. In Zukunft werde die MultiProzess-Technologie sukzessive erweitert, so Mozilla in einem Blogpost. Die Entwicklung umfasse unter anderem den plattformübergreifenden Ausbau der Sandbox unter Windows, Linux und macOS. Zudem wollen die Entwickler die Multi-Prozess-Technologie um weitere Prozesse ausbauen, um die Stabilität der Open-SourceTools nochmals zu erhöhen. www.mozilla.org

application-LifecycleManagement

Perforce zeigt auf der Embedded World 2017 eine Komplettlösung Die Digitalisierung steigert kontinuierlich den Bedarf an Embedded-Systemen. Gleichzeitig werden bei deren Entwicklung die Einhaltung von Sicherheitsund Compliance-Standards, die Effizienz in der Qualitätssicherung und die Auslieferungsgeschwindigkeit immer wichtiger. Dies gilt nicht nur für traditionell regulierte Branchen wie die Medizintechnik, sondern aus Haftungsgründen auch für alle anderen Industrien. Das bedeutet, dass der gesamte Software-Lebenszyklus, vom Anforderungsmanagement bis hin zu den abschließenden Tests, digital gemanagt werden muss. Damit die Unternehmen diese Herausforderung meistern können, präsentiert der Versionsmanagement-Spezialist Perforce Software auf der Embedded World 2017 vom 14. bis 16. März in Nürnberg an seinem Stand 4-141 in Halle 4 einen

3.2017 www.webundmobile.de


aKTUELL

News

DVAG-Studie

vollständigen Application-Lifecycle-Management-Stack. Damit lassen sich Projektmanagement und Entwicklung inklusive Defect Tracking, Anforderungsmanagement und Tests effizient miteinander verbinden. Besonders hoch regulierte Branchen wie die Medizintechnik unterliegen bereits seit geraumer Zeit strengen Compliance-Vorschriften, die ein lückenloses Nachweisen aller Stufen im Entwicklungsprozess erforderlich machen. Ähnlich strenge Anforderungen gelten dabei auch im Automotive-Bereich, denn auch hier kann – ähnlich wie bei medizinischen Geräten – jeder Defekt in der Softwaresteuerung für Motoren oder Bremsen weitreichende – im schlimmsten Fall vielleicht sogar tödliche – Konsequenzen nach sich ziehen. Um einer potenziellen Haftung vorzubeugen, wird es für Hersteller zunehmend unerlässlich, den gesamten Prozess der SoftwareEntwicklung von der ersten Idee über Planung und Entwicklung bis hin zu Fehlerbehebung und Testphase mit einer IT-Lösung aus einer Hand abzudecken und damit die Umsetzung aller notwendigen Anforderungen im fertigen Produkt lückenlos zu protokollieren. www.perforce.com

www.webundmobile.de 3.2017

neue OpenStack-Version von Red Hat

Optimierte Skalierbarkeit und Benutzerfreundlichkeit Red Hat präsentiert mit Red Hat OpenStack Platform 10 die neueste Version seiner massiv skalierbaren und agilen CloudInfrastructure-as-a-ServiceLösung (IaaS). Basierend auf dem OpenStack Newton Release umfasst Red Hat OpenStack Platform 10 neue Features, die die systemweite Skalierbarkeit erhöhen, das Infrastruktur-Management vereinfachen und die Orchestrierung verbessern – bei einer gleichzeitig optimierten NetzwerkPerformance und Plattform-Sicherheit. Darüber hinaus bietet Red Hat OpenStack Platform 10 einen neuen Software-Lebenszyklus mit einem optionalen Support von bis zu fünf Jahren. Mit Red Hat OpenStack Platform 10 steht eine stabile Cloud-Plattform zur Verfügung, die auf dem bewährten Red Hat Enterprise Linux basiert. Integriert mit Red Hats gehärtetem OpenStack Community Code bietet Red Hat OpenStack Platform die benötigte Agilität für die schnelle Umsetzung von Anwenderanforderungen – ohne Beeinträchtigung von ▶

gen zu anderen klassischen Sparprodukten erreichen ein Plus von 43 Prozent. Die grundlegende Frage, welche Möglichkeiten es überhaupt für die Geldanlage gibt, wird zum Jahresstart online rund ein Drittel häufiger gestellt als im 12-Monats-Durchschnitt. Mit den Frühlingsgefühlen scheint dann auch die Risikobereitschaft der deutschen Finanzsurfer zu erwachen. Suchanfragen rund um den Aktienmarkt erreichen im März ihr Jahreshoch - mit einem Plus von rund 25 Prozent. Einzig ihre Gesundheit scheint den Deutschen zu Jahresbeginn noch mehr am Herzen zu liegen. Das Suchvolumen rund um das Thema Krankenversicherung steigt im Januar um mehr als das Doppelte an. Bei der privaten Krankenversicherung sind es immerhin noch mehr als 30 Prozent. www.webcheckfinanzfragen.dvag

Finanzfragen bei Google im Januar: Was muss ich rund um die gesetzliche Krankenversicherung wissen?

+118,68 %

Welche Krankenversicherung/Krankenkasse passt zu mir?

+118,51 %

Was muss ich rund um das Tagesgeld wissen?

+56,74 %

Welche Sozialabgaben habe ich als Arbeitnehmer?

+54,96 %

Was muss ich rund um das Festgeld wissen? Welche Möglichkeiten gibt es für das klassische beziehungsweise sichere Sparen? Arbeitsunfall: Wer zahlt was und wann? Welche Möglichkeiten habe ich, Geld anzulegen?

+49,70 %

+43,29 %

+38,46 %

+35,27 %

Welche Versicherungen für Reise und Freizeit sind sinnvoll?

+31,71 %

Was muss ich rund um die private Krankenversicherung wissen?

+31,40 %

Deutschen Vermögensberatung AG (DVAG)

Perforce präsentiert auf der Embedded World 2017 einen vollständigen Application-Lifecycle-Management-Stack

Google-Suchen rund um Finanzfragen Mit dem Jahresbeginn schießen deutschlandweit die Google-Suchen rund um Finanzfragen nach oben. Das zeigt die Studie »Webcheck Finanzfragen« der Deutschen Vermögensberatung AG (DVAG). Rund 180 Millionen Suchanfragen wurden dafür zwischen März 2015 und Februar 2016 analysiert. Über 40 Prozent der untersuchten Finanzfragen haben demnach im Januar das höchste Suchaufkommen des Jahres; betrachtet man das gesamte erste Quartal, sind es sogar fast 85 Prozent. Direkt nach dem Jahreswechsel besonders im Fokus der Finanzsurfer: Sparen und das möglichst risikofrei. So werden konkrete Informationen zu Tages- und Festgeld im Januar rund 50 Prozent häufiger gegoogelt als im Monatsdurchschnitt des gesamten Jahres; Suchanfra-

Bei diesen Finanzfragen stieg das Suchvolumen im Januar am stärksten an (Basis: üblicher Monatsdurchschnitt)

11


aKTUELL

News

Materna

Trends Lieblingsmarken der Deutschen Im Oktober 2016 führte das Meinungsforschungsinstitut Forsa im Auftrag der Brandmeyer Markenberatung eine repräsentative telefonische Befragung zum Thema Lieblingsmarken durch. Insgesamt wurden 3052 Deutsche ab 14 Jahren aus Deutschland befragt. Davon haben 1928 Personen eine Lieblingsmarke genannt. Der Sportartikelhersteller Nike steht

Die Marke apple steht in Sachen Beliebtheit bei den Deutschen weit oben bei Jugendlichen in Deutschland ganz hoch im Kurs: Jeder dritte Teenager sagt, dass Nike seine Lieblingsmarke ist. Die drittliebste Marke von Jugendlichen in diesem Jahr ist der amerikanische Computerund Smartphone-Hersteller Apple mit 11,1 Prozent. Auf dem fünften Platz landet der IT-Wettbewerber Microsoft mit 5,2 Prozent. Apple hat im Vergleich zu 2014 wieder leicht gewonnen und liegt nach Platz 7 im Vorjahr nun auf dem fünften Platz. Der große Apple-Rivale Samsung verliert nach den publik gewordenen technischen Problemen mit den Galaxy-Akkus an zwar etwas an Beliebtheit, behält jedoch den zehnten Platz. www.brandmeyermarkenberatung.de

12

Private Cloud nach Public-Cloud-Regeln

Die OpenStack Platform 10 bietet eine erneuerte Bedienoberfläche und anforderungsspezifisch anpassbare Rollen Verfügbarkeit, Performance oder IT-Sicherheit. Die Red Hat OpenStack Platform enthält zudem Red Hat CloudForms, eine Hybrid-Cloud-Management- und Monitoring-Plattform, mit der nicht nur OpenStack-Infrastruktur-Komponenten, sondern auch die auf einer bestimmten OpenStackCloud laufenden Workloads verwaltet werden können. Darüber hinaus stehen 64 TByte Storage-Kapazität über Red Hat Ceph Storage zur Verfügung; Anwender profitieren damit von den flexiblen, massiv skalierbaren Eigenschaften der führenden Storage-Lösung für OpenStack-Umgebungen. www.redhat.com

GrammaTech

Neue Version 4.5 von CodeSonar Auf der Embedded World zeigt GrammaTech die neueste Version 4.5 des Flaggschiffprodukts CodeSonar. Es ist das derzeit leistungsstärkste verfügbare Analysesystem. CodeSonar 4.5 adressiert Kunden mit Fokus auf Sicherheit und Schutz. Ihnen bietet das Tool zusätzliche Integrationsfunktionen einschließlich Microsoft Visual Studio und erhöhten Support für C++ 14. Neu ist auch ein ManagementDashboard als wertvolle Grundlage, um technisch nicht ver-

sierten QA-, Entwicklungs- und Produktmanagern ein tieferes Verständnis für Softwarerisiken auf hohem Niveau zu vermitteln. CodeSonar ist die einzige statische Analyselösung auf dem Markt mit Binäranalysetechnologie für Intel- und ARM-Prozessoren. Ohne Prüfung von Sicherheit, Qualität und Schutz von Open-Source-, Third-Party- und Legacy-Code geben Unternehmen Software schneller frei, gehen aber zugleich größere Risiken für ernste Sicherheitsprobleme im Zuge des Einsatzes ein. CodeSonar vermindert diese Risiken durch die Analyse dieses Codes und bietet Anschauungsmaterial, um Anwendern aufzuzeigen, wo ihr Code ungeschützt ist. Embedded-Entwickler auf der ganzen Welt setzen auf CodeSonar, um Qualitäts-, Sicherheits- und Schutzprobleme in ihrem Code aufzufinden und zu beheben. www.grammatech.com

Materna bietet über IBM Bluemix Private Cloud deutschlandweit eine Private-Cloud-Umgebung, die nach den Regeln der Public Cloud realisiert und aus einem deutschen Rechenzentrum betrieben wird. Der Dortmunder IT-Dienstleister Materna baut zusammen mit IBM sein Angebot für Cloud-Services weiter aus. Zukünftig können Unternehmen über den Cloud Service Provider (CSP) auf die offene Cloud-Umgebung von IBM Bluemix Private Cloud zugreifen. Die Cloud basiert auf der Open-Source-Infrastruktursoftware OpenStack und ermöglicht Unternehmen den Betrieb einer Private Cloud in einer Public-Cloud-Umgebung. Damit erleichtert Materna mittelständischen Unternehmen den Weg in die Cloud. Erst vor wenigen Wochen prognostizierten die Auguren von Gartner, dass 2020 eine No-Cloud-Strategie bei Unternehmen so selten sein wird wie heute eine No-Internet-Strategie. PCaaS heißt das Kürzel, über das Materna seinen neuen Private Cloud as a Service ausflaggt. Mit dem Angebot reagiert der Cloud Service Provider (CSP) auf die steigende Nachfrage nach Cloud-Services. www.materna.de

Die aktuellste Version 4.5 der Analyse-Tools CodeSonar bietet zahlreiche Neuerungen

3.2017 www.webundmobile.de


Jetzt kostenlos testen!

2x

gratis!

Das Fachmagazin fĂźr .nET-Entwickler Testen Sie jetzt 2 kostenlose Ausgaben und erhalten Sie unseren exklusiven Newsletter gratis dazu.

probeabo.dotnetpro.de/kostenlos-testen/


aKTUELL

IBM Bluemix neue Bluemix Services für DevOps-Teams Mit dem Bluemix Continuous Delivery-Service beschleunigt IBM die Entwicklung von cloudbasierten Apps. Dank integrierter DevOps-Tools wie GitHub oder Slack lassen sich zukünftig in der Cloud vorkonfigurierte Toolchains mit wenigen Mausklicks aufsetzen und gemeinsam im Team nutzen. Toolchains sind WerkzeugProgramme für Entwickler, die in der Regel in Form einer Kette nacheinander eingesetzt werden. Bei IBM Bluemix bestehen die Toolchains aus verschiedenen DevOps-Services, mit denen sich Anwendungen unternehmensweit programmieren, testen und bereitstellen lassen. Die DevOps-Werkzeuge bringen Struktur in cloudbasierte App-Entwicklungen und unterstützen die teamübergreifende Ab-

Erweiterte Cloud-Services auf IBM Bluemix erleichtern DevOps-Teams die Entwicklung unternehmensweiter Apps wicklung von Softwareprojekten. Mit IBM Bluemix Continuous Delivery steht DevOps-Teams nun ein zentraler Hub zur Verfügung, über den sich vorkonfigurierte Toolchains einfach erstellen, verwalten und skalieren lassen. www.ibm.com

14

News

Finanzunternehmen

Neun von zehn Tweets bleiben ohne Reaktion Weiterempfehlen, was man im Netz findet, Inhalte mit der eigenen Web-Community sharen: Das ist eigentlich eine der Schlüsselfunktionen von sozialen Medien wie Twitter. Die Online-Kommunikationsanalyse »So gefährlich sind Fintechs für Banken« von der Kommunikationsberatung Faktenkontor und Ubermetrics Technologies zeigt nun aber: Artikel aus klassischen journalistischen Online-Nachrichtenportalen werden zweibis fünfmal häufiger geteilt und kommentiert als Tweets. Für die Studie wurden mehr als 150.000 Nennungen aus mehr als 400 Millionen öffentlichen Internetquellen zu vier Banken, fünf Sparkassen und 149 Fintechs mit Hilfe des Monitoring-Tools Ubermetrics Delta erfasst und ausgewertet. Es zeigt sich: 93 Prozent der Tweets, die eine der untersuchten Banken erwähnen, haben zu keinerlei Interaktion geführt. Sie wurden weder retweetet noch kommentiert oder verlinkt. Weitere vier Prozent dieser Twitter-Posts wiesen genau einen Kommentar oder eine Weiterverbreitung auf. Lediglich drei Prozent der Tweets führten zu mehr als einer Interaktion. Demgegenüber werden Artikel auf redaktionellen Nachrichtenportalen, die die untersuchten Banken behandeln, zu elf Prozent vielfach kommentiert und verlinkt. Weitere elf Prozent bringen es auf genau eine Interaktion dieser Art. 78 Prozent bleiben ohne öffentlichen Kommentar und Weiterverbreitung. Insgesamt wird damit ein rund dreimal größerer Anteil der journalistischen Texte kommentiert oder weiterverbreitet als bei den Tweets. Ähnlich sieht es bei den Sparkassen aus: Tweets bleiben hier

zu 97 Prozent ohne Reaktion, ein Prozent bringt es auf eine, zwei Prozent auf mehrfache Interaktionen. Artikel auf journalistischen Webseiten, wie den Online-Präsenzen von Tageszeitungen und Magazinen, weisen hier zu zehn Prozent mehrfache Kommentare und Verlinkungen auf. Sechs Prozent kommen auf eine Interaktion, 84 Prozent auf keine. Hier sind

»Wer Viralität will, muss Nachrichten schaffen«, lautet deshalb das Fazit von Dr. Roland Heintze, Geschäftsführender Gesellschafter und SocialMedia-Experte des Faktenkontors. »Egal ob klassische Bank, Sparkasse oder Fintech: Wer eine hohe Sichtbarkeit und Nutzer-Interaktion im Web erreichen will, muss Inhalte liefern, die für Journalisten interessant sind und so über thematische Relevanz ihren Weg in die redaktionelle Berichterstattung finden.« www.faktenkontor.de

SmartDeviceLink

Ford und Toyota gründen SmartDeviceLink-Konsortium Dr. Roland Heintze ist Geschäftsführender Gesellschafter und Social-Media-Experte des Faktenkontors die News-Interaktionen im Vergleich zu Twitter damit anteilig mehr als fünfmal so groß. Fintechs erreichen mit einem kleinen Vorsprung vor den Banken die größte Interaktionsquote auf Twitter: Tweets, die eines der untersuchten Fintech-Unternehmen erwähnen, bleiben nur zu 91 Prozent ohne Reaktion. Fünf Prozent werden einmal weiterverbreitet oder kommentiert, vier Prozent mehrfach. Hingegen führen 14 Prozent der Artikel auf Nachrichtenportalen mit journalistischen Inhalten, die sich mit den Fintechs beschäftigen, zu multiplen Interaktionen. Sechs Prozent werden einmal kommentiert oder verlinkt, 80 Prozent gar nicht. Trotz der vergleichsweise hohen Interaktionsrate auf Twitter führen damit auch bei Fintechs die redaktionellen Inhalte rund doppelt so häufig zu Kommentaren und Verweisen wie Tweets.

Das Netzwerk ist als Non-Profit-Organisation ausgelegt und soll als Plattform für OpenSource-Software zur Entwicklung von im Fahrzeug nutzbaren Smartphone-Apps dienen. Ein wesentliches Ziel ist es, bei Automobilherstellern und Zulieferern einen brancheneinheitlichen Standard für die Einbindung von Smartphone-Apps in Automobile zu etablieren. Die Autofahrer würden durch diese offene Plattform eine größere Bandbreite an Möglichkeiten erhalten, wie sie die Apps auf ihrem persönlichen Smartphone mit ihrem Fahrzeug verbinden sowie während der Fahrt nutzen und steuern können. Als erste Automobilhersteller neben Ford und Toyota haben sich auch die Mazda Motor Corporation, die PSA Group, Fuji Heavy Industries Ltd. (FHI) und die Suzuki Motor Corporation dem Konsortium angeschlossen. Zu den ersten Mitgliedern zählen zudem Zulieferer wie Elektrobit, Luxoft und Xevo. Mit Harman, Panasonic, Pioneer und QNX erklärten weitere namhafte Unternehmen durch Letters of In-

3.2017 www.webundmobile.de


News

tent ihre Absicht, dem Konsortium beizutreten. Technisch basiert SmartDeviceLink auf dem von Ford eingebrachten Standard AppLink, den das Unternehmen 2013 für die Open-Source-Community bereitstellte. Die Ford-AppLinkSoftware ist aktuell für mehr als fünf Millionen kompatible Fahrzeuge weltweit verfügbar. Schon heute stehen für ausgewählte Märkte Apps wie Pandora, Spotify, iHeartRadio, AccuWeather und viele weitere für Ford-AppLink-Nutzer bereit. www.smartdevicelink.com

Progress

Cortana für alle Plattformen

DataDirect Connector for Apache Cassandra

Mit dem Cortana Skills Kit und dem Cortana Devices SDK hat Microsoft neue Werkzeuge vorgestellt, über die Entwickler die digitale Assistentin mit intelligenten Anwendungen anreichern können oder Cortana auf Hardware bringen. Die Tools sollen die plattformübergrei-

Progress DataDirect for Apache Cassandra adressiert die zunehmende Verbreitung von Apache Cassandra in Unternehmen, die auf eine zuverlässige, relationale Anbindung und sofortige Kompatibilität in den Bereichen Datenbank- und Applikationsintegration angewiesen sind. DataDirect for Apache Cassandra ist eine neue Sammlung von Konnektoren, die zur Progress DataDirect Enterprise Data Connectivity Suite gehören. DataDirect for Apache Cassandra verwendet SQL-basierte ODBC- und JDBC-Standards und schafft so eine sofortige Kompatibilität der CassandraNoSQL-Datenbank mit den ▶

Bild: www.microsoft.com

Entwickler-Tools von Microsoft

Das Cortana Skills Kit erlaubt Entwicklern, Cortana mit Bots aus dem Microsoft Bot Framework zu verbinden

www.webundmobile.de 3.2017

Bluetooth Special Interest Group (SIG) Bluetooth 5 ist ab sofort verfügbar Die neueste Bluetooth-Spezifikation treibt interoperables, drahtloses IoT weiter voran. Bluetooth 5 verspricht doppelte Geschwindigkeit, vierfache Reichweite und achtfache Übertragungskapazität. Ab sofort ist mit Bluetooth 5 die neue Kernspezifikation für Bluetooth verfügbar. Das hat die Bluetooth Special Interest Group (SIG) diese Woche bekannt gegeben. Neben einer höheren Reichweite und Geschwindigkeit gehört auch eine höhere Übertragungskapazität sowie eine verbesserte Interoperabilität und störungsfreie Nutzung mit anderen drahtlosen Technologien zu den wichtigsten Neuerungen. Bluetooth 5 ermöglicht einfache und mühelose Interaktionen über weite Strecken mit vernetzten Geräten und fördert dadurch die Nutzung des Internet of Things (IoT). Die wichtigsten Neuerungen sind eine vierfache Reichweite, doppelte Geschwindigkeit und achtfache Übertragungskapazi-

Schon in den nächsten Monaten sollen die ersten Produkte mit Bluetooth 5 verfügbar sein tät. Die höhere Reichweite bietet eine komplette Haus- sowie Gebäudeabdeckung und ermöglicht so robustere sowie zuverlässigere Verbindungen. Die höhere Geschwindigkeit sorgt für leistungsstärkere und reaktionsschnellere Geräte. Die höhere Übertragungskapazität beschleunigt die Datenübertragung für verbesserte und stärker kontextbezogene Lösungen. Bluetooth 5 enthält zudem Updates, die mögliche Störungen in Zusammenhang mit anderen drahtlosen Technologien reduzieren. Dadurch lassen sich Bluetooth-fähige Geräte in einer zunehmend komplexen IoT-Umgebung einsetzen. Gleichzeitig sorgen der geringe Stromverbrauch und die hohe Flexibilität dafür, dass die Anforderungen von Entwicklern hinsichtlich ihrer Geräte oder Applikationen erfüllt werden. www.bluetooth.com

Bild: www.bluetooth.com

Ford und Toyota haben das SmartDeviceLink-Konsortium (SDL) ins Leben gerufen

fende Integration von Cortana weiter fördern und Entwickler unterstützen, weltweit 145 Millionen Cortana-Nutzer zu erreichen – ob auf Windows, Android, iOS, Xbox oder neuer Hardware. Das Cortana Skills Kit erlaubt Entwicklern, Cortana mit Bots aus dem Microsoft Bot Framework zu verbinden, um die digitale Assistentin mit neuen Fähigkeiten oder Diensten aus dem Bereich der künstlichen Intelligenz auszustatten. So erlaubt das Skills Kit, Programme auf Basis von Cortana proaktiver und persönlicher zu machen. Das Cortana Devices SDK ermöglicht die Integration von Cortana auf (IoT-)Hardware von Drittanbietern. Es befähigt Hardwarehersteller, zukünftig eine neue Generation von persönlichen und intelligenten Geräten für alle Plattformen zu entwickeln – beispielsweise KIDevices ohne Bildschirm, für zu Hause oder auch unterwegs in vernetzten Autos. www.microsoft.com

aKTUELL

15


News

Microsoft HoloLens Einkaufen mit der HoloLens In Zusammenarbeit mit Saturn bringt Microsoft die Mixed-Reality-Technologie in den stationären Handel. In einem eigens eingerichteten Demo-Raum in Hamburg steht eine interaktive Microsoft HoloLensStation bereit, um Besuchern erste Gehversuche in der Mixed-Reality-Umgebung zu ermöglichen. Möglich macht das eine von der Agentur MSM eigens für die HoloLens entwickelte App. Die Anwendung reichert das Einkaufserlebnis im stationären Handel mit Mixed-Reality-Elementen an. Über die HoloLens können zusätzliche Informationen zu Microsoft-Produkten und PCs der Hardwarehersteller, wie beispielsweise Produkt-Spezifikationen, passendes Zubehör und spezielle Features eingeblendet werden. Die neue Flagship-Area im Saturn Hamburg, dem weltgrößten

neues Einkaufserlebnis dank Microsoft HoloLens

Bild: www.microsoft.com

Elektrofachmarkt, wird die größte eigene Verkaufsfläche für Consumer-Produkte von Microsoft in Deutschland, die das gesamte Spektrum von Microsofts Produkthighlights in Form von anwenderorientierten Themenwelten visualisiert. www.microsoft.com

16

DataDirect for apache Cassandra ist eine neue Sammlung von Konnektoren bei Unternehmen vorhandenen Applikationen. Darüber hinaus bietet der Treiber mit der neuen ODBC-4.0-Spezifikation kompatible Funktionen. IT-Architekten in den Unternehmen können mit der DataDirect-Lösung ihre CassandraDaten, einschließlich der Collections, in ihrem relationalen Pendant abbilden: wohlstrukturierte Child-Tabellen, die sich auf eine primäre Parent-Tabelle beziehen. Mit den leistungsfähigen Funktionalitäten von Cassandra-ODBC- und JDBC-Connectivity ist DataDirect Vorreiter im Markt und erhielt dafür auch das U.S. Patent 9.471.654. Progress ist weltweit führend bei einer zuverlässigen NoSQLConnectivity und führt als erster Anbieter das Konzept normalisierter NoSQL-Datenmodelle für Business Intelligence (BI) und Analytics ein. Außer für Cassandra bietet Progress DataDirect-Treiber für verschiedene Big-Data-Datenquellen wie MongoDB, Spark SQL, Impala, SAP HANA und Apache Hive sowie kommerzielle Hive-Distributionen von Amazon, Cloudera, Hortonworks, MapR, IBM und Pivotal. Dazu kommen die hoch leistungsfähigen relationalen und SaaS-Applikations-Adapter von Progress DataDirect für Salesforce Connect, Salesforce.com, Hubspot, Marketo, Eloqua, Oracle Sales Cloud, Oracle Service Cloud, ServiceMax, Oracle, Microsoft SQL Server, MySQL, Progress Open-

Edge, Progress Rollbase und viele mehr. »Führende Unternehmen nutzen Cassandra, um die Performance, Skalierbarkeit und Verfügbarkeit zu erzielen, wie sie die heutigen umfangreichen Internetlösungen erfordern«, sagt Dion Picco, General Manager Data Connectivity & Integration bei Progress. »Durch die Bereitstellung der Daten als normalisierte, relationale Tabellen ermöglicht Progress DataDirect Unternehmen den Einsatz einer Industrie- und SQL-standardbasierten Lösung mit ODBC- und JDBC-Connectivity« www.progress.de

Tibco Mashery Local 4.0

API-Management in hybriden GatewayUmgebungen Tibco Software, Anbieter von Integrations-, API-Management- und Analysesoftware, hat mit Tibco Mashery Local 4.0 die neueste Version seiner Lösung für das API-Management auf den Markt gebracht. Im Blickpunkt stehen dabei die Unterstützung von Containerbasierten Implementierungen und die verbesserte End-toEnd-Sicherheit. Der besondere Ansatz der Mashery-Local-Lösung, bei dem der API-Traffic unter Verwendung eines hybriden Gateways on-premise gemanagt wird, verbindet den Komfort und die schnelle Einsatzbereitschaft einer SaaS-Lösung mit der hohen Sicherheit und Flexibilität eines vor Ort stattfindenden API-Managements. Für die Anwender bedeutet das, so verspricht Tibco, ein spürbares Plus an Sicherheit und operativer Unterstützung, mit dem sie unabhängig von unternehmensinternen IT-Programmen API-gestützte Initia-

tiven für die digitale Transformation definieren und umsetzen können. »Bisher haben Anbieter von API-Management-Lösungen entweder SaaS- oder On-Premise-Software bereitgestellt, nicht jedoch ein hybrides Produkt, das die besten Merkmale aus beiden Welten vereint«, erklärt Rajeev Kozhikkattuthodi, Vice President Product Ma-

Bild: www.mashery.com

aKTUELL

Tibco Mashery Local 4.0 unterstützt containerbasierte Implementierungen und bietet verbesserte End-to-EndSicherheit nagement & Strategy bei Tibco. »Mit Mashery Local 4.0 verfolgen wir einen hybriden Ansatz, der nicht nur branchenweit seinesgleichen sucht, sondern auch eine der flexibelsten und kosteneffektivsten Lösungen ergibt, die derzeit zu haben sind.« Die hybride Architektur von Mashery Local ermöglicht die Verknüpfung von Mashery-Local-Gateways, die in einer gemischten Container- und MultiCloud-Umgebung ausgeführt werden, und deren kollektive Verwaltung über eine zentrale Administrationskonsole. Mashery Local lässt sich in jeder Cloud-Umgebung einsetzen, die Docker-Container unterstützt, wie etwa Amazon Web Services oder Microsoft Azure. API-Gateways können damit sehr viel einfacher an der Unternehmensperipherie implementiert werden, das heißt in direkter Nähe zur Quelle vieler API-Programme und DigitalTransformation-Initiativen. www.mashery.com

3.2017 www.webundmobile.de


Tr

T

aining

s

Updates für Ihr Know-How „Erfolgreiche Entwickler haben den für ihre Software passenden Testmix. Lernen Sie, wie man externe wie interne Qualität effizient sicherstellt.“ Sebastian Bergmann PHP-Consultant und Trainer

PHP Security

Zend Framework 3

Trainer: Arne Blankerts

Trainer: Ralf Eggert

2 Tage, Hamburg, Termin nach Absprache

3 Tage, 13.-15.06.2017, Köln

Ab EUR 1.799,- zzgl. MwSt.

Ab EUR 2.199,- zzgl. MwSt.

Domain Driven Design mit PHP

PHPUnit erfolgreich einsetzen

Trainer: Stefan Priebsch

Trainer: Sebastian Bergmann

2 Tage, München, Termin nach Absprache

2 Tage, Köln, Termin nach Absprache

Ab EUR 1.799,- zzgl. MwSt.

Ab EUR 1.799,- zzgl. MwSt.

Ihr Ansprechpartner: Fernando Schneider +49 (0)89 74117-831 – fernando.schneider@developer-media.de

developer-media.de/trainings


Java

Foto: xxxxxxxxxxxx

FEaTURE

aUSBLICK aUF DIE VERSIOn 9 VOn JaVa

Modularität, Portabilität und Produktivität Java 9 bietet weniger neue Sprachmittel, doch dafür zahlreiche zentrale Verbesserungen und hilfreiche Ergänzungen.

Z

u den Verbesserungen und Ergänzungen gehören erstmals ein Modulkonzept für die gesamte Java-Plattform (JDK, JRE), neue Programmier-Tools und eine Optimierung der Speicherverwaltung. Java als Plattform und Sprache hat inzwischen mehr als zwei Jahrzehnte auf dem Buckel und kann auf einen nachhaltigen Erfolg zurückblicken. In zahlreichen Marktanalysen zur Verbreitung und Popularität von Programmiersprachen nimmt Java immer noch eine Position an der Spitze ein (Bild 1). Dies gilt vorwiegend für das Backend und Frontend von Desktop- und Web-Apps, derzeit jedoch weniger für die mobile Welt und das Internet der Dinge (Internet of Things/IoT). In der mobilen Welt favorisierten Hersteller wie Apple (iOS) oder Google (Android) ihre eigenen proprietären Ent-

18

wicklungsansätze. Analoges gilt im IoT – dort tummeln sich aktuell abhängig vom Anwendungsgebiet noch wesentlich mehr Softwarehäuser und Hardwarelieferanten. Leider entwickelte sich die Java-Plattform und damit die APIs im Lauf der Zeit durch verschiedene hardware- und anwendungsspezifische Varianten auseinander. Im Unterschied zu den genannten Plattformen besitzt Java mit Version 9 jetzt die Chance, sich stärker auf allen Zielumgebungen zu etablieren.

Write once – run anywhere Auf dem klassischen Desktop entstand die Java SE (Standard Edition), im Unternehmensumfeld etablierte sich Java EE (Enterprise Edition), während Oracle im mobilen und Embedded-Bereich auf zwei abgespeckte Java MEs (Micro Editions)

3.2017 www.webundmobile.de


Java

setzte. Daraus resultierten differierende JDKs und Laufzeitumgebungen. Mit Version 8 begann die Vereinheitlichung von Java auf der Basis zahlreicher Spracheigenschaften, die man durchgängig für alle genannten Java-Editions verfügbar machte. Zudem nahm Oracle eine Restrukturierung der kompletten Codebasis zu einer einheitlichen Plattform vor. Dieses Vorgehen erleichtert zukünftig die Programmierung plattformübergreifenden Quellcodes und erhöht im Unterschied zur Vergangenheit wesentlich die Portabilität. Mit der neuen Version 9 stellt Oracle der Java Community die wohl wichtigsten Features seit dem Entstehen des Java-Ökosystems bereit. Mit diesen Neuerungen wandelt sich die JavaPlattform selbst zu einer echten portablen und vor allem flexiblen Entwicklungsumgebung, die es erleichtert, Anwendungen und Dienste entsprechend den vorliegenden Anforderungen zu modularisieren (Bild 2). Damit erfüllt Java wichtige Kriterien des Software-Engineering für eine effiziente und produktive Entwicklung. Schließlich erlaubt erst diese Modularisierung des JDK, auch die JRE optimal auf die individuellen, spezifischen Bedürfnisse einer konkreten Hardware abzustimmen. Diese Vorgehensweise haucht gewissermaßen dem schon länger totgesagten Ansatz des Write once, run anywhere (WORA) erneutes Leben ein. Zudem zwang die zunehmende Weigerung der Browserhersteller, einige Plug-in-Technologien wie Flash, Silverlight oder Java noch länger zu unterstützen, Oracle dazu, mit der neuen Version 9 das Applet-API als deprecated zu erklären. Somit dürfte sich auch der Leidensspruch eines jeden Java-Programmierers, Write once, debug/ test everywhere, automatisch abschwächen.

Endlich im Software-Engineering angekommen Leider besteht in der Praxis kein Zusammenhang zwischen Einsatzbreite beziehungsweise Verbreitungsgrad einer Programmiersprache und deren Qualität beziehungsweise Eignungsgrad in der Anwendungsentwicklung. Eine wesentliche Voraussetzung seitens des Software-Engineering an eine

Java nimmt seit vielen Jahren in Auswertungen über die Popularität von Programmiersprachen wie PYPL, Developer Survey Results (Stack Overflow), RedMonk oder TIOBE eine Spitzenposition ein (Bild 1)

www.webundmobile.de 3.2017

FEaTURE

Oracle reduzierte für die Einführung eines Modulsystems die Abhängigkeiten innerhalb der Java-Plattform und erreichte damit eine echte modulare Anwendungsentwicklung für die Programmiersprache Java (Bild 2)

Sprache stellt die Unterstützung eines Modulsystems dar. Diese Erkenntnis hatte schon Sun und dann auch Oracle seit vielen Jahren gewonnen und sich öffentlich seit Version 7 dazu bekannt. So arbeiteten Oracle und die Mitglieder des OpenJDK-Projekts in verschiedenen Projekten an der Implementierung eines Modulsystems für Java. Bereits im JDK 7 wollte man mittels Superpackages ein spezielles Sprachkonstrukt für Module einführen und diese über verschiedene JSRs (Java Specification Requests) realisieren. Jedoch erkannte man im Rahmen der Umsetzungsbemühungen, dass eine schnelle Lösung der gravierenden Bedeutung eines Modulsystems nicht gerecht wird. Aus diesem Grund initiierte das OpenJDK-Team unter Federführung von Oracle ein eigenständiges Projekt Jigsaw. Auf der Basis bisheriger Arbeitsergebnisse der JSRs sollte ein Java Platform Module System und mittels neuer JDK Enhancement Proposals (JEPs) ein modulares JDK entstehen. Nach mehrjähriger Entwicklungszeit und parallelen Reviews im Rahmen aktuell laufender OpenJDK-Aktivitäten (Java Version 7, 8 und 9) gelang dem Jigsaw-Projekt die Realisierung eines einzigartigen Modulsystems. Dieses erfüllt mit Version 9 von Java wichtige und für die Plattform und deren weitere zukünftige Verbreitung in der Praxis zentrale Anforderungen: Flexibilität und Skalierbarkeit: Restrukturierung des Quellcodes und neue, spezielle Werkzeuge versetzen Ent- ▶

19


FEaTURE

Java

wickler in die Lage, mittels einer einheitlichen Java SE auf die eigenen Bedürfnisse abgestimmte JREs für spezifische Zielumgebungen bereitzustellen. Sicherheit und Wartbarkeit: Die Restrukturierung führte teilweise zu Neuimplementierungen; so musste das bisherige Security-System neu realisiert werden. Gleichzeitig gewährleistete man für die Supported APIs eine höhere Kompatibilität – eine Anwendung, die nur Supported APIs verwendet und mit Java Release N lauffähig ist, soll dies auch für den Nachfolger N+1 gewährleisten, sogar ohne erneute Übersetzung. Bessere Unterstützung der Software-Entwicklung: Neue und überarbeitete JDK-Werkzeuge sollen die Programmierung, Wartung, Portierung und Verteilung insbesondere großer Anwendungslandschaften erleichtern. Höhere Performance: Verschiedene Benchmarks zeigten bereits für die Early-Access-Releases (EA) von Java 9 Verbesserungen im Laufzeitverhalten. Dies betrifft sowohl das Übersetzen mit neuen Compilertechniken wie Smart Java und Ahead-of-Time Compilation (AOT) als auch das Laufzeitverhalten (segmentierter Code-Cache, überarbeitete Klassen).

Den Quellcode des Moduls se.callista.java9.modules.common findet man in den beiden Unterverzeichnissen api und internal (Bild 4)

che und ergänzender Werkzeuge, um schon während der Entwicklung möglichst produktiv zu arbeiten. Im Mittelpunkt steht der Begriff des Moduls, das aus einem Schnittstellenund einem Implementierungsteil besteht. Dem Nutzer eines Moduls bleibt die Implementierung verborgen, er muss nur die Schnittstelle kennen. Aus Sicht der Architektur einer Anwendung stellt ein Modul eine unabhängig verteilbare Einheit (Deployment Unit) dar.

In der Vergangenheit war die größte Schwäche der JavaJava-Module definieren und deren Technologie die ständig ansteigende Größe einer Java RunServices nutzen time. Obwohl Java 8 sogenannte Compact Profiles einführte, Aus dem Blickwinkel der Programmierung betrachtet stellt konnte man die JRE nicht noch weiter in eine für die Zielein Modul eine Gruppierung von Code dar – in der Java-Welt umgebung und Anwendung geeignetere Untermenge teilen. entspricht dieser Gruppierung einer Sammlung von PaEine Java-Installation umfasste immer alle für die jeweilige ckages. Ein Modul enthält somit Referenzen auf Java-QuellPlattform vorgesehenen Bibliotheken (beispielsweise die code, betriebssystem- und maschinenspezifische Dateien, APIs zu SQL, Swing oder XML), selbst wenn die Anwendung Entwicklungsressourcen oder Konfigurationsdateien. Die diese APIs nicht benötigte. Dieser Ballast erschwerte den geDeklaration eines Moduls erfolgt in einer Datei mit dem Nasamten Entwicklungsprozess und erhöhte wesentlich die men module-info.java; diese module-info.java-Datei befindet Kosten, auch in der Produktion zur Laufzeit. sich in einem Verzeichnis, das den Namen des Moduls trägt. Bis zur Version 8 kannte die Java-Plattform lediglich eine Die zu einem Modul gehörenden Bestandteile wie JavaDatenkapselung (Encapsulation) im Sinne von Parnas: SpeziQuellcode, Ressourcen und Ähnliches elle Sprachkonstrukte (private, public, befinden sich standardmäßig unterhalb default, protected) verbergen Daten in des Modul-Verzeichnisses (Bild 4). Den (abstrakten) Klassen und Interfaces vor Namen eines Moduls kann man belieeinem äußeren Zugriff. Dabei unterbinbig wählen; um Eindeutigkeit sicherzudet das Schlüsselwort private den direkstellen, sollte man sich am URL-Naten Zugriff auf interne Java-Datenstrukmensschema des zugehörigen Package turen, während public einen Zugriff auf orientieren. Die requires-Anweisungen ausgewählte Datenstrukturen über deverdeutlichen, welche anderen Module finierte Schnittstellen erlaubt (Bild 3). das aktuelle Modul für eine ÜbersetDieses Geheimnisprinzip (Informationzung und Ausführung benötigt, wähHiding) bietet lediglich Zugriffsschutz; rend die exports-Anweisungen die berücksichtigt aber nicht FragestellunSchnittstelle des Moduls extern zugen zur Laufzeit wie Shadowing oder gänglich macht, das heißt, die für andeVersionierung. re Module öffentlichen Typen des PaVersion 9 der Java-Plattform erweitert ckage festlegt. das Geheimnisprinzip (Information Kapselung stellt eine einheitliche KomErgänzend zum öffentlich zugängliHiding) einer Kapselung von Objekten munikation über definierte Schnittstellen beziehungsweise Klassen auf eine Kap- mit dem Objekt sicher, gemäß den Prinzipi- chen API eines Moduls enthält dessen Ablagestruktur auch die nur internen, selung zur Laufzeit für ganze Bibliothe- en Information-Hiding (Datenkapselung) ken mittels Modulen. Dies erfolgt an- und dem Black-Box-Modell des Software- nicht exportierten Packages und deren Quellcode (Bild 4). Natürlich kann man hand neuartiger Konstrukte der Spra- Engineering (Bild 3)

20

3.2017 www.webundmobile.de


Java

Module in einer beliebig anderen Verzeichnisstruktur ablegen. Das standardmäßig vorgesehene Layout bietet jedoch den Vorteil, durch Angabe nur eines Suchpfads alle Module mit einem einzigen Compilerlauf übersetzen zu können. Soll ein Modul lediglich zur Laufzeit sichtbar sein, fügt man der requires-Anweisung die optionale Angabe for reflection hinzu; soll es nur zur Compilezeit verfügbar sein, drückt dies der Zusatz for compilation aus.

Teamarbeit und Software-Marketing Der Java-Compiler überführt eine Modul-Deklarationsdatei (module-info.java) wie eine herkömmliche .java-Quelldatei in eine module-info.class-Datei, den sogenannten Modul-Deskriptor. In Java 9 übersetzt die neue javac-Option --modulesource-path (Modul-Source-Pfad) den Quellcode des Moduls und alle von ihm benötigten Module, vorausgesetzt, diese liegen ebenfalls im Quellcode vor. Somit kompiliert ein einziges Kommando alle Module einer Anwendung und legt die CLASS-Dateien strukturiert in einem einheitlichen Ausgabeverzeichnis ab:

FEaTURE

Neue Version mit passendem Nummernschema Das Schema zur Nummernvergabe für eine JDK-Version wurde im Lauf der Zeit seitens Sun/Oracle immer wieder einmal geändert. So entschloss sich Sun, die JDK-Versionen 1.2 bis 1.5 unter der Bezeichnung Java 2 (Kurzform: J2SE) zu vermarkten. Ab der Version 1.5 erkannte auch Sun, dass die Bezeichnung Java 2 eher verwirrend war, und benannte diese kurzerhand in Java 5 um. Ab Version 1.6 ließ man die hinter dem Produktnamen Java 2 stehende Idee insgesamt fallen. So erhielten die JDK-Version 1.7 beziehungsweise JDK 1.8 die Namen Java 7 beziehungsweise Java 8. Jedoch gab im Unterschied zum Java-Produktnamen die JVM als Versionsnummer immer noch die Zahl 1 aus. So entsprach Java 7 der Versionsnummer 1.7 und Java 8 der Versionsnummer 1.8. Java 9 behebt nun diesen Missstand. Sämtliche VersionStrings, die innerhalb der JVM vorhanden sind, basieren auf dem Schema 9.x.x, sodass die bisher unverständliche 1 vor der JDK-Version entfällt.

# Alle .java-Quelldateien eines Moduls # inklusive der benoetigten Module uebersetzen # und im Ordner build ablegen $ javac -d build --module-source-path src \ $(find src -name "*.java")

Liegen Module lediglich in übersetzter Form als CLASS-Dateien (Bytecode) vor, so greift man auf den in Java 9 eingeführten --module-path (kurz: --mp) zurück. Diese CompilerOption kompiliert den Quellcode eines Moduls, ohne dass für die anderen benötigten Module der Quellcode vorliegen muss. Für den Java-9-Compiler reicht der Bytecode (CLASSDateien) aller benötigten Module aus, um das eigene Modul zu übersetzen:

In Java schränken Zugriffs- und Sichtbarkeitsmodifizierer (Access/Visibility Modifier) die Rechte auf andere Objekte ein (Kapselung) oder verlangen von deren Subklasse ein bestimmtes Verhalten (Vererbung/Abstraktion) (Bild 5)

# Das Modul com.firma.awse unter Einbezug

Alternativen für Java-Applets Da zukünftige Java-Plattformen nach Version 10 nicht mehr das Netscape-Plug-in-API-Protokoll (NPAPI) für Applets unterstützen, sollte man baldmöglichst Alternativen nutzen: Java Web Start: Mit J2SE 1.4 stellte Oracle erstmals die JavaWeb-Start-Technologie vor, um Java-Anwendungen unabhängig vom Webbrowser über HTML-Links zu starten und auch Updates durchzuführen. Neben einer Portabilität über Webbrowser hinweg bietet Java Web Start die Möglichkeit, ganz gezielt einen bestimmten Release der Java-Plattform zu nutzen. native Betriebssystem-Installer: Diese eignen sich nur für Desktop-Anwendungen, die keine zentrale Administration benötigen und eine auf dem jeweiligen Betriebssystem installierte JRE nutzen können. WebView-Komponente von JavaFX: Dabei handelt es sich um die auf WebKit basierte Embedded-Browsertechnologie von JavaFX. WebView unterstützt vollständig CSS, JavaScript, DOM und HTML5.

www.webundmobile.de 3.2017

# des Bytecodes der benoetigten Module uebersetzen $ javac --module-path build -d build/com.firma.awse \ src/com.firma.awse/module-info.java

Dadurch ermöglicht der Modulpfad eine arbeitsteilige Realisierung eines Anwendungssystems, sodass man einzelne Module als Arbeitspakt verschiedenen Mitgliedern eines Entwicklungs- oder Projektteams zuordnen kann. Gleichzeitig schafft der Modulpfad die Voraussetzung, ganze Java-Module als eigenständige Bibliotheken auf dem Softwaremarkt zu vertreiben. Zudem schützt das neue Modulkonzept geistiges Eigentum, da dessen Quellcode nicht offen zugänglich sein muss. Gegenüber den Vorgängerversionen ändern sich mit Java 9 die Regeln für die Sichtbarkeit von Namen. Bis zur Version 8 (Bild 5) kann man auf jede Deklaration, die als public gekennzeichnet ist, ohne zusätzliche Vorkehrungen direkt im Quellcode und zur Laufzeit über den Klassenpfad (classpath) zugreifen. Version 9 bietet Entwicklern erstmals eine modulare Programmierung und implementiert hierzu eine strenge ▶

21


FEaTURE

Java

Datenkapselung (strong Encapsulation). Nur als public deklarierte Namen, die sich in einem exportierten Package eines Moduls befinden, können von anderen Modulen angesprochen werden.

abwärtskompatibilität, Javaarchiv und Modul-Typen Das nach der Übersetzung folgende Packaging für die Softwareverteilung (Deployment) erfolgt in Java 9 unter Einbezug der Module. Wie bisher erzeugt das Java Archive-Tool (jar) aus allen CLASS-Dateien (inklusive dem Modul-Deskriptor) und den dort referenzierten Ressourcen ein JAR (Ja- Das Java archive-Tool (jar) besitzt in Version 9 eine Vielzahl neuer Aufrufparameter va Archive). Für die zugehörige JAR-Datei und Optionen (Bild 6) verwendet man in der Java-9-Terminologie den Begriff eines modular JAR (Modulle-descriptor für ein modulares JAR den Modul-Deskriptor JAR). Dabei handelt es sich um eine gewöhnliche JAR-Datei, aus. Um den Inhalt eines build-Ordners in eine JAR-Datei zu die in ihrem Wurzelverzeichnis zusätzlich eine module-info. packen, greift man auf den nachfolgenden Befehl zurück; daclass-Datei enthält. bei ist die Angabe der Startklasse über den Aufrufparameter Diese Konzeption für den Aufbau eines Java-Archivs und (--main-class) optional: ein neuer Lademechanismus für Modul-JARs gewährleisten die Abwärtskompatibilität (Backward Compatibility) einer # Ausgehend von den .class-Dateien erstellt das JAR-Datei. Da module-info.java keinem gültigen Namen ent# jar-Tool im Verzeichnis mlib das Java-Archiv spricht, ignorieren ältere JVMs einfach die übersetzten mo# Anwnd.jar. dule-info.class-Dateien. Eine JVM ab Version 9 greift zur # Die Startklasse stellt com.firma.awse.Verkauf dar. Ausführung einer JAR-Datei auf den Modulpfad (java --mp) zurück. In Anlehnung an den alten Klassenpfad (classpath) $ cd build gibt man über den Modulpfad JARs beziehungsweise ganze $ jar --create --file mlib/Anwnd.jar \ Verzeichnisse an, aus denen Module geladen werden. --main-class com.firma.awse.Verkauf Ferner erhält das jar-Tool mit Java 9 eine Fülle neuer ParaUm eine Koexistenz herkömmlicher und modularer JARs zu meter und Optionen, die der Befehl jar --help in einem Tergewährleisten, implementiert Java 9 nachfolgende Vorgeminalfenster anzeigt (Bild 6). So gibt die Option --print-modu-

OpenJDK, JEPs, JSRs und JCPs Seit mehr als zehn Jahren favorisieren Sun und danach Oracle mittels der OpenJDK-Community eine OpenSource-Implementierung der Java Platform, Standard Edition (Java SE): OpenJDK: Das OpenJDK-6-Projekt stellte auf Basis von JDK 7 erstmals eine Open-Source-Version (primär abgestimmt auf die Anforderungen von Java 6) vor. Die OpenJDK-Implementierung dient allen Beteiligten als eigenständige, frei zugängliche Referenzplattform. JEP: Ein JDK Enhancement Proposal entspricht einem seitens Oracle getriebenen Prozess, der sich Das OpenJDK-Projekt setzt JSRs als Referenzimplementierung um; Hermit wichtigen neuen Anforderungen an das JDK besteller überprüfen Implementierungen mittels der Compatibility Test Suite schäftigt und – entsprechende Eignung vorausgesetzt – zukünftig in einem JSR endet. JSR: Ein Java Specification Request beschreibt in formal aufge JCP: Ein Java Community Process definiert eine Vorgehensweise bauten Dokumenten neue, für die Java-Plattform vorgeschlazur Bereitstellung von JSRs; er führt vor der offiziellen Freigabe gene Spezifikationen oder Technologien. eines JSR öffentliche Reviews mit den JCP-Mitgliedern durch.

22

3.2017 www.webundmobile.de


Java

hensweise: Übergibt man einer JVM im Modulpfad JARs ohne Moduldeskriptor (bisher klassisches JAR), so wird zur Laufzeit ein Moduldeskriptor automatisch generiert. Man spricht dann von einem automatischen Modul (Automatic Module), dieses exportiert alles (exports all) und wird allen anderen Modulen als Abhängigkeit hinzugefügt (requires all). Im Unterschied dazu bezeichnet man Module eines modularen JAR als explizite (benannte) Module. Sollen alle JARs eines Klassenpfads (classpath) als Module zugreifbar sein, so erzeugt man zur Laufzeit sogenannte Unnamed Modules (requires all). Parallel zur Modularisierung der Java-Plattform gruppierte Oracle die JDK-APIs in verschiedene Kategorien. Diese Gruppen helfen Programmierern, die Portierung einer Anwendung auf Java 9 und die nachfolgenden Versionen in Einzelschritten vorzubereiten und so insgesamt zu erleichtern: Supported: Nur diese API-Kategorie ist für den externen Gebrauch von Entwicklern in eigenen Programmen vorgesehen. Zu ihnen gehören alle vom JCP verabschiedeten Standard-APIs des JDK wie java.* oder javax.*. Zusätzlich kommen einige JDK-spezifische APIs wie com.sun.* oder jdk.* hinzu. Unsupported: Bei dieser API-Kategorie handelt es sich um JDK-interne APIs, die man nicht extern in eigenen Anwendungen verwenden sollte; sie umfassen die meisten sun.*Packages.

FEaTURE

Listing 1: Deklaration eines Moduls awse /* * In der Datei module-info.java steht die * Modul-Deklaration * Die module-Anweisung gibt dem Modul * den Namen com.firma.awse * Das Verzeichnis src\com.firma.awse (Windows) * beziehungsweise * src/com.firma.awse * (Mac OS X, Linux) enthaelt die module-info.java* Datei (Deklarationsdatei) * Den zum Modul com.firma.awse gehoerenden Quellcode * findet man unter Windows in den * Unterverzeichnissen src\com.firma.awse, unter * anderem findet man dort *

src\com.firma.awse\sysa\kunde

*

src\com.firma.awse\sysa\produkt

*/ module com.firma.awse { // hier die benoetigten Module auflisten requires sysb.lager; requires sysb.bestell; // hier die Dienstleistungen des Moduls // verfuegbar machen exports sysa.kunde;

Die letzte API-Kategorie der unsupported APIs, also die JDKinternen APIs, unterteilt Oracle in zwei weitere Gruppen. Für beide Gruppen zeigt Oracle frühzeitig mögliche Migrationspfade für Anwendungen auf, um auf diese Weise Programmierer bestmöglich zu unterstützen: non-critical: Diese Kategorie findet außerhalb des JDK in Anwendungen keine Verbreitung, höchstens zu Informationszwecken. Version 9 kapselt diese in eigenständige Module und nutzt diese nur für interne Zwecke.

OSGi – OSGi Service Platform Die OSGi Alliance unterstützt mittels der OSGi Service Platform die Modularisierung von Java-Anwendungen nicht nur zum Entwicklungszeitpunkt, sondern auch zur Laufzeit unter anderem mit folgenden Features: Komponenten/Module: OSGi diente zur Realisierung von Java-Komponenten (Module, Bundles/Services). Auf der Ebene von Packages deklariert man Abhängigkeiten zwischen den Komponenten. Shadowing: Besitzen zwei Objekte denselben Namen, kennt man aus der Softwaretechnik verschiedene Strategien für den Zugriff auf das gewünschte Objekt. Auch OSGi verfügt über verschiedene Strategien zur Auflösung (Resolution) von Namensgleichheiten auf Modul-Ebene. Versionierung: OSGi umfasst ein Versionskonzept unter anderem für den gleichzeitigen Betrieb mehrerer Versionen eines Moduls.

www.webundmobile.de 3.2017

exports sysa.produkt; }

Critical: Sie beinhalten Funktionen, die man außerhalb des JDK nur schwer, wenn überhaupt, implementieren kann. Zu ihnen zählen sun.misc.* und sun.reflect.*. JDK 9 erklärt die critical internal APIs als deprecated (veraltet). Es ist geplant, die in Version 9 noch benutzten critical APIs ab Version 10 vollständig zu beseitigen.

Das JDK Enhancement Proposal 260 beschreibt alle kritischen internal APIs, die so lange in zukünftigen Java-Versionen verfügbar bleiben, bis für sie ein Ersatz geschaffen wurde. Um eigene Anwendungen auf den Gebrauch derartiger APIs zu untersuchen, enthält das JDK seit Version 8 den Java Class Dependency Analyzer jdeps. Dieses Tool analysiert auch Abhängigkeiten von JARs und Modulen. Version 9 bringt für jdeps einige Verbesserungen und Erweiterungen, um alle Klassen eines JAR, einer CLASS-Datei, eines Verzeichnisses oder eines voll qualifizierten Klassennamens zu analysieren.

Eine Vielzahl von aufrufparametern Zudem besitzt jdeps eine Vielzahl von Aufrufparametern und unterstützt auch Filter, um die Ergebnisse einer Abhängigkeitsanalyse bedarfsorientiert einzuschränken; auch über Muster mittels regulärer Ausdrücke kann gesucht werden. Leider kennt jdeps in Java 9 wie bisher nur statische Ab- ▶

23


FEaTURE

Java

hängigkeiten. Dynamische Abhängigkeiten, die zur Laufzeit entstehen, bleiben nach wie vor bei der Analyse unberücksichtigt. Bei jdeps handelt es sich also um ein sogenanntes statisches Analysewerkzeug.

Qualitative Erweiterungen Ein Modul-Readability-Graph entsteht durch einen Modul-Abhängigkeits-Graphen, indem implizit vorhandene Lesebeziehungen zwischen den Modulen berücksichtigt werden. Um eine Lesbarkeit beziehungsweise einen Zugriff für ein Modul an ein anderes implizit weiterzureichen, Eine analyse von javafx-swt.jar mit jdeps und der Ausgabeoption -dotoutput besitzt Java 9 für die Moduldeklaration bei der erzeugt zwei DOT-Dateien: javafx-swt.jar.dot und summary.dot (Bild 7) requires-Anweisung einen optionalen publicModifier. Ein requires public eines Moduls A in ein Service-Interface java.sql.Driver über den Service-Proder Deklaration des Moduls Z bedeutet, dass jedes anderes vider com.mysql.jdbc.Driver. Diese Vorgehensweise legt beModul B über eine requires-Anweisung auf Z auch lesend auf reits vor der Ausführung eines Programms eine versteckte Modul A zugreifen kann. Implementierungsklasse für das Modulsystem offen. Beide Ergänzend zur losen Kopplung von Modulen über eine imKonstrukte requires public und provides … with dienen dem plizite Lesebeziehung mittels requires public kennt Java Compiler als qualitätssichernde Maßnahmen bereits bei der auch eine lose Kopplung von Programmen über Service-InÜbersetzung einer Anwendung, um spätere Laufzeitfehler bei terfaces und Service-Provider. Über den Klassenpfad (classder Programmausführung auf ein Minimum zu beschränken. path) findet die JVM zur Laufzeit einen passenden ServiceProvider. analyse von Modul-Graphen Ein Service-Interface macht man in einer Modul-DeklaraÜber die Option -help gibt jdeps für sämtliche verfügbaren tion über eine provides … with-Anweisung anderen Modulen Aufrufparameter eine Zusammenfassung in einem Terminalverfügbar. So definiert in einer Modul-Deklaration die Anfenster aus. Zusätzliche Informationen erhält man auf der für weisung: jdeps speziell eingerichteten Homepage. Zur Planung der provides java.sql.Driver with com.mysql.jdbc.Driver; Migration einer Anwendung auf das JDK 9 sollte man diese mittels jdeps und der Option jdkinternals analysieren, um Abhängigkeiten von internal APIs zu erkunden. Für alle nicht in JEP 260 aufgeführten APIs benötigt man baldmöglichst einen Java 9 mit durchgängigem Multi-Release-Support Ersatz, da diese in Java 9 für die Programmierung von AnErstmals unterstützt Java 9 sogenannte Multi-Release-JARs. wendungen generell nicht mehr zugänglich sind. Dabei handelt es sich um JARs, die für unterschiedliche JavaUm die mittels einer jdeps-Analyse ermittelten AbhängigVersionen vorgesehen sind. keiten in eine DOT-Datei zu schreiben, steht die Option -dotAb Java 9 verfügen der Java-Compiler (javac) und das Java output <verzeichnis> zur Verfügung. jdeps erzeugt im speziArchive Tool (jar) über einen neuen Aufrufparameter -release. fizierten Ordner <verzeichnis> für jede zu analysierende Damit generiert der Java-Compiler von Version 9 Bytecode für CLASS- oder JAR-Datei eine eigene DOT-Datei mit den zudie Zielplattformen Java 6 bis Java 9. gehörigen Abhängigkeiten. Zusätzlich erstellt das AnalyseDem Java Archive Tool teilt man über die --release-Option Tool eine summary.dot-Datei, in der alle Abhängigkeiten zudarüber hinaus auch mit, in sammenfassend aufgeführt sind (Bild 7). welches Verzeichnis das Ein so erzeugte DOT-Datei dient als Grundlage, um die AbMulti-Release-JAR unterhängigkeiten über eine Grafiksoftware (zum Beispiel Graphhalb META-INF/versions viz) visuell darzustellen. Die grafische Darstellung des Mojeweils nach Versionen dul-Graphen erleichtert die Planung von Einzelschritten für gruppiert gespeichert werdie Migration einer Anwendung. Zur Vorbereitung einer Miden soll. gration stellen die nachfolgenden Aufrufoptionen von jdeps hilfreiche Informationen oder gar weiterverwendbare Arbeitsergebnisse bereit: list-deps: Gibt die Abhängigkeiten und die verwendeten Ein Multi-Release-JaR unterstützt gleichzeitig JDK-internen APIs aus. list-reduced-deps: Arbeitet wie -list-deps, berücksichtigt verschiedene Javaaber keine impliziten Lesebeziehungen. Laufzeitumgebungen. add-modules <modul-namen>: Fügt die übergebenen Modu-

24

3.2017 www.webundmobile.de


Java

le zur Menge der bisher zu untersuchenden CLASS/JARDateien hinzu. check <modul-namen>: Analysiert die in den aufgeführten Modulen enthaltenen Abhängigkeiten, gibt deren ModulDeskriptor aus und identifiziert nicht verwendete qualifizierte Exporte. generate-module-info <verzeichnis>: Erzeugt eine moduleinfo.java-Datei für die im jdeps-Befehl genannten JAR-Dateien und legt diese im genannten Verzeichnis ab. Version 9 des JDK enthält erstmals als eigenständiges Tool einen Java-Linker: jlink genannt. Das Werkzeug baut Anwendungen mit minimaler Java Runtime, die ausschließlich verwendete (das heißt, vom Programm benutzte) Module aus der JDK-Modulmenge umfassen. Da der Java-Linker nur die wirklich benötigten Module verwendet, erzeugt er eine minimale Java-Laufzeitumgebung; jlink führt quasi eine Runtime-Optimierung durch. Greift etwa eine Anwendung nicht auf die XML-Funktionalität des JDK zurück, so kopiert jlink dieses Modul auch nicht in die Laufzeitumgebung.

FEaTURE

Sichtbarkeit von Namen in Java 9 Mit der neuen Java-Version ändern sich grundlegend die Regeln für Zugriffe auf public-deklarierte Namen: Mit public deklarierte Namen, die ein Modul exportiert, sind für alle sichtbar und damit direkt verwendbar. Führt ein Modul lediglich ein exports von Packages für bestimmte Module durch (exports packages_names to module_ names), so beschränkt sich die Sichtbarkeit auf die nach to genannten Module (Qualifizierter Export / Qualified Export). Auf alle übrigen (die bisherigen) public-Deklarationen können lediglich andere Klassen, die sich innerhalb desselben Moduls befinden, zugreifen.

Platzsparende Runtime Ergebnis eines jlink-Aufrufs stellt eine platzsparende Runtime unter Berücksichtigung aller selbst programmierten und benutzten Anwendungsmodule dar; man spricht von einer möglichst kleinen ausführbaren Distribution. Außer Applikationsimages erzeugt der Java-Linker auch alle anderen für die Ausführung oder die Wiederverwendung von Bytecode erforderlichen Dateitypen (Bild 8). Ausgehend von CLASS-/ JAR-/JMOD-Dateien generiert der Linker Modul-Bibliotheken (.jmod), Java-Archive (.jar), Java-Bibliotheken oder ausführbare Distributionen (JVM-Image). Dem Java-Linker übergibt man mittels -module-path die aus dem JDK benötigten Module und macht ihm zusätzlich mit der Option -addmods die selbstprogrammierten Module zugänglich. Aus diesen über -module-path und -addmods zugeführten Modulen schreibt der Linker seine Arbeitsergebnisse in das über -output festgelegte Verzeichnis: jlink --modulepath $JAVA_HOME/jmods:mlib --addmods Verkauf \ --output myimage

Der Java-Linker verarbeitet drei verschiedene Bytecode-Typen und erzeugt aus ihnen je nach Zielrichtung verschiedene Bytecode-Typen zur Wiederverwendung (Bild 8)

www.webundmobile.de 3.2017

Java 9 besitzt eine interaktive Kommandozeile, um Java-Befehle zu verarbeiten und deren Ergebnisse anzuzeigen (Bild 9)

Sollte der Linker Module vermissen, so gibt er entsprechende Fehlermeldungen aus. In dem durch die Option -output genannten Verzeichnis legt der Linker die Unterverzeichnisse: bin, conf und lib an und erstellt zusätzlich eine Datei mit dem Namen release. Die release-Datei enthält systemrelevante Informationen wie den Zeitpunkt des Linkvorgangs oder die Versionsnummer des Betriebssystems und des JDK. Ergänzend besitzt der Linker eine Plug-in-Architektur, damit Werkzeughersteller den Link-Prozess an ihre eigenen Bedürfnisse anpassen können. Mittels -plugins-module-path teilt man dem Linker mit, in welchem Pfad er eventuell benötigte Plug-ins findet.

JShell – die interaktive Kommandozentrale für Java Einige Programmiersprachen besitzen im Umfeld ihrer Entwicklungsumgebung ein Werkzeug, häufig Shell genannt, um direkt Befehle der Sprache auszuführen. Derartige Werkzeuge sind unter dem Akronym REPL (Read-Evaluate-Print Loop) schon länger bekannt. Als Programmierer übergibt man der Shell Sprachbefehle, diese führt die Befehle aus und zeigt die Ergebnisse unmittelbar am Bildschirm an. Mit Java 9 steht für Entwickler auch eine derartige Shell zur Verfügung: die JShell. Entwickler arbeiten interaktiv mit der JShell; sie ist recht tief mit dem JDK integriert, kennt zum Beispiel auch import-Befehle. Ergänzend besitzt die JShell auch ein eigenes API, um sie von anderen Anwendungen aus nutzen zu können. JShell stellt keine neue Sprache oder eine neue ▶

25


FEaTURE

Java

Syntax dar, vielmehr verarbeitet sie reines Java. Sie eignet sich besonders für Anfänger, die Java schnell erlernen wollen, da man nach Eingabe der Befehle von der JShell eine sofortige Rückmeldung erhält. Java-lernende Anwender wie Studenten können so mit dem JDK und den Fähigkeiten von Java experimentieren und mit der JShell schrittweise komplexeren Code schreiben. Damit unterstützt die JShell erstmals Prototyping für Java, ohne den sonst üblichen und länger dauernden Edit-Compile-Execute-Zyklus einhalten zu müssen. Die Nutzung der JShell setzt eine Installation des JDK 9 voraus. Ihre Befehlszeile erreicht man über die Eingabe des Kommandos jshell auf der Betriebssystemebene (Bild 9). Bereits von der JShell verarbeitete Befehle legt sie in einem History-Speicher ab, zusätzlich besitzt sie Editier- und TabulatorFunktionen. Generell kennt die JShell zwei verschiedene Befehlstypen: Java-anweisungen: Dabei handelt es sich um Java-Quellcode, also Java-Befehle, woraus im Allgemeinen eine Deklaration oder eine Ausführung von Befehlen resultiert. Zu ihnen gehören auch alle über das JDK verfügbaren Funktionen, extern zugängliche Packages sowie die Verarbeitung ganzer Java-Ausdrücke. Nicht erlaubt sind derzeit Befehle, welche die externe Umgebung modifizieren, wie die Definition von Packages oder die Verwendung von public private … oder static final. JShell-Kommondos: Sie dienen zur Steuerung des Tools oder um Informationen über das Tool zu erhalten. Um JShellKommandos von Java-Anweisungen zu unterscheiden, beginnen diese immer mit einem Slash-Zeichen /. JShellKommandos bestehen aus fünf Befehlsgruppen: zur Information wie /list, /vars oder /types, der Befehlskontrolle wie /edit, /save oder /open, Session-Befehlen wie /exit oder /reload, History-Befehlen wie /history oder /-n und allgemeinen Befehlen wie /set oder /help. Für ein produktiveres Arbeiten mit der JShell benötigt man bestimmtes Wissen seitens ihrer Implementierung. Konzeptionell basiert das Editieren der Zeilen in der JShell auf der Open-Source-Bibliothek JLine. Dabei handelt es sich um eine Java-Bibliothek, die Eingaben von einer Konsole des Betriebssystems verarbeitet und damit verbundene Java-Befehle ausführt. Die Realisierung von JLine besitzt keinerlei weitere Abhängigkeiten zu anderen Bibliotheken.

Java 9 kennt zwei weitere Modul-Typen Neben den Modul-Typen zur Gewährleistung der Abwärtskompatibilität (Backward Compatibility) kennt das neue Modulsystem noch zwei weitere Modul-Typen: Plattform-Module (Platform Modules): Dabei handelt es sich um Module, die aufgrund der Modularisierung der Java SE entstanden. Anwendungsmodule (Application Modules): Diese stammen aus der Modularisierung von Bibliotheken und Anwendungen.

26

Die Funktionalität von JLine bildet die Fähigkeiten der Shells moderner Betriebssysteme wie bash oder tcsh ab. Auf diese griff das OpenJDK-Projekt zurück, um dem Programmierer mit der JShell eine interaktive Java-Shell bereitzustellen. Spezielle Cursor-Steuerungen sind für die Navigation innerhalb der Befehlshistorie sowie für die Autovervollständigung von Java- oder Shell-Kommandos vorgesehen. So führt man mit der Return-Taste eingegebene Befehle aus oder holt diese aus dem History-Speicher, um sie nochmals auszuführen.

Cursor-Steuerungstasten Mit den Cursor-Steuerungstasten bewegt man den I-Beamer innerhalb der Eingabezeile oder scrollt mit ihnen durch die im History-Speicher abgelegten Befehle. Die Tabulatortaste hilft bei der automatischen Vervollständigung einer aktuell in der Kommandozeile stehenden Zeichenkette. Mit dem /list-Kommando zeigt man sich die aktuell im Speicher der JShell befindlichen Befehle an. Über /save <dateiname> speichert man diese Befehle in einer externen Datei mit dem übergebenen Namen ab. Über /open <dateiname> führt die JShell alle in der genannten Datei enthaltenen Befehle unmittelbar aus. Will man sich die im jeweiligen Ordner enthaltenen Dateinamen anzeigen lassen, so genügt die Eingabe eines Anfangsbuchstabens ihres Namens oder einer in ihm enthaltenen Zeichenkette; anschließend zeigt ein Druck auf die Tabulatortaste die dazu passenden Dateien an. Die beiden Befehle /methods und /vars geben gezielt einzelne Methoden beziehungsweise Variablen oder alle der JShell aktuell zugänglichen aus. Die Kenntnis der Zeilensteuerung des Emacs-Editors ist recht hilfreich, da die JShell diese unterstützt. Um einen laufenden Prozess oder die Zeilenverarbeitung zu unterbrechen, greift man auf [Strg/Ctrl C] zurück.

Modul-Graphen und deren Eigenschaften Allgemein beschreibt ein Modul-Graph Beziehungen zwischen Modulen (Knoten: Module, Kanten: Beziehung zwischen den beteiligten Modulen). Java 9 unterteilt diesen (gerichteten) Graphen in zwei weitere Typen: Modul-abhängigkeits/Dependency-Graph: Er bildet alle requires-Beziehungen zwischen Modulen rekursiv ab. Ausgehend von einem Modul als Startknoten dienen die von ihm gelesenen Module als Endknoten. Die Kante zwischen Startund Endkonten stellt die requires-Beziehung dar. Danach betrachtet man Endknoten als neue Startknoten zur rekursiven Erweiterung des Graphen. Module-Readability Graph: Dieser Graph-Typ entsteht durch Erweiterung des Modul-Abhängigkeitsgraphen um diejenigen Endknoten und Beziehungen, die lesend auf den Endknoten als Modul von einem Startknoten aus zugreifen – obwohl das Start-Modul keine direkte requires-Beziehung zum Endknoten besitzt.

3.2017 www.webundmobile.de


Java

Die beiden Unix-Shells: bash und tcsh Als freie Unix-Shell und Teil des GNU-Projekts findet man die bash als Standard-Shell auf vielen Unix-basierten Betriebssystemen. Die bash beherrscht viele Befehle der Bourne-Shell (sh) und die meisten Funktionen der Korn-Shell (ksh). Bei der weitgehend mit der C-Shell (csh) kompatiblen tcsh handelt es sich um die mit BSD-basierten Systemen wie FreeBSD ausgelieferte Root-Shell. Als sogenannte Root-Shells zielen beide darauf ab, das Arbeiten mit dem Betriebssystem für den Administrator (häufig Superuser genannt) zu erleichtern. Dem Superuser als Benutzerkonto zugeordnet ist das Root-Konto. Dieser Account eignet sich nicht für alltägliche Aufgaben, da er mit umfassenden Rechten versehen ist, sondern ist nur für besondere Verwaltungsaufgaben vorgesehen. Um diese Aufgaben der Administration und Verwaltung vornehmen zu können, verfügen beide Shells über zahlreiche eingebaute Befehle und weitere Schlüsselwörter für die Programmierung. Damit sind sie in der Lage, Befehle des Betriebssystems direkt auszuführen. Zusätzliche Features wie Befehlszeilenergänzung oder Setzen von Umgebungsvariablen tragen wesentlich zu der Mächtigkeit beider Shells bei.

Verbesserungen beim Einsatz von Betriebssystemprozessen Im Zentrum der Spezifikation der Programmiersprache Java stand die Unabhängigkeit von einer bestimmten Plattform. Diese Unabhängigkeit bezog sich vor allem auf das Betriebssystem und andere plattformabhängige Schnittstellen. Die Vergangenheit hat jedoch gezeigt, dass man zur Realisierung spezifischer Anwendungen dennoch innerhalb eines JavaProgramms plattformabhängige Programme, die nicht auf Java basieren, ausführen oder auf diese zugreifen können muss. Aus diesem Grund besitzt das JDK schon seit Längerem ein Process API. Dieses Process API bildet die Schnittstelle der JVM zum Betriebssystem, denn Java selbst unterstützt kein Prozessmodell, mit dem man verschiedene Prozesse innerhalb derselben virtuellen Maschine parallel behandeln kann. Daher handelt es sich bei diesen seitens der Java-Anwendung verwalteten Prozesse um reine Verarbeitungseinheiten, die innerhalb des Betriebssystems und nicht innerhalb der JVM ablaufen. Ein über die start()-Methode der ProcessBuilder-Klasse erzeugter Prozess läuft daher außerhalb der JVM auf der Ebene des Betriebssystems. Die Kommunikation zwischen der virtuellen Maschine und dem externen Prozess des Betriebssystems erfolgt über dessen InputStream und OutputStream. Mit Java 9 verbessert sich das Process API, sodass man als Entwickler leichter zwischen Java und dem Betriebssystem Informationen austauschen kann. In Version 9 kann man mittels des Process API in Java aktuell laufende Prozesse anzeigen lassen und zusätzlich einige ihrer Eigenschaften wie ProcessID, Name und Status ab-

www.webundmobile.de 3.2017

FEaTURE

fragen. So ermittelt zum Beispiel der nachfolgende Befehl die dem aktuell laufenden Prozess zugeordnete ProcessID: System.out.println("Die ProcessID ist " + Process.getCurrentPid());

Insgesamt gestaltet sich mit Version 9 das Management von Prozessen auf der Ebene des Betriebssystems wesentlich einfacher. Eine wichtige Erleichterung brachte ein neues Interface ProcessHandle und dessen Methoden. So macht dieses die nachfolgende bisher notwendige Aufteilung der betriebssystemseitigen Zeichenketten über das @-Zeichen hinfällig: Integer.parseInt(processName.split("@")[0]);

Jetzt ermittelt man direkt die gewünschten Informationen wie Startparameter, Benutzer oder Pfad über die Abfrage der gewünschten Felder von ProcessHandle.Info. Dafür stehen die Methoden allProcesses(), arguments(), children(), command(), current(), descendants(), parent() oder user() und weitere zur Verfügung.

HTTP/2-Protokoll für effizientere netzkommunikation Die Kommunikation über das Netz gestaltet sich auf der Basis des alten HTTP-Protokolls extrem zeitaufwendig, zumal weder Multiplexing noch Resource Correlation unterstützt werden. Um in der Vergangenheit mit Java in Anwendungen performant über HTTP kommunizieren zu können, musste man daher häufig auf lästige, codeaufwendige Workarounds zurückgreifen. Zu den gängigen Workarounds zählen CSSSprites, Domain/Hostname Sharding, Image Spriting oder Resource Inlining; sie alle besitzen eine wesentlich schlechtere Performance als das neue binäre HTTP/2-Protokoll. Mit Version 9 bietet Oracle erstmals für die Java SE einen HTTP/2-Support an und ersetzt den bisher gängigen Einsatz des HttpURLConnection-API. Das neue HTTP/2-API lässt sich relativ leicht benutzen und deckt die meisten in der Praxis auftretenden Anwendungsfälle ab. Die Kommunikation über das Netz kann dabei sowohl synchron als auch asyn- ▶

jmod – sowohl Werkzeug als auch Dateiformat Mit Java 9 liefert Oracle ein neues Dienstprogramm jmod aus, um JMOD-Dateien zu erzeugen oder deren Inhalt zu erkunden: jmod-Dateiformat: Das mit Java 9 eingeführte JMOD-Format geht wesentlich über das JAR-Format hinaus. Es beinhaltet alle Dateien, die man aus Sicht der Anwendung benötigt, die allerdings nicht per se in ein Java-Archiv gehören. jmod-Tool: Die Befehlssyntax des Werkzeugs lautet: jmod (create | list) <options> jmod-file. Mit create erzeugt man JMOD-Dateien; dazu stehen über options verschiedene Aufrufparameter bereit. Um eine an das Tool übergebene JMODDatei zu analysieren und deren Inhalt anzuzeigen, steht der Befehl list zur Verfügung.

27


FEaTURE

Java

Die zentralen Vorteile von HTTP/2 Version 2 von HTTP macht bisherig gängige Verfahren für das Design der Netzkommunikation hinfällig, da zeitlich aufwendige Roundtrips nicht mehr auftreten. Im Unterschied zur Version 1.x kommuniziert HTTP/2 nicht textuell, sondern über ein Binärformat. HTTP/2 arbeitet nicht mit Blocking/Ordering, sondern bietet durchgängiges Multiplexing und benötigt zur Parallelisierung lediglich eine Verbindung. Um den Overhead der Kommunikation zu senken, komprimiert es die Header. Requests in HTTP/2 lassen sich priorisieren. Server auf Basis von HTTP/2 pushen aktiv in Client-Caches ihre Antwort zur Verbesserung der Performance.

chron erfolgen. Bei der Implementierung achtete man auf Rückwärtskompatibilität, da Java 9 sowohl HTTP 1.1 als auch HTTP/2 unterstützt. In bestehenden HTTP-Anwendungen sind nur die alten HTTP/1.1-Workarounds zu beseitigen. Im Zentrum der Implementierung stehen der wiederverwendbare HTTP-Client-Container und HttpRequest. Ein HttpResponse erfolgt über die response()-Methode mittels Blocking, die Methode responseAsync() arbeitet asynchron; zudem können mehrere Responses asynchron über multiResponseAsync erzeugt werden. Innerhalb eines Response lassen sich HTML-Bodies mit einem BodyProcessor behandeln. Standardmäßig verarbeitet dieser in Java 9 die Datentypen Array, String und File; weitere eigene Datentypen definiert man selbst. Der in Java 9 integrierte MultiProcessor verfügt über die Interface-Methoden onStart und onComplete, um auf Standardereignisse zu reagieren. Über die multiFile()-Methode von HttpResponse erhält man einen MultiProcessor für Files, der Bodies für Dateien schreibt und eine Map<URI,Path> zurückliefert. Damit lassen sich ganze Bündel von Dateien asynchron verarbeiten. Diese mit HTTP/2 verbundenen Features

Der Prozess-Begriff in der Informatik In der Informatik stellt ein Prozess die Abstraktion einer Verarbeitungseinheit seitens des Betriebssystems dar. Das Betriebssystem unterteilt diese Verarbeitungseinheiten mittels einer Hierarchie in mehrere aufeinander abgestimmte Arbeitsschritte, die wiederum Verarbeitungseinheiten bilden. Als nebenläufige Ausführungseinheiten nennt man diese Threads. Auf der obersten Hierarchieebene entspricht eine Verarbeitungseinheit einem Programm. Ein Prozess existiert immer nur zur Laufzeit des Programms und nimmt während seiner Ausführung verschiedene Zustandsinformationen ein. Die Kontrolle des Prozesses, das heißt, seine Ausführung und dergleichen, erfolgt immer durch das Betriebssystem. Das Betriebssystem stellt dem Prozess erforderliche Ressourcen in einer Ablaufumgebung zur Verfügung.

28

nahm Oracle als Grundlage in die Servlet-4-Spezifikation der neuen, auf Java 9 basierenden Java-EE-Version auf.

Vereinfachungen für Collections Datensammlungen (Collections) stehen schon lange in Java zur Verfügung und wurden kontinuierlich über die verschiedenen Versionen hinweg weiterentwickelt. Man denke nur an das Collection-Framework, das java.util.concurrent-Package oder die mit Java 8 eingeführten Verbesserungen wie das Iterable-Interface (forEach, removeIf, replaceAll) und Ähnliches. Version 9 liefert jetzt sogar fertige Factory-Methoden für Collections: List.of(), Set.of(), Map.of(). Mit ihnen kann man Listen, Mengen oder Maps in fixer Länge (bis zu 10 Elemente), aber auch selbst programmiert in variabler Länge erzeugen: // Liste mit drei String-Elementen List<String> stringList = List.of("Otto", "Karl", "Bernd"); // Menge mit vier Integer-Elementen Set<Integer> intSet = Set.of(1, 2, 3, 4); // Map mit drei Eintraegen Map<String,Integer> stringMap = Map.of("a",1, "b",2, "c",3);

Das bisherige, leider seit Jahren wenig veränderte, java.util. logging-API des JDK erforderte einen sehr großen Aufwand für die Programmierung von Logs und deren Ausgabe. Daher griffen viele Entwickler in der Vergangenheit auf spezielle Logging-Frameworks (Log4j, Logback, SLF4J) zurück. Mit Version 9 existiert jetzt ein minimales Logging-API im JDK mit einem speziellen Service-Interface, das die Aufzeichnung von Logs wesentlich vereinfacht. Zusätzlich kann dieses Service-Interface Logging-Nachrichten an ein externes Logging-Framework weiterreichen, um auch dieses in der Entwicklung zu nutzen (Redirected Platform Logging).

Reactive-Streams-Spezifikation Java 9 enthält eine Implementierung der Reactive-StreamsSpezifikation und schafft so eine Basis für die ersten Schritte in Richtung reaktiver Programmierung in Java. Die damit verbundenen Prinzipien sollen die Zusammenarbeit zwischen den bereits für Java verfügbaren Bibliotheken und Frameworks der reaktiven Programmierung für das JDK ebnen. Die Neuerungen der Reactive Streams basieren auf dem Publish-Subscribe-Pattern. Nach der Anlage eines Publishers und eines Subscribers kommunizieren beide direkt asynchron über eine zuvor anzulegende Subscription-Beziehung. Damit besitzt das JDK 9 ein Publish-Subscribe-Framework; zudem ist über den JSR ein Technology Compatibility Kit (TCK) für Dritthersteller verfügbar. Bereits Sun lieferte seit Version 2 als Bestandteil des JDK das Dokumentationswerkzeug Javadoc aus. Damit dokumentieren Entwickler über Kommentare und Tags ihre Programme direkt im Java-Quellcode. Javadoc erzeugt aus diesen die

3.2017 www.webundmobile.de


Java

seitens des JDK bekannte API-Dokumentation als Standardausgabe im HTML-Format. Mit Version 9 unterstützt Javadoc jetzt zusätzlich zum bisherigen HTML 4.01 über den -html5Parameter eine HTML5-Ausgabe. Ferner prüft das -XdoclintFeature, ob sich innerhalb der Javadoc-Kommentare Fehler befinden. Eine neue Suchfunktion für die generierte API-Dokumentation findet direkt Module, Packages, Typen und Member.

Jeder GC hat spezifische Vor- und Nachteile Die vier gängigen Garbage Collectors (GC) arbeiten alle generationsbasiert; sie teilen den Heap (Speicherbereich für JavaObjekte) in zwei verschiedene, auf die Lebensdauer der Objekte ausgerichtete Segmente (Young- versus Old-Generation). Während kurzlebige Objekte über den Young-Generation Heap angelegt und baldmöglichst dem GC zugeführt werden, wandern langlebige oder permanente Objekte in den Old-Generation Heap: Serial-Collector: Er eignet sich nur für kleine Heap-Größen und ist auf Single-Threaded-Umgebungen ausgerichtet; kommt deshalb fast nie zum Einsatz. Parallel / Throughput-Collector: Er war bisher der Standard-GC, unterstützt mehrere Threads und einen kompakten Heap. Nachteilig wirkte sich der Ausführungsstopp von Threads aus, wenn die JVM nur kleine oder vollständige Speicherbereinigungen durchführt. CMS-Collector: Als Algorithmus basiert dieses GC auf parallelen Scans durch den Heap; unbenutzte Objekte werden als recyclebar markiert. Dieser GC arbeitet besonders gut bei der Verfügbarkeit mehrerer CPUs und einer Heap-Größe kleiner als 4 GByte. G1-Collector: Wurde speziell für Heaps größer als 4 GByte entwickelt. Er basiert auf mehreren Threads, die im Hintergrund Scans durch den Heap ausführen und so die Größe des Heap dynamisch verwalten.

Zentrale Verbesserungen für die Sprache Java 8 brachte Default-Methoden für Interfaces in die Diskussion, um diese flexibler gestalten und einfacher weiterentwickeln zu können. Leider führte dieser Ansatz für die Erweiterbarkeit von Interfaces über Methoden dazu, dass man sie im Fall einer Wiederverwendung als public deklarieren oder ihre Implementierung in eigene Helper-Klassen auslagern musste. Java 9 beseitigt nun diese Schwäche: Methoden in einem Interface können als private (static) deklariert werden: public interface Api { // private Methoden private int pruefen (int data) { System.out.println("Eingabe prüfen: "); return true; } }

Java 7 schaffte den häufig fehleranfälligen finally-Block für die try-Anweisung ab; das Schließen der beteiligten Ressourcen (Reader, Sockets, Streams) erfolgte ab Version 7 am Ende des try-Blocks automatisch. In Java 9 erlaubt die Try-WithResources-Anweisung den Einsatz von Variablen, solange diese als (effective) final anzusehen sind. Damit kann diese Variable direkt dem try-Konstrukt übergeben werden: // Fuer Konstante als Ressource // keine weitere Behandlung erforderlich try (resource) {

Reactive Programming Aktuell befindet sich die Reaktive Programmierung als neues Programmierparadigma häufig in der Diskussion. Dieses Paradigma orientiert sich nicht an Anweisungen, die sequenziell abgearbeitet werden, sondern an zueinander in Beziehung stehenden Datenflüssen. Das Ausführungsmodell des Reactive Programming basiert auf der automatischen Propagierung von Änderungen. Ändert sich ein Wert innerhalb eines Datenbestands, so löst die Propagierung dieser Änderung alle erforderlichen Aktualisierungen automatisch aus. Daher befinden sich nach Propagierung einer Änderung die von ihr betroffenen Datenbestände wieder in einem aktuellen, konsistenten Zustand.

www.webundmobile.de 3.2017

FEaTURE

resource.doSomething(); }

Anonyme Klassen stellen einen Spezialfall einer lokalen Klasse dar: Sie besitzen keinen eigenen Namen und werden stets innerhalb einer new-Anweisung definiert. Damit existiert eine anonyme Klasse immer nur im Kontext einer bestimmten Klasse. Da sie keinen Namen besitzt, beansprucht eine anonyme Klasse auch keinerlei Ressourcen im Namensraum der Klassen. Im Unterschied dazu erbt eine anonyme Klasse jedoch von anderen gemäß der Klassenhierarchie. Java 9 macht den mit Version 7 eingeführten Diamant-Operator (Paar spitzer Klammern <>) für anonyme Klassen zugänglich: NeueKlasse<?> neukla = new NeueKlasse<>(1) { // Anonyme innere Klasse };

Die Anwendung des Diamant-Operators für eine anonyme Klasse setzt voraus, dass der Datentyp dem Compiler bekannt oder zumindest aus dem Kontext ableitbar ist. Ist der Typ nicht bekannt, ist er also auch nicht aus dem Kontext der Anweisungen ableitbar, muss der Typ explizit bei der new-Anweisung mit angegeben werden. Diese Notwendigkeit resultiert aus dem Sachverhalt, dass zur Ausführung des Codes ▶ letztlich die JVM den passenden Typ kennen muss.

29


FEaTURE

Java

Bei der Ausführung einer Java-Anwendung übernimmt die JVM schon immer das Speichermanagement. Im Unterschied zu C müssen Java-Programmierer den eigenen Speicher nicht selbst verwalten. Ein im Hintergrund laufender sogenannter Garbage Collector (GC) gibt nicht mehr benötigten Speicherplatz wieder frei. Als Einige der aufrufparameter für das Garbage-Collection der JVM stehen ab Entwickler kann man allerdings Einfluss auf die Java 9 nicht mehr zur Verfügung (Bild 10) Auswahl der vom Garbage Collector einzusetzenden Algorithmen nehmen. In der Regel legt man diese über die Start-Flags der JVM für den gewünschDeklaration: final und effective final ten GC fest. Java kennt lediglich die final-Deklaration für Variablen/ParaEine falsche Wahl des GC-Algorithmus hatte immer drastimeter. Bei einer final-Deklaration handelt es sich um eine Konsche Auswirkungen auf die Performance einer Anwendung. stante, die per Definition programmseitig unveränderbar ist. Um dies den Entwicklern bewusst zu machen, hat Oracle beEnthält ein Programm eine Variable oder einen Parameter, die reits mit Java 8 einige dieser Start-Flags als deprecated eroder der zwar nicht als final deklariert ist, aber sich wie eine klärt (Bild 10). Mit Java 9 erhält man als Entwickler nun keiKonstante verhält, also seitens des Programms nicht verändert nen Zugriff mehr auf diese, zumal sie auch zunehmend seltewird, so bezeichnet man diese Variable oder diesen Parameter ner benutzt wurden. Die Umsetzung dieser deprecated GCals effective final. Die Entscheidung, ob eine Variable oder ein Kombinationen erwies sich aufgrund neuer Sprachfeatures Parameter als effective final anzusehen ist, kann bereits wähauch als recht komplex. Oracle realisierte den G1-Collector rend der Übersetzung des Programms getroffen werden. bereits mit Java 7 und liefert ihn seit 2012 mit dem Update 4

Links zum Thema

Homepage des JDK-9-Entwicklungsprojekts https://jdk9.java.net

Download-Site für JDK 9 Early Access Releases und JavaFXBeispielprogramme https://jdk9.java.net/download

Release-Informationen zur Unterstützung von Betriebssystemen, Webbrowser und Embedded-Hardware https://jdk9.java.net/jdk9_supported_platforms.html

JDK Docs (Javadocs) zur Java Platform SE 9 API Specification http://download.java.net/java/jdk9/docs/api

Java Platform SE 9 Early Access Documentation http://download.java.net/java/jdk9/docs

Homepage von Oracle mit Informationen rund um OpenJDK http://openjdk.java.net

Homepage des Java Class Dependency Analyzer (jdeps) http://docs.oracle.com/javase/8/docs/technotes/tools/ unix/jdeps.html

JEP 260: Encapsulate Most Internal APIs http://openjdk.java.net/jeps/260

Homepage von Graphviz – Graph Visualization Software http://graphviz.org

Der Oracle-Blog zur JShell https://blogs.oracle.com/java/jshell

Homepage des Open-Source-Projekts JLine http://jline.sourceforge.net

Homepage des Reactive-Streams-Projekts www.reactive-streams.org

30

Java7u4 im JDK aus. G1 arbeitet parallel, mit kleinen, kurzen und vorhersagbaren Pausen beim GC; zudem minimiert G1 die Pausen innerhalb des GC. Insbesondere gelang es, mit Version 9 die Performance des G1 in zentralen Bereichen (Strings, Class-Unloading, Collections) zu verbessern. So speichert G1 mehrfach vorhandene Zeichenketten als String nur einmal ab. Klassen ohne aktive Objekte lagert G1 automatisch aus; dies kann aber über das Start-Flag -XX:+ClassUnloadingWithConcurrentMark ausgeschaltet werden. Die Verwaltung von Collections erfolgt über G1 wesentlich effizienter. Darum und wegen weiterer Vorteile erklärte Oracle G1 zum neuen, standardmäßig eingestellten GC für Java 9. Auch bedeutende Java-Frameworks und Anwendungen aus den Bereichen GUI, Online Analytical Processing (OLAP), In-Memory-Computing und Data-Analytics-Plattformen setzen seit Java 8 wegen der schnelleren Laufzeiten G1 ein. Andere Hersteller einer JVM wie Google oder Azul Systems preisen jedoch ihren GC als besser an. Daher sollte im konkreten Umfeld einer Anwendung unter Berücksichtigung von Infrastruktur und Benutzungsszenarien eine individuelle Entscheidung für die Auswahl des GC getroffen werden. ◾

Frank Simon arbeitet in der Softwareentwicklung mit den aktuellen Arbeitsgebieten Entwicklung, Programmierung, Test und Debugging von Cloud-, RichInternet- und Webanwendungen inklusive deren System-Management. web_mobile_developers@gmx.eu

3.2017 www.webundmobile.de


Tr

T

aining

s

Updates für Ihr Know-How „Die Faszination der Softwareentwicklung liegt darin begründet, dass nur die eigene Fantasie und Kreativität begrenzen, was möglich ist.“ Golo Roden Technologischer Visionär, Sprecher, Autor

Agiles Produktmanagement Trainer: Björn Schotte 2 Tage, Ort & Termin nach Absprache Ab EUR 1.799,- zzgl. MwSt.

Hybrid-Apps mit Ionic 2, Cordova und Angular 2 Trainer: Hendrik Lösch 3 Tage, 19.-21.06.2017, Dresden Ab EUR 2.199,- zzgl. MwSt.

Webanwendungen mit React Trainer: Golo Roden 2 Tage, Ort & Termin nach Absprache Ab EUR 1.799,- zzgl. MwSt.

Moderne Webentwicklung mit ASP.NET Core Trainer: David Tielke 3 Tage, 29.-31.05.2017, Köln Ab EUR 2.199,- zzgl. MwSt.

Ihr Ansprechpartner: Fernando Schneider +49 (0)89 74117-831 – fernando.schneider@developer-media.de

developer-media.de/trainings


HTML/CSS/JaVaSCRIPT

JavaScript

COnTInUOUS InTEGRaTIOn FüR nODE.JS-PROJEKTE

Qualität steigern Dieser Artikel zeigt, wie sich das CI-System Jenkins für Node.js-Projekte einsetzen lässt.

C

ontinuous Integration kann bei Softwareprojekten dabei helfen, die Qualität der Software zu steigern. Werden Änderungen in das jeweilige Versionskontrollsystem (Git, Subversion et cetera) committet, dann führt das CI-System (Continuous Integration System) automatisch kontinuierlich bestimmte Prozesse aus. Dazu zählen beispielsweise das Kompilieren von Quelltext, Unit- oder Integrationstests, Tests bezüglich der Codequalität, Ermittlung der Testabdeckung oder Ähnliches. Schlagen dabei einzelne Prozesse beziehungsweise Tests fehl, wird der Entwickler, der den jeweiligen Commit durchgeführt hat, oder beliebige andere Personen per E-Mail oder auf anderen Wegen darüber informiert und man hat somit zeitnah eine Rückmeldung. Sind die Tests erfolgreich beziehungsweise kann die Software erfolgreich gebaut werden, kann sie auch direkt ausgeliefert werden. Dann spricht man nicht nur von Continuous Integration, sondern von Continuous Deployment. Gemeint ist damit die kontinuierliche Bereitstellung von Versionen einer Software (Bild 1).

Installation von Docker für macOS (Bild 2)

Installation Prinzipiell lassen sich mit CI-Systemen beliebige automatisierte Workflows dieser Art konfigurieren. Das Ziel dabei ist immer, den Prozess des Erstellens von Software zuverlässiger zu machen und Fehler im Entwicklungsprozess frühzeitig erkennen zu können. Dabei lassen sich die diversen CI-Systeme, die es auf dem Markt gibt, wie etwa Jenkins (https://jenkins.io), Travis CI (https://travis-ci.org) oder Circle CI (https://circleci.com) prinzipiell für beliebige Programmiersprachen verwenden. Der folgende Artikel soll nun zeigen, wie sich konkret das CI-System Jenkins für JavaScript- beziehungsweise Node.jsProjekte einsetzen lässt. Damit die Beispiele dabei auch ohne entsprechende Server-Infrastruktur lokal auf dem eigenen Entwicklungsrechner nachvollzogen werden können, wird gezeigt, wie Jenkins mit Hilfe von Docker lokal genutzt wer-

… und steht anschließend in der Toolbar zur Verfügung (Bild 4)

Docker startet als Dienst … (Bild 3)

den kann. Zudem wird ein lokaler Git-Server aufgesetzt, ebenfalls als Docker-Container, von dem Jenkins dann den Quelltext bezieht. Hier bietet sich Gogs (https://gogs.io) an, ein in Go geschriebener Git-Server inklusive einer GitHubähnlichen Oberfläche.

Das Prinzip von Continuous Integration (Bild 1)

32

3.2017 www.webundmobile.de


JavaScript

HTML/CSS/JaVaSCRIPT

anmeldung: Anmelden über den Git-Account (Bild 7)

Konfiguration: Hier erfolgt die Konfiguration von Gogs (Bild 5)

Git-account: Die Registrierung eines Git-Accounts (Bild 6)

anlegen eines neuen Git-Repositorys (Bild 8)

Als Voraussetzung muss also Docker installiert sein. Die Installation gestaltet sich dabei für alle gängigen Betriebssysteme sehr einfach, die einzelnen Installationsanweisungen findet man auf der Docker-Homepage unter https://docs.do cker.com/engine/installation. Im Folgenden wird Docker unter macOS ausgeführt. Docker for Mac (https://docs.docker. com/engine/installation/mac) lässt sich – wie bei macOS gewohnt – per Drag and Drop installieren (Bild 2) und nistet sich dann als Dienst in der Toolbar von macOS ein (Bild 3, Bild 4). Die Installation des Git-Servers Gogs beziehungsweise das Erstellen eines entsprechenden Docker-Containers gestaltet sich relativ einfach. Eine detaillierte Anleitung dazu findet man unter https://github.com/gogits/gogs/tree/master/do cker. Im Wesentlichen reicht es, die im Folgenden beschriebenen Befehle auf der Kommandozeile auszuführen. Zunächst wird das Docker-Image von Gogs heruntergeladen:

figurationsdateien, Logs et cetera. Prinzipiell kann dies ein beliebiges Verzeichnis sein:

docker pull gogs/gogs

Anschließend wird ein lokales Verzeichnis erstellt, in dem Gogs seine Daten speichert, sprich die Git-Repositories, Kon-

www.webundmobile.de 3.2017

mkdir -p /var/gogs

Im nächsten Schritt wird dann basierend auf dem DockerImage gogs/gogs ein neuer Container erstellt und direkt gestartet: docker run --name=gogs -p 10022:22 -p 10080:3000 -v / var/gogs:/data gogs/gogs

Über den Parameter -p (beziehungsweise --publish) werden dabei die Ports 22 und 3000 über die Ports 10022 und 10080 auf dem Host-Rechner zur Verfügung gestellt. Ersterer dient dem SSH-Zugriff auf die Git-Repositories, über Letzteren gelangt man an die Weboberfläche von Gogs. Über den Parameter -v (beziehungsweise --volume) wird zudem das zuvor auf dem Host-Rechner erstellte Verzeichnis angegeben, in dem Gogs seine Daten speichern soll. Außerdem ist es sinnvoll, dem Container über den Parameter ▶

33


HTML/CSS/JaVaSCRIPT

JavaScript

--name einen Namen zuzuweisen (im Beispiel lautet dieser gogs). Dann kann der Container – für den Fall, dass er gestoppt wurde – bequem über docker start gogs erneut gestartet werden, und dies muss nicht etwa über die interne Container-ID erfolgen. Nach abgeschlossener Konfiguration und erfolgreichem Starten des Docker- Erzeugen eines neuen SSH-Schlüssels (Bild 9) Containers sollte nun auf dem Entwicklungsrechner die Weboberfläche von die Vorlagen auch wirklich verwendet werden, muss man zuGogs unter http://localhost:10080 zur Verfügung stehen und sätzlich die Checkbox Repository mit ausgewählten Dateien den Entwickler mit einem entsprechenden Installationsdiaund Vorlagen initialisieren aktivieren. log begrüßen (Bild 5). Zu guter Letzt muss noch ein SSH-Schlüssel hinzugefügt In diesem Dialog lassen sich nun verschiedene Konfigurawerden, um vom eigenen Rechner auf das angelegte Repositionen angeben, wobei für das Beispiel fast alle Einstellungen tory auch zugreifen zu können. Unter Linux und Mac kann auf den Standardwerten belassen werden. Das Einzige, was man dies beispielsweise über das Kommandozeilen-Tool sshder Einfachheit halber angepasst wird, ist die verwendete Dakeygen erledigen: tenbank: Hier ist es für den Moment am einfachsten, SQLite3 anstelle des vorselektierten MySQL auszuwählen. Hat man ssh-keygen -t rsa die Einstellungen bestätigt, geht es nun daran, einen neuen Git-Nutzer einzurichten (Bild 6) und sich anschließend mit Standardmäßig wird der hierdurch erzeugte Schlüssel in dem diesem am System anzumelden (Bild 7). Verzeichnis ~/.ssh/id_rsa.pub gespeichert, dessen Inhalt sich Ein neues Repository erzeugen wie folgt ausgeben lässt: GitHub-Nutzern dürften die in Gogs vorhandenen Funktiocat ~/.ssh/id_rsa.pub nalitäten bereits sehr bekannt vorkommen, und die Verwendung von Gogs wird ihnen intuitiv von der Hand gehen. Um Über das Menü ganz rechts oben in der Gogs-Weboberfläche beispielsweise ein neues Repository zu erzeugen, wählt man gelangt man über Ihre Einstellungen und SSH-Schlüssel in einfach oben rechts im Menü den Eintrag Neues Repository. die Verwaltung der SSH-Schlüssel und kann dort den eben In der anschließenden Eingabemaske (Bild 8) wählt man generierten Schlüssel hinzufügen (Bild 9). den Nutzer, dem das Repository zugeordnet werden soll, verAnschließend ist das Repository einsatzbereit und kann gibt einen Namen, stellt die Sichtbarkeit ein (privat oder öfbeispielsweise wie folgt auf den lokalen Entwicklungsrechfentlich) und fügt optional eine Beschreibung, eine .gitignorener geklont werden: Vorlage, eine Lizenz sowie eine Readme-Datei hinzu. Damit

Listing 2: Unit-Test für die Klasse

Listing 1: Eine einfache Klasse 'use strict';

'use strict'; const assert = require('assert');

module.exports = class Calculator

const Calculator = require('../lib/Calculator');

{ static sum(x, y) { return x + y; }

describe('Calculator', () => { it('should calculate the sum', () =>

static subtract(x, y) {

{

return x - y;

let result = Calculator.sum(5, 6);

}

assert.equal(result, 11);

static product(x, y) { return x * y; }

}); it('should calculate the product', () => {

static divide(x, y) {

let result = Calculator.product(5, 6);

return x / y; } }

34

assert.equal(result, 30); }); });

3.2017 www.webundmobile.de


JavaScript

HTML/CSS/JaVaSCRIPT

Listing 3: Dockerfile FROM debian:jessie RUN useradd -d "/var/jenkins_home" -u 1000 -m -s / bin/bash jenkins RUN mkdir -p /var/log/jenkins RUN chown -R jenkins:jenkins /var/log/jenkins VOLUME ["/var/log/jenkins", "/var/jenkins_home"] USER jenkins CMD ["echo", "Daten-Container Jenkins"]

Jenkins steht in verschiedenen Varianten zur Verfügung (Bild 10)

Listing 4: Dockerfile für Jenkins FROM jenkinsci/jenkins

git clone http://localhost:10080/cleancoderocker/

USER root

hello-world.git

RUN curl -sL https://deb.nodesource.com/setup_7.x | bash -

Damit ist auf Git-Seite eigentlich alles vorbereitet. Bevor es nun an die Installation von Jenkins geht, sei aber schnell noch ein kleines Mini-Projekt hinzugefügt, das der Einfachheit halber lediglich aus einer einzelnen Klasse (Listing 1) und einem dazugehörigen Unit-Test (Listing 2) besteht:

RUN apt-get install -y nodejs RUN mkdir /var/log/jenkins RUN mkdir /var/cache/jenkins RUN chown -R jenkins:jenkins /var/log/jenkins RUN chown -R jenkins:jenkins /var/cache/jenkins USER jenkins

git init

ENV JAVA_OPTS="-Xmx4096m"

git add lib/Calculator.js git add test/CalculatorTest.js git commit -m "Added example class and unit test" git push -u origin master

Jenkins ist eines der bekannteren CI-Systeme und steht für unterschiedliche Betriebssysteme und in verschiedenen Formen zur Verfügung (Bild 10), unter anderem auch als DockerImage (https://hub.docker.com/r/jenkinsci/jenkins). Bei der Installation bietet es sich an, wie unter https://www. cloudbees.com/blog/get-started-jenkins-20-docker beschrieben, Jenkins auf zwei Docker-Images zu verteilen: Ein Image enthält die eigentliche Jenkins-Installation inklusive CI-Server, das andere Image enthält die Konfigurationsdaten für die

Vor der ersten Benutzung muss das Admin-Passwort eingegeben werden (Bild 11)

einzelnen Jenkins-Jobs. Durch diese Trennung ist es prinzipiell auch möglich, die Job-Konfigurationen mit verschiedenen Jenkins-Installationen zu verwenden. Folglich werden im nächsten Schritt zwei Dockerfile-Dateien benötigt: Dockerfile-data enthält den in Listing 3 gezeigten Code, Dockerfile den in Listing 4 gezeigten Code. Basierend auf diesen Images erstellt man nun über die folgenden beiden Befehle zwei Docker-Container: docker build -t jenkins-data -f Dockerfile-data . docker build -t jenkins-master .

Anschließend lassen sich die beiden Container wie folgt starten: docker run --name=jenkins-data jenkins-data docker run -p 8080:8080 -p 50000:50000

auswahl der zu installierenden Plug-ins (Bild 12)

Installation der Standard-Plug-ins (Bild 13)

www.webundmobile.de 3.2017

35


HTML/CSS/JaVaSCRIPT

JavaScript

--name=jenkins-master --volumesfrom=jenkins-data -d jenkins2

Sind die beiden Container gestartet, steht die Weboberfläche von Jenkins unter der Adresse http://localhost:8080 zur Verfügung. Standardmäßig ist dabei ein Nutzer mit dem Nutzernamen admin registriert, das entsprechende Passwort zur Eingabe in die Eingangsmaske (Bild 11) kann man sich über folgenden Befehl aus dem Jenkins-Container ausgeben lassen: Eingabemaske für die Installation weiterer Plug-ins (Bild 17) docker exec jenkins-master cat /var/ jenkins_home/secrets/

abschluss der Installation

se JavaScript-Projekte anlegt und konfiguriert, müssen noch einige Plug-ins manuell nachinstalliert werden. Die entsprechende Maske zur Verwaltung der Plug-ins findet man unter Jenkins, Jenkins verwalten und Plugins verwalten. Unter dem Reiter Verfügbar und mit Hilfe des dortigen Suchfelds (Bild 17) installiert man nun mindestens folgende Plug-ins aus der Plug-in-Registry: TAP Plugin: zur Darstellung von Testergebnissen, Checkstyle Plugin: zur Darstellung von Code-Qualität beziehungsweise Code-Style, NodeJS Plugin: zur Konfiguration von Node.js.

Für den Moment soll aber auch hier der Standardnutzer admin ausreichen, sodass man entsprechend Continue as admin auswählt (übrigens fällt hier und an vielen anderen Stellen in der Weboberfläche etwas negativ auf, dass die Sprache in Jenkins nicht konsequent immer Englisch beziehungsweise immer Deutsch ist). Damit ist die Installation abgeschlossen (Bild 15) und man hat Zugriff auf die Weboberfläche (Bild 16). Bevor im nächsten Schritt endlich gezeigt wird, wie Optionales anlegen eines weiman einzelne Jenkins-Jobs teren Admin-Accounts (Bild 14) für Node.js- beziehungswei-

Darüber hinaus muss ein weiteres Plug-in, das Clover-Plugin, installiert werden, das zur Darstellung von Code-Coverage-Berichten dient. Dessen Installation geschieht allerdings nicht wie bei den anderen Plug-ins über die globale Plug-in-Registry, weil die Version dort nicht mit der aktuellen Jenkins-Version funktioniert. Stattdessen muss man die entsprechende Datei von http://repo.jenkins-ci.org/releases/org /jenkins-ci/plugins/clover/4.6.0/clover-4.6.0.hpi herunterladen und anschließend über den Reiter Erweiterte Einstellungen unter dem Bereich Plugin hochladen manuell installieren (Bild 18). Übrigens: Wer sich an dem teilweise etwas veralteten Design von Jenkins stört, kann sich optional auch noch das Simple Theme Plugin installieren, das in dieser Hinsicht etwas nachbessert (Tabelle 1).

initialAdminPassword

Anschließend hat man die Möglichkeit, entweder eine Vorauswahl populärer Jenkins-Plug-ins zu installieren oder sich selbst eine Auswahl zusammenzustellen (Bild 12). Für den Moment reicht Ersteres (Bild 13), weitere Plug-ins werden später manuell nachinstalliert. Nach Installation der Standard-Plugins hat man im nächsten Schritt die Möglichkeit, einen weiteren Administrator-Nutzer anzulegen (Bild 14).

Bestätigung über die erfolgreiche Konfiguration (Bild 15)

So sieht die Willkommensseite von Jenkins aus (Bild 16)

36

Manuelles Hochladen von Jenkins-Plug-ins (Bild 18)

3.2017 www.webundmobile.de


JavaScript

HTML/CSS/JaVaSCRIPT

angabe des Git-Repositorys für den Jenkins-Job (Bild 21) Erzeugen eines neuen Jobs (Bild 19)

allgemeine Konfiguration eines Jenkins-Jobs (Bild 20)

Festlegen der Build-Auslöser (Bild 22)

Nachdem Jenkins nun so weit für den ersten Einsatz konfiguriert ist, ist der nächste Schritt, einen neuen Job anzulegen. Dies kann man entweder, sofern noch keine Jobs vorhanden sind, über den Link Legen Sie einen neuen Job an, um loszulegen, oder über den Menüeintrag Element anlegen. Anschließend öffnet sich die in Bild 19 gezeigte Eingabemaske, über die man den Namen des Jobs sowie dessen Typ auswählen kann. Für Node.js-Projekte eignet sich hierbei die Auswahl Free Style Softwareprojekt bauen. Die Konfiguration des Jobs erstreckt sich über verschiedene Bereiche. Un-

ter dem Reiter General (Bild 20) lässt sich beispielsweise eine Beschreibung des Jobs ergänzen; man kann angeben, ob alte Builds verworfen werden sollen, und einiges mehr. Im Reiter Source-Code-Management definiert man das Versionskontrollsystem, von dem Jenkins seine Daten beziehen soll (Bild 21). Zur Auswahl stehen hier standardmäßig Git und Subversion, wobei für das in diesem Artikel beschriebene Beispiel Ersteres verwendet wird. Unter Repository URL gibt man den URL zu dem Git-Repository ein. Allerdings kann hier nicht die localhost-Adresse verwendet werden, die zuvor beim Klonen des Repositorys verwendet wurde. Der Grund: Für den Docker-Container, in dem Jenkins läuft, ist Gogs (das ja ebenfalls in einem anderen DockerContainer läuft) nicht über localhost sichtbar. Stattdessen muss in diesem Fall die interne Adresse von Docker verwendet werden. Herausfinden lässt sich diese wie folgt:

Tabelle 1: Auswahl an nützlichen Jenkins-Plug-ins name

URL

Checkstyle Plug-in

https://wiki.jenkins-ci.org/display/JENKINS/ Checkstyle+Plugin

Clover Plugin

https://wiki.jenkins-ci.org/display/JENKINS/ Clover+Plugin

NodeJS Plugin

https://wiki.jenkins-ci.org/display/JENKINS/ NodeJS+Plugin

Simple Theme Plugin

https://wiki.jenkins-ci.org/display/JENKINS/ Simple+Theme+Plugin

TAP Plugin

https://wiki.jenkins-ci.org/display/JENKINS/ TAP+Plugin

www.webundmobile.de 3.2017

docker run -i -t ubuntu /bin/bash apt-get update apt-get install -y netstat netstat -nr | grep '^0\.0\.0\.0' | awk '{print $2}'

Unter dem Reiter Build-Auslöser lässt sich konfigurieren, welche Ereignisse den Jenkins-Job auslösen (Bild 22). Dies kann durch ein externes Skript geschehen (Auswahl 1), nach einem anderen Jenkins-Job (Auswahl 2), zeitgesteuert (Auswahl 3), bei neuen Commits (Auswahl 4) oder durch eine zeitgesteuerte Prüfung, ob neue Commits vorhanden sind ▶

37


HTML/CSS/JaVaSCRIPT

JavaScript

Listing 5: Die Datei package.json { "name": "hello-world", "version": "1.0.0", "description": "Beispielprojekt zur Demonstration von Continuous Integration

Die ausgabe eines Jobs kann jederzeit eingesehen werden (Bild 23)

für JavaScript-Projekte", "main": "index.js", "scripts": { "test": "gulp test", "test-ci": "gulp test --silent > test.tap", "coverage": "gulp test-coverage", "coverage-ci": "gulp test-coverage", "eslint": "gulp lint", "eslint-ci": "gulp lint --silent > checkstyle-result.xml" },

Festlegen der genauen Build-Schritte (Bild 24) "repository": { "type": "git",

(Auswahl 5). Bei den zeitgesteuerten Varianten muss unter Zeitplan ein Muster in Cron-Syntax angegeben werden: Das Pattern H * * * * gibt beispielsweise an, dass einmal pro Stunde nach neuen Commits geprüft werden soll. Zusätzlich ist es aber auch möglich, jeden Job manuell über die Weboberfläche von Jenkins zu starten, was insbesondere zu Testzwecken ganz hilfreich ist. Ebenfalls hilfreich ist dabei die Tatsache, dass sich jederzeit der Output einsehen lässt, den der jeweilige Job auf der Kommandozeile erzeugt (Bild 23).

"url": "http://localhost:10080/cleancoderocker/ hello-world.git" }, "keywords": [ "javascript", "ci" ], "author": "Philip Ackermann", "license": "MIT",

Konfiguration der ablauflogik

"devDependencies": {

Die eigentliche Konfiguration der Ablauflogik eines JenkinsJobs geschieht über den Reiter Buildverfahren (Bild 24). Hier lassen sich unter Shell ausführen beliebige Shell-Skripts ausführen. Im Fall von Node.js-Projekten liegt es dabei nahe, die konkreten Build-Schritte über Grunt- oder (wie im Beispiel) über Gulp-Skripts einzubinden und diese dann über NPM anzustoßen:

"gulp": "^3.9.1", "gulp-eslint": "^3.0.1", "gulp-istanbul": "^1.1.1", "gulp-mocha": "^3.0.1", "istanbul": "^0.4.5", "mocha": "^3.2.0" } }

npm cache clean npm install npm run test-ci npm run coverage-ci npm run eslint-ci

Durch obige Befehle wird der Cache von NPM geleert (Zeile 1), die Abhängigkeiten vom Projekt installiert (Zeile 2), die Unit-Tests ausgeführt (Zeile 3), die Testabdeckung ermittelt (Zeile 4) sowie die Codequalität geprüft (Zeile 5). Für die letzten drei Schritte sind dabei entsprechende Befehle in dem scripts-Bereich in der Datei package.json angegeben (Listing 5), über die wiederum verschiedene GulpTasks ausgeführt werden (Listing 6). Der Task test im Gulp-Skript erzeugt die Testergebnisse im TAP-Format, der Befehl gulp test -silent > test.tap sorgt da-

38

für, dass diese Ergebnisse in die Datei test.tap geschrieben werden. Um die Ergebnisse in Jenkins zu integrieren, fügt man dort die Post-Build-Aktion Publish TAP Results hinzu und gibt den Namen der Datei an (Bild 25). Nach Ausführen des Jobs stehen dann die Testergebnisse in Jenkins unter TAP Extended Test Results zur Verfügung (Bild 26).

Integration in Jenkins Die Task test-coverage im Gulp-Skript ermittelt die Testabdeckung und speichert die Ergebnisse direkt im Verzeichnis coverage. Für die Integration in Jenkins müssen dabei unter reporters mindestens die Reporter lcov und clover angegeben ▶ werden.

3.2017 www.webundmobile.de


JavaScript

HTML/CSS/JaVaSCRIPT

Listing 6: Die Datei gulpfile.js 'use strict'; const gulp = require('gulp');

function () { return gulp.src(['./test/*.js'])

const mocha = require('gulp-mocha');

.pipe(mocha({timeout: 5000}))

const istanbul = require('gulp-istanbul');

.pipe(istanbul.writeReports({

const eslint = require('gulp-eslint');

dir: './coverage', reporters: [ 'lcov', 'clover', 'json', 'text', 'text-summary'],

gulp.task('test', () =>

}))

gulp.src('./test/*.js', {read: false}) .pipe(mocha({reporter: 'tap', timeout: 5000}))

.pipe(istanbul.enforceThresholds({ thresholds: {

);

global: 50 } })); });

gulp.task('pre-test-coverage', function () { return gulp.src(['./lib/**/*.js']) .pipe(istanbul())

gulp.task('lint', () => { return gulp.src(['**/*.js','!node_modules/**'])

.pipe(istanbul.hookRequire());

.pipe(eslint())

});

.pipe(eslint.format('checkstyle', process.stdout));

gulp.task('test-coverage', ['pre-test-coverage'],

});

Konfiguration der TAP-Darstellung als Post-Build-Aktion (Bild 25) Darstellung der Code-Coverage-Ergebnisse (Bild 28)

Darstellung der TAP-Testergebnisse (Bild 26)

Code-Coverage pro Datei (Bild 29)

Konfiguration von Clover als Post-Build-Aktion (Bild 27)

www.webundmobile.de 3.2017

Konfiguration von Checkstyle als Post-Build-Aktion (Bild 30)

39


HTML/CSS/JaVaSCRIPT

JavaScript

Über die Post-Build-Aktion Publish Clover Coverage Report (Bild 27) fügt man das Verzeichnis hinzu, das die Berichte zur Testabdeckung enthält (coverage), sowie den Namen der Datei, welche die Ergebnisse im Clover-Format enthält (clover.xml). Nach Ausführen des Jobs kann man dann die Ergebnisse unter Clover Summary Report und Clover HTML Report als Übersicht (Bild 28) beziehungsweise im Detail pro JavaScriptDatei (Bild 29) einsehen. Fehlt noch die Ermittlung der Codequalität. Dazu gibt es im Gulp-Skript einen Task lint, das Ergebnis landet in der Datei checkstyle-result.xml. In Jenkins fügt man die Post-Build-Aktion Veröffentliche Ergebnisse der Checkstyle-Analyse hinzu (Bild 30), trägt dort den Namen der erzeugten XML-Datei ein und erhält anschließend unter Checkstyle Warnungen einen entsprechenden Report (Bild 31).

Darstellung der Checkstyle-Ergebnisse (Bild 31)

Jenkins mit node.js steuern Die Konfigurationen für einzelne Jobs speichert Jenkins intern im XML-Format. Ein Beispiel hierzu zeigt Listing 7. Über ein von Jenkins bereitgestelltes API (https://wiki.jenkins-ci.

Listing 7: Jenkins-Job-Konfigurationsdatei (Teil 1) <?xml version='1.0' encoding='UTF-8'?>

</blockBuildWhenDownstreamBuilding>

<project>

<blockBuildWhenUpstreamBuilding>false

<actions/>

</blockBuildWhenUpstreamBuilding>

<description>Beispielprojekt zur Demonstration von

<triggers>

Continuous Integration für JavaScript-Projekte

<hudson.triggers.SCMTrigger>

</description>

<spec>H * * * *</spec>

<keepDependencies>false</keepDependencies>

<ignorePostCommitHooks>false

<properties/>

</ignorePostCommitHooks> </hudson.triggers.SCMTrigger>

<scm class="hudson.plugins.git.GitSCM"

</triggers>

plugin="git@3.0.1">

<concurrentBuild>false</concurrentBuild>

<configVersion>2</configVersion> <userRemoteConfigs> <hudson.plugins.git.UserRemoteConfig> <url>http://172.17.0.1:10080/cleancoderocker/

<builders> <hudson.tasks.Shell> <command>npm cache clean

hello-world.git</url>

npm install

<credentialsId>

npm run test-ci

12c1e5a2-8876-414e-b98d-ae8112618c68

npm run coverage-ci

</credentialsId> </hudson.plugins.git.UserRemoteConfig> </userRemoteConfigs>

npm run eslint-ci</command> </hudson.tasks.Shell> </builders>

<branches> <hudson.plugins.git.BranchSpec> <name>*/master</name> </hudson.plugins.git.BranchSpec>

<publishers> <org.tap4j.plugin.TapPublisher plugin="tap@2.0.1"> <testResults>test.tap</testResults>

</branches>

<failIfNoResults>false</failIfNoResults>

<doGenerateSubmoduleConfigurations>false

<failedTestsMarkBuildAsFailure>false

</doGenerateSubmoduleConfigurations>

</failedTestsMarkBuildAsFailure>

<submoduleCfg class="list"/>

<outputTapToConsole>false</outputTapToConsole>

<extensions/>

<enableSubtests>false</enableSubtests>

</scm>

<discardOldReports>false</discardOldReports> <todoIsFailure>false</todoIsFailure>

40

<canRoam>true</canRoam>

<includeCommentDiagnostics>false

<disabled>false</disabled>

</includeCommentDiagnostics>

<blockBuildWhenDownstreamBuilding>false

<validateNumberOfTests>false

3.2017 www.webundmobile.de


JavaScript

org/display/JENKINS/Remote+access+API) lassen sich existierende Konfigurationen aktualisieren oder auch Konfigurationen für neue Jobs erstellen. Dies bietet sich insbesondere dann an, wenn man viele Jobs auf einmal anlegen oder verändern möchte und nicht jede Änderung über die Weboberfläche durchführen möchte. Ein praktisches Modul für Node.js, das in diesem Zusammenhang einen Blick wert ist, ist das Modul node-jenkins (https://github.com/silas/node-jenkins). Hier handelt es sich um ein Plug-in für Grunt (für Gulp gibt es leider noch nichts Vergleichbares), über das sich Jobs anlegen, aktualisieren oder einfach (im XML-Format) als Backup sichern lassen. Insgesamt stehen drei Grunt-Tasks zur Verfügung: jenkinsinstall-jobs erstellt ausgehend von den lokalen XML-Konfigurationen in Jenkins neue Jobs oder aktualisiert bestehende Jobs. jenkins-backup-jobs erstellt ausgehend von existierenden Jenkins-Jobs lokal neue XML-Konfigurationen oder aktualisiert bestehende XML-Konfigurationen. jenkins-verify-jobs prüft, ob die lokalen XML-Konfigurationen mit den bestehenden Jenkins-Jobs übereinstimmen.

HTML/CSS/JaVaSCRIPT

Fazit Jenkins lässt sich relativ einfach für die Verwendung in Node.js-Projekten konfigurieren. Dieser Artikel hat gezeigt, wie sich Jenkins und ein lokaler Git-Server mit Hilfe von Docker installieren und konfigurieren lassen. Außerdem wurde an zahlreichen Beispielen demonstriert, wie sich innerhalb des Entwicklungsprozesses das Ausführen von Unit-Tests sowie das Ermitteln der Testabdeckung und der Codequalität auto◾ matisieren und integrieren lassen.

Philip ackermann arbeitet beim Fraunhofer-Institut für Angewandte Informationstechnik FIT und ist Autor mehrerer Fachbücher und Fachartikel über Java und JavaScript. http://philipackermann.de

Listing 7: Jenkins-Job-Konfigurationsdatei (Teil 2) </validateNumberOfTests>

<failedTotalAll></failedTotalAll>

<planRequired>true</planRequired>

<failedTotalHigh></failedTotalHigh>

<verbose>true</verbose>

<failedTotalNormal></failedTotalNormal>

<showOnlyFailures>false</showOnlyFailures>

<failedTotalLow></failedTotalLow>

<stripSingleParents>false</stripSingleParents>

<failedNewAll></failedNewAll>

<flattenTapResult>false</flattenTapResult>

<failedNewHigh></failedNewHigh>

<skipIfBuildNotOk>false</skipIfBuildNotOk>

<failedNewNormal></failedNewNormal>

</org.tap4j.plugin.TapPublisher>

<failedNewLow></failedNewLow> </thresholds>

<hudson.plugins.checkstyle.CheckStylePublisher

<shouldDetectModules>false</shouldDetectModules>

plugin="checkstyle@3.47">

<dontComputeNew>true</dontComputeNew>

<healthy></healthy>

<doNotResolveRelativePaths>false

<unHealthy></unHealthy>

</doNotResolveRelativePaths>

<thresholdLimit>low</thresholdLimit>

<pattern>**/checkstyle-result.xml</pattern>

<pluginName>[CHECKSTYLE] </pluginName>

</hudson.plugins.checkstyle.CheckStylePublisher>

<defaultEncoding></defaultEncoding>

<hudson.plugins.clover.CloverPublisher

<canRunOnFailed>false</canRunOnFailed>

plugin="clover@4.6.0">

<usePreviousBuildAsReference>false

<cloverReportDir>coverage</cloverReportDir>

</usePreviousBuildAsReference>

<cloverReportFileName>clover.xml

<useStableBuildAsReference>false

</cloverReportFileName>

</useStableBuildAsReference> <useDeltaValues>false</useDeltaValues>

<healthyTarget> <methodCoverage>70</methodCoverage>

<thresholds plugin="analysis-core@1.81"> <unstableTotalAll></unstableTotalAll>

<conditionalCoverage>80</conditionalCoverage> <statementCoverage>80</statementCoverage>

<unstableTotalHigh></unstableTotalHigh>

</healthyTarget>

<unstableTotalNormal></unstableTotalNormal>

<unhealthyTarget/>

<unstableTotalLow></unstableTotalLow> <unstableNewAll></unstableNewAll> <unstableNewHigh></unstableNewHigh> <unstableNewNormal></unstableNewNormal> <unstableNewLow></unstableNewLow>

www.webundmobile.de 3.2017

<failingTarget/> </hudson.plugins.clover.CloverPublisher> </publishers> <buildWrappers/> </project>

41


HTML/CSS/JaVaSCRIPT

CSS

STyLESHEETS OPTIMaL ORGanISIEREn

Praktikable Styles BEM, OOCSS, SUIT CSS und Co. bieten Strategien für wiederverwendbare Stylesheets.

B

ei dem als Schmetterlingseffekt bekannten Phänomen geht es darum, dass bestimmte Systeme sehr empfindlich auf kleine Abweichungen in den Anfangsbedingungen reagieren. Ob das beim Wetter so ist, sei dahingestellt. Aber eines ist klar: Auf Stylesheets passt es – hier kann eine kleine Änderung an einer Stelle auf eine ganz andere Stelle Auswirkungen haben. Schuld daran ist das C in CSS, das heißt, die in ihren Auswirkungen sehr weitreichende Kaskade (Cascading). Dieses Verhalten von CSS erschwert die Arbeit, vor allem dann, wenn mehrere Personen an einem Stylesheet arbeiten. Um diese Situation zu verbessern, gibt es CSS-Methoden oder auch CSS-Strategien. Im Unterschied zu Frameworks beinhalten Methoden nicht vorgefertigte, direkt einsetzbare Styles, sondern Überlegungen, wie Stylesheets zu erstellen sind. Das Ziel von Strategien sind wartbare, modifizierbare, und lesbare Stylesheets. Wichtig ist außerdem die Vorhersehbarkeit und Unabhängigkeit. Vorhersehbarkeit: Der Aufbau von Stylesheets soll vorhersehbar sein, genauso auch die Benennungen und die Art der Selektoren. Unabhängigkeit: Einzelne Bestandteile sollen unabhängig voneinander sein. Das gilt in zweierlei Hinsicht: Zum einen sollen die CSS-Teile nicht zu sehr voneinander abhängen (sonst haben wir den Schmetterlingseffekt), und zum anderen soll der CSS-Code nicht zu eng mit dem HTML-Code verknüpft sein. Wenn zum Beispiel eine UI-Komponente an einer anderen Stelle platziert wird, soll das ohne weitere Änderungen möglich sein. Ein weiterer Vorteil bei der Verwendung einer der Methoden ist, dass damit auch neuen Teammitgliedern einfach kommuniziert werden kann, wie Stylesheets zu erstellen sind. Im Folgenden werden bekannte Methoden vorgestellt, nämlich SMACSS, OOCSS, BEM, SUIT CSS und Atomic CSS.

Sehen wir uns die Typen nun genauer an: Die Basisregeln – Base – definieren die Default-Styles für Elemente. Hierfür kommen Typselektoren wie body oder a zum Einsatz. Basisregeln sind zum Beispiel die grundlegenden body-Formatierungen für die Schriftart oder die Hintergrundfarbe. Die Layoutformatierungen (Layout) betreffen die großen Bereiche der Site wie den Header, die Sidebar, den Inhaltsbereich und den Footer. Diese Bereiche können über IDs angesprochen werden, es kann aber auch Nachfahrenkombinatoren geben, wenn das Layout Modifikationen erhält. Im folgenden Beispiel haben wir eine Standard-Sidebar #sidebar und eine modifizierte Sidebar mit fester Breite: #sidebar { width: 20%; float: right; } .l-fixed #sidebar { width: 200px; }

Die Layoutregeln betreffen die grobe Struktur der Seite, bei den Modulen (Module) handelt es sich hingegen um kleinere Komponenten. Dazu gehören Navigationsleisten, Dialogfenster, Widgets und Ähnliches. Der Code für Module sollte so geschrieben sein, dass die Module als selbstständige Komponenten existieren können. Für Module verwendet man typischerweise Klassenselektoren wie etwa .module; Typselektoren sollten vermieden werden. Wenn Module in unterschiedlichen Kontexten verschieden aussehen, haben wir sogenannte Submodule. Anstatt diese durch Nachfahrenkombinatoren wie .special .pod anzuspre-

SMaCSS Die Abkürzung SMACSS steht für »Scalable and Modular Architecture for CSS« (Bild 1). Erfinder dieser Strategie ist Jonathan Snook. Als Entwickler arbeitete Jonathan Snook lange als Einzelkämpfer und wechselte dann in ein größeres Team. Da wurde ihm klar, dass es Strategien braucht, wenn mehrere Kollegen gleichzeitig, effektiv und ohne sich in die Quere zu kommen am CSS-Code arbeiten sollen. Das war die Geburtsstunde von SMACSS. Eine wichtige Komponente von SMACSS ist die Kategorisierung von CSS-Regeln. Unterschieden werden die Typen Base, Layout, Module und Submodule, State und Theme.

42

So präsentiert sich die Website von SMACSS (Bild 1)

3.2017 www.webundmobile.de


CSS

HTML/CSS/JaVaSCRIPT

chen, sollten zusätzliche Klassen definiert werden. So wäre beispielsweise für das Modul .pod das Submodul .pod-con_ strained denkbar. Beim Submodul stehen dann beide Klassen, wie der HTML-Ausschnitt zeigt:

Präsentation von Nicole Sullivan zu OOCSS (Bild 2)

<div class="pod pod-constrained">...</div>

Eine weitere Kategorie sind die Zustände (States). Ein Accordion hat beispielsweise den Zustand aus- oder eingeklappt. Zustände werden üblicherweise zu Elementen hinzugefügt, für die bereits Layout- oder Modulregeln gelten. So könnte eine Hinweiskomponente den Zustand is-error haben:

<div class="msg is-error">

JavaScript-Verhalten, Listeners und Methoden, die mit dem Objekt in Zusammenhang stehen.

Ein Fehler ist aufgetreten! </div>

Ein Objekt kann zum Beispiel folgendermaßen aussehen:

Zustände sind üblicherweise mit JavaScript verbunden. Die Verwendung von !important ist bei ihnen gestattet, weil Zustände die anderen Angaben überschreiben sollen. Die letzte Kategorie von Regeln sind Themes, die Farben und Hintergründe betreffen. Wenn diese separat notiert werden, lassen sie sich bei alternativen Themes leichter überschreiben. Ein Projekt kann aber auch ganz ohne Themes auskommen.

<div class="mod">

Depth of applicability Ein wichtiges Ziel von SMACSS ist es, die Depth of Applicability (Anwendbarkeitstiefe) zu verringern: Bei vielen Projekten sind Selektoren wie die Folgenden üblich: #sidebar div ul {}

Das Problem daran ist, dass detaillierte Annahmen über den HTML-Code gemacht werden und dass für die Funktionsweise somit genau diese HTML-Struktur notwendig ist. Komponenten lassen sich dann nicht verschieben; will man eine Komponente an anderer Stelle platzieren, muss man die Regeln doppeln. Die Lösung besteht darin, die Tiefe der Verschachtelung zu reduzieren und von dem Wurzelelement der Komponente selbst auszugehen. SMACSS bietet eine klare Strukturierung von Stylesheets, erlaubt aber verschiedene Arten von Selektoren – ID-Selektoren oder Nachfahrenselektoren sind nicht verpönt. Das ist in den meisten neueren CSSHerangehensweisen anders, bei denen durchweg auf Klassen gesetzt wird – wie etwa bei OOCSS.

OOCSS Das Konzept OOCSS steht für Object Oriented CSS (Bild 2) und stammt von Nicole Sullivan. In Programmiersprachen wie Java und PHP arbeitet man mit Klassen und Objekten, und dieses Konzept wird nun auf HTML/CSS übertragen. Ein Objekt besteht aus vier Bestandteilen: HTML, das heißt, ein oder mehrere DOM-Knoten, CSS-Deklarationen für die Styles der Knoten, die mit dem Klassennamen des umfassenden Knotens beginnen, Komponenten wie Hintergrundbilder,

www.webundmobile.de 3.2017

<div class="inner"> <div class="hd">Block Head</div> <div class="bd">Block Body</div> <div class="ft">Block Foot</div> </div> </div>

Das Objekt ist in diesem Fall ein Modul, erkenntlich am Namen mod. Es beinhaltet vier Knoten, die nicht unabhängig vom Modul existieren können. In OOCSS gelten zwei wichtige Grundprinzipien. Beide sprechen dafür, einfache Klassenselektoren einzusetzen: Struktur von aussehen trennen (Separate structure and skin): Damit Formatierungen wie background- und border-Angaben sich problemlos wiederverwenden lassen, sollten sie über CSS-Klassen hinzugefügt werden und nicht über HTML-Elemente/Typselektoren. Container und Inhalte voneinander trennen (Separate container and content): Ein Objekt soll immer gleich aussehen, unabhängig davon, wo es platziert wird. Wenn es um die Formatierung einer h2-Überschrift geht, ist ein Nachfahrenkombinator wie .myObject h2 ungünstig. Besser ist es, der h2-Überschrift selbst eine Klasse zu geben, über die sie angesprochen werden kann, also beispielsweise <h2 class= “category“>. Bei der objektorientierten Programmierung ist das Konzept der Vererbung wichtig. Eine Kindklasse erweitert die Elternklasse durch weitere Eigenschaften beziehungsweise Methoden. Auch in OOCSS können Komponenten erweitert werden, das heißt, dass sie zusätzliche oder andere Formatierungen erhalten. Das geschieht durch Hinzufügen einer zusätzlichen Klasse. Von der Benutzung von IDs als CSS-Selektoren wird abgeraten, aber natürlich benötigt man ID-Attribute für Verlinkungen und eventuell auch zur Auswahl mit JavaScript. Falls man Nachfolgeselektoren einsetzt, sollten sie nicht zu weit oben im DOM-Baum auftauchen. Erlaubt sind sie, wenn ein Element Teil eines größeren Objekts ist und nicht unab- ▶

43


HTML/CSS/JaVaSCRIPT

CSS

hängig existieren kann. Folgt man diesen Prinzipien, so arbeitet man in den meisten Fällen mit einfachen Klassenselektoren und in ausgewählten Fällen mit Kombinatoren.

BEM Das Konzept BEM (Block Element Modifier) (Bild 3) wurde zuerst von Yandex eingeführt. Block, Element und Modifier stehen dabei für die Beispiel für Blöcke und Elemente bei BEM (Bild 4) drei Kategorien von Klassennamen, die unterschieden werden. ment deutlich, ohne dass diese – wie sonst oft – durch NachAuf einer Webseite ist beispielsweise das Logo ein Block fahrenselektoren abgebildet wird. An dieser Stelle Nachfah(eigenständige Einheit), ebenso das Suchfeld oder auch das renselektoren wie .block .block__element {} zu verwenden ist Menü. Die Menüpunkte sind hingegen nicht eigenständig, bei BEM nicht erwünscht. Andernfalls würde die Spezifität sondern Teil des Menüblocks. Menüpunkte sind damit Eleerhöht werden, was wiederum Änderungen bei der Formamente (Bild 4). tierung solcher Elemente schwierig macht. Aus demselben Neben Blocks und Elementen gibt es die Modifizierer. MoGrund sollte der Name des HTML-Elements nicht vor den difizierer können die Elemente in verschiedener Hinsicht verKlassennamen geschrieben werden: ändern, etwa für Hervorhebungen oder beim Theming. Ein Beispiel sind Buttons, die je nach Funktion in unterschiedli/* empfohlene Auswahl von Elementen */ chen Farben oder Größen dargestellt werden. .block__element {} Sehen wir uns das Grundprinzip von BEM konkret an. /* nicht empfohlen hingegen */ Blocks erhalten einfache Klassennamen wie block. p.block__element { } <div class="block"></div>

.block .block__element {}

Für die Auswahl per CSS schreiben Sie den Klassenselektor .block { }. Elemente sind, wie erwähnt, nicht eigenständig, sondern Teil eines Blocks. Das zeigt sich auch bei der Benennung; Elemente erhalten nämlich als Präfix den Namen des Blocks, gefolgt von zwei Unterstrichen __ und dem Elementnamen. Ein Element können also zum Beispiel block__element heißen.

Kommen wir nun zu den Modifizierern. Auch ihr Name besteht aus dem Elementpräfix, diesmal gefolgt von zwei Minuszeichen (--) und dem Modifizierernamen.

<div class="block"> <p class="block__element">...</p>

.block--mod {}

In diesem Beispiel haben wir einen Blockmodifizierer. Im HTML-Code – und das ist entscheidend – werden dann mindestens zwei Klassen vergeben; die eine für den Block und die andere für den Blockmodifizierer:

</div> <div class="block block--mod">...</div>

Angesprochen werden die Elemente in CSS nur über ihren Klassennamen, das heißt, im Beispiel .block__element {} Dadurch, dass der Name des Blocks bei einem Element am Anfang steht, wird die Beziehung zwischen Block und Ele-

Es sind natürlich auch mehrere Modifiziererklassen möglich. Da immer nur Klassenselektoren eingesetzt werden, die dieselbe Spezifikation haben, müssen die Modifizierer nach den Element-/Blockklassen im Stylesheet definiert werden: .block { } .block--mod {}

Normalerweise wird von der Verwendung von Kombinatoren abgeraten. Aber hier gilt eine Ausnahme. Wenn sich ein Element aufgrund der Modifizierung des Blocks ändert, sollte man das auch mit dem Selektor abbilden.

BEM-Prinzipien BEM: Block Element Modifier (Bild 3)

44

Ein wichtiges Prinzip bei BEM ist die Blockunabhängigkeit: Man kann einen Block irgendwo auf der Seite platzieren und

3.2017 www.webundmobile.de


CSS

sicher sein, dass er nicht von der Umgebung beeinflusst wird. Dies bedeutet, dass die Verwendung eines Normalize-Stylesheets dem Grundprinzip von BEM widerspricht, weil damit das Aussehen eines Blocks von einem Drittanbieter-Code abhängt. Bisher hatten wir nur einfache Strukturen, ein HTML-Element kann aber auch zu zwei Blöcken gehören:

HTML/CSS/JaVaSCRIPT

für Objects und u für Utilities (Helferklassen) vor, sowie isund has- für Zustände. <div class="o-media c-user c-user--premium"> <img src="" alt="" class="o-media__img c-user__photo c-avatar" /> <p class="o-media__body c-user__bio">...</p> </div>

<div class="block1 block2">

Und ein HTML-Element kann gleichzeitig Block und Element sein: <div class="block1__element block2">

Außerdem können Blöcke verschachtelte Elemente beinhalten: <div class="block">

BEM setzt auf Präfixe am Anfang der Klassennamen. Man kann jetzt zusätzlich mit Suffixen arbeiten und damit am Ende eines Klassennamens kennzeichnen, was eine Klasse unter bestimmten Umständen – zum Beispiel beim Ausdruck oder bei einer bestimmten Viewport-Breite – macht. o-media@md bedeutet, dass das Element ein Media-Objekt bei der Viewport-Größe Medium (md) ist. Sinnvoll kann auch eine Klasse wie u-hidden@print sein, um zu kennzeichnen, dass etwas nicht ausgedruckt werden soll. Im Stylesheet muss das @-Zeichen allerdings mit einem \ maskiert werden:

<div class="block__elem1"> <div class="block__elem2">

@media print { .u-hidden\@print {

<div class="block__elem3"></div>

display: none;

</div> }

</div> </div>

}

Aber auch in diesem Fall bleiben die Selektoren einfach; dadurch kann die Struktur jederzeit geändert werden:

Noch ein Tipp: Wer sich an die Verschachtelung von Selektoren in Sass gewohnt hat, muss bei BEM umlernen, da diese Verschachtelungen und die dadurch erzeugten Nachfahrenselektoren nicht erwünscht sind. Wer diese Verschachtelungen als Strukturierung beibehalten möchte, kann auf folgende Syntax zurückgreifen:

.block {} .block__elem1 {} .block__elem2 {} .block__elem3 {}

.block {

Das strenge formale Benennungsschema bei BEM macht es einfach, einzelne Typen hervorzuheben und zu überprüfen, ob die Namen konform sind. Dafür eignen sich die folgenden Attributselektoren:

@at-root #{&}__element {

/* Klassen kennzeichnen */

}

background: black; } @at-root #{&}--modifier { color: red;

[class] {

}

outline: 5px solid red; } /* BEM-Elemente */ [class*="__"] { outline: 5px solid yellow;

Eingesetzt wird dabei das in Sass 3.3 eingeführte @at-root, wodurch die Angabe auf der obersten Ebene angesiedelt und nicht verschachtelt wird. Durch #(&) wird der angegebene Blockname als Präfix genutzt. Das erzeugt dann den folgenden Code:

} .block__element { background: black;

/* BEM-Modifizierer */ [class*="--"] { outline: 5px solid grey;

} .block--modifier { color: red;

} }

Das Prinzip von BEM lässt sich auch noch erweitern. So können Sie beispielsweise – wie Harry Roberts zeigt – Namensräume einsetzen. Harry Roberts schlägt c für Components, o

www.webundmobile.de 3.2017

Es gibt eine Reihe von Tools für BEM, wie beispielsweise den BEM-Constructor von Daniel Guillan. Er hilft bei der Ver- ▶

45


HTML/CSS/JaVaSCRIPT

CSS

wendung von BEM mit Sass. Bei Bedarf kann man auch andere Trennzeichen definieren als die doppelten Unter- oder Bindestriche.

SUIT CSS SUIT CSS (Bild 5) nennt sich »Style tools for UI components«, das heißt, die Ausrichtung ist die komponentenbasierte UIEntwicklung. Es stammt von Nicolas Gallagher. Neben der Vorstellung einer Herangehensweise beinhaltet SUIT CSS auch Pakete und Build-Tools wie CSS-Präprozessoren. Ein wichtiger Bestandteil von SUIT CSS ist die Namenskonvention, die an BEM erinnert, aber in Details davon abweicht. Das Grundprinzip von SUIT CSS ist, dass es keine unsemantischen Bindestriche gibt. Das heißt, wenn ein Klassennamen aus mehreren Wörtern besteht, werden diese in der CamelCase-Schreibweise geschrieben. Außerdem gibt es Präfixe wie u für Helferklassen (utility). Das folgende Beispiel

von BEM. Die Namen von Descendents werden in CamelCase-Schreibweise angegeben, sie bestehen aus dem Namen der Komponente, gefolgt von einem Bindestrich und dem Namen des Descendents. Im folgenden Beispiel sind Tweet-header und Tweet-bodyText Descendents. <article class="Tweet"> <header class="Tweet-header"> </header> <div class="Tweet-bodyText"> </div> </article>

Außerdem gibt es Zustände, die mit is beginnen. Diese Klassen sollten im Stylesheet nicht alleine stehen, sondern immer nur mit dem zugehörigen Komponentennamen. .Tweet { /* ... */ } .Tweet.is-expanded { /* ... */ }

Webseite von SUIT CSS (Bild 5)

Im HTML-Code werden beide Klassen angegeben: <article class="Tweet is-expanded"> ... </article>

Die Klasse is-expanded wäre ebenfalls nützlich bei einem Accordion, allerdings muss jede Komponente ihre eigenen Styles für den Zustand definieren. zeigt Helferklassen und die Verwendung der CamelCaseSchreibweise:

.Accordion { /* ... */ }

<div class="u-cf">

Normalerweise werden bei SUIT CSS einfache Selektoren eingesetzt, bei den Zuständen sind es hingegen doppelte Klassenselektoren. Diese Abweichung vom allgemeinen Prinzip ist jedoch beabsichtigt. Der Vorteil besteht darin, dass diese doppelten Klassen sich gegenüber den einfachen durchsetzen. .Accordion.is-expanded hat eine höhere Spezifität als .Accordion und gilt damit immer – unabhängig von der Reihenfolge der Regeln im Stylesheet. Neben den Benennungsregeln bietet SUIT CSS eine Reihe von Komponenten, die man bei Bedarf einsetzen kann. Das wären beispielsweise Überprüfungs-Tools, um die Konformität des Codes zu testen. Eine weitere Komponente ist SUIT CSS Base, die ein paar Ergänzungen zu Normalize bietet. SUIT CSS Utilities schließlich sind Helferklassen für die Ausrichtung, die Darstellungsart, fürs Layout, für Links, Texte, Größen und mehr. Zusätzlich erlaubt suitcss-preprocessor das Schreiben von Code, wie er teilweise in Spezifikationen vorgesehen, aber noch nicht in Browsern implementiert ist.

<div class="u-sizeFit">...</div> <div class="u-sizeFill">...</div> </div>

Außerdem gibt es responsive Helferklassen. Bei diesen wird nach dem u die Viewport-Größe geschrieben, für die sie gelten, wie beispielsweise u-sm-<name> oder u-md-<name>. Komponenten können ein Namensraumpräfix haben oder auch nicht, sie werden in PascalCase-Schreibung angegeben. Im Gegensatz zur CamelCase-Schreibung beginnen die Bezeichner bei PascalCase mit einem Großbuchstaben. Ein Beispiel für einen PascalCase-Komponentennamen wäre MyComponent. Die Namen für Modifizierer beinhalten den Namen der Komponente, gefolgt von zwei Bindestrichen (wie bei BEM) und dem Modifizierernamen, beispielsweise also .Button--default {}. Im HTML-Code werden beide Klasse verwendet. <button class="Button Button--default" type="button">...

.Accordion.is-expanded { /* ... */ }

</button>

atomic CSS

Nichtselbstständige Bestandteile von Komponenten heißen bei SUIT CSS Descendents – sie entsprechen den Elementen

Eine Klarstellung vorweg: Die nun vorgestellte CSS-Strategie Atomic CSS hat nichts zu tun mit dem Atomic Design genannten Design-Ansatz von Brad Frost.

46

3.2017 www.webundmobile.de


CSS

HTML/CSS/JaVaSCRIPT

Zurück zur Methode Atomic CSS (Bild 6). Wie viele Klassen sind sinnvoll und notwendig? Zu den Anfangszeiten von CSS war man da eher sparsam, inzwischen dürfen es gerne auch mal mehr sein. Ein Extremfall ist in dieser Hinsicht Atomic CSS, wo es CSS-Klassen für alle denkbaren CSS-Formatierungen gibt: <div class="Bgc(#0280ae) C(#fff) P(20px)"> Lorem ipsum </div>

Dieser Code ist direkt verständlich. Es werden eine Hintergrundfarbe, eine Schriftfarbe sowie ein padding definiert. Das heißt, bei Atomic CSS schreibt man keinen CSS-Code, sondern arbeitet mit Klassen im HTML-Code zur Formatierung. Da manche Zeichen in Klassennamen nicht erlaubt sind, muss man sie in CSS escapen; dies wirkt auf den ersten Blick recht kryptisch:

atomic CSS: Kleinste CSS-Komponenten (Bild 6)

.P\(20px\) {

Gegenüber Inline-Styles hat Atomic CSS zwei eindeutige Vorteile: Es ist sowohl die Verwendung von Pseudoklassen wie :hover als auch von Media Queries möglich, was bei Inline-Styles nicht geht. Atomic CSS verfolgt einen grundlegend anderen Ansatz als die bisher vorgestellten Herangehensweisen und wird durchaus nicht von allen Entwicklern positiv aufgenommen. Ob Atomic CSS tatsächlich für alle Sorten von Projekten geeignet ist, sei dahingestellt. Aber es gibt zweifellos Fälle, in denen diese Herangehensweise praktisch sein kann; beispielsweise für WYSIWYG-Editoren, welche die Formatierungen der Benutzer umsetzen müssen, oder wenn man einen Prototyp erstellt. In solchen Fällen kann es durchaus hilfreich sein, wenn HTML-Code und Formatierung an derselben Stelle stehen.

padding: 20px; } .C\(\#fff\) { color: #fff; } .Bgc\(\#0280ae\) { background-color: #0280ae; }

Der Ansatz von Atomic CSS ist auf jeden Fall gewöhnungsbedürftig und es erscheint nicht so weit von Inline-Styles entfernt. Warum dann nicht gleich mit dem Folgenden arbeiten:

Links zum Thema

SMACSS https://smacss.com https://www.smashingmagazine.com/2012/04/ decoupling-html-from-css

OOCSS https://github.com/stubbornella/oocss/wiki/faq www.slideshare.net/stubbornella/object-oriented-css

BEM http://getbem.com/introduction https://en.bem.info https://github.com/danielguillan/bem-constructor http://csswizardry.com/2015/08/bemit-taking-thebem-naming-convention-a-step-further

SUIT CSS https://suitcss.github.io https://philipwalton.com/articles/introducing-htmlinspector

Atomic CSS https://acss.io

www.webundmobile.de 3.2017

<div style="background-color: #0280ae; color: #fff; padding: 20px"> Lorem ipsum </div>

Fazit Bei größeren Projekten oder bei der Arbeit im Team kommt man heute nicht mehr darum herum, sich Gedanken über die Strategie für das CSS zu machen. An sich gibt es zwei Möglichkeiten: Entweder verwendet man eine bereits existierende, bekannte Strategie, was den Vorteil hat, dass diese bereits dokumentiert ist. Oder man modifiziert eine Strategie und entwickelt daraus einen eigenen Ansatz. So oder so: Die Zeiten, in denen man ohne Methodik einfach so lange am Stylesheet gebastelt hat, bis die Website das gewünschte Ausse◾ hen zeigte, sind vorbei.

Dr. Florence Maurice ist Autorin, Trainerin und Programmiererin in München. Sie schreibt Bücher zu PHP und CSS3 und gibt Trainings per Video. Außerdem bloggt sie zu Webthemen unter: http://maurice-web.de/blog

47


HTML/CSS/JaVaSCRIPT

Framework

JaVaSCRIPT-FRaMEWORK MERCURy

Gruppe von Modulen Das Mercury-Framework besteht aus einer Gruppe von relativ unabhängigen Modulen.

Installation Das auf GitHub unter https://github.com/Raynos/mercury gehostete Framework kommt am einfachsten unter Nutzung von Node auf Ihre Maschine. Der Autor arbeitet in den folgenden Schritten mit einer Ubuntu-14.04-Workstation. Erzeugen Sie im nächsten Schritt ein Arbeitsverzeichnis, und geben Sie folgendes Kommando ein, um den relevanten Code aus dem GitHub-Repository herunterzuladen: tamhan@TAMHAN14:~/mercuryworkspace$ npm init This utility will walk you through creating a package. json file. It only covers the most common items, and tries to guess sensible defaults.

48

Foto: Shutterstock / Danang Setiawan

J

avaScript-Frameworks werden normalerweise nach der Methode »Friss oder stirb« ausgeliefert: Wer nur einzelne Module oder Funktionen benutzen möchte, hat Pech gehabt. Mercury geht dieses Konzept auf eine komplett andere Art und Weise an. Das von Jake Verbaten seit einigen Jahren mehr oder weniger im Alleingang entwickelte Framework besteht aus einer Gruppe von Modulen, die untereinander nur vergleichsweise wenig Dependenzen aufweisen. Eines der erklärten Ziele des Entwicklers ist, dass die Anwender Komponenten mehr oder weniger nach Belieben mit anderen Frameworks kombinieren können. In der Dokumentation werden beispielsweise und ohne Anspruch auf Vollständigkeit folgende Kombinationen genannt: Backbone und Mercury, Immutable und Mercury sowie JSX und Mercury. Wir wollen in diesem Artikel einen Blick auf Mercury werfen und das Verhalten der diversen Module des Frameworks näher ansehen. Dazu sollen einige kleine Beispiele realisiert werden, die den Vergleich zwischen den Konzepten von Mercury und den in anderen Frameworks verwendeten Vorgehensweisen ermöglichen.

... tamhan@TAMHAN14:~/mercuryworkspace$ npm install mercury --save mercuryworkspace@1.0.0 /home/tamhan/mercuryworkspace └── mercury@14.1.0

extraneous

npm WARN EPACKAGEJSON mercuryworkspace@1.0.0 No description npm WARN EPACKAGEJSON mercuryworkspace@1.0.0 No repository field.

Im ersten Schritt wird hier – wie gewohnt – ein neues NPMRepository angelegt. Achten Sie darauf, dass das Modul auf keinen Fall mercury heißen darf, sonst kommt es zu einem Fehler mit Bezug auf rekursive Paketinklusion. Das zweite Kommando lädt die im Repository befindlichen Daten des Frameworks herunter und integriert sie in package.json.

3.2017 www.webundmobile.de


Framework

Die im Rahmen des Deployments geworfenen Fehlermeldungen sind für uns nicht weiter relevant. Das Fehlen einer Paketbeschreibung mag aus Sicht des Repositorys einen Syntaxfehler darstellen, betrifft Nutzer des Frameworks aber nicht weiter. Erstellen Sie danach auf Ebene der Paketdatei eine JavaScript-Datei namens index.js, die im Rest des Artikels als Träger für den Beispielcode dienen wird. Fürs Erste wollen wir ein kleines Counterbeispiel realisieren, das einen Gutteil der in Mercury implementierten Funktionalitäten streift. Beginnen Sie mit der Node-üblichen Inklusion der zu verwendenden Module:

HTML/CSS/JaVaSCRIPT

function incrementCounter(state) { state.value.set(state.value() + 1); }

Als Nächstes folgt die Rendering-Funktion. Diese Funktion ist in Mercury per Definition zustandslos und wird vom Rest des Frameworks immer dann aufgerufen, wenn eine Änderung des Zustands eine Aktualisierung der angezeigten Daten erfordert: App.render = function render(state) { return h('div.counter', [ 'The state ', h('code', 'clickCount'),

'use strict';

' has value: ' + state.value + '.',

var document = require('global/document');

h('input.button', {

var hg = require('mercury');

type: 'button',

var h = require('mercury').h;

value: 'Click me!', 'ev-click': hg.send(state.channels.clicks)

In der Mercury-Welt hat sich die Nutzung von use strict als Quasistandard etabliert, weshalb wir das betreffende Flag ebenfalls setzen. Interessanter sind hier allerdings die Flags h und hg: hg verweist auf das Hauptmodul von Mercury, während h einen Verweis auf die im nächsten Abschnitt näher besprochene Hilfsfunktion für die Erzeugung von DOM-Graphen darstellt. Im nächsten Schritt folgt die App-Funktion, die als Einsprungpunkt in unser Programm dient. Wir rufen hierbei die state-Methode von hg auf, die ein JSON-Array mit weiteren Attributen übergeben bekommt: function App() { return hg.state({ value: hg.value(0), channels: { clicks: incrementCounter } }); }

Das an die state-Funktion zu übergebende Objekt spielt zwei Rollen: Einerseits gibt es von Mercury vorgegebene Flags wie channels, die die Beeinflussung bestimmter Parameter des Frameworks ermöglichen. Im Fall des Channels-Arrays sind dies beispielsweise Ereigniskanäle, die mit bestimmten Handlern verdrahtet werden. Sonstige Variablen dienen als Ablageort für Parameter, die für die Programmausführung erforderlich sind. Im Fall unseres Beispiels gibt es hier das Feld value, der anfangs den in einen Wrapper verpackten numerischen Wert null aufweist.

Convenience-Funktion Als Nächstes folgt im vom Entwicklerteam vorgegebenen Beispiel eine Convenience-Funktion, die den Zustand, der im globalen state-Objekt vorgehalten wird, verändert. Beachten Sie hier die an Knockout erinnernde Syntax, die eine Art Observable realisiert und dem Framework die Reaktion auf Änderungen der gespeicherten Informationen ermöglicht:

www.webundmobile.de 3.2017

}) ]); };

Im Moment ist die Rolle der h()-Funktion für uns nicht weiter relevant. Für die folgenden Schritte reicht die Feststellung aus, dass es sich dabei um eine Funktion handelt, die DOMElemente belebt.

Graphentheorie Interessanter ist in diesem Zusammenhang die Frage, wie Mercury reagiert, wenn render neu aufgerufen wird. Das in den folgenden Schritten näher beschriebene virtuelle DOM ist eine Art Graph, der nach der in der Graphentheorie definierten Differenzoperation bearbeitet wird. Daraus folgt, dass normalerweise nur jene Elemente aktualisiert werden, die auch Änderungen erfahren. Ein Aufruf von render ist normalerweise keine besonders aufwendige Operation. Zu guter Letzt fehlt noch ein Aufruf der Funktion app, die für das eigentliche Rendering zuständig ist. Sie bekommt – unter anderem – einen Verweis auf document.body übergeben. Dies weist die Methode darauf hin, dass sie ihre Arbeit im Body-Tag des Testharnischs bewerkstelligen soll: hg.app(document.body, App(), App.render);

Für die Programmausführung wollen wir in den folgenden Schritten Browserify verwenden. Es handelt sich dabei um ein Universal-Utility, das JavaScript-Dependancen zusammenpackt und für normale Browser ansprechbar macht. Die Installation erfolgt über folgende Kommandos: tamhan@TAMHAN14:~/mercuryworkspace$ npm install -g browserify /home/tamhan/.nvm/v4.1.1/bin/browserify -> /home/tamhan/.nvm/v4.1.1/lib/node_modules/browserify/ bin/cmd.js /home/tamhan/.nvm/v4.1.1/lib └─┬ browserify@13.1.1

49


HTML/CSS/JaVaSCRIPT

Framework

Nach Abarbeitung dieses Kommandos sehen Sie eine neue Datei namens out.js, die ein von Abhängigkeiten befreites Kompilat der Applikation darstellt. Für die Ausführung des Programms ist sodann ein Testharnisch erforderlich, der sich so aufbauen lässt:

wollen wir uns das betreffende Modul von Mercury näher ansehen. Öffnen Sie dazu die Datei readme.md, die im Projektverzeichnis /node_modules/virtual-dom bereitsteht. Die hier verwendete Markdown-Syntax mag nicht jedermanns Sache sein; mit etwas gutem Willen erschließt sich der Inhalt des Dokuments allerdings ohne Probleme. Im in Bild 2 gezeigten Abschnitt der Dokumentation findet sich eine Passage, die auf eine eigene Readme-Datei hinweist: Sie ist ausschließlich für die h-Funktion und ihre Helfer vorgesehen. Das in MD-Dateien enthaltene Markdown ist ein im Jahr 2004 entwickeltes Beschreibungsformat, das eine Art »HTML light« darstellt. Seine Autoren haben es unter anderem für Dokumentationen vorgesehen, die sich bei Bedarf einfach in HTML umwandeln lassen. Im Fall unserer Readme-Dateien würde sich dazu beispielsweise das als Web-App verfügbare Werkzeug Dillinger (http://dillinger.io) anbieten.

<html>

HyperScript-Programmierframework

├── assert@1.3.0 tamhan@TAMHAN14:~/mercuryworkspace$ npm install

Das eigentliche Verpacken des Quellcodes lässt sich in Browserify folgendermaßen durchführen: Mit -o übergeben Sie den Namen der anzulegenden Konvolutdatei, die das Resultat der Auflösung aller require()-Direktiven aufnimmt: tamhan@TAMHAN14:~/mercuryworkspace$ browserify index.js -o out.js

<body> <script src="out.js"></script> </body> </html>

Der nicht sonderlich komplizierte Code der hier als worker. htm bezeichneten Webseite beschränkt sich darauf, das Ergebnis der Kompilation über ein script-Tag einzubinden und ein <body>-Tag bereitzustellen, in dem unser Beispiel nach Belieben herumfuhrwerken kann.

Webserver starten Zu guter Letzt müssen wir noch einen Webserver starten, über den wir die Inhalte des Verzeichnisses für Browser zugänglich machen. Unter Ubuntu bietet sich hierbei der in Python enthaltene SimpleHTTP-Server an, der sich in jedem Konsolenfenster aufrufen lässt und den Inhalt des gerade aktiven Arbeitsverzeichnisses über Port 8000 bereitstellt:

Jake Verbaten orientierte sich bei der Entwicklung am von Dominic Tarr erdachten HyperScript-Programmierframework. Es handelt sich dabei um eine Bibliothek, die Entwicklern das Erzeugen von HTML-Markup aus einer Gruppe von Funktionen und Parameterobjekten ermöglicht. Der Name der Funktion ist damit übrigens auch erklärbar – er steht für Hypertext beziehungsweise HyperScript. Um HyperScript hat sich eine Gruppe von Werkzeugen entwickelt, die beispielsweise HTML-Inhalte in eine Abfolge von Skriptfunktionen konvertieren können. Zudem findet sich auf der Webseite des Produkts eine umfangreiche Dokumentation. Wer mit der h()-Funktion von Mercury Probleme hat, sollte unter https://github.com/dominictarr/hyperscript vorbeischauen.

tamhan@TAMHAN14:~/mercuryworkspace$ python -m SimpleHTTPServer Serving HTTP on 0.0.0.0 port 8000 ... 127.0.0.1 - - [30/Dec/2016 19:06:41] "GET /worker.htm HTTP/1.1" 200 –

Laden Sie die Webseite über den URL http://localhost:8000/ worker.htm und klicken Sie den Button einige Male an, um die Inkrementierung des angezeigten Wertes zu erhalten. Wer den Quellcode der geladenen Webseite in Firefox öffnet, sieht nur den Testharnisch. Der von Mercury generierte Code kommt nur dann auf den Bildschirm, wenn Sie den Debugger öffnen und in den Inspector-Tab wechseln (Bild 1).

Die Kombination aus Browserify und Mercury generiert zur Laufzeit vergleichsweise komplexes Markup (Bild 1)

Markdown-Syntax Damit ist erwiesen, dass unser Programm problemlos funktioniert. Zum Verständnis dessen, was hinter den Kulissen passiert,

50

Die etwas seltsam aussehende abfolge von Klammern beschreibt in Markdown einen Hyperlink (Bild 2)

3.2017 www.webundmobile.de


Framework

Mit diesem Wissen können wir uns an die Syntax der h-Funktion heranwagen, die im Normalaufbau zwei oder drei Parameter entgegennimmt:

HTML/CSS/JaVaSCRIPT

Nach einem abermaligen Aufruf von Browserify ist das Programm ausführungsbereit. Bild 3 zeigt, was auf der Workstation des Autors im Firefox-Browser auftauchte. Interessant ist hier vor allem, dass Mercury es mit der in HyperScript spezifizierten Erkennung von Nicht-HTMLTags nicht sonderlich genau nimmt. Unser Programm erzeugt ein <nmg>-Tag, das im HTML5-Standatd nicht vorkommt, aber immerhin die Klasse nmgzwei aufweist:

h(selector, properties, children)

Der Selektor ist dabei ein nach dem Schema name.class1.class2#id aufgebauter String. Der erste Teil, also der Die Erkennung von Nicht-Tags funktioWert bis zum ersten Punkt, beschreibt niert mit Mercury nicht sonderlich zuverdabei den Namen des anzulegenden lässig (Bild 3) Tags. Wird hier beispielsweise a übergeben, so entsteht ein Hyperlink. <div id="page"> Eventuell folgende Strings beschreiben sodann eine oder ... mehrere Klassen, die dem neu anzulegenden Objekt zuge<nmg class="nmgzwei">Zweites Div!</nmg> wiesen werden. Hinter dem Rautezeichen folgt sodann eine </div> ID, die das individuelle Objekt beschreibt. Berücksichtigen Sie, dass das Übergeben von ID und KlasMit diesem Wissen können wir unseren Harnisch wieder in se nicht unbedingt erforderlich ist. Es wäre beispielsweise den Ursprungszustand zurückversetzen. Diesmal wollen wir auch in Ordnung, einfach a#nmg zu übergeben, um ein <a>statt eines Knopfes gleich mehrere Buttons anlegen: Tag mit der ID NMG zu generieren. In der Dokumentation findet sich zudem ein Verweis auf eiApp.render = function render(state) { ne kleine Sonderintelligenz: Wird der name-Tag nicht in Form return h('div#page',[ eines gültigen HTML-Objekts übergeben, erzeugt Hyperh('input.button#btn1', { Script – so zumindest die Spezifikation – ein <div>-Tag und type: 'button', value: 'Knopf 1!', betrachtet auch den ersten Teil des Strings als Klassendekla'ev-click': hg.send ration. Zum Testen dieses Verhaltens und zur Vorführung von (state.channels.clicks) }), HyperScript passen wir unser Programm ein wenig an: h('br'), App.render = function render(state) {

h('input.button#btn2', {

return h('div#page',

type: 'button', value: 'Knopf 2!',

[h('div.counter',"Erstes Div!"),

'ev-click': hg.send

h('nmg.nmgzwei',{}, "Zweites Div!")]);

(state.channels.clicks) })

};

]); };

Hinter der – absichtlich etwas eigenwilligen – Formatierung verbirgt sich ein nicht sonderlich komplexes DOM-Element: Wir liefern das Resultat einer h()-Funktion, die ein <div> erstellt, das die ID page aufweist. Der Aufruf von h() bekommt neben dem Namen div und der anzulegenden ID auch ein Array übergeben, das die im Tag anzulegenden Kinder beschreibt. Wir legen hierbei zwei Kinder an: einerseits ein <div> mit der Klasse counter und zweitens ein NMG-Element mit der Klasse nmgzwei. Beide Aufrufe von h() bekommen zudem einen String übergeben, der den zur Laufzeit darzustellenden Inhalt anliefert. Im Fall von nmgzwei übergeben wir aus didaktischen Gründen noch ein leeres JSON-Objekt, das anzeigt, dass keine Properties vorhanden sind.

Interessant ist, dass wir die Aufrufe von h() nun mit einem vollwertigen Properties-Array ausstatten. Neben der Be- ▶

Reihenfolge beachten Bei Betrachtung dieser Funktionen fällt auf, dass die h-Funktion sehr flexibel ist: Sie erkennt automatisch, ob ein Parameter Kinder (Typ: Array) oder Properties (Typ: Objekt) anliefert. Wichtig ist hierbei nur, dass die in der Syntax angegebene Reihenfolge nicht vertauscht wird.

www.webundmobile.de 3.2017

Das br-Tag kommt ohne Parameter und Kinder aus, weshalb seine Erzeugung primitiv ist (Bild 4)

51


HTML/CSS/JaVaSCRIPT

Framework

stimmung des Typs des anzulegenden Knopfes legen wir einen Event-Handler fest. Die verwendete Syntax ist etwas eigenwillig, wird sich aber im nächsten Abschnitt erschließen. Sie können den Code zu diesem Zeitpunkt gern in Firefox und Co. ausführen, um sich davon zu überzeugen, dass die beiden Buttons komplett übereinander erscheinen. Wer h() mit nur einem Parameter aufruft, bekommt ein normales Element ohne Eigenschaften und Kinder (Bild 4).

Eventorientierte architekturen Die Eventverarbeitung ist traditionell eine der wichtigsten Aufgaben eines JavaScript-Frameworks. Das in Mercury implementierte Ereignisverwaltungssystem kommt von Haus aus mit rund einem Dutzend Ereignisse, die in der Datei domdelegator/index.js deklariert sind. Insbesondere befindet sich darin folgendes Array: var commonEvents = [ "blur", "change", "click", "contextmenu", "dblclick", "error","focus", "focusin", "focusout", "input", "keydown", "keypress", "keyup", "load", "mousedown", "mouseup", "resize", "select", "submit", "touchcancel", "touchend", "touchstart", "unload" ]

Ein kurzer Blick auf die im Feld commonEvents enthaltenen Strings zeigt, dass unser Klick-Event von Mercury unterstützt und somit automatisch geroutet wird. Diese auf den ersten Blick unbedeutend erscheinende Unterteilung ist insofern von Relevanz, als alle Ereignisse in einem als DOM-Delegator bezeichneten Modul zusammenlaufen. Es handelt sich dabei um ein unter node_modules/dom-delegator/dom-delegator.js deklariertes eigenständiges Modul, das bei Bedarf durch Inklusion unabhängig vom Rest von Mercury in eigene Projekte eingebunden werden kann. Jedes der in commonEvents genannten Ereignisse wird zur Laufzeit über einen Kanal präsentiert. Im Fall des clicked-Ereignisses heißt dieser auf Seiten des Benutzerinterfaces evclick. Das gleichnamige Attribut erlaubt uns nun das Einschreiben von mehr oder weniger beliebigen Methoden, die im Ereignisfall aktiviert werden. Im Moment sieht der dazugehörende Code so aus: h('input.button#btn2', { type: 'button', value: 'Knopf 2!', 'ev-click': hg.send(state.channels.clicks) })

ev-click wird hierbei mit der Methode hg.send verbunden, die für das Abfeuern von Ereignissen im Framework verantwortlich ist. Der übergebene Parameter beschreibt dabei ein Element des Channels-Felds, das im globalen state-Objekt untergebracht ist. Das Channels-Feld ist eine Besonderheit von Mercury. Das Framework arbeitet intern mit einer weitere Gruppe von Kanälen, die im Rahmen der App-Methode angelegt werden

52

und systemweit zur Verfügung stehen. Wir wollen den im Beispiel schon vorhandenen clicks-Kanal nun weiterverwenden. Die von ihm aufgerufene Methode muss um einen Aufruf von console.log erweitert werden, um bei Aktivierung eine Nachricht in die Debugger-Konsole zu schreiben: function incrementCounter(state) { console.log("Hallo!"); }

Wer das vorliegende Programm in einem Browser ausführt, stellt fest, dass das Anklicken der Knöpfe zu einer Anpassung der Ausgabe in der Debugger-Konsole führt. Das Ereignis ev clicks ist übrigens nicht auf das Absetzen von Nachrichten an Channels beschränkt; Sie können beliebige andere Funktionen aufrufen. Direktes Einschreiben von Ereignissen ist hilfreich, wenn es um die Implementierung bestimmter Komponentenverhalten geht. Falls Sie Ereignisse auf systemweite Art und Weise abpassen wollen, können Sie direkt mit dem Delegator zusammenarbeiten. Als Beispiel dafür wollen wir eine Methode anlegen, die bei Klicks auf beliebige Steuerelemente aktiviert wird. Dazu müssen Sie im ersten Schritt die Deklaration der Buttons anpassen, um keine direkten Event-Handler mehr anzulegen: App.render = function render(state) { return h('div#page',[ h('input.button#btn1', { type: 'button', value: 'Knopf 1!' }), ...

Als Erstes müssen wir das delegator-Objekt unter Nutzung von require laden. Die hier verwendete Syntax entspricht im Großen und Ganzen dem, was man von Node.js und Co. kennt: var delegator = require("dom-delegator")

Der eigentliche Aufruf von Elementen des Delegators ist in zweierlei Hinsicht seltsam: Erstens liefert require eine Art Blaupause zurück, die wie eine Methode aufgerufen werden muss, um eine verwendbare Instanz zu bekommen.

Eventnamen ohne Präfix Zweitens sind die zu übergeben Eventnamen ohne das Präfix ev- anzuschreiben – wer addGlobalEventListener einen String der Bauart ev-* übergeben würde, bekommt zur Laufzeit keine Ereignisinformationen angeliefert. Als zweiten Parameter bekommt die Funktionen einen Verweis auf den Event-Handler, der beim Auftreten des Events zu aktivieren ist: function App() { delegator().addGlobalEventListener('click', runMe);

3.2017 www.webundmobile.de


Framework

tion um ein diesbezügliches Feld erweitern, dem sogleich einige Werte eingeschrieben werden:

return hg.state({ ...

Im nächsten Schritt legen wir eine Handler-Funktion an. Das an die Methode übergebene Objekt – der Autor nennt es hier aus Gründen der Bequemlichkeit a – ist ein klassisches JavaScript-Informationsträgerelement, das unter anderem Daten über das Steuerelement anliefert, das für die Auslösung des Ereignisses zuständig war:

var ObservArray = require("observ-array") function App() { delegator().addGlobalEventListener ('click', runMe); return hg.state({ myField:ObservArray(["A", "B", "C"]), channels: { ...

Als Nächstes ist eine Anpassung in der Methode render erforderlich. Sie muss für jedes Element im Observable-Array ein neues Element in den DOM-Baum einfügen, um am Ende eine Liste aller Elemente zu erzeugen. Dieses Problem lässt sich am Einfachsten über ein leeres Array lösen, das nach vollständiger Bevölkerung in das finale DOM-Element eingebaut wird. Ein Weg zur Implementierung sieht so aus:

function runMe(a){ console.log(a);

Der Delegator liefert Informationen, die die Korrelation von Ereignissen erleichtern (Bild 5)

}

HTML/CSS/JaVaSCRIPT

Bild 5 zeigt, wie sich das Objekt in der Debugger-Konsole von Firefox präsentiert. JavaScript-Entwickler aller Couleur leiden seit Jahr und Tag unter einer Design-Entscheidung des Spracherfinders: Er vergaß, die Sprache um eine Möglichkeit zum Abfeuern von Notifications zu ergänzen, die von der Runtime beim Zugriff auf bestimmte Variablen ausgelöst werden. Es gibt kaum ein Framework, das hier keine eigene Implementierung mitbringt. Im Fall von Mercury ist dies insofern besonders interessant, als das betreffende Modul klein und leicht weiterverwendbar ist.

Gruppe von Modulen Zur Begründung der folgenden Schritte wollen wir einen Blick hinter die Kulissen werfen. In der Datei index.js findet sich unter anderem eine Struktur, die zeigt, dass das Mercury-Hauptframework aus einer Gruppe von Modulen zusammengestellt ist. Auffällig ist auch, dass die Observable-Logik selbst modular ist. Es ist erlaubt und legitim, nur bestimmte Elemente zu laden: var mercury = module.exports = { ...

App.render = function render(state) { var objCache=[]; state.myField.forEach(function (what, index) { objCache.push(h('br')); objCache.push(h('div',{},what)); });

Interessant ist in diesem Zusammenhang, dass das in Mercury mitgelieferte Observable-Array dual ist. Das bedeutet, dass eine Instanz zur Laufzeit sowohl durch ein Observable als auch durch ein normales JavaScript-Array repräsentiert wird. Diese Vorgehensweise erleichtert den Zugriff auf die im Container befindlichen Informationen immens. Wir nutzen diese Dualität zur Realisierung einer for-Schleife, die die weiter oben erwähnte for-Schleife mit diversen Elementen bevölkert. Für jedes Feld entsteht ein neues div-Tag und ein neues <br>. Das so entstehende Feld wird im nächsten Schritt in das finale DOM-Element eingebunden, das von return als Rückgabewert in Richtung von Mercury gesendet wird. Hier fällt die enorme Flexibilität von HyperScript auf. Das Framework erkennt automatisch, dass eines der Elemente des Kinder-Arrays ein weiteres Array ist, das durch Rekursion abgearbeitet wird:

array: require('observ-array'), struct: require('observ-struct'), varhash: require('observ-varhash'),

return h('div#page',[ h('input.button#btn1', {

value: require('observ'),

type: 'button',

state: state,

value: 'Knopf 1!'

...

Wir wollten in den folgenden Schritten einige der Observables verwenden, um unseren Testharnisch um einige Aspekte einer Data-Binding-Applikation zu bereichern. Als ersten Akt müssen wir hierbei das Modul ObservableArray laden und die Zustandsvariable der gesamten Mercury-Applika-

www.webundmobile.de 3.2017

}), objCache, h('input.button#btn2', { type: 'button', value: 'Knopf 2!' })

53


HTML/CSS/JaVaSCRIPT

Framework

]); };

Wer das Programm in der vorliegenden Form ausführt, wird mit dem in Bild 6 gezeigten Verhalten belohnt. Unsere nächste Aufgabe be- Der Inhalt des arrays wird steht in der Realisierung eines zwischen den beiden KnöpEvent-Handlers, der das Feld fen ausgegeben (Bild 6) bei jedem Anklicken um ein weiteres Element ergänzt. Im Idealfall – also bei korrektem Funktionieren von Mercury – würde dies eine Aktualisierung des DOM-Baums hervorrufen. Der am Bildschirm angezeigte Inhalt des Arrays müsste also immer mit dem Zustand des Feldes d‘accord gehen. Beginnen wir unsere Arbeiten mit dem Einschreiben eines Event-Handlers in btn2, der über einen neuen Mercury-Kanal mit dem Rest der Applikationslogik kommuniziert:

durchschnittliche DOM-Objekt aus einigen Hundert Elementen besteht, bekommt man Kopfschmerzen. Erfreulicherweise bietet Mercury mit dem KomponentenSubsystem eine komfortable Möglichkeit zur Generierung von Widgets an, die als Ganzes in den DOM-Tree eingefügt werden können und das Hantieren mit den einzelnen h()Aufrufen abstrahieren. Wir wollen uns als erstes Beispiel einem vom Entwicklerteam als Einstiegsaufgabe empfohlenen Widget zuwenden, das ein mehr oder weniger beliebiges DOM-Objekt einpackt. Es enthält in der vorgegebenen Variante zudem einen kleinen Fehler, der uns das Hantieren mit den Debugging-Möglichkeiten von Browserify und Co. ermöglicht. Dazu müssen Sie eine neue Datei namens WrapperWidget. js erzeugen, die mit folgendem Code ausgestattet wird: var createElement = require ('virtual-dom/create-element.js'); var diff = require('virtual-dom/diff'); var patch = require('virtual-dom/patch');

h('input.button#btn2', {

var document = require('global/document');

type: 'button', value: 'Knopf 2!',

module.exports = PureWrapperWidget;

'ev-click': hg.send (state.channels.updateField) })

Diese auf den ersten Blick umständlich wirkende Vorgehensweise ist erforderlich, weil wir so am bequemsten auf eine Instanz des globalen stage-Objekts zugreifen können. Zur Deklaration des neuen Kanals müssen wir das an App übergebene Feld ein wenig anpassen: function App() { ... channels: { clicks: incrementCounter,

An erster Stelle finden sich in der Datei die üblichen Inklusionen. Beachten Sie, dass das Erzeugen eines Widgets keine Einbindung von Mercury als Ganzes voraussetzt. Stattdessen reicht es, einige DOM-Hilfsobjekte zu laden und das Widget-Objekt über die Export-Funktionalität zu exponieren. Widgets entstehen nach den von Osmani und Co. eingeführten Regeln der objektorientierten Programmierung in JavaScript. Als Erstes beschaffen wir deshalb einen Verweis auf den Prototyp der Objektfamilie, der im nächsten Schritt ein Type-Wert eingeschrieben wird. Es ist von eminenter Bedeutung, dass das Feld den Wert Widget annimmt. Mercury erkennt die Komponenten zur Laufzeit anhand eines StringVergleichs gegen ebendieses Memberfeld:

updateField: fieldWorker }

var proto = PureWrapperWidget.prototype;

});

proto.type = 'Widget';

Die eigentliche Intelligenz zur Anpassung des Arrays findet sich nur in der Hilfsmethode fieldWorker. Sie ruft die PushMethode von myField auf, um das neue Element ins Array zu schieben und ein Aktualisierungs-Event abzufeuern:

Die Spezifikation von Mercury-Widgets schreibt zudem vor; dass zwei Funktionen vorhanden sein müssen. Als Erstes findet sich die Funktion Init, die für die Erzeugung einer neuen Instanz des jeweiligen Steuerelements zuständig ist und folgendermaßen aussieht:

function fieldWorker(state){ state.myField.push("Neuer Wert");

proto.init = function init() { var elem = createElement(this.currVnode);

}

var container = document.createElement('div');

Wer das vorliegende Programm ausführt und den Button einige Male anklickt, stellt fest, dass sich die Struktur des Formulars permanent verändert. Damit ist bewiesen, dass unser Observable auf Basis von Mercury problemlos funktioniert. Auch wenn HyperScript das eine oder andere Komfortfeature anbietet: Lange Verkettung von h-Aufrufen werden bald unübersichtlich. Wenn man davon ausgeht, dass das

54

container.appendChild(elem); return container; };

Aktualisierungen der Struktur haben in der Methode update zu erfolgen. Der Code beschränkt sich darauf, eingehende DOM-Elemente in den Container weiterzuschreiben.

3.2017 www.webundmobile.de


Framework

HTML/CSS/JaVaSCRIPT

Im Interesse der Geschwindigkeit der gesamten Applikation prüfen wir hier noch, ob eine Aktualisierung wirklich notwendig ist. Die Methode replaceChild wird nur dann aufgerufen, wenn Änderungen anstehen:

require in das Hauptprogramm einbinden. Im lokalen Verzeichnis liegende Module werden in Browserify durch das Voranstellen des Strings ./ angesprochen – der Punkt steht in Unix für das lokale Verzeichnis:

proto.update = function update(prev, elem) {

var OurWrapper = require("./wrapper")

var prevVnode = prev.currVnode; var currVnode = this.currVnode; var patches = diff(prevVnode, currVnode); var rootNode = elem.childNodes[0]; var newNode = patch(rootNode, patches);

Damit ist unser Widget einsatzbereit. Unsere nächste Handlung besteht darin, die render-Funktion anzupassen, um eine Instanz des Steuerelements auf den Bildschirm zu bekommen:

if (newNode !== elem.childNodes[0]) { elem.replaceChild(newNode, elem.childNodes[0]);

App.render = function render(state) { var btn = document.createElement("BUTTON");

}

var t = document.createTextNode("Inhalt");

};

btn.appendChild(t);

Damit fehlt uns der Konstruktor des Widgets, der in der offiziellen Dokumentation nicht korrekt beschrieben wird. Eine funktionierende Version des Codes sieht so aus:

return h('div#page',[

function PureWrapperWidget(vnode) {

]);

OurWrapper(btn), h('b',"Test!")

if (!(this instanceof PureWrapperWidget)) {

};

return new PureWrapperWidget(vnode); } this.currVnode = vnode; }

Der this-Parameter muss im Rahmen jedes Durchlaufs des Konstruktors gegen den Typ der Klasse verglichen werden. Schlägt dieser Vergleich fehl, so müssen Sie von Hand eine neue Instanz des Widgets anlegen und diese retournieren. Es handelt sich dabei um eine kleine Besonderheit des Mercury-Frameworks, auf die man nicht auf den ersten Blick kommt. Unterbleiben Prüfung und Return, so wird init() zur Laufzeit nicht aufgerufen und das Widget erscheint nicht am Bildschirm. Falls Sie dieses seltsame Verhalten von Hand nachprüfen möchten, ergänzen Sie init einfach um einen Aufruf von console.log: proto.init = function init() { console.log("Running init!"); ...

Als primäres Hindernis zeigt sich hier die Erstellung eines passenden Inhalts für das Widget. Wir wollen bei diesem kleinen Beispiel ohne jQuery und Co. auskommen, weshalb die DOM-APIs des Browsers zum Einsatz kommen. In der Theorie ist unser Programm an dieser Stelle einsatzbereit. Wer den Code im Browser lädt, findet sich jedoch stattdessen mit der in Bild 7 gezeigten Fehlermeldung konfrontiert. Die Frage lautet nun, wieso dies passiert.

Fehlersuche mit Browserify Unser Programmbeispiel besteht aus einigen Dutzend Zeilen. Nach der Bearbeitung mit Browserify wächst es durch die Inklusion diverser Module und Dateien auf mehrere Tausend Zeilen Code an. Zur Lösung dieses Problems bietet sich die Nutzung von Source Maps an: Es handelt sich dabei um Hilfsdateien, die Debuggern eine Korrelation zwischen dem generierten Code und den Quelldateien ermöglichen. Die Generierung ebendieser Files erfolgt durch Übergeben des Parameters --debug an Browserify. Berücksichtigen Sie, dass die Präambel aus zwei Minuszeichen besteht:

}; tamhan@TAMHAN14:~/mercuryworkspace$ browserify index.js

Damit ist die Arbeit am Korpus des Widgets abgeschlossen. Sein Code lässt sich durch einen spezialisierten Aufruf von

-o out.js –debug

Vom Entwickler vorgegebener Beispielcode muss nicht unbedingt perfekt sein (Bild 7)

www.webundmobile.de 3.2017

Browserify unterscheidet sich insofern von anderen Systemen, als es die Mappinginformationen direkt in die Ausgabedatei schreibt. Dies lässt sich durch einen Vergleich der Dateigrößen bestätigen. Bei aktivierter Debuggerunterstützung verdreifacht sich die Länge der relevanten Datei. ▶

55


HTML/CSS/JaVaSCRIPT

Framework

Dank der in out.js eingebetteten Sourcemap zeigt Chrome die Stelle des Fehlers direkt an (Bild 8)

Weil eine seperate .map-Datei fehlt, stößt Firefox hier an seine Grenzen. Als Workaround bietet sich die Nutzung von Google Chrome an, wo sich der Fehler wie in Bild 8 gezeigt präsentiert. Besonders nett ist die Möglichkeit der Platzierung von Breakpoints auf Ebene der Originaldateien. Der Debugger zeigt sogar die Variablenwerte korrekt an. Wer unbedingt mit Firefox debuggen möchte, kann das unter https://www.npmjs.com/package/exorcist bereitstehende Werkzeug exorcist zur Generierung der benötigten .map-Dateien einsetzen. Mit diesem Wissen lässt sich die Fehlerquelle auf die Zeile

Im nächsten Schritt wird der Code von render() angepasst, um statt einem DOM-Element ein vdom-Element anzuliefern: App.render = function render(state) { var btn = new vnode('input', { type: 'button', value: 'Knopf!' }); return h('div#page',[ OurWrapper(btn), h('b',"Test!") ]);

var elem = createElement

};

(this.currVnode);

Damit ist unser kleines hauseigenes Widget einsatzbereit. zurückführen: elem ist nach Abarbeitung der Zuweisung null, was auf fehlerhafte Parameter in createElement zurückzuführen ist. Wer den Code der Methode createElement weiterverfolgt, endet bei der Methode isVirtualNode. Ihr Aufbau präsentiert sich folgendermaßen: var version = require("./version") module.exports = isVirtualNode function isVirtualNode(x) { return x && x.type === "VirtualNode" && x.version === version }

Das gesamte vdom-Modul von Mercury kann nur mit jenen Nodes zusammenarbeiten, die Teil des virtuellen DOM sind. Aus diesem Grund müssen wir index.js um die Inklusion der notwendigen Generatorfunktion erweitern.

56

Jedes Modul von Mercury bringt seine eigenen Kompatibilitätsanforderungen mit – im Fall von geval ist IE8 ausgenommen (Bild 9)

3.2017 www.webundmobile.de


Framework

In Webapplikationen findet man immer wieder archaische Event-Frameworks wie Radio.js. Das zugegebenermaßen nicht besonders große Modul mag ein grundlegendes Handling von Ereignissen ermöglichen, bietet aber kaum Komfort. Dies ist insofern schade, weil Mercury ein wesentlich umfangreicheres Event-Subsystem mitbringt. Als nächstes Beispiel wollen wir uns diesem System zuwenden. Das Modul hört auf den Namen geval. Als Erstes sei an dieser Stelle angemerkt, dass geval mit dem Internet Explorer 8 nicht funktioniert (Bild 9). In diesem Artikel wollen wir ein kleines Eventsystem auf Basis von geval realisieren. Entwickler haben dabei die Wahl zwischen dem einfacheren Event und dem komplexeren Event-Emitter, der das eine oder andere Komfortfeature bietet. Im Fall des Event-Emitters beginnt der Code mit dem Laden der relevanten Klasse: var EventEmitter = require('events').EventEmitter

Als Nächstes müssen wir eine Methode anlegen, die von Mercury im Fall des Auftretens des Ereignisses aufgerufen werden soll. Wir wollen hier auf console.log zurückgreifen:

HTML/CSS/JaVaSCRIPT

EventEmitter stellen diverse Hilfsfunktionen zur Verfügung (Bild 10)

te, sollte einen Breakpoint platzieren und das Objekt als Ganzes reflektieren. Auf der Workstation des Autors präsentierte sich als Ergebnis davon unter Chrome der in Bild 10 gezeigte Aufbau. Wer die vergleichsweise methodenlastige Syntax des Event-Emitters nicht goutiert, kann als Alternative auch auf das klassische Event-Element zurückgreifen. Die Inklusion und die Deklaration des Objekts erfolgen folgendermaßen:

function onNMG(){ console.log("Ereignis ist aufgetreten!");

var Event = require('geval')

} var stream = {

Aus Gründen der Bequemlichkeit nutzen wir den weiter oben angelegten Delegator weiter. Er bietet einen einfachen Weg zum Abgreifen von Klickereignissen. Als Nächstes legen wir ein neues Ereignis an. Die on-Methode nimmt sowohl einen String als auch eine Methode entgegen, die beim Auftreten des betreffenden Events aufzurufen ist: function App() { delegator().addGlobalEventListener('click', runMe); window.eventStream=new EventEmitter(); window.eventStream.on('nmg', onNMG); ...

geval unterscheidet sich von anderen Eventsystemen insofern, als die Steuerung über ein Ereignisobjekt erfolgt. Wir legen die von EventEmitter zurückgelieferte Instanz in window ab, um sie aus anderen Methoden aus aufrufen zu können. Der Variablenname Stream ist hierbei eine Konvention in Mercury. Event-Verwaltungsobjekte werden von Jake Verbaten stets als Datenstrom betrachtet und haben deshalb so gut wie immer einen auf Stream endenden Namen. Für die Aktivierung greifen wir auf die aus dem vorhergehenden Beispiel bekannte Methode runMe zurück, die bei beliebigen Klicks in der Webseite aktiviert wird: function runMe(a){ window.eventStream.emit('nmg'); }

Die Dokumentation der EventEmitter-Klasse ist denkbar schlecht. Wer mehr über den inneren Aufbau erfahren möch-

www.webundmobile.de 3.2017

ondata: Event(function () { ... }), onend: Event(function () { ... }) }

Das Stream-Objekt lässt sich sodann durch Aufrufen der angelegten Felder aktivieren. Ein großer Vorteil dieser Vorgehensweise besteht darin, dass Nutzer des Stream-Objekts nur jene Ereignisse auslösen können, die im Rahmen der Initialisierung angelegt wurden.

Fazit Mercury ist ein Framework, das im Vergleich zu seinen Mitbewerbern durch einen extrem schlanken und sehr modularen Aufbau punkten kann. Leider ist die Dokumentation – auch im Vergleich zu im Allgemeinen schlecht dokumentierten Web-Frameworks – wirklich mangelhaft. Lehrreich ist ein Blick in den sehr interessant aufgebauten Korpus des Frameworks auf jeden Fall – und dass sich das eine oder andere Modul auch außerhalb von Mercury gut ◾ macht, steht ebenfalls außer Frage.

Tam Hanna ist Autor, Trainer und Berater mit den Schwerpunkten Webentwicklung und Webtechnologien. Er lebt in der Slowakei und leitet dort die Firma Tamoggemon Holding k.s. Er bloggt sporadisch unter: www.tamoggemon.com

57


API

Foto: LOVELUCK / Shutterstock

HTML/CSS/JaVaSCRIPT

DaS WEBSOCKET aPI

Bidirektional Das WebSocket API ermöglicht die bidirektionale Kommunikation zwischen Client und Server.

B

evor wir uns dem WebSocket API und damit der bidirekDie Kommunikation von Client und Server geschieht also tionalen Kommunikation zwischen Client und Server unidirektional, in eine Richtung vom Client zum Server. Auch widmen, sei einleitend zunächst nochmal ein Überblick über die Tatsache, dass der Server mit Antworten reagiert und man die normale Kommunikation zwischen Client und Server gegeben, sprich über die unidirektionale Kommunikation, und darüber, welche Vorgehensweisen sich in den vergangenen Jahren herausgebildet haben, um die Einschränkungen dieser Art der Kommunikation zu umgehen. Bei der Kommunikation über HTTP geschieht die Kommunikation vom Client aus, unabhängig davon, ob es sich um eine klassische Website handelt oder um eine moderne Webanwendung, die auf Ajax basiert. In allen Fällen ist es der Client, der die (HTTP-)Anfragen an den Server formuliert, auf die dieser dann mit (HTTP-)Antworten reagiert. Der Server kann über HTTP keine Daten von sich aus an einen Client schiDas Prinzip des Polling (Bild 1) cken. So viel dürfte bekannt sein.

58

3.2017 www.webundmobile.de


API

HTML/CSS/JaVaSCRIPT

http://caniuse.com

somit natürlich in zwei Richtungen kommuniziert, ändert nichts daran, dass die aktive Kommunikation nur in eine Richtung geht. Der Server kann also erst einmal nicht aktiv Daten an den Client senden. In der Vergangenheit haben sich daher verschiedene Techniken herausgebildet, die diese Einschränkungen umgehen. Eine dieser Techniken ist das sogenannte Polling: Dabei fragt der Client im Hintergrund (durch Ajax-Anfragen) beim Server regelmäßig nach neuen Daten, und der Server beantwortet diese Anfragen dann entsprechend (Bild 1). Eine Variante der Polling-Technik ist dabei Das Prinzip des Long Polling (Bild 2) das Long Polling, bei dem der Client ebenfalls im Hintergrund Anfragen an den Server sendet (Bild 2), das sich aber folgendermaßen vom normalen Polling unterscheidet: Liegen neue Daten auf dem Server bereit, liefert der Server umgehend eine Antwort; liegen dagegen keine neuen Daten vor, hält der Server die HTTP-Verbindung so lange offen, bis entweder neue Daten auf dem Server vorliegen oder ein zuvor festgelegter Timeout überschritten wurde. In beiden Fällen gilt: sobald der Client die entsprechende Antwort vom Server erhält, sendet er erneut eine Anfrage, wobei der Server die Verbindung wieder offenhält und so weiter. Der Nachteil hierbei ist jedoch der relativ hohe Overhead, der durch die ständigen Anfragen vom Das Prinzip von Web Sockets (Bild 3) Client an den Server hervorgerufen wird, weshalb sowohl Long Polling als auch das normale weise https://html.spec.whatwg.org/multipage/comms.html Polling heute nur noch der Abwärtskompatibilität wegen ver#network), um die es im Folgenden gehen soll. Über dieses wendet werden sollten. API können – wie der Name schon sagt – Socket-VerbindunBidirektionale Kommunikation gen zwischen Client und Server hergestellt werden, dauerMittlerweile gibt es nämlich auch Standardtechnologien, bei hafte Verbindungen, über die sowohl Client als auch Server denen der Server wirklich Daten an den Client senden kann an den jeweils anderen Daten schicken können (Bild 3). und die damit eine echte bidirektionale Kommunikation erDie Spezifikation umfasst dabei lediglich einen Typ (beziemöglichen. Eine von diesen Technologien ist das sogenannte hungsweise ein Interface), und zwar den Typ WebSocket. WebSocket API (www.w3.org/TR/websockets beziehungsUm eine WebSocket-Verbindung herzustellen, verwendet ▶

Browsersupport für das WebSocket API (Bild 4)

www.webundmobile.de 3.2017

59


HTML/CSS/JaVaSCRIPT

API

man die entsprechende Konstruktorfunktion in der folgenden Weise, wobei man den URL des WebSocket-Servers als Parameter übergibt (Bild 4):

Listing 1: Event-Handler für WebSocket-Verbindung 'use strict'; let connection = new WebSocket('ws://localhost:4080/

const URL = 'ws://localhost:4080/tests';

tests');

let connection = new WebSocket(URL);

connection.onopen = event => {

Bezüglich des Verbindungsaufbaus stellt WebSocket drei Event-Handler zur Verfügung: Der Event-Handler onopen wird aufgerufen, wenn die WebSocket-Verbindung geöffnet wurde, der Event-Handler onerror, wenn beim Verbindungsaufbau ein Fehler auftritt, und der Event-Handler onclose, wenn die Verbindung wieder geschlossen wurde (Listing 1). Um Daten, die vom Server gesendet werden, verarbeiten zu können, verwendet man den Event-Handler onmessage. Das Event ist dabei vom Typ MessageEvent, das unter anderem die Eigenschaft data bereitstellt, um an die übermittelten Daten zu gelangen:

};

console.log('Verbindung gëffnet'); connection.onerror = error => { console.log('Fehler: ${error} '); }; connection.onclose = event { console.log('Verbindung geschlossen'); }; connection.onmessage = event => { console.log(event.data); };

connection.onmessage = event => { console.log(event.data);

connection.onmessage = event => { let data = JSON.parse(event.data);

}; };

Umgekehrt lassen sich über die Methode send() Daten an den Server schicken, wobei sowohl Strings, Binary Large Objects (kurz Blobs) und Array-Buffer als auch typisierte Arrays übergeben werden können. Um Daten im JSON-Format zu versenden, müssen die entsprechenden JavaScript-Objekte also zunächst per JSON.stringify() umgewandelt werden: let message = { subject: 'Hallo Welt', body: 'Wie geht’s?' }; connection.send(JSON.stringify(message));

Empfängt man JSON-Daten vom Server, müssen diese analog über JSON.parse() umgewandelt werden:

Des Weiteren können, wie auch schon beim Versenden von Nachrichten an den Server, vom Client auch Binary Large Objects und Array-Buffer empfangen werden. Dazu setzt man entsprechend die Eigenschaft binaryType der WebSocket-Verbindung auf den Wert blob oder arraybuffer. Über die Methode close() lässt sich eine WebSocket-Verbindung wieder schließen.

Beispielanwendung: Chat Am einfachsten lässt sich die Verwendung des WebSocket API an einem konkreten Beispiel demonstrieren. Und was liegt hier näher als die Implementierung einer Chat-Anwendung? Dies ist sicherlich das Paradebeispiel für die Verwendung von Web Sockets.

Listing 2: Implementierung des WebSocket-Servers 'use strict'; let express = require('express');

wss.on('connection', ws => { ws.on('message', message => {

let app = express();

console.log('Empfangene Nachricht:

let server = require('http').Server(app);

${message}');

let url = require('url');

wss.clients.forEach(client => {

let WebSocketServer = require('ws').Server;

client.send(message);

let wss = new WebSocketServer({ server: server }); let port = 4080;

}); }); });

app.use(express.static(__dirname + '/public')); server.listen(port, () => { app.get('/index', (request, response) => { response.sendFile(__dirname + '/public/index.html'); });

60

console.log('Server läuft unter Port ${server.address().port}') });

3.2017 www.webundmobile.de


API

HTML/CSS/JaVaSCRIPT

Den Code für dieses Beispiel zeigen einen HTTP-Server benötigt (in unseListing 2 (JavaScript-Code für den rem Beispiel etwa dazu, um die ChatWebSocket-Server in Node.js), Listing 3 Oberfläche bereitzustellen). (HTML-Code für die Chat-OberfläÜber den folgenden Befehl wird che) und Listing 4 (JavaScript-Code für zunächst die Klasse Server importiert, den WebSocket-Client). Bild 5 zeigt die die den WebSocket-Server repräsenOberfläche des Clients. tiert.: Doch der Reihe nach: Werfen wir zuconst WebSocketServer = nächst einen Blick auf den Code für require('ws').Server den WebSocket-Server. Da die Implementierung in JavaScript unter Node. Anschließend wird über new WebSojs geschieht, muss zunächst ein Modul cketServer() eine neue Instanz erher, das die Implementierung von zeugt, wobei als Parameter ein KonfiWebSocket-Servern vereinfacht. Hier Chats sind das klassische Beispiel für die gurationsobjekt mit einer Referenz auf bietet sich das Modul ws an (https:// Verwendung von Web Sockets (Bild 5) den HTTP-Server zu übergeben ist. github.com/websockets/ws), das laut Über die Methode on() lassen sich im Entwicklerseite die schnellste Implenächsten Schritt Event-Listener registrieren, unter anderem mentierung des WebSocket-Protokolls (https://tools.ietf.org/ auch für das connection-Event, das immer dann ausgelöst html/rfc6455) darstellt und entweder alleine verwendet werwird, wenn sich ein neuer WebSocket-Client mit dem Server den kann, um einen reinen WebSocket-Server zu implemenverbindet. ▶ tieren, aber auch in Kombination mit Express.js, wenn man

Listing 3: HTML-Code für den Chat <!DOCTYPE html>

<div class="panel-footer">

<html>

<div class="input-group">

<head>

<input id="message" type="text"

<title>Node.js Chat</title>

class="form-control input-sm"

<meta charset="utf-8">

placeholder="Nachricht eingeben ..." />

<link rel="stylesheet" href="styles.css" />

<span class="input-group-btn">

<link rel="stylesheet" href=

<button class="btn btn-warning

"https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/

btn-sm" id="send">

css/bootstrap.min.css" integrity="..."

Abschicken</button>

crossorigin="anonymous">

</span>

</head>

</div>

<body>

</div> </div>

<div class="container"> <div class="row"> <div class="col-md-5"> <img id="avatar" class="img-circle"

</div> </div> </div> <script

width="50px"/>

src="https://code.jquery.com/jquery-3.1.1.min.js"

<div id="name"></div>

integrity="sha256-

</div>

hVVnYaiADRTO2PzUGmuLJr8BLUSjGIZsDYGmIJLv2b8="

</div>

crossorigin="anonymous"></script>

<div class="row"> <div class="col-md-5"> <div class="panel panel-primary"> <div class="panel-heading"> <span class="glyphicon glyphicon-comment"> </span> Chat </div> <div class="panel-body"> <ul id="chat" class="chat"></ul> </div>

www.webundmobile.de 3.2017

<script src="https://maxcdn.bootstrapcdn.com/ bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZx UPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script> <script src="faker.min.js"></script> <script src="moment.min.js"></script> <script src="main.js"></script> </body> </html>

61


HTML/CSS/JaVaSCRIPT

API

Die als Event-Listener übergebene Funktion erhält dabei als Parameter ein Objekt, das die WebSocket-Verbindung repräsentiert. Auf diesem Objekt lassen sich wiederum – ebenfalls über die Methode on() – Event-Listener registrieren, die im Zusammenhang mit der WebSocket-Verbindung aufgerufen werden. Im Beispiel wird dies dazu genutzt, eingehende Chat-Nachrichten abzufangen und dann an alle Chat-Teilnehmer weiterzuleiten. Auf der Clientseite kommt dann das WebSocket API zum Einsatz. Über let connection = new WebSocket(‘ws://localhost:4080‘) wird zunächst eine Verbindung zu dem eben gezeigten WebSocket-Server hergestellt. Jedes Mal, wenn eine Nachricht eingegeben und auf die Schaltfläche zum Abschicken der Nachricht geklickt wurde, wird über send() ein entsprechendes Objekt im JSON-Format als Zeichenkette an den Server gesendet. Das Objekt enthält

dabei den Nutzernamen (name), der URL des Profilbilds (avatarURL) und den eingegebenen Nachrichtentext (body). Nutzername und Profilbild werden zu Demonstrationszwecken bei jedem Neuladen der Anwendung mit Hilfe der Bibliothek Faker.js (https://github.com/marak/Faker.js) zufällig generiert (übrigens eine sehr hilfreiche Bibliothek, wenn es um das Erstellen von Dummy-Daten geht). Nachdem der Server die Nachricht geparst und per Broadcast an alle Chat-Teilnehmer versendet hat, wird die empfangene Nachricht über die Methode appendChatMessage() in das HTML des Chat eingebaut. Sicherlich ist das Beispiel etwas vereinfacht und verzichtet beispielsweise auf Chat-Räume oder private Nachrichten zwischen einzelnen Nutzern, aber es zeigt schön den prinzipiellen Ablauf bei der Socket-Kommunikation zwischen Client(s) und Server.

Listing 4: Client für den Chat 'use strict'; function init() {

buttonSend.addEventListener('click', event => { let message = {

faker.locale = 'de';

name: user.name,

let user = {

avatarURL: user.avatarURL,

name: faker.name.firstName(),

body: textFieldMessage.value

avatarURL: faker.image.avatar()

}

}

connection.send(JSON.stringify(message)); });

let connection = new WebSocket ('ws://localhost:4080');

function appendChatMessage(name, avatarURL,

connection.onmessage = event => {

message) {

let message = JSON.parse(event.data);

let date = moment().format('h:mm:ss');

appendChatMessage(message.name,

let html = `<li class="left clearfix">

message.avatarURL, message.body);

<span class="chat-img pull-left">

}

<img src="${avatarURL}" class="img-circle"

connection.onopen = event => {

width="50px"/>

console.log('Verbindung gëffnet');

</span>

};

<div class="chat-body clearfix">

connection.onerror = error => {

<div class="header">

console.log('WebSocket Error ' + error);

<strong class="primary-font">${name}

};

</strong>

connection.onclose = event => {

<small class="pull-right text-muted">

console.log('Verbindung geschlossen');

<span class="glyphicon glyphicon-time">

};

</span>${date} </small>

let elementUserName =

</div>

document.getElementById('name');

<p>${message}</p>

elementUserName.innerText = user.name;

</div>

let elementAvatar =

</li>`;

document.getElementById('avatar');

chatContent.innerHTML += html;

elementAvatar.src = user.avatarURL;

console.log(html)

let textFieldMessage = document.getElementById('message');

} }

let buttonSend = document.getElementById('send'); let chatContent = document.getElementById('chat');

62

document.addEventListener('DOMContentLoaded', init);

3.2017 www.webundmobile.de


API

HTML/CSS/JaVaSCRIPT

Listing 6: Client für den Chat

Listing 5: Implementierung des WebSocket-Servers 'use strict';

'use strict';

let express = require('express');

function init() {

let app = express(); let server = require('http').Server(app);

faker.locale = 'de';

let wss = require('socket.io')(server);

let user = { name: faker.name.firstName(),

let port = 4080;

avatarURL: faker.image.avatar() app.use(express.static(__dirname + '/public'));

}

app.get('/index', (request, response) => {

let socket = io();

response.sendFile(__dirname +

socket.on('connection', socket => {

'/public/index.html');

console.log('Verbindung gëffnet');

});

}); socket.on('disconnect', event => {

wss.on('connection', ws => {

console.log('Verbindung geschlossen');

console.log("connected")

});

ws.on('chat-message', message => {

socket.on('error', error => {

console.log('Empfangene Nachricht: ${message}');

console.log('WebSocket Error ' + error);

wss.sockets.emit('chat-message', message);

});

});

socket.on('chat-message', event => {

});

let message = JSON.parse(event);

server.listen(port, () => {

appendChatMessage(message.name,

console.log('Server läuft unter

message.avatarURL, message.body);

Port ${server.address().port}')

});

});

// Restlicher Code unverändert }

Socket.io Eine im Zusammenhang mit Web Sockets interessante Bibliothek ist Socket.io (http://socket.io) .Dabei handelt es sich um eine Bibliothek, die allgemein die bidirektionale Kommunikation zwischen Client und Server abstrahiert: Standardmäßig verwendet Socket.io das WebSocket API, falls dieses jedoch vom jeweiligen Browser nicht unterstützt wird, werden als Fallback-Lösung entweder Polling oder Long Polling verwendet. Wie das Chat-Beispiel mit Hilfe von Socket.io realisiert werden könnte, zeigen Listing 5 und Listing 6. Vom Ablauf her bleibt alles beim Alten, lediglich das API unterscheidet sich

Links zum Thema

WebSocket API https://html.spec.whatwg.org/multipage/comms. html#network

Socket.io http://socket.io

ws https://github.com/websockets/ws

WebSocket-Protokoll https://tools.ietf.org/html/rfc6455

www.webundmobile.de 3.2017

document.addEventListener('DOMContentLoaded', init);

in einigen Punkten. Der HTML-Code dagegen bleibt fast unverändert, nur die Socket.io-Bibliothek muss zusätzlich eingebunden werden.

Fazit Über das WebSocket API lässt sich eine bidirektionale Kommunikation zwischen Client und Server realisieren. Techniken wie das Polling oder das Long Polling sollten nur in Ausnahmefällen wie zum Beispiel aus Gründen der Abwärtskompatibilität verwendet werden. Hier kann auch die Bibliothek Socket.io helfen, die bei älteren Browserversionen auf Fallback-Lösungen zurückgreift, in modernen Browsern aber Web Sockets verwendet. ◾

Philip ackermann arbeitet beim Fraunhofer-Institut für Angewandte Informationstechnik FIT und ist Autor mehrerer Fachbücher und Fachartikel über Java und JavaScript. http://philipackermann.de

63


MOBILE DEVELOPMEnT

iOS

aDD-InS FüR IOS IMESSaGE PROGRaMMIEREn

My Message Mit iOS 10 können erstmals Add-ins für die iMessage-App entwickelt werden.

D

as Schreiben und Empfangen von Nachrichten ist wohl eine der wichtigsten Aktivitäten im Smartphone-Bereich. Im Gegensatz zu früheren Zeiten genügt es nicht mehr, einfach nur Textnachrichten verschicken zu können. Es muss ebenfalls möglich sein, Grafiken, Links, Sounds und sogar mit der Kamera erstellte Filme komfortabel an den oder die Empfänger verschicken zu können. Im September 2016 hat Apple iOS 10 veröffentlicht. Die iMessage-App von iOS 10 wurde komplett neu entwickelt und um viele interessante Funktionen erweitert. Eines der neuen Features ist nicht nur für die Anwender, sondern auch für Entwickler äußerst interessant. Es gibt nun die Möglichkeit, eigene Erweiterungen (Addins) für iMessage zu programmieren. Der Funktionsumfang von iMessage lässt sich so quasi grenzenlos erweitern. Möglich wird die Erweiterung durch das in iOS 10 neu eingeführte Message-Framework. Es stellt ein entsprechendes API zur Verfügung, über das die iMessage-App angepasst werden kann. In Xcode (ab Version 8.0) macht sich das neue Framework durch die Integration zweier neuer Vorlagen bemerkbar: Sticker Pack Application und iMessage Application (Bild 1). In diesem Artikel werden beide Möglichkeiten an je einem Beispiel demonstriert.

Sticker Pack application Die Sticker Pack Application ist eine Erweiterung für iMessage, die Bilder oder auch Bildsequenzen zum Einfügen in Nachrichten enthält. Die Sticker Packs können im AppStore auch kommerziell angeboten werden. Eine Besonderheit ist, dass sich der AppStore für iMessage-Erweiterungen auch direkt aus iMessage heraus aufrufen lässt. Solche Erweiterungen können erstellt werden, ohne dass programmiert werden muss. Man braucht lediglich die gewünschten Bilder zusammenzustellen. Um eine Sticker Pack Application zu erstellen, muss die entsprechende Vorlage für ein neues Projekt gewählt werden. Während der Anlage des Projekts ist wie üblich ein Projektname zu vergeben. Die übersichtliche Struktur einer Sticker Pack Application zeigt Bild 2. Eine Codedatei gibt es nicht, da für diesen Anwen-

Vorlagen des neuen Message-Frameworks (Bild 1)

dungstyp nicht programmiert werden muss. Selektiert man im Project Navigator von Xcode die Datei Stickers.xcstickers, werden in der Übersicht ein Bereich für die App-Icons sowie ein weiterer für die Bilder angezeigt.

Bilder hinzufügen Bilder kann man einem Sticker-Pack-Projekt via Drag and Drop hinzufügen (Bild 3). In Xcode ist dafür ein entsprechend beschrifteter Bereich vorhanden. Die Bilder können also bequem aus dem entsprechenden Verzeichnis direkt in das Projekt befördert werden. Es werden die Bildformate PNG, GIF und JPG unterstützt. Für animierte Bilder muss das APNGoder GIF-Format verwendet werden. Die Dateigröße der Bilder darf 500 Kilobyte nicht überschreiten. Gute Ergebnisse erzielt man, wenn die Bilder eine Auflösung von 100 x 100 oder 206 x 206 Punkten haben. In einer Sticker Pack App werden drei Bildgrößen unterstützt: Small, Medium und Large. Die verwendete (Bild-)Größe kann im Attributes Inspector von Xcode eingestellt werden. Zuletzt benötigt man für den Upload in den AppStore natürlich noch die passenden App-Icons. Es werden unterschiedliche Größen benötigt, die von Xcode vorgegeben wer-

Struktur einer Sticker Pack App (Bild 2)

64

3.2017 www.webundmobile.de


iOS

Hinzufügen von Bildern zur App (Bild 3)

den. Ratsam ist es hier, einen der vielen im Netz verfügbaren Dienste zu verwenden, welche die erforderlichen Größen automatisch erstellen, zum Beispiel der Service unter http:// makeappicon.com/imessageicon. Folgende Größen werden benötigt: 1024 x 1024 Punkte (für den iMessage AppStore), 27 x 20 Punkte (in @1x, @2x, @3x), 32 x 34 Punkte (in @1x, @2x, @3x). Für iPhone-/ iPad-Einstellungen 29 x 29 Punkte (in @1x, @2x, @3x), 60 x 45 Punkte (in @2x, @3x), 67 x 50 Punkte (in @1x, @2x) und 74 x 55 Punkte (@2x) für das iPad Pro. Apple bietet auch ein passendes Template für diese Größen zum Herunterladen an. Hat man alle Icons beisammen, dann müssen diese nur noch via Drag and Drop in den entsprechenden Bereich der App (iMessage App Icon) eingefügt werden (Bild 4). Im letzten Schritt kann die Sticker-Pack-Erweiterung für iMessage nun ausprobiert werden. Für den Test wird nicht zwangsläufig ein iOS-Gerät benötigt, denn er kann komplett im Simulator durchgeführt werden. Hierzu muss das Projekt lediglich über die Xcode-Schaltfläche Build & Run auf dem

app-Icons in das Projekt einfügen (Bild 4)

www.webundmobile.de 3.2017

MOBILE DEVELOPMEnT

gewünschten Simulator aktiviert werden. Da es sich um eine Erweiterung für iMessage handelt, wird in der Regel auch automatisch iMessage auf dem Gerät gestartet. Nach dem Start der App wird die Erweiterung im entsprechenden Bereich (AppStore) der App angezeigt. Durch Auswahl wird die Erweiterung aktiviert, und es kann ein Bild aus dem Sticker Pack in einer neuen iMessage-Nachricht eingefügt werden (Bild 5). Innerhalb der iMessageApp werden auch zwei Kon- Test der Sticker Pack App im ten für Anwender simuliert. Simulator (Bild 5) So lässt sich nicht nur der Versand einer Nachricht testen, sondern auch der Empfang. Zwischen den beiden Benutzern kann über den <-Button umgeschaltet werden. Neben der Vorlage Sticker Pack Application gibt es noch einen weiteren Vorlagentyp, der die Entwicklung von speziell angepassten Add-ins ermöglicht: iMessage Application.

iMessage application Im folgenden Abschnitt soll einmal eine triviale Erweiterung für iMessage umgesetzt werden, bei der in eine neue Nachricht auf Knopfdruck ein Text eingefügt werden soll. Nachdem sich der Dialog für das Anlegen eines neuen Projekts geöffnet hat, muss die Vorlage iMessage Application ausgewählt werden. Xcode erzeugt anschließend das zugehörige Projekt. Das besteht im Wesentlichen aus zwei Teilen: Storyboard und Klassendatei. Während die Storyboard-Datei den Namen MainInterface trägt, wird die zugehörige Klassendatei mit dem Namen MessagesViewController angelegt. Innerhalb der Klasse sind bereits einige Methoden enthalten, die beispielsweise beim Start der Übertragung einer Nachricht didStartSending eine Interaktion ermöglichen. Als Parameter werden in den Methoden unter anderem MSMessage und MSConversation übergeben. MSConversation repräsentiert den gerade stattfindenden Nachrichtenaustausch und ermöglicht den Zugriff daraif. So kann man hier beispielsweise eine neue Nachricht (MSMessage wird grafisch innerhalb einer Blase angezeigt) einfügen und an den Empfänger übertragen. MSMessage enthält eine einzelne Nachricht der Konversation. Die Klasse MSMessageTemplateLayout ermöglicht die Konfiguration des Layouts einer Nachrichtenblase. In dieser kann ja nicht nur Text, sondern zum Beispiel auch ein Bild eingefügt werden. Der Zugriff auf eine Instanz von MSMessageTemplateLayout ist relativ wichtig, da über diesen Weg Änderungen am Layout der Nachricht möglich sind. Hierfür werden einige Eigenschaften bereitgestellt. Damit man das Layout den ▶

65


MOBILE DEVELOPMEnT

iOS

eigenen Vorstellungen entsprechend bearbeiten kann, muss man sich mit dem Aufbau von MSMessageTemplateLayout auseinandersetzen. Im Nachrichtenfenster gibt es beispielsweise die Eigenschaften Image Title und Image Subtitle. Wie die Bezeichnung vermuten lässt, können diese beiden Eigenschaften genutzt werden, um Bildunterschriften einzufügen. Außerdem gibt es noch weitere Eigenschaften zur Beschriftung: Caption, Subcaption, Trailing Caption und Trailing Subcaption. Eine detaillierte Beschreibung aller Eigenschaften und Methoden der Klasse finden Sie in der Apple-Dokumentation. Nach Betätigung des Plus-Buttons eines Steppers soll in einer Instanz von MSMessageTemplateLayout die zuvor im Stepper eingestellte Zahl innerhalb der Nachricht angezeigt

werden. Die Zahl wird in das Nachrichtenfeld geschrieben, sobald der Button mit der Bezeichnung Text erzeugen betätigt wurde. Listing 1 zeigt den erforderlichen Code. Er besteht im Wesentlichen aus zwei Methoden. Innerhalb der Ereignismethode btnPressed befindet sich der Code, der ausgeführt wird, sobald der Button betätigt wurde. Um den Text in der Nachricht später anzeigen zu können, wird im ersten Schritt eine Instanz der Klasse MSMessageTemplateLayout angelegt. Dieser Instanz wird neben einem Text (Eigenschaft: caption) zusätzlich noch ein Bild (Eigenschaft: image) zugewiesen. Dieses Bild wird innerhalb der Methode generateImage erzeugt. In der Methode ist hierzu zuerst eine neue Label-Instanz (label) anzulegen. Anschlie-

Listing 1: MessagesViewController import UIKit

func insertImage() -> UIImage? {

import Messages

let uiView = UIView(frame: CGRect(x: 0, y: 0, width: 200,

class MessagesViewController:

height: 200))

MSMessagesAppViewController

uiView.backgroundColor =

{

UIColor.white @IBOutlet var uiStepper: UIStepper!

let label = UILabel(frame:

@IBOutlet var uiLabel: UILabel!

CGRect(x: 50, y: 50, width: 100,

override func viewDidLoad() {

height: 100))

super.viewDidLoad()

label.font = UIFont.systemFont(

}

ofSize: 56.0) label.backgroundColor =

override func

UIColor.green

didReceiveMemoryWarning() {

label.textColor = UIColor.white

super.didReceiveMemoryWarning()

label.text = "\(Int(uiStepper.value))"

}

label.textAlignment = .center

@IBAction func uiStepperPressed(_ sender: Any) {

uiView.addSubview(label)

uiLabel.text =

uiView.frame.origin = CGPoint(

String(uiStepper.value)

x: view.frame.size.width,

}

y: view.frame.size.height) view.addSubview(uiView)

@IBAction func btnPressed(_ sender: Any) {

UIGraphicsBeginImageContextWithOptions(

if let image = insertImage(), let conversation =

uiView.frame.size, false,

activeConversation {

UIScreen.main.scale)

let messageTemplateLayout =

uiView.drawHierarchy(in:

MSMessageTemplateLayout()

uiView.bounds,

messageTemplateLayout.image = image

afterScreenUpdates:

messageTemplateLayout.caption = "Stepper-Wert"

true)

let message = MSMessage()

let image =

message.layout = messageTemplateLayout

UIGraphicsGetImageFromCurrentImageContext()

message.url = URL(string: "emptyURL")

UIGraphicsEndImageContext()

conversation.insert(

uiView.removeFromSuperview()

message, completionHandler: {

return image

(error: Error?) in

}

print(error as Any) })

//Quellcode entfernt

} }

66

}

3.2017 www.webundmobile.de


iOS

ßend werden die Abmessungen des Layouts angepasst und der Inhalt des UIStepperControls wird als String zugewiesen. Außerdem wird als Hintergrundfarbe Grün festgelegt (Bild 6). Im Anschluss an die Konfiguration der Label-Instanz wird diese der UIView-Instanz übergeben, die zu Beginn der Methode definiert wurde (Methode: addSubview). Abschließend wird mittels der Methode UIGraphicsGetImageFromCurrent ImageContext eine ImageIn die nachricht wird automaInstanz erzeugt und aus der tisch ein Bild eingefügt (Bild 6) Methode zurückgegeben. Nachdem die MSMessageTemplateLayout-Instanz fertig konfiguriert wurde, wird diese zur Anzeige in iMessage einem MSMessage-Objekt als Layout übergeben. In den aktuellen Nachrichten-Thread (conversation-Instanz) wird die neue MSMessage-Instanz dann mittels der Methode insert eingefügt.

MOBILE DEVELOPMEnT

AN EVENT OF

Fazit Die Erweiterung der iMessage-App ist ab iOS 10 aufgrund des neuen Message-Frameworks kein Problem mehr. Über die umfangreichen Schnittstellen lassen sich sehr einfach Er◾ weiterungen für diese App programmieren.

Links zum Thema

Message Framework Reference https://developer.apple.com/reference/messages

App-Icon-Templates https://developer.apple.com/ios/human-interfaceguidelines/resources

MessageTemplateLayout https://developer.apple.com/reference/messages/ msmessagetemplatelayout

Christian Bleske ist Autor, Trainer und Entwickler mit den Schwerpunkten Client/Server und mobile Technologien. Erreichbar ist er unter: cb.2000@hotmail.de

www.webundmobile.de 3.2017

Mobile has become fundamental to our everyday lives. It has inextricably changed how we communicate, interact, work and play as individuals. It is transforming entire industries, bringing new levels of productivity and efficiency to enterprises. Over three decades, mobile has evolved from an emerging communications technology to a phenomenon that is now at the foundation of everything we do. How can we describe the role of mobile in today’s world?

Elemental. Mobile is revolutionary, dynamic, ever adapting. It’s the force behind every emerging innovation, every forward-thinking enterprise. Join us in Barcelona for Mobile World Congress 2017, where the world comes together to showcase, celebrate and advance mobile.

WWW.MOBILEWORLDCONGRESS.COM

67


MOBILE DEVELOPMEnT

Entwickler-Tools

EXPOnEnT – LaUFZEITUMGEBUnG FüR naTIVE aPPS

Laufzeitumgebung Es gibt ein Spannungsfeld zwischen Webanwendungen und nativen Apps.

U

nter nativen Apps versteht man heute fast ausschließlich Anwendungen für die beiden größten Mobil-Plattformen iOS und Android. Obwohl native und Web-Apps oft als sehr unterschiedlich dargestellt werden, gibt es aber auch immer mehr Gemeinsamkeiten: Webanwendungen können durch den Fortschritt moderner Webbrowser immer mehr Features nutzen, die man ursprünglich nur in nativen Apps vorfand. Gleichzeitig übernehmen auch native Apps Errungenschaften, die sich erst durch Webanwendungen etabliert haben: Responsives UI-Design oder Deep-Linking sind dabei nur zwei typische Themen. Auch wenn die jeweiligen Anhänger ihren technologischen Ansatz gern als Sieger über den anderen erklären: Bis heute sind beide Arten von Apps wichtig und je nach Anwendungsszenario auszuwählen.

Web-Vorteil: Browser als Laufzeitumgebung

Exponent-Website: So präsentiert sich die Projektseite von Exponent (Bild 1)

Mit React Native können Webentwickler native Apps entwickeln und dabei mit JavaScript und React auf Technologien zurückgreifen, die sie bereits aus dem Webumfeld kennen. Dennoch müssen sie auch mit React Native noch mit den herstellerspezifischen Werkzeugen Apps bauen. Exponent (Bild 1) führt den Ansatz von React Native noch einen weiteren Schritt weiter in Richtung Web: In Apples App Store und Googles Play Store kann man kostenlos die App Exponent herunterladen. Dabei handelt es sich nur um eine Shell-Anwendung, mit der man in React Native implementierte und über das Exponent SDK bereitgestellte native Apps auf den eigenen Geräten ausführen kann. Gewissermaßen ist dies das Gegenstück des Webbrowsers. Der Entwickler benötigt dafür weder ein Entwicklerkonto bei Apple oder Google, noch müssen die Geräte als Entwicklergeräte angemeldet werden. Es genügt vollkommen, die frei verfügbare App Exponent zu installieren. Bild 2 zeigt, wie die App nach dem Start unter iOS aussieht. Über das Textfeld kann der Nutzer einen Exponent link eingeben. In einer Liste darunter sind einige Beispielprojekte lediglich einen Fingertipp entfernt. Die App registriert auch einen Link-Handler mit den Mobil-Betriebssystemen, sodass man auch einfach im Mobil-Webbrowser oder Mail-Client auf einen Exponent-Link klicken kann, um die zugehörige App zu öffnen.

Ein unschätzbarer Vorteil von Webanwendungen ist, dass man lediglich einen Webbrowser benötigt. Die Anwendung selbst kann sowohl auf Desktop-Rechnern als auch auf mobilen Geräten funktionieren. Man besucht einfach die Website und kann die App sofort nutzen. Eine Einstiegshürde gibt es nicht. Auch eine Installation ist nicht notwendig. Doch nicht nur für die Nutzer sind Webanwendungen einfacher: Als Webentwickler benötigt man eigentlich nicht mehr als einen Webbrowser und einen Texteditor. Zählt man webbasierte Entwicklungsumgebungen wie Cloud9 dazu, dann kann man sogar alles über einen modernen Webbrowser erledigen. Diese einfache Zugänglichkeit erleichtert den Einstieg in die Entwicklung von Webanwendungen enorm. Im Gegensatz dazu sind die Anforderungen bei nativen Apps bis heute enervierend hoch. Der Entwickler muss die jeweiligen Entwickler-Tools des Herstellers installieren. Er benötigt möglicherweise ein Entwicklerkonto. Bei iOS benötigt man auch zwingend einen Mac, denn Xcode und die iOS-SDKs funktionieren nur unter macOS. Möchte man die eigenen Apps ausprobieren, so sind dafür ein geeigneter Simulator oder physische Geräte notwendig. Die Bereitstellung der Apps auf den Testgeräten ist wesentlich umständlicher und komplizierter, als Webentwickler dies gewohnt sind. Ohne die passenden Zertifikate auf den Geräten funktioniert nichts. Möchte man am Ende die eigene App anderen zur Verfügung stellen, dann muss man den ebenfalls aufwendigen Prozess der Einstel- Der Exponent-Client unter iOS (Bild 2) lung in einen App Store durchlaufen.

68

Installation des Exponent SDK Während der Exponent-Client auf den Mobilgeräten bereitsteht, so dient auf der Entwicklermaschine die XDE (Exponent Developer Environment, UI des Exponent SDK) dazu, die Quelltexte in ein Bundle zu über-

3.2017 www.webundmobile.de


Entwickler-Tools

MOBILE DEVELOPMEnT

setzen. Dieses wird dann vom Exponententweder mit Simulatoren arbeitet oder Client geladen und ausgeführt. Die Ineigene Tunneling-Werkzeuge verwenstallation der XDE ist einfach und entden möchte. spricht den gängigen Konventionen unEntwicklungsmodus ter den unterstützten Betriebssystemen Eine weitere Option hinter dem Zahnrad(macOS, Windows, Linux). Bild 3 zeigt, Symbol ist der Development Mode. Sowie man die XDE unter macOS installiert, lange die Anwendung im Development indem man wie gewohnt die App einfach Mode bereitgestellt wird, lässt sie sich in den Programme-Ordner zieht. Nach live neustarten und in Chrome debugdem Start erscheint ein Login-Fenster Installation der Exponent XDE (Bild 3) gen. Dies kann jedoch die Anwendung (Bild 4). Hat man sich darüber angemelverlangsamen. Stellt man den Developdet, öffnet sich das XDE-Projektfenster. ment Mode ab, dann verliert man diese Möglichkeiten, kann XDE startet für das in ihr laufende Projekt zwei Serverprojedoch die volle Geschwindigkeit der App prüfen. zesse. Der eine Prozess ist der React Native Packager Server. Über die Schaltfläche mit dem Blitz-Symbol gelangt man Er beobachtet die Quelltexte des Projekts und generiert bei ins Projektmenü und kann mit New Project ein neues Projekt Änderungen ein neues Bundle. Der zweite Prozess ist der Exanlegen. Schon direkt nach dem Erstellen des Projekts baut ponent Development Server. Dieser stellt die Verwaltungsder React Native Packager ein initiales Bundle. Der im Pround Deployment-Schnittstelle dar. Der Exponent-Client auf jektfenster angezeigte URL kann im Exponent-Client geöffdem Mobilgerät ruft zuerst vom Exponent Development Sernet werden. Man kann ihn entweder abtippen oder einfach ver eine Manifest-Datei (JSON) ab. Darin sind der Name des per Send Link-Schaltfläche als E-Mail verschicken. Auf dem Projekts und alle weiteren für die Entwicklung relevanten Testgerät reicht ein Klick auf den Link in der E-Mail, dann Metadaten enthalten. Danach lädt er das Bundle vom Paöffnet sich die Exponent-Client-App und startet das Bundle. ckager Server und dazu eventuell noch weitere Assets wie in Die Hauptview der initialen App fordert auf, die JavaScriptder Manifest-Datei beschrieben. Datei main.js zu öffnen, um weiterzuentwickeln (Listing 1). netzwerk-Transparenz Der Kenner sieht sofort, dass es sich dabei um eine sehr einDamit der Exponent-Client die beiden Serverprozesse finden fache React-Native-App handelt. Das einzig Auffällige ist, kann, übergibt man ihm einen URL, der das XDE-Projektdass am Ende Exponent.registerRootComponent(App) anfenster anzeigt. Normalerweise ist das ein URL mit dem Cusstelle des sonst üblichen AppRegistry.registerComponent betom-Schema exp und einem öffentlich verfügbaren Domainnutzt wird. Namen, der auf exp.direct endet. XDE nutzt automatisch den Bearbeitet man den Text Open up main.js to start working sicheren Tunnel-Dienst ngrok (http://ngrok.com). on your app! und schreibt stattdessen Hallo Welt, dann wird Auf diese Weise sind die Serverprozesse auch durch die Anwendung sofort nach dem Abspeichern von main.js Firewalls hindurch erreichbar. Möchte man dies nicht, so neu gestartet und das Hallo Welt erscheint auf dem Testgekann man mit dem Zahnrad neben dem URL für die Option rät. Gegenüber einem nur auf React Native aufbauenden EntHost statt Tunnel entweder LAN oder localhost wählen. Bei wicklungs-Setup spart man sich mit Exponent die Installation LAN wird kein Tunnel mehr nach außen freigegeben, stattvon Xcode oder des Android SDK und kann dennoch direkt dessen stehen die Serverprozesse unter der LAN-Adresse des auf den Testgeräten testen. Entwicklerrechners zur Verfügung. Wählt man localhost, On-Device-Entwicklermenü dann kann man nur noch direkt vom Entwicklerrechner auf Der Exponent-Client bietet eine Reihe von eingebauten Feadie Prozesse zugreifen. Dies kann sinnvoll sein, wenn man tures, die das Debuggen und Analysieren der App erleichtern sollen. Indem man das Gerät schüttelt, öffnet sich das EntXDE-Login: wicklermenü (Bild 5). Mit Reload kann man die App neustarAnmeldung ten. Debug JS Remotely verbindet sich mit einem Chrome auf zur Exponent der Entwicklermaschine und führt das JavaScript der App in Developer einem Web Worker aus. So kann man die Anwendung mit Environment dem von Chrome gewohnten Debugger debuggen. Leider (Bild 4) funktionieren die Source Maps in Chrome unzuverlässig, sodass Breakpoints, die man interaktiv setzt, nicht immer wie gewünscht funktionieren. Stattdessen wird empfohlen, direkt im Sourcecode mit debugger-Statements zu arbeiten. Der Entwickler kann sich per Entwicklermenü auch zwischen Live Reload und Hot Reloading entscheiden. Bei Letzterem wird der Zustand der Anwendung bei Änderungen im Code so weit wie möglich bei▶ behalten.

www.webundmobile.de 3.2017

69


MOBILE DEVELOPMEnT

Entwickler-Tools

Da der Elements-Tab in den Chrome-Entwickler-Tools beim Debuggen der Exponent-App nicht funktioniert, kann man die in der App gerenderten Komponenten so nicht überprüfen. Allerdings kann man im Entwicklermenü des Exponent-Clients mit Show Inspector direkt auf dem Gerät ein Overlay einblenden, mit dem man Informationen über die Elemente und Komponenten ermitteln kann (Bild 6). Auch ein Performance-Monitor (Bild 7) lässt sich einblenden (Show Perf Monitor). Dieser zeigt unter anderem an, wie viel RAM die App belegt und wie viele Views es gibt.

native Features nutzen Ein einfacheres Entwicklungs-Setup ist nur einer der Vorteile von Exponent. React Native bietet ohne native Erweiterungen nur ein sehr minimales Set von Anbindungen an die nativen Plattform-APIs. Alles Weitere muss der Entwickler selbst über die React Native Bridge implementieren. Für Exponent ist das noch in einer anderen Hinsicht kritisch: Aufgrund der App-Store-Beschränkungen kann man keine nativen Erweiterungen nachinstallieren; infolgedessen funktioniert nur das, was mit dem jeweils installierten Stand des Exponent-Clients mitgeliefert wird. Glücklicherweise bietet die App von Beginn an ein vielfältiges Angebot an plattformübergreifend implementierten nativen Features an. Mit den modernen Mobil-Betriebssystemen sind auch neue Modelle des Rechtemanagements etabliert worden. Der Nutzer muss zustimmen, dass eine App beispielsweise Zugriff auf

Das Exponent-ClientEntwicklermenü (Bild 5)

Exponent Client Inspektor (Bild 6)

seinen Standort erhält oder Push Notifications empfangen darf. Als Entwickler muss man dazu auf native APIs zugreifen. Exponent bietet dafür das plattformübergreifend implementierte Permissions-Modul an. Mit Permissions.askAsync() kann man das System interaktiv nach einem bestimmten Recht fragen. Hat der Benutzer bereits zugestimmt, so wird nicht nachgefragt. Hat er noch nicht zugestimmt, wird der übliche Systemdialog angezeigt. Möchte man stattdessen einfach nur programmatisch – ohne den Benutzer danach zu fragen – ermitteln, ob ein bestimm-

Listing 1: main.js Listing 2: Location.watchPositionAsync()

import Exponent from 'exponent'; import React from 'react';

async trackPosition() { const { Location, Permissions } = Exponent;

import {

const { status } = await

StyleSheet, Text, View, } from 'react-native';

Permissions.askAsync(Permissions.LOCATION);

class App extends React.Component {

if (status === 'granted') { this._locationWatcher =

render() { return (

Location.watchPositionAsync({

<View style={styles.container}>

enableHighAccuracy: true,

<Text>Open up main.js to start working on

timeInterval: 1000, // Millisekunden

your app!</Text>

distanceInterval: 5 // Meter

</View>

},

);

({coords})=>{

}

this.setState({coords: coords})

}

});

const styles = StyleSheet.create({ container: { flex: 1,

} }, componentWillMount () {

backgroundColor: '#fff',

trackPosition()

alignItems: 'center',

}

justifyContent: 'center',

componentWillUnmount () {

},

if (this._locationWatcher) {

});

this._locationWatcher.remove() }

Exponent.registerRootComponent(App);

70

}

3.2017 www.webundmobile.de


Entwickler-Tools

MOBILE DEVELOPMEnT

tes Recht genehmigt ist, dann ruft man stattDieser Beispielcode implementiert dessen die Funktion Permissions.getAsync() eine Komponente GalleryView, die auf. Das Beispiel zeigt auch gleich ein weiteBilder in einem Gitter darstellt. Mit res durch Exponent angebotenes Modul: Loeiner Tippfläche an der Unterseite cation. Damit kann man den aktuellen Standkann man per Exponent.ImagePicker ort ermitteln (Location.getCurrentPositionein Foto aus der Fotobibliothek des Async()). Möchte man kontinuierlich über die Geräts auswählen. Dazu wird einÄnderungen des Standorts benachrichtigt fach ImagePicker.launchImageLibwerden, so kann man mit Location.watchraryAsync() aufgerufen und mittels PositionAsync() einen Callback registrieren Der Exponent Client Performance await auf ein Ergebnis gewartet. Monitor (Bild 7) (Listing 2). Wenn der Nutzer den Dialog abgeDie Beispiel-Methode trackPosition kann brochen und kein Foto ausgewählt in einer React-Komponente wie oben gezeigt hat, dann ist die Eigenschaft canverwendet werden. Die einfachen Implementierungen von celled des Ergebnisobjekts wahr. Ist das nicht der Fall, dann componentWillMount() und componentWillUnmount() zeiwird im Beispiel einfach der URI des ausgewählten Fotos in gen, wie man das Tracking starten und stoppen kann, wenn ein Array auf dem State der GalleryView-Komponente gedie Komponente ins DOM hinzugefügt oder entfernt wird. steckt. Diese wird somit automatisch neu gerendert und stellt Mit dem Modul Contacts kann man plattformübergreifend das neue Bild dar (Bild 8). Möchte man stattdessen ein Foto auf die Kontakte-Datenbank zugreifen. Das Modul bietet mit der Kamera aufnehmen und hinzufügen, so muss der Aufdafür bislang die Funktion Contacts.getContactsAsync() an. ruf ImagePicker.launchImageLibraryAsync({}) gegen ImageDieser Funktion kann man ein Array aus den gewünschten Picker.launchCameraAsync({}) ausgetauscht werden. Datenfeldern übergeben (Listing 3). accelerometer und Gyroskop Im Beispiel werden mit Contacts.getContactsAsync() die Fast jedes heutige Mobilgerät enthält einen BeschleuniKontakte abgerufen und in React Native in eine ListView.Dagungssensor, auch Accelerometer genannt. Exponent bietet taSource gesteckt. Unter iOS wird der Nutzer beim ersten Zudafür die Funktionen Exponent.Accelerometer.addListener(), griff auf die Kontakte automatisch per Dialog um Erlaubnis Exponent.Accelerometer.removeAllListeners() und Expogefragt. Die Exponent-Entwickler haben bereits angekünnent.Accelerometer.setUpdateInterval() an. Damit kann sich digt, dass man in kommenden Versionen auch die Profildie Anwendung beim Beschleunigungssensor registrieren Thumbnails der Kontakte abrufen können soll. und erhält als Ereignisdaten Objekte mit den Attributen x, y Bilder und Kamerazugriff und z, welche die jeweilige Beschleunigung in die entspreEin weiterer sehr gängiger Anwendungsfall für mobile Apps chende Richtung angeben. ist der Zugriff auf die gespeicherten Fotos oder die im Gerät Auf die gleiche Weise funktioniert das API für den Zugriff verbauten Kameras. Exponent bietet dafür das ImagePickerauf die Gyroskop-Daten: Exponent.Gyroscope.addListener(), Modul an (Listing 4). Exponent.Gyroscope.removeAllListeners() und Exponent. ▶

Listing 3: Contacts.getContactsAsync() import React from 'react'

})

import {ListView, Text, View, StyleSheet}

}

from 'react-native'

async componentDidMount () {

import {Contacts} from 'exponent'

let contacts = await Contacts.getContactsAsync([

const Row = ({contact}) => (

Contacts.PHONE_NUMBERS

<View style={styles.row}>

])

<View style={styles.avatar}/>

this.setState({

<Text style={styles.text}>

contacts: this.state.contacts.cloneWithRows

{contact.name}

(contacts)

</Text>

})

</View>

}

)

render () {

export default class ContactsView extends

return (<ListView dataSource={this.state.contacts}

React.Component {

renderRow={this.renderRow}/>)

state = {

}

contacts: new ListView.DataSource({ rowHasChanged: (r1, r2) => r1.id !== r2.id

www.webundmobile.de 3.2017

renderRow = (data)=>(<Row contact={data}/>) }

71


MOBILE DEVELOPMEnT

Entwickler-Tools

Gyroscope.setUpdateInterval() können dazu genutzt werden. Das Ereignisobjekt enthält wieder die Eigenschaften x, y und z – die Werte entsprechen hierbei jedoch der Änderung des Rotationswinkels der jeweiligen Achse. Ein sehr wichtiges Feature für Mobilanwendungen sind Notifications. Es gibt dabei einerseits die typischen Push Notifications, die entfernt durch einen Netzwerkdienst ausgelöst und durch das Gerät empfangen werden, und es gibt Local Notifications, die durch Apps oder das Betriebssystem selbst erzeugt werden. Mit Exponent.Notifications.addListener() kann die App auf lokale oder Push-Notifications lauschen. Lokale Notifications verschickt man einfach aus der App heraus mit Exponent.presentLocalNotificationAsync(). Sollen sie zeitlich verzögert verschickt werden, dann nutzt man dafür Exponent.scheduleLocalNotificationAsync(). So kann die Notification zu einem bestimmten Zeitpunkt oder in festge-

legten Intervallen ausgelöst werden. Mit Exponent.cancelScheduledNotificationAsync() kann eine geplante Notification abgebrochen werden. Ist eine lokale Notification einmal präsentiert, dann kann man sie mit der Funktion Exponent. dismissNotificationAsync() programmatisch wieder entfernen. Mit Exponent.dismissAllNotificationsAsync() kann man alle durch die App präsentierten lokalen Notifications auf einmal entfernen. Das Versenden von Push Notifications ist dagegen nicht so einfach. Denn zusätzlich zur App benötigt man dafür auch einen Dienst im Internet. Exponent selbst stellt einen kostenlosen Dienst bereit, der die Auslieferung der Push Notifications an die Android- oder iOS-Geräte übernimmt. Dazu können die Geräte in der App einen sogenannten Push-Token abrufen, der dann zum Beispiel an einen eigenen Server weitergereicht werden kann. Dort kann er beispielsweise mit dem

Listing 4: GalleryView.js import React from 'react'

<Image key={img}

import {

source={{uri:img}}

View,

style={{width:width/3, height:width/3}}

Text,

/>))}

Image,

</View>

Dimensions,

)

TouchableHighlight,

}

StyleSheet

const Button = ({onPress, label}) => (

} from 'react-native'

<TouchableHighlight onPress={()=>{onPress()}}>

import {ImagePicker} from 'exponent'

<Text style={styles.button}>{label}</Text>

const styles = StyleSheet.create({ gallery: {

</TouchableHighlight> )

alignItems: 'stretch',

export default class GalleryView extends

justifyContent: 'center',

React.Component {

flex: 1,

state = {

paddingTop: 20,

images: []

backgroundColor: '#555'

}

},

render() {

grid: {

return (

flex: 1,

<View style={styles.gallery}>

flexDirection: 'row',

<ImageGrid images={this.state.images}/>

flexWrap: 'wrap'

<Button label="Add Image"

},

onPress={this.addImage}/>

button: {

</View>

padding: 12,

)

fontSize: 16,

}

textAlign: 'center',

addImage = async() => {

lineHeight: 53,

let result = await

backgroundColor: '#ddd'

ImagePicker.launchImageLibraryAsync({})

}

if (!result.cancelled) {

})

this.setState({

const ImageGrid = ({images}) => {

images: this.state.images.concat([result.uri])

const {width} = Dimensions.get('window')

})

return (

}

<View style={styles.grid}> {images.map((img) => (

72

} }

3.2017 www.webundmobile.de


Entwickler-Tools

MOBILE DEVELOPMEnT

Nutzer der App verknüpft werden. Möchte kunde den State der Komponente auf die man eine Push Notification absenden, dann aktuelle Uhrzeit setzt (updateTime(). Die sendet der eigene Server einen POST-HTTPKomponente rendert die SVGClock dann Request mit dem Push-Token und der Pushanhand dieses States. Nachricht an den Exponent-Server mit dem GLView und Video Domain-Namen https://exp.host/. Eine ImExponent ergänzt React Native auch um Erplementierung für Node.js wurde in dem weiterungen für OpenGL und Video. Die Node-Modul exponent-server-sdk realisiert. Komponente GLView realisiert ein zu WebBei dem aus dem Webbrowser bekannten GL ähnliches API für React Native unter iOS React gehört auch SVG zu den möglichen und Android. Mit Exponent.Components. Elementen. React Native kennt in der BasisVideo wiederum kann man ein Video innerfassung kein SVG, es gibt aber die native Erweiterung react-native-svg. Diese imple- GalleryView mit dem ImagePicker halb anderer React-Native-UI-Elemente darstellen. mentiert SVG-Komponenten für iOS und erstellen (Bild 8) Komplexe Single-Page-WebanwendunAndroid. Exponent liefert diese Erweiterung gen verwenden üblicherweise einen Router, bereits mit, sodass man SVG ohne weiteren um die Anwendung in verschiedene Bereiche aufzuteilen, Aufwand verwenden kann (Listing 5). zwischen denen der Nutzer navigieren kann. Auch bei natiDie Komponente SVGClock realisiert eine Uhr, deren Zeiven Apps kennt man ähnliche Konzepte eines Navigationsger auf die per props übergebenen Werte für Stunde, MinuControllers – beispielsweise die Storyboards und Segues bei te und Sekunde eingestellt sind. Die Zeiger werden alle in iOS, mit denen einzelne Views und Übergänge dazwischen derselben Richtung (Position 0/12 Uhr) gezeichnet und dann modelliert werden können. mit der SVG-prop rotate auf die passende Ausrichtung rotiert. React Native bietet mit Navigator und NavigatorIOS beBis auf das Modul react-native-svg ist der Code auch im Web reits zwei Komponenten an, um die Navigation innerhalb der einsetzbar. In React Native kann die Uhr wie in Listing 6 geApp zu implementieren. Navigator ist dabei eine reine Javazeigt eingesetzt werden. Beim Einhängen der CurrentTimeScript-Implementierung, wird aber seit einiger Zeit nicht ▶ Clock-Komponente wird ein Intervall gestartet, das jede Se-

Listing 5: SVG-Beispiel import React from 'react'

cx={cx}

import Svg, {Circle, Line} from 'react-native-svg'

cy={cy}

const Handle = ({cx, cy, size, weight, rotate, color})

size={1/2}

=> (

weight="8"

<Line

rotate={hour/12*360} />

x1={cx}

<Handle

y1={cy}

cx={cx}

x2={cx}

cy={cy}

y2={cy-cy*size}

size={5/6}

stroke={color||'red'}

weight="5"

strokeWidth={weight}

rotate={minute/60*360} />

rotate={rotate}//{hour/12*360}

<Handle

origin={'${cx}, ${cy}'} /> )

cx={cx}

const SVGClock = ({hour, minute, second, size}) => {

cy={cy}

let cx = size / 2 + 10

size={5/6}

let cy = size / 2

weight="2"

return (

color="blue"

<Svg height={size} width={size}>

rotate={second/60*360} />

<Circle

<Circle

cx={cx}

cx={size/2+10}

cy={cy}

cy={size/2}

r={(size/2)-20}

r={size/60}

stroke="black"

stroke="black"

strokeWidth="2"

strokeWidth="2" />

fill="transparent" /> <Handle

www.webundmobile.de 3.2017

</Svg>) }

73


MOBILE DEVELOPMEnT

Entwickler-Tools

mehr weiterentwickelt, daher ist von der Nutzung abzuraten. NavigatorIOS basiert auf dem unter iOS verfügbaren UINavigationController. Dieser funktioniert deshalb auch nur unter iOS. Ein sehr neuer Ansatz ist das Modul NavigatorExperimental, das in der offiziellen React-Native-Dokumentation bereits empfohlen wird – es gilt als nicht mehr so experimentell, wie der Name zuerst vorgibt, ist jedoch eher Low-Level. Das Exponent-Team arbeitet zum Teil sehr eng mit den React-Native-Entwicklern zusammen und hat basierend auf NavigatorExperimental das Modul ExNavigation entwickelt. Diese stellt eine auf Routen basierte High-Level-NavigationsLibrary für React Native dar, die sowohl mit iOS als auch mit Android funktioniert (Listing 7). Mit createRouter erzeugt man eine globale Router-Instanz. Dazu übergibt man eine Funktion, die ein Objekt zurückgibt, das die Namen der Routen auf React-Komponenten abbildet. Routen sind bei ExNavigation einfach nur React-Komponenten. Als Top-Level-Komponente der App wird mit dem NavigationProvider der Router registriert. Die im Beispiel benutz-

Listing 6: SVGClock import {View, Text, Dimensions, SVG} from 'react-native' function getTime() { let date = new Date() return {

te Komponente StackNavigation implementiert eine Navigation, bei der mit pop() und push() Routen auf einen Navigations-Stack gelegt und wieder entfernt werden können. Mit der prop initialRoute kann man die Route festlegen, die beim Start der App gewählt werden soll. Als Routen benutzte Komponenten benötigen eine Eigenschaft route an ihrem Prototyp-Objekt. Dies kann man mit der ES2015-Klassensyntax am einfachsten per static-Schlüsselwort erreichen (Listing 8). Diese Komponente HomeScreen rendert einfach nur einen Text und danach eine Tippfläche, mit der man auf einen OptionsScreen wechseln können soll. Die statische Eigenschaft route enthält Optionen, die von ExNavigation ausgewertet werden. In diesem Fall soll der Titel der Navigationsleiste den Text Home enthalten. Tippt man auf Go to Options, dann wird die in Listing 9 gezeigte Komponente mit this.props.navigator. push() auf den Navigations-Stack gelegt. Auch hier gibt es eine Tippfläche, mit der man diesmal zurücknavigieren kann. Dazu wird einfach mit this.props.navigator.pop() die aktuelle Komponente vom Navigations-Stack entfernt. ExNavigator kümmert sich dabei automatisch um eine passende Animation für die Übergänge zwischen den Screens. Mit der statischen Eigenschaft route kann man nicht nur den Titel festlegen, sondern auch, welche Komponenten auf der linken oder rechten Seite der Navigationsleiste dargestellt werden sollen. Der OptionsScreen muss sich dann aber noch beim back-Ereignis des Event-Emitters registrieren. Bild 9 zeigt die beiden Screens des Beispiels und die Übergänge dazwischen. Leider verkompliziert diese Verschaltung

hour: date.getHours(), minute: date.getMinutes(), second: date.getSeconds()

Listing 7: ExNavigation

} }

import Exponent from 'exponent'

class CurrentTimeClock extends React.Component {

import React from 'react'

componentWillMount() {

import {

this.setState(getTime)

createRouter,

this._timer = setInterval(this.updateTime, 1000)

NavigationProvider, StackNavigation

} componentWillUnmount() { clearInterval(this._timer)

} from '@exponent/ex-navigation' import HomeScreen from './HomeScreen'

}

import OptionsScreen from './OptionsScreen'

render() {

const Router = createRouter(() => ({ home: () => HomeScreen,

let {width, height} = Dimensions.get("window")

options: () => OptionsScreen

let maxSize = Math.min(width, height) - 20 return ( <SVGClock size={maxSize}

})) class App extends React.Component { render() {

hour={this.state.hour}

return (

minute={this.state.minute}

<NavigationProvider router={Router}>

second={this.state.second}

<StackNavigation initialRoute={Router.

/>

getRoute('home')} />

)

</NavigationProvider>

} )

updateTime = () => { }

this.setState(getTime) } }

74

} Exponent.registerRootComponent(App)

3.2017 www.webundmobile.de


Entwickler-Tools

MOBILE DEVELOPMEnT

jeweiligen App Stores veröffentlichen könnte. Leider reicht dieses Feature nicht so weit. Der Unterschied ist, dass nach einem Publish das Bundle auch unabhängig von den XDEProzessen der Entwicklermaschine über Amazon CloudFront bereitgestellt wird. Wie im Entwicklungsmodus erhält man einen URI, den man mit jedem Exponent-Client öffnen kann.

Fazit

navigations-Controller für Android und iOS (Bild 9)

die Komponente und erfordert, dass man die Ereignis-Handler in einem componentWillUnmount() wieder beseitigt. Hier kann man hoffen, dass die bereits angekündigte Weiterentwicklung derartige Fälle einfacher macht. ExNavigation hat noch eine große Zahl weiterer Features. Man kann damit auch sehr einfach eine Tab-Navigation oder Drawer-Navigation (ein Menü, das seitlich hereinfährt) verwirklichen. Nicht nur in Zusammenhang mit Exponent gilt ExNavigation deshalb momentan als eine der besten Lösungen für UI-Navigation in React Native. Die Schaltfläche mit der Aufschrift Publish in der XDE verrät es bereits: Man kann damit erstellte Apps auch veröffentlichen. Nun wäre es natürlich ein echtes Wunder, wenn man durch einen Druck auf eine solche Schaltfläche die App in die

Exponent macht das Entwickeln nativer Apps für iOS und Android fast so einfach wie Webentwicklung. Der ExponentClient entspricht dem Webbrowser, und mit der XDE werden im Editor geänderte Quellen live auf den neuesten Stand gebracht. Neben den hier vorgestellten Features bietet Exponent noch eine ganze Reihe weiterer: Man kann beispielsweise mit der Kamera des Geräts Barcodes scannen lassen und erhält als Ergebnis die in den Barcodes codierten Daten. ◾

Jochen H. Schmidt ist als Autor, Berater und Software-Entwickler tätig. Schwerpunkte seiner Aktivitäten sind Webentwicklung und Webtechnologien. Er ist Verfasser von bekannten Fachbüchern zum Thema Common Lisp. redaktion@webundmobile.de

Listing 9: Komponente HomeScreen

Listing 8: static-Schlüsselwort import React from 'react'

import React from 'react'

import {View, Text, TouchableHighlight}

import {View, Text, TouchableHighlight}

from 'react-native'

from 'react-native'

export default class HomeScreen extends

export default class OptionsScreen extends React.

React.Component {

Component { static route = {

static route = {

navigationBar: { title: 'Options' }

navigationBar: { title: 'Home' } }

} render() {

render() {

return (

return ( <View style={{

<View style={{ alignItems: 'center', justifyContent:

alignItems: 'center',

'center', flex: 1 }}>

justifyContent: 'center',

<Text>HomeScreen!</Text>

flex: 1 }}>

<TouchableHighlight onPress=

<Text>Options</Text>

{this.gotoOptions}>

<TouchableHighlight onPress={this.gotoBack}> <Text>Go Back</Text>

<Text>Go to Options!</Text>

</TouchableHighlight>

</TouchableHighlight>

</View>

</View> )

) }

}

gotoBack = () => {

gotoOptions = () => {

this.props.navigator.pop()

this.props.navigator.push('options') }

} }

www.webundmobile.de 3.2017

}

75


MOBILE DEVELOPMEnT

Swift

SWIFT: PROPERTIES IM DETaIL

Wichtige Elemente Properties sind ein essenzielles Sprachmerkmal von Swift.

P

roperties sind ein grundlegender Bestandteil von Apples Programmiersprache Swift (Bild 1). Sie beschreiben Variablen und Konstanten, die innerhalb eines Typs (also beispielsweise innerhalb einer Structure oder Klasse) deklariert sind, und dienen dazu, verschiedene Werte für einen solchen bestimmten Typ zu speichern. Im Gegensatz zu Variablen und Konstanten sind Properties aber deutlich mächtiger und vielfältiger und bringen einige besondere Funktionen mit. Auch wird zwischen verschiedenen Arten von Properties in Swift unterschieden, um unterschiedliche Anforderungen und Aufgaben zu erfüllen. Dieser Artikel stellt diese verschiedenen Arten von Properties und ihre jeweilige Funktionsweise im Detail vor. Im Anschluss kennen Sie alle Facetten von Properties und können Properties entsprechend bestmöglich in Ihren eigenen Projekten verwenden und einsetzen.

Stored Properties Die Standardform von Properties stellen die sogenannten Stored Properties dar. Diese sind am ehesten mit den herkömmlichen Variablen und Konstanten in Swift vergleichbar. Stored Properties halten Werte im Speicher und geben diese beim Zugriff darauf zurück. Eine einfache Deklaration zweier Properties vom Typ Int innerhalb einer Structure zeigt das folgende Listing: struct AStructure { var variableProperty: Int var constantProperty: Int }

Die Property variableProperty ist als Variable deklariert, wodurch es sich bei dieser Property um eine sogenannte ReadWrite Property handelt; man kann sie also sowohl auslesen als auch ihren Wert ändern. Die Property constantProperty hingegen ist als Konstante deklariert, weshalb es sich dabei um eine sogenannte Read-Only Property handelt. Deren Wert kann also nach einer erstmaligen Zuweisung nicht geändert, sondern nur noch ausgelesen werden. Über Instanzen der so erzeugten Structure AStructure ist es nun möglich, auf die beiden deklarierten Properties zuzugrei-

76

fen und diese auszulesen. Im Fall der als Variablen deklarierten Property variableProperty ist es darüber hinaus möglich, den Wert dieser Property zu verändern. Das folgende Listing zeigt die beispielhafte Verwendung und den Zugriff auf die so erstellten Properties mittels der sogenannten Punktnotation: var myStructure = AStructure(variableProperty: 19, constantProperty: 99) myStructure.variableProperty = 28 print("variableProperty = \(myStructure.variableProperty)") print("constantProperty = \(myStructure.constantProperty)") // variableProperty = 28 // constantProperty = 99

Auf die in den folgenden Abschnitten vorgestellten weiteren Arten von Properties kann ebenfalls auf die gleiche Art und Weise zugegriffen werden. Dabei gibt es bei Stored Properties ein Detail zu beachten, wenn diese als Teil einer Structure (sprich eines Value Types in Swift) deklariert sind. Dann nämlich können die Werte von Read-Write Properties wie variableProperty nur geändert werden, wenn die Instanz der Structure ebenfalls als Variable und nicht als Konstante deklariert ist. Den Properties einer Structure, deren Instanz als Konstante deklariert ist, können nämlich nach der erstmaligen Wertzuweisung genau wie bei Read-Only Properties keine neuen Werte mehr zugewiesen werden. Da es sich bei der AStructure-Instanz myStructure um eine Variable handelt, ist eine Änderung der Property variableProperty möglich. Die im folgenden Listing deklarierte Konstante anotherStructure vom Typ AStructure hingegen kann nachträglich keine Änderung an der Property variableProperty vornehmen: let anotherStructure = AStructure(variableProperty: 19, constantProperty: 99) anotherStructure.variableProperty = 99 // Fehler: variableProperty der Konstanten anotherStructure kann nicht geändert werden.

Bei Klassen (sprich Reference Types) spielt das beschriebene Problem keine Rolle. Auch wenn eine Instanz eines Reference

3.2017 www.webundmobile.de


Swift

Types selbst als Konstante deklariert ist, können deren ReadWrite Properties trotzdem verändert werden.

Lazy Stored Properties Bei den sogenannten Lazy Stored Properties handelt es sich um eine Sonderform der Stored Properties. Ganz grundlegend entsprechen Lazy Stored Properties in ihrer Funktionsweise den Stored Properties und dienen dazu, bestimmte Werte zu halten, damit auf diese zugegriffen werden kann. Dabei werden Lazy Stored Properties immer als Variablen mit dem Schlüsselwort var deklariert, was in ihrer eigentlichen Besonderheit begründet ist: Lazy Stored Properties werden erst in dem Moment initialisiert, in dem erstmals auf sie zugegriffen wird. Bis dahin besitzen diese Properties keinen Wert, und da Read-Only Properties aber nach der Initialisierung der zugrunde liegenden Instanz zwingend einen Wert besitzen müssen, können Lazy Stored Properties daher immer nur als Variablen umgesetzt werden. Bei der Deklaration einer Lazy Stored Property kommt das Schlüsselwort lazy zum Einsatz, das der eigentlichen Property-Deklaration vorangestellt wird. Davon abgesehen ist die Deklaration und Verwendung von Lazy Stored Properties identisch mit der von Stored Properties. Lediglich ein Standardwert beziehungsweise ein Initializer muss zwingend in Verbindung mit einer Lazy Stored Property verwendet werden. Denn Lazy Stored Properties müssen nicht über den zugrunde liegenden Typ initialisiert werden; ihr Vorteil besteht ja gerade darin, dass ihr Wert erst zu einem späteren Zeitpunkt ermittelt wird. Doch für diese Aufgabe muss einer Lazy Stored Property die entsprechende Logik zugewiesen sein, damit sie einen solchen Wert selbsttätig ermitteln kann; ent-

apples Programmiersprache wartet mit interessanten Sprachmerkmalen auf (Bild 1)

www.webundmobile.de 3.2017

MOBILE DEVELOPMEnT

weder in Form eines Initializers oder durch die simple Zuweisung eines Standardwerts. Im folgenden Listing ist ein einfaches Beispiel einer Structure namens AnotherStructure zu sehen, die eine einzige Lazy Stored Property deklariert: struct AnotherStructure { lazy var lazyStoredProperty = 19 }

In diesem Beispiel wird der Lazy Stored Property ein Standardwert zugewiesen. Alternativ könnte ihr – wie Stored Properties auch – ein Closure zugewiesen werden, das den Standard- beziehungsweise Initialwert der Property bei erstmaliger Verwendung automatisch berechnet, ermittelt und zuweist. Ein solcher Initializer für eine Property wird aber nur maximal einmal aufgerufen, und zwar dann, wenn das erste Mal auf besagte Property zugegriffen wird und ihr zuvor nicht explizit bereits ein anderer Wert zugewiesen wurde. Lazy Stored Properties kommen im Vergleich zu Stored Properties in der Regel immer dann zum Einsatz, wenn der ihnen zugewiesene Wert recht umfangreich oder komplex ist und gleichzeitig noch nicht zwingend bei Erstellung der zugrunde liegenden Instanz benötigt wird (die Property möglicherweise für die Verwendung der Instanz also gar nicht benötigt wird). In diesen Szenarien sorgen Lazy Stored Properties für geringere Last, da sie erst dann initialisiert werden, wenn sie auch tatsächlich verwendet und genutzt werden.

Computed Properties Computed Properties unterscheiden sich in ihrer Funktionsweise stark von den zuvor vorgestellten Stored und Lazy Stored Properties. Wie ihr Name bereits andeutet, halten sie keinen spezifischen Wert im Speicher, sondern ermitteln diesen dynamisch. Sie sind also eher mit Methoden vergleichbar, die jeweils eine bestimmte Funktion ausführen, abhängig davon, ob eine Computed Property ausgelesen oder ihr ein neuer Wert zugewiesen wird. Basis von Computed Properties sind die sogenannten Getter und Setter. Einfach ausgedrückt handelt es sich dabei um jene beschriebenen Methoden, die bei Verwendung einer entsprechenden Computed Property aufgerufen werden. Der Getter kommt dabei zum Einsatz, wenn lesend auf eine Property zugegriffen wird, während der Setter im Fall einer Wertzuweisung zu einer Computed Property ausgelöst wird. Bei der Deklaration einer Computed Property spielen diese Getter und Setter eine essenzielle Rolle. Eine Computed Property wird dabei zunächst immer mit dem Schlüsselwort var deklariert, niemals mit let. Das liegt darin begründet, dass eine Computed Property immer dynamisch die hinterlegten Befehle ausführt und es so bei jeder Verwendung zu einem anderen Ergebnis kommen kann. Entsprechend ist der Wert einer Computed Property aus Prinzip immer variabel, niemals konstant. Ebenso wird einer Computed Property immer der gewünschte Typ fest mittels Type Annotation zugewiesen. Nach dieser grundlegenden Deklaration geht es dann aber direkt los mit den Unterschieden zu Stored Properties: ▶

77


MOBILE DEVELOPMEnT

Swift

Nach der Angabe des Property-Typs folgen geschweifte Klammern, innerhalb derer die Implementierung von Getter und Setter folgt. Der Getter wird dabei in Form des Schlüsselworts get deklariert, wieder gefolgt von einem geschweiften Klammernpaar, innerhalb dessen die Befehle eingetragen werden, die ausgeführt werden sollen, wenn lesend auf die entsprechende Property zugegriffen wird. Als Nächstes folgt der Setter, der mit Hilfe des Schlüsselworts set deklariert wird. Auch im Anschluss an set folgen geschweifte Klammern, zwischen denen die Implementierung des Setters erfolgt. Listing 1 zeigt diesen grundlegenden Aufbau einer typischen Computed Property mit Getter und Setter im Detail. Wichtig beim Getter: Dieser muss in jedem Fall immer einen passenden Wert des Property-Typs mittels return zurückgeben. Die sonstige Implementierung von Getter und Setter ist vollkommen dem Entwickler selbst überlassen und entspricht der Implementierung von Methoden in Swift. Um innerhalb des Setters auf den Wert zuzugreifen, welcher der entsprechenden Computed Property zugewiesen wurde, kann innerhalb des set-Blocks auf die temporäre Konstante newValue zugegriffen werden. Diese enthält jenen Wert, den der Setter dann auf die gewünschte Art und Weise weiterverarbeiten kann.

Listing 1: Aufbau von Computed Properties struct ComputedPropertyStructure { var aComputedProperty: Int { get { // Implementierung des Getters } set { // Implementierung des Setters } }

Listing 2: Abbildung einer Fläche import Foundation struct Cube { var width: Double var height: Double var area: Double { get { return width * height } set { width = sqrt(newValue) height = sqrt(newValue) } }

78

var myCube = Cube(width: 5, height: 5) print("Fläche von myCube: \(myCube.area)") // Fläche von myCube: 25.0 myCube.area = 100 print("Breite von myCube: \(myCube.width)") print("Ḧhe von myCube: \(myCube.height)") // Breite von myCube: 10.0 // Ḧhe von myCube: 10.0

Listing 2 zeigt ein konkretes Beispiel für die Verwendung von Computed Properties. Darin wird eine Structure namens Cube zur Abbildung eines Würfels erstellt, die zunächst über die zwei Stored Properties width und height (zur Abbildung von Breite und Höhe) verfügt. Daneben besitzt die Structure eine Computed Property namens area, die die Fläche eines solchen Würfels zurückgeben soll. Da sich dieser Wert aus der Breite und Höhe ergibt und somit dynamisch berechnet werden kann, ist die Property als Computed Property umgesetzt. Der Getter gibt dabei schlicht das Ergebnis der Multiplikation der Stored Properties width und height zurück, während der Setter die Wurzel aus einer neu zugewiesenen Fläche zieht und anschließend jeweils width und height als neue Breite und Höhe zuweist. Der neu zugewiesene Wert kann dabei, wie zuvor beschrieben, über die temporäre Konstante newValue innerhalb des Setters ausgelesen werden. Eine Computed Property selbst kann ansonsten auf dieselbe Art und Weise verwendet werden wie eine Stored Property auch, wie Listing 3 zeigt.

Shorthand Setter

}

}

Listing 3: Zugriff auf eine Computed Property

Der Setter einer Computed Property verfügt zusätzlich noch über eine Besonderheit bezogen auf den Wert, der diesem bei einer Zuweisung zu der entsprechenden Computed Property übergeben wird. Innerhalb des Setters lässt sich standardmäßig über die temporäre Konstante newValue auf den übergebenen Wert beim Setzen einer Computed Property zugreifen. Dieses Verfahren wird auch als Shorthand Setter Declaration bezeichnet, da die eigentliche Deklaration des übergebenen Wertes automatisch durch Swift erfolgt. Es lässt sich aber auch problemlos ein anderer Bezeichner für diese temporäre Konstante definieren. Dazu setzt man innerhalb runder Klammern direkt nach Deklaration des Setters über das Schlüsselwort set den gewünschten Bezeichner, der dann statt newValue innerhalb des Setters zur Verfügung steht. Die Betonung liegt dabei explizit auf statt, denn wenn ein eigener Bezeichner definiert ist, steht newValue nicht länger automatisch im Setter zur Verfügung. In Listing 4 ist nochmals die Structure Cube aufgeführt, dieses Mal allerdings mit einer eigenen Deklaration für den Bezeichner des Setters. Dieser wird dort auf den Namen newArea festgesetzt, womit beim Ändern der Computed Property area

3.2017 www.webundmobile.de


Swift

der neu zugewiesene Wert über diesen neuen Bezeichner abgerufen werden kann. Für die Zuweisung eines Wertes zu dieser Property hat diese Änderung keinerlei Einfluss.

Listing 5: Read-Only Computed Property struct Person { var firstName: String

Read-Only Computed Properties Computed Properties müssen überdies nicht zwingend über einen Setter verfügen. Soll beispielsweise eine Computed Property lediglich dynamisch einen Wert ermitteln und zurückgeben (zum Beispiel die Fläche eines Würfels), wobei ihr aber kein neuer Wert zugewiesen werden soll, dann kann sie als sogenannte Read-Only Computed Property deklariert werden. In diesem Fall verfügt die Computed Property über keinen Setter, und die Zuweisung eines Wertes zu dieser Property würde umgehend zu einem Compiler-Fehler führen (ähnlich dem Versuch, einer bestehenden Konstante in Swift einen neuen Wert zuzuweisen). Um eine Read-Only Computed Property zu erstellen, muss lediglich der set-Block bei der Deklaration der Property weggelassen werden. In Listing 5 ist ein Beispiel dazu zu sehen. Dort wird eine neue Structure namens Person deklariert, die über die beiden Stored Properties firstName und lastName (zur Abbildung von Vor- und Nachnamen einer Person) verfügt. Zusätzlich bestitzt die Structure noch eine Computed Property fullName, deren Getter den vollen Namen durch die Zusammensetzung von firstName und lastName zurückgibt. Da über diese Property kein neuer Name gesetzt werden soll, fehlt der entsprechende set-Block, wodurch die Property zugleich zu einer Read-Only Computed Property wird. Swift bietet für die Deklaration derartiger Read-Only Computed Properties auch eine Kurzschreibweise an. Da nämlich eine Read-Only Computed Property ausschließlich über den Getter-Block verfügt, kann in diesem Fall auch vollständig auf die Erstellung des get-Blocks verzichtet werden und stattdessen die Implementierung des Getters direkt innerhalb der geschweiften Klammern nach der Deklaration der Computed Property stattfinden. Wie das aussieht, zeigt Listing 6. Die letzte Form von Properties in Swift sind die sogenannten Type Properties. Type Properties unterscheiden sich von

Listing 4: Deklaration eines eigenen Bezeichners import Foundation struct Cube { var width: Double var height: Double var area: Double { get { return width * height } set(newArea) { width = sqrt(newArea) height = sqrt(newArea) } } }

www.webundmobile.de 3.2017

MOBILE DEVELOPMEnT

var lastName: String var fullName: String { get { return "\(firstName) \(lastName)" } } }

Listing 6: Kurzschreibweise struct Person { var firstName: String var lastName: String var fullName: String { return "(firstName) \(lastName)" } }

den bisher vorgestellten Properties dahingehend, dass sie nicht an eine spezifische Instanz eines Typs gebunden sind, sondern einmalig übergreifend für den gesamten Typ gelten. Der Wert einer Type Property ist also an jeder Stelle innerhalb eines Projekts derselbe, und wird er an einer Stelle geändert, ist die Änderung auch für alle sichtbar. Type Properties können sowohl als Stored Properties (nicht als Lazy Stored Properties!) wie auch als (Read-Only) Computed Properties umgesetzt werden. Statt über eine Instanz des zugrunde liegenden Typs werden sie direkt über den zugehörigen Typ aufgerufen, wie wir gleich sehen werden. Deklariert werden Type Properties mit Hilfe des Schlüsselworts static. In Klassen für Type Properties, die als Computed Properties umgesetzt sind, kann alternativ das Schlüsselwort class verwendet werden. Das ist immer dann notwendig, wenn die entsprechende Property in Subklassen überschreibbar sein soll. In Listing 7 ist ein Beispiel zur Deklaration und Verwendung von Type Properties aufgeführt. aStoredTypeProperty ist dabei eine Stored Property, während aComputedTypeProperty eine Read-Only Computed Property ist. Beide Properties können nur direkt über den Typ TypePropertyStructure, innerhalb dessen sie deklariert sind, verwendet und aufgerufen werden. Über Instanzen dieser Structure stehen die Properties nicht zur Verfügung. Eingesetzt werden Type Properties typischerweise immer für Informationen eines Typs, die für jede Instanz dieses Typs gleichermaßen gelten. Bildet man beispielsweise eine KfzWerkstatt ab, könnte diese als Type Property die aktuelle Anzahl an zu reparierenden Wagen speichern. Ganz allgemein gilt aber schlicht die Faustregel: Bezieht sich eine Proper- ▶

79


MOBILE DEVELOPMEnT

Swift

ty explizit auf eine bestimmte Instanz eines Typs, dann wird sie als Instance Property (dem Gegenteil einer Type Property) umgesetzt; bezieht sie sich dagegen auf eine allgemeine Information für den zugrunde liegenden Type, ist der Einsatz einer Type Property sinnvoller.

Property Observer

Eine Stored Property kann beide oder auch nur einen der genannten Property Observer implementieren, je nachdem, welche Information benötigt wird (vor Durchführung einer Änderung oder nach Durchführung einer Änderung). Property Observer werden dabei auf dieselbe Art und Weise implementiert wie der Getter- und Setter-Block von Computed Properties, nur dass anstelle des jeweiligen Blocks das Schlüsselwort willSet beziehungsweise didSet für die Deklaration verwendet wird. In Listing 8 sehen Sie ein Beispiel zur Verwendung und Implementierung von Property Observer. Dort wird eine Structure Person mit einer einzigen Stored Property name deklariert, wobei diese Property beide der genannten Property Observer implementiert. In beiden Fällen wird ein einfacher print()-Befehl ausgeführt, um so innerhalb von willSet den neuen Wert und innerhalb von didSet den alten Wert der Property auszugeben. Ähnlich wie beim Setter in Computed Properties kann der Bezeichner der temporären Konstante, die jeweils innerhalb eines Property Observers zur Verfügung steht, geändert werden. Dazu wird der gewünschte Bezeichner innerhalb von runden Klammern nach dem Schlüsselwort willSet beziehungsweise didSet aufgeführt. Innerhalb des jeweiligen Blocks kann dann ausschließlich dieser eigens definierte Bezeichner verwendet werden, um auf den neuen Wert (in willSet) beziehungsweise den alten Wert (in didSet) zuzugreifen.

Zum Abschluss dieses Artikels möchte ich noch auf eine Technik eingehen, die für Stored Properties (nicht Lazy Stored Properties) in Swift zur Verfügung steht: die sogenannten Property Observer. Diese können jeder Stored Property hinzugefügt werden und dienen dazu, über Änderungen einer Stored Property zu informieren. Wann immer sich dann eine entsprechende Property ändert, können eigens definierte Befehle ausgeführt werden. Das kann man beispielsweise dazu nutzen, um bei Änderung einer bestimmten Property eine zugehörige View zu aktualisieren. Dabei gibt es generell zwei Ausführungen von Property Observer: willSet: Der willSet-Block wird aufgerufen, bevor sich der Wert der zugehörigen Property ändert. Innerhalb dieses Blocks lässt sich über die Konstante newValue auf den Wert zugreifen, der der Property gleich zugewiesen wird.

Listing 7: Deklaration von Type Properties struct TypePropertyStructure { static var aStoredTypeProperty = "Type property" static var aComputedTypeProperty: String { return "Computed type property" } } TypePropertyStructure.aStoredTypeProperty = "Stored type property" print ("\(TypePropertyStructure.aStoredTypeProperty)") print ("\(TypePropertyStructure.aComputedTypeProperty)")

Listing 8: Deklaration von Property Observer struct Person { var name: String { willSet { print("Der neue Name lautet: \(newValue)")

didSet: Der didSet-Block wird aufgerufen, nachdem sich der Wert der zugehörigen Property geändert hat. Innerhalb dieses Blocks lässt sich über die temporäre Konstante oldValue auf den Wert zugreifen, den die Property vor der Änderung besaß.

Fazit Properties gehören bei der Programmierung in Swift zu den wichtigsten Elementen. Sie dienen aber nicht einfach nur der Speicherung von Werten verschiedener Eigenschaften einer Instanz, sondern können noch deutlich mehr. Mittels Computed Properties können sich Properties wie Methoden verhalten und dynamisch Werte ermitteln und zurückgeben. Und Property Observer erlauben das einfache Überwachen von Änderungen an Properties sowie die passende Implementierung von Befehlen, die bei Durchführung einer entsprechenden Änderung ausgeführt werden sollen. Hat man die Funktionen und Möglichkeiten von Properties erst einmal verinnerlicht, erlauben sie es einem, den eigenen Code besser zu ◾ strukturieren und zu optimieren.

} didSet { print("Der alte Name lautete: \(oldValue)") } } } var me = Person(name: "Thomas")

Thomas Sillmann ist iOS-App-Entwickler und Autor. Freiberuflich tätig entwickelt er eigene Apps für den App Store sowie Apps in Form von Kundenaufträgen. www.thomassillmann.de

me.name = "Thomas Sillmann"

80

3.2017 www.webundmobile.de


07.-08. März 2017, München

Jetzt kostenloses Ticket sichern! tickets.internetworldmesse.de

The Future of Commerce Kommen Sie zu Europas größter E-Commerce Messe am 7. und 8. März 2017 in München

400 Aussteller und Partner

150 PraxisVorträge auf 5 Arenen

50 Top-Speaker in der TrendArena


„The Future of Commerce“ Internet World – Die E-Commerce Messe am 7. und 8. März 2017 auf dem Münchner Messegelände

Alle Vorträge sind für registrierte Besucher der Internet World Messe kostenlos

Mit rund 400 Ausstellern ist die Internet World Messe die größte Messe zum Thema E-Commerce in Europa. Sie richtet sich an Online-Händler jeder Branche mit einem breiten Produkt- und Dienstleistungsangebot für den E-Commerce, das von eShopsoftware über Onlinemarketing, E-Payment bis zu eLogistics reicht. Ein Sonderthema sind Produkte für den Händler, der online und stationär Ware anbietet. Die Ausstellung wird ergänzt durch ein breites Angebot an Informations- und Fortbildungsveranstaltungen. An erster Stelle steht die TrendArena in Halle A5, auf der die Stars des E-Commerce in Deutschland und Europa zwei Tage lang ihre strategischen Perspektiven vorstellen und diskutieren. Dazu gibt es über 150 Praktiker-Präsentationen zu allen Aspekten des E-Commerce auf 5 Infoarenen. Internet World – die E-Commerce Messe ist für Besucher nach Registrierung unter tickets.internetworld-messe.de kostenlos.

150 Praxis-Vorträge auf 5 Arenen Themen: E-Commerce, Onlinemarketing, E-Payment und eLogistics Das vollständige Programm unter: internetworld.de/Messe/Messeprogramm In den Messehallen der Internet World gibt es fünf Infoarenen, auf denen am 7. und 8. März über 150 Praxis-Vorträge angeboten werden. Auf den Arenen 1 bis 4 geht es im 20-Minuten-Takt vor allem um Produkte und Diensleistungen, die für den Online-Handel angeboten werden. Auf der Arena 5 bietet Google am 7. März zwei Workshops zum Thema Doubleclick mit den Schwerpunkten Rich Media, Programmatic Buying und Search an. Am 8. März findet auf derselben Bühne ein Kompakt-Workshop für stationäre Händler auf dem Weg ins Internet statt. Partner sind hier die Handelsfachzeitschriften SAZ sport, SAZ Bike und Telecom Handel. Die Vorträge zum Thema E-Commerce (Auswahl): Geschäftsmodelle der Zukunft • Handel mit der Schweiz • Die Verbindung zwischen Online- und Offline-Handel • Von Multichannel bis No-Line-Commerce •  Mehr Profil(e) bitte • Digitale Wachstumssstrategien für Händler und Hersteller • Kartenzahlung im Online-Handel • Wie cleverer Kundenservice Ihren Erfolg boostet • Preiskampf im Online-Handel • Warensendung Plus & Mailings mit Grip • Crossborder solutions • Verkaufen über alle Kanäle mit plentymarkets • Wie Machine Learning den E-Commerce verändert • Mit der eigenen App in die Hosentasche des Kunden • App beats web • E-CommerceRecht • Warenwirtschaftslösung für den Onlinehandel • Intelligente ContentProduktion verbindet Kommunikationskanäle • Die 5 schlimmsten Fehler im

B2B E-Commerce und wie Sie diese vermeiden • Mobile first • Disruptive Trends im B2B E-Commerce • Sicher und erfolgreich international verkaufen • Mehr Umsatz durch Webchats • Facebook Messenger • Whatsapp und Videoberatung • Das wertvollste Kapital im Online-Handel • Wenn die EU im Online-Handel mitmischt • Kriminalität 2.0 • Online Marketplaces are the future of German E-Commerce • Preisbeobachtung für Online-Retail • Agilies Marketing im Zeitalter des Kunden • Tipps und Best Practices für die Praxis • Storytelling richtig einsetzen • 10 Fragen für Ihre individuelle B2B ECommerce Strategie • Trends bei Kartenzahlungen im E-Commerce • Digitale Transformation – Survival of the fittest • Mobile first-responsive war gestern

Die Vorträge zum Thema Onlinemarketing (Auswahl): Bots sind die mobile Zukunft • Best practice SEO • Customer journey und Attributionsmodell • E-Mail-Marketing – der Clevere gewinnt • Programmatic Advertising • Von Branding zu Performance • Mit besseren User-Signals zum TopRanking bei Google & Co • Mit Conversion-Heuristiken kurzfristig 20 % Conversion-Rate-Steigerung erreichen • Digitales Marketing repariert • Erfolg-

reiche Conversion Optimierungs-Cases • Kampagnenstrategien für mehr Response • Marketing Automation • Erfolgsfaktoren für Data Driven Marketing •   Personalisierung 2.0 durch präskriptive Analaysen aus der Steckdose • Do’s und Dont’s im E-Mailmarketing • Online-Suche und Recommendation • So gelingt dynamische Personalisierung auf allen digitalen Kanälen

E-Payment (Auswahl): Globale Payment Trends • Bezahlmethoden – worauf kommt es an? • Innovatives Payment im E-Commerce • Kartenzahlung im Online-Handel • Gesicherter Rechnungskauf für B2B Onlinehändler in Echtzeit • WMF & Wirecard: Omnichan-

nel experience at its best - und wie WMF Kunden aus aller Welt davon konkret profitieren • Innovatives Payment im E-Commerce • Trends bei Kartenzahlungen im E-Commerce

eLogistics (Auswahl): Europaweite E-Commerce-Logistik am Beispiel des Autoteile-Onlinehändlers ATP • Professionelles Retourenmanagement • Maßgeschneiderte Automatisierung für den E-Commerce • Logistik für Start-ups • India the slee-

ping dragon • Turn one-tie shoppers into lifelong customers-succeed after checkout • Praxis-Tipps zur smarten und fehlerfreien Lagerlogsitik im E-Commerce • Von der Bestellung bis zur Retoure • Checkout to China

Vollständiges Programm unter: www.internetworld-messe.de/TrendArena


400 Aussteller und Partner

Mit freundlicher UnterstĂźtzung von:

Auszug aus der Aussteller- und Partnerliste


„Händler haben erkannt, dass sie ihren Kunden flexible Lösungen bieten müssen. Entsprechend steigt der Druck auf die gesamte KEP (KurierExpress-Paket)-Branche, diese Lösungen auch anzubieten.“ Nils Fischer, LieferFactory GmbH, Mitgründer und Geschäftsführer

„Es steckt ein hohes Potential in der Kombination aus Onlineund Offline-Angebot, indem die Vorteile beider Welten als Synergien genutzt werden. Wir sehen die Digitalisierung der Branche als Anreiz und Chance, den Kunden das beste Angebot mit dem besten Multichannel-Kauferlebnis zu bieten.“ Dr. Mirco Caspar Mister Spex GmbH, Geschäftsführer

„Durch neue Technologien werden Unternehmen in den kommenden Jahren gezwungen sein, kontinuierlich ihre Geschäftsmodelle zu überdenken und neu zu erfinden.“ Dr. Jens-Uwe Meyer Innovationsvordenker, Autor und Management-Berater, Innolytics GmbH

„Viele unserer Einzelhandelspartner sind auf die Onlinedynamik nicht vorbereitet und verlieren weiter an Bedeutung, insbesondere bei der nächsten Generation.“ Marc Freyberg Leineweber GmbH & Co. KG, Geschäftsleiter Brax Marketing / E-Commerce / Unternehmenssprecher

In der TrendArena um die Zukunft Die Redaktion der Fachzeitschrift INTERNET WORLD Business ist für das Vortragsprogramm der TrendArena verantwortlich und hat mehr als 50 Topspeaker auf die Bühne gebracht. Besonders hinweisen möchten wir auf die zwei Podiumsdiskussionen am 7. März. Einmal mit dem Thema, wie sich traditionelle Handelsketten der Herausforderung disruptiver Startups stellen. Dabei dienen der Brillen- und Matratzenhandel als Beispiele. In der zweiten Paneldiskussion geht es um die Erfolgsmessung im Online-Handel anhand von Zahlen. Wie Insider wissen, kommen immer noch sehr unterschiedliche Umsatzzahlen an die Öffentlichkeit, was dem Online-Handel selbst nicht gut tut.

Dienstag, 07. März Die digitale Zukunft der Wirtschaft in Bayern Erwin Huber, Staatsminister a.D., MdL Digitale Disruption: Wie Sie die Logik der digitalen Zukunft verstehen und selbst mitgestalten Dr. Jens-Uwe Meyer, Innolytics GmbH Auf die Spur gebracht: Wie Lucas F. Flöther Unister zurück in die schwarzen Zahlen führte Prof. Dr. Lucas F. Flöther, Rechtsanwalt und Insolvenzverwalter, Kanzlei Flöther & Wissing Plattform statt Produkte: Integrated Commerce bei Zalando Moritz Hau, Zalando SE Watson als Shop-Assistent: Wie kognitive Technologien dazu genutzt werden können, Kunden zu begeistern und Umsätze zu maximieren Marilies Rumpold-Preining, IBM Deutschland GmbH Matratzen und Brillen: Wie sich traditionelle Handelsketten disruptiven Startups stellen Vincent Brass, muun GmbH • Dr. Mirko Caspar, Mister Spex GmbH • Marcus Diekmann, Beter Bed Holding • Peter Gumpelmayer, ECOO European Council of Optometry and Optics • Britta Schafrin, Fünf Höfe Optik OHG • Moderation: Alexander Graf, Spryker Systems GmbH Handel der Zukunft: Warum der Handel Innovationen wie Drohnen, Roboter, künstliche Intelligenz oder Connected Hardware braucht Fabian J.G. Westerheide, Asgard - smart VC for AI Schneller als ein Traditionsunternehmen erlaubt: Omnichannel-Strategie bei Brax Marc Freyberg, Leineweber GmbH & Co. KG Digitalisierung im Retail: Neue Kundenerlebnisse durch Virtual Reality Martin Böker, Samsung Electronics GmbH BMW: Autonomous Driving, Dr. Klaus Büttner, BMW Group

„Es ergeben sich insbesondere im vollautomatisierten Betrieb autonomer Autos riesige Potentiale. Flotten können effizient eingesetzt werden und so insbesondere bei der Logistik den Verkehrsfluss vergleichmäßigen.“ Dr. Klaus Büttner BMW Group, Vicepresident Projects Autonomous Driving

Braucht Nestlé digitale Distributionskanäle? Ralf Butterbach, Nestlé Deutschland AG Vom YouTuber zur Handelsmarke, Dennis Ben Brahim, CEO, REASON GmbH & Co. KG • Arne Huwald, Creative Consultant Alibaba Group: A Gateway to China, Karl Wehner, Alibaba Group Deutschland Weg mit dem Zahlensalat: E-Commerce braucht verlässliche Daten Martin Groß-Albenhausen, Bundesverband E-Commerce und Versandhandel Deutschland e.V. • Stephan Tromp, Handelsverband Deutschland e.V. • Lars Hofacker, EHI Retail Institute GmbH • Dr. Kai Hudetz, IFH Institut für Handelsforschung GmbH • Prof. Dr. Gerrit Heinemann, Hochschule Niederrhein • Moderation: Peter Höschl, shopanbieter.de

Vollständiges Programm unter: www.internetworld-messe.de/TrendArena


Unsere Top-Speaker (Auszug) Sophie Bielmeier, Senior Project Manager Digital Global Digital Management, WMF Group GmbH

dreht sich alles des Handels

Martin Böker, Director B2B, Samsung Electronics GmbH

Die wichtigsten Lieferanten solcher Zahlen werden auf der TrendArena darüber diskutieren, wie man hier zu eindeutigen Ergebnissen kommen kann. Am 8. März gibt es drei Podiumsdiskussionen. Am Vormittag geht es um die E-Commerce-Logistik, die eine entscheidende Größe für den Erfolg des Online-Handels ist. Danach folgt eine Podiumsdiskussion über Marktplätze im Internet, die zum einen Reichweite bringen, aber zum Anderen immer auch ein Stück Freiheit kosten. Am Nachmittag folgt dann eine Diskussion zum Lebensmittel-Handel im Netz. Hier rüstet sich eine Branche für den erwarteten Markteintritt von Amazon Fresh auf.

Mittwoch, 08. März Global Marketplaces and the Prisoners Dilemma for Retailers Wijnand Jongen, CEO, thuiswinkel.org; Chairman of Executive Committee, Ecommerce Europe; Founder, Global Ecom Summit Leifheit: Wie schafft man 30 Prozent E-Commerce-Wachstum, Herr Junkert? Christoph Junkert, LEIFHEIT AG Warenhaus digital – Wie wird man Omnichannel-Sieger? Arik Reiter, Galeria Kaufhof GmbH E-Commerce-Logistik: Auf dem Weg zum Nahversorger? Nils Fischer, LieferFactory GmbH • Frank Rausch, Hermes Germany GmbH • Michael Löhr, tiramizoo GmbH • Peer Bentzen, Deutsche Post DHL Group • Moderation: Bernd Kratz, EMA GmbH Marktplatz-Roundtable: „Abhängigkeiten vermeiden: Welche Marktplätze lohnen sich noch?“ Denis Burger, Ebay Germany • Dr. Gerald Schönbucher, Hitmeister GmbH und real,- Digital Services GmbH • Jörn Rehse, idealo internet GmbH • Guido Schulz, Rakuten Deutschland • Moderation: Mark Steier, Wortfilter mytheresa.com: Von der Münchner Modeboutique zum internationalen OnlineRetailer für Luxusmode Sebastian Dietzmann, mytheresa.com Omnichannel international: Wie WMF-Kunden aus aller Welt davon profitieren Sophie Bielmeier • Hendrik Koepff, WMF Group GmbH Digitale Transformation: Wie Metro die Menschen in die digitale Zukunft mitnimmt Gabriele Riedmann de Trinidad, Metro Group Lebensmittel im Web: Die neue Bedrohung des Einzelhandels? Dr. Heiko Hegwein, Lidl E-Commerce International GmbH & Co. KG • Dr. Achim Dünnwald, DHL Paket GmbH • Dr. Michael Lierow, Oliver Wyman GmbH • Markus Buntz, J. Bünting Beteiligungs AG • Moderation: Peer Schader, Supermarktblog.com Siroop und wie der offene Online-Marktplatz den Schweizer Handel digitalisiert Dr. Constantin Hilt, Siroop AG David gegen Goliath – Wie sich ehotel gegen Reiseriesen wie booking.com oder hrs durchsetzt Michael Grumm, ehotel AG

Vollständiges Programm unter: internetworld-messe. de/TrendArena

Stand vom 17.01.2017, Programmänderung vorbehalten

Ralf Butterbach, Head of eCommerce, Nestlé Deutschland AG Dr. Klaus Büttner, Vice President Autonomous Driving Projects, BMW Group Dr. Mirko Caspar, Geschäftsführer, Mister Spex GmbH Marcus Diekmann, Director Digital, eCommerce & Omnichannel, Beter Bed Holding, u.a. Matratzen Concord GmbH Sebastian Dietzmann, Managing Director, mytheresa.com Dr. Achim Dünnwald, CEO DHL Paket Deutschland / CEO DHL Parcel Europe, DHL Paket GmbH Marc Freyberg, Geschäftsleiter Brax Marketing / E-Commerce / Unternehmenssprecher, Leineweber GmbH & Co. KG Alexander Graf, Herausgeber, Kassenzone.de, Gründer und Geschäftsführer, Spryker Systems GmbH Moritz Hau, Country Manager Germany, Zalando SE Dr. Heiko Hegwein, Bereichsvorstand E-Commerce, Lidl E-Commerce International GmbH & Co. KG Dr. Jens-Uwe Meyer, Innovationsvordenker, Autor und Management-Berater, Innolytics GmbH Arik Reiter, Chief Product Officer, Galeria Kaufhof GmbH Gabriele Riedmann de Trinidad, Group Director Business Innovation, Metro Group Marilies Rumpold-Preining, IBM Watson Customer Engagement Executive for Germany, Switzerland and Austria, IBM Deutschland GmbH Karl Wehner, Business Development Director, Alibaba Group Deutschland Martin Wild, Chief Digital Officer, Media-Saturn-Holding GmbH

Vollständiges Programm unter: www.internetworld-messe.de/TrendArena


Wir freuen uns auf Sie! 07.- 08. März 2017 I 9.00 Uhr bis 18.00 Uhr Messe München I Halle A5/A6, Eingang Ost

5 Top-Gründe für den Besuch der Internet World 2017 1

Rund 400 Aussteller und Partner zeigen auf der Internet World Messe ihre neuesten Produkte und Dienstleistungen, die jeder Händler im Internet braucht.

2

Ca. 50 Spitzenvertreter der wichtigsten nationalen und internationalen E-Commerce-Unternehmen teilen ihre Erfahrungen und Visionen in der neuen TrendArena mit Ihnen. Freuen Sie sich auf Vorträge, Podiumsdiskussionen und Interviews mit den „Stars des E-Commerce“.

3 InfoArena

150 Praxis-Vorträge an zwei Tagen auf fünf Infoarenen: Holen Sie sich praktische Tipps für Ihr Business von Branchen-Experten.

4

eLogistics World: Neu ist die Sonderfläche eLogistics World. Hier tragen wir der Bedeutung der Logistik Rechnung, wenn es um schnelle und fristgerechte Zustellung der gekauften Produkte geht. Ausgewählte Aussteller präsentieren Ihnen ihre Produkte und Lösungen zum Thema eLogistics.

5

Internet World Shop: Zukunftstechnologien zum Anfassen. Ob Beacons, Mobile Payment-Applikationen oder QR-Shopping-Lösungen: Erleben Sie die Digitalisierung am Point of Sale und die Trends von morgen.

Partnerveranstaltungen: CMCX – Content-Marketing Conference & Exposition

http://content-marketing-conference.com/

www.data-driven-marketing-ecommerce.de

Veranstalter:

tickets.internetworld-messe.de


PHP

BaCKEnD

PHP-FRaMEWORK LaRaVEL

Eigene Wege Laravel bietet PHP-Entwicklern einige interessante Features.

U

rsprünglich wurde das PHP-Framework Laravel 2011 als eine Alternative zu CodeIgniter entwickelt, inzwischen beschreitet es aber eigene Wege. Die aktuelle Version 5.3 benötigt mindestens die PHP-Version 5.6.4 und versteht sich auch gut mit PHP 7 (Bild 1). Das Framework erfreut sich einer recht großen Beliebtheit. Die aktive Community betreut inzwischen Teile der ursprünglichen Laravel-Kernkomponenten. Die Dokumentation ist gut, außerdem steht eine Menge anderer Informationsquellen zur Verfügung. An erster Stelle ist hier sicher Laracasts (https://laracasts.com) zu nennen: eine Plattform, auf der Sie eine Vielzahl von Screencasts finden können, die Ihnen einen schnellen Einstieg ermöglichen (Bild 2). Laravel steht unter der MIT-Lizenz und stellt inzwischen auch einen Long-Term Support (LTS) zur Verfügung, sodass man auch bei größeren Projekten keine Angst haben muss, dass es plötzlich keine Bugfixes mehr gibt. Zu guter Letzt soll nicht unerwähnt bleiben, dass es auch Erweiterungen für Entwicklungsumgebungen wie PhpStorm gibt.

Installationsvarianten Für die Installation von Laravel gibt es verschiedene Möglichkeiten. Bevor ich zu der bevorzugten Variante komme, möchte ich kurz auf Homestead eingehen. Bei Laravel Homestead handelt es sich um eine virtuelle Maschine, die alles mitbringt, was man für die Arbeit mit Laravel benötigt – ein sehr

auf Laracasts finden Sie viele hilfreiche Screencasts (Bild 2)

spannendes Konzept. Homestead basiert auf Ubuntu Linux (aktuell in der Version 16.04) und setzt voraus, dass Sie Vagrant und Virtual Box 5.1, VMware oder Parallels installiert haben. Nutzen Sie noch keine Virtualisierungsumgebung, dann sollten Sie vielleicht einen Blick auf Virtual Box werfen. Wie gesagt bringt Homestead alles (PHP, NGINX, Datenbanken et cetera) mit, was Sie für die Entwicklung mit Laravel benötigen, und hat den großen Vorteil, dass es auf Linux basiert. Somit können Sie weiter mit Ihrem bevorzugten Betriebssystem arbeiten, aber Ihre Anwendung trotzdem auf Linux entwickeln und testen.

Installation ohne Homestead Nun aber zurück zur Installation ohne Homestead. Um Laravel zu installieren, benötigen Sie zunächst den Composer, den Sie unter https://getcomposer.org herunterladen können. Sobald der Composer verfügbar ist, können Sie den Laravel Installer mit composer global require "laravel/installer"

So präsentiert sich die Homepage des Laravel-Frameworks (Bild 1)

www.webundmobile.de 3.2017

installieren. Beachten Sie, dass Sie eventuell in Abhängigkeit von Ihrem Betriebssystem den Composer mit php composer. phar aufrufen müssen. Nachdem der Installer heruntergeladen wurde, können Sie entweder über den Befehl laravel new oder über composer create-project ein neues Projekt anlegen. Oft ist es einfa- ▶

87


BaCKEnD

PHP

cher, mit dem Composer zu arbeiten, weil im diesem Fall unter Umständen noch Pfade gesetzt werden müssen. Mit dem Befehl composer create-project --prefer-dist laravel/laravel shop

legen Sie ein neues Projekt im Ordner shop an. Anstelle von shop können Sie natürlich auch einen kompletten Pfad angeben. Eine der Besonderheiten von Laravel ist der Kommandozeilenbefehl artisan. Der Befehl bietet einige spannende Features – zum Beispiel dieses: Wenn Sie in das Verzeichnis wechseln, in dem Sie das Projekt angelegt haben, und php artisan serve auf der Kommandozeile eingeben, dann wird ein Webserver gestartet. Der Server ist zudem so konfiguriert, dass er weiß, dass er auf den Ordner public zugreifen soll. Bei diesem Ordner handelt es sich um das Document-Root-Verzeichnis der Anwendung. Die Startseite der Anwendung kann nun über http://local host:8000 aufgerufen werden (Bild 3). Mit Hilfe dieses kleinen Servers kann man eine ganze Menge machen. Trotzdem werde ich im Verlauf des Artikels dann doch auf einen ApacheServer umsteigen, weil eben doch nicht alle Möglichkeiten eines großen Servers zur Verfügung stehen.

Model-View-Controller

üblicherweise auch die Models abgelegt. Dass es kein eigenes Verzeichnis für Models gibt, begründet das Laravel-Team damit, dass es oft unklar ist, was ein Model eigentlich zu leisten hat. Sprich, ist das Model nur für die Datenhaltung beziehungsweise Kommunikation mit der Datenbank zuständig oder enthält das Model auch die Applikationslogik? Zugegebenermaßen ist dieses Thema öfter Gegenstand von Diskussionen, daher finde ich den Ansatz gar nicht so schlecht. Ein Model im Sinne von Laravel dient nur dem Zugriff auf die Datenbank. Die Konfigurationsdaten sind im Ordner config zu finden. Wichtig ist noch der Ordner routes. Hier finden Sie die Routen, also die URLs, unter denen Ihre Anwendung angesprochen werden kann.

Konfiguration der anwendung Wie gerade schon erwähnt, liegt die Konfiguration der Anwendung im Ordner config. Grundsätzlich ist das auch richtig, allerdings gibt es hier eine Besonderheit. Laravel setzt im Hintergrund die Bibliothek PHP dotenv ein. Sie sorgt dafür, dass eine Datei namens .env, die sich im Installationsverzeichnis Ihrer Anwendung befindet, geladen wird. Diese enthält ebenfalls eine Konfiguration. Die Idee hinter den .env-Dateien (es können mehrere sein), ist, dass Sie auf Ihrem lokalen System sicher eine andere Konfiguration benötigen als auf dem Live-System. Daher können Sie dort die lokale Konfiguration speichern, während die Dateien im config-Ordner dann die Konfiguration für das Live-System beinhalten. Wir werden hier auf die .env-Dateien verzichten. Bevor Sie sie aber löschen, sollten Sie noch eines erledigen: Die Datei .env enthält eine Zeile mit einem APP_KEY, die in etwa so aussieht:

Auch Laravel setzt, wie die meisten Frameworks, auf das Model-ViewController-Entwurfsmuster (MVC). Grob gesagt ist dabei die View für die Darstellung von Daten beziehungsweise Webseiten zuständig. Das Model ist für die Verwaltung der Daten verantwortlich, und oft ist hier auch die Applikationslogik zu finden. Der dritte im Bunde, der APP_KEY=base64:p1AY+hEeQ5ttfndoP+ Controller, ist dann derjenige, der Homepage der Anwendung auf dem lokalen 0PyL4APavyVcGRNhxo27xi+FY= das Zusammenspiel der beiden ko- Server (Bild 3) ordiniert. Kopieren Sie alles nach dem GleichEine tiefergehende Erläuterung heitszeichen und fügen Sie den Key in die Datei config/app. würde hier leider den Rahmen sprengen, aber bei Wikipedia php ein. Dort ergänzen Sie die Zeile oder auf anderen Webseiten finden Sie ausführliche Erläuterungen zum Thema MVC. 'key' => env('APP_KEY') Nun aber zurück zum Code. Wie jedes Framework gibt auch Laravel eine Verzeichnisstruktur vor. Und um die Beeinfach um den Key. Danach können Sie die Datei .env besonderheit vorwegzunehmen: Es gibt kein Unterverzeichnis, denkenlos löschen oder umbenennen. Sollten Sie später noch das models heißt. Bleiben wir erst einmal bei den VerzeichProbleme der Art haben, dass plötzlich alte Usernamen beim nissen, die vorhanden sind. Zugriff auf die Datenbank auftauchen oder Ähnliches, dann Zunächst ist da das Verzeichnis public, das öffentlich zukann es helfen, wenn Sie auf der Kommandozeile php artisan gängliche Verzeichnis der Anwendung, also der Documentcache:clear eingeben. Root. Der Code für die Views beziehungsweise die Templates für die Darstellung im Browser sind in resources/views zu Routing finden. Im Ordner routes liegen drei Dateien, wobei die Datei web. Die meisten Dateien, die zu Ihrer Applikation gehören, php dafür zuständig ist, die Routen für eine Webanwendung werden im Verzeichnis app abgelegt. Die Controller finden zu registrieren. Hier wird definiert, welche Programmteile Sie unterhalb von Http wieder. Im Verzeichnis app werden

88

3.2017 www.webundmobile.de


PHP

ausgeführt werden, wenn ein bestimmter URL aufgerufen wird. Andere Frameworks bestimmen Controller, Action und View meist direkt aus dem URL. Laravel ist hier flexibler und ermöglicht es Ihnen, beliebige Controller und Actions anzusprechen. Die grundsätzliche Syntax lautet folgendermaßen:

BaCKEnD

bene Parameter nicht dem regulären Ausdruck, dann matcht die Route nicht und es wird ein 404-Fehler generiert: Route::get('user/{userId}/confirm/{token}', function() {} )->

Route::get('foo/bar', function () {

where(['userId' => '\d+', 'token' => '[a-z]+']);

// Code der ausgeführt werden soll });

Hier wird eine Route für einen GET-Request registriert. Dass es sich um einen GET-Request handelt, wird dadurch festgelegt, dass die Methode get() genutzt wird. Für andere Request-Typen stehen noch die Methoden post(), put(), patch(), delete() und options() zur Verfügung.

aufruf der Startseite Jede der Methoden bekommt als ersten Parameter den URL übergeben, der registriert werden soll. Das obige Beispiel legt also fest, was passieren soll, wenn http://server/foo/bar aufgerufen wird. Mit dem Parameter / könnte an dieser Stelle der Aufruf der Startseite definiert werden. Bevor ich auf den zweiten Parameter eingehe, die Funktion, möchte ich Ihnen noch eine kleine Erweiterung vorstellen. In den meisten Frameworks wird ja erst innerhalb der aufgerufenen Methode geprüft, ob Parameter gültig sind. Laravel kann das automatisch für Sie erledigen. Dabei stellt sich natürlich erst einmal die Frage, wie innerhalb des URL Parameter deklariert werden. Dazu sind Strings in geschweiften Klammern vorgesehen: Route::get('user/{userId}/confirm/{token}' function() {});

Hier werden die Parameter userId und token deklariert, sodass dieser URL also beispielsweise mit user/123/token/abc aufgerufen werden kann. Üblicherweise müssten Sie jetzt in der Methode, die ausgeführt wird, testen, ob die übergebenen Daten plausibel sind. Laravel unterstützt Sie hier aber und sieht die Methode where() vor, die diese Prüfung direkt durchführen kann. Ihr können Sie ein Array übergeben, das die Namen der Parameter und reguläre Ausdrücke enthält. Entspricht der überge-

Diese Route kann nur dann aufgerufen werden, wenn der Parameter userId nur aus Ziffern besteht und token nur aus Kleinbuchstaben (Bild 4). Nun aber zurück zum zweiten Parameter, den ich eben übersprungen habe. Dabei handelt es sich in diesen Beispielen um eine Funktion, die ausgeführt wird, wenn der URL aufgerufen wird. Hier habe ich die Funktion direkt im Code anonym implementiert. Um die beiden Parameter aus dem obigen Beispiel an die Funktion zu übergeben, deklarieren Sie die Funktion einfach als function($userId, $token){}. Alternativ können Sie hier auch den Namen eines Controllers, gefolgt vom Namen einer Methode beziehungsweise Action angeben. Um die Methode show() aus dem CommentController aufzurufen, würden Sie beispielsweise den String ’CommentController@show’. Angeben. Auch in diesem Fall können Sie die Parameter aus dem URL als Parameter an die Methode übergeben.

Hello World Nun wissen Sie zwar, wie das Routing funktioniert, aber wir brauchen natürlich noch einen Controller und eine View für eine erste kleine Anwendung. Den Controller legen Sie am einfachsten über artisan an. Mit php artisan make:controller DataController wird ein Controller namens DataController im Verzeichnis app/Http/ Controllers angelegt. Den generierten Controller habe ich hier schon um eine Methode beziehungsweise Action namens input() ergänzt: namespace App\Http\Controllers; use Illuminate\Http\Request; class DataController extends Controller { public function input() { return view ('input' , ['what' => 'Welt']); } }

Um die Action mit einer View zu verknüpfen, liefert die Methode den Rückgabewert des View-Helpers zurück. Der Parameter ’input’ referenziert dabei den Namen der View. Mit dem Array, das hier als zweiter Parameter genutzt wird, können Daten an die View übergeben werden. Bevor ich weiter auf das Template eingehe, hier noch schnell die Route, die ich in der Datei web.php ergänzt habe: Route::get('data/input' , 'DataController@input');

ausgabe bei fehlerhaften Parametern, mit Debug-Info (Bild 4)

www.webundmobile.de 3.2017

Dadurch, dass ich input an den View-Helper übergeben habe, erwartet Laravel ein Template namens input.blade.php ▶

89


BaCKEnD

PHP

im Verzeichnis resources/views. zungen vornehmen. Zuerst müsDas Suffix blade resultiert dasen Sie im Abschnitt providers raus, dass Laravel eine Templadie folgende Zeile ergänzen: te-Engine namens Blade nutzt. Collective\Html\ Noch vor einigen Jahren haHtmlServiceProvider::class ben deutlich mehr Frameworks Die erste ausgabe der eigenen Applikation (Bild 5) Template-Engines genutzt als Des Weiteren müssen Sie den heute. Inzwischen wird in den Abschnitt aliases um die folgenden Zeilen ergänzen: Templates meist direkt auf PHP gesetzt. Die Nutzung von Engines bieten allerdings einige Vorteile: Die Templates können kompiliert und gecacht werden. 'Form' => Collective\Html\FormFacade::class, Template-Designer müssen kein PHP lernen, sondern kön'Html' => Collective\Html\HtmlFacade::class, nen mit der Template-Sprache arbeiten. Die Template-Sprache ist auf die Ausgabe von Daten speWenn Sie das erledigt haben, können Sie innerhalb der View zialisiert. auf {!! Form:: ... !!} zugreifen. Die Deklaration des Formulars erfolgt direkt im Template über den Aufruf statischer MethoEin einfaches Template kann beispielsweise folgendermaßen den. Für jedes Formular-Element, das Sie aus HTML kennen, aussehen: gibt es dabei eine eigene Methode. <html> <head> <title>Eingabe</title> </head> <body> Hallo {{ $what }} </body> </html>

Wie Sie sehen, handelt es sich um einfaches HTML, das um das {{ $what }} ergänzt wurde. Mit Hilfe von doppelten geschweiften Klammern können Sie also eine Variable, die genau wie in PHP mit einem Dollar-Zeichen deklariert wird, ausgeben lassen. Um Probleme bei der Nutzung von JavaScript in Templates zu vermeiden, können Sie die Funktionalität der geschweiften Klammen mit einem vorangestellten @-Zeichen unterdrücken. Das @-Zeichen dient übrigens auch dazu, die meisten anderen Befehle, die in Blade bekannt sind, einzuleiten. Leider kann ich hier nicht die komplette Syntax vorstellen, aber in den meisten Fällen können Sie einfach die alternative PHPSyntax mit einem vorangestellten @ nutzen (@if – @endif / @ for – @endfor et cetera) (Bild 5). Umfangreiche Informationen – gerade auch zum Aufbau von Layouts – finden Sie im Laravel-Manual unter https://la ravel.com/docs/5.3/blade.

Erstellen von Formularen Bei fast allen Webanwendungen müssen Daten eingegeben werden, wozu Sie ein Formular benötigen. Da konventionelle HTML-Formulare in der heutigen Zeit aber immer weniger genutzt werden, wurden die Klassen zum Erstellen von Formularen aus dem Laravel-Kern entfernt. Im Umkehrschluss heißt das, dass Sie die benötigten Komponenten nachinstallieren müssen, was mit composer require ”laravelcollective/ html”:”^5.3.0” geschieht. Zusätzlich müssen Sie noch in der Datei app.php, die im Verzeichnis config liegt, zwei Ergän-

90

Formular-Elemente Die Methoden für die Formular-Elemente bekommen dabei zuerst den Wert für das name-Attribut übergeben. Danach folgt zunächst der Wert für das value-Attribut, wenn das Element dieses unterstützt. Als dritten Parameter können Sie ein optionales Array angeben, mit dem Sie beliebige Attribute wie CSS-Klassen et cetera festlegen können. Ein einfaches Formular zur Erfassung von Namen, Geburtstag, Telefon und Land könnte demnach wie in Listing 1 aufgebaut sein. Ich denke, dass die meisten Einträge hier selbsterklärend sind. Beim Geburtsdatum gilt, dass der Wert, der dort angezeigt werden

Listing 1: Formular {!! Form::open(['action' => 'DataController@input', 'method' => 'post']) !!} {!! Form::label('name', 'Name') !!} {!! Form::text('name', '', ['id' => 'name']) !!} <br> {!! Form::label('birthday', 'Geburtstag') !!} {!! Form::date('birthday', \Carbon\Carbon::now()) !!} <br> {!! Form::label('phone', 'Telefon') !!} {!! Form::text('phone', '', ['id' => 'phone']) !!} <br> {!! Form::label('country', 'Land') !!} {!! Form::select('country', $countries, 0) !!} <br> {!! Form::submit('Speichern') !!} {!! Form::close() !!}

3.2017 www.webundmobile.de


PHP

BaCKEnD

soll, mit Hilfe der Klasse Carbon übergeWerfen wir zunächst einen Blick auf ben werden muss, die Laravel mitbringt. die Arbeit mit Eloquent. Um das GrundEine Dokumentation zu Carbon finden gerüst des Models generieren zu lassen Sie unter der Adresse http://carbon.nes können Sie php artisan make:model bot.com. KundenModel auf der Kommandozeile Erwähnenswert ist auch die Optionseintippen. liste, die als vorletztes Element hinzugeNachfolgend sehen Sie den generierfügt wird. Die Optionen werden hierbei ten Code, den ich schon um den Namen als zweiter Parameter in Form eines Arder Datenbanktabelle ergänzt habe: rays übergeben. Die Variable $countries Das Formular in Google Chrome (Bild 6) namespace App; habe ich dabei nach dem bereits beuse kannten Schema aus dem Controller Illuminate\Database\Eloquent\Model; übergeben. Der dritte Wert legt in dieclass KundenModel extends Model sem Fall fest, welches Array-Element als { Default-Wert dargestellt werden soll. protected $table = 'kunden'; In Bild 6 und Bild 7 sehen Sie die Dar} stellung des Formulars in Google Chrome und Firefox unter macOS. Zusätzlich könnten Sie hier noch einen In Chrome wird ein schickes DatumsPrimärschlüssel mit Hilfe der Eigenschaft feld mit Date-Picker dargestellt, was in $primaryKey festlegen. In diesem Fall Firefox leider nicht funktioniert. Das liegt daran, dass Laravel kein JavaScript ein- Das Formular im Firefox-Browser (Bild 7) geht Eloquent davon aus, dass die Spalte id der Primärschlüssel ist. Die Tabelle, bindet, um das Feld zu generieren, sondie ich nutze, ist in Listing 2 deklariert. dern einfach auf HTML5-Elemente setzt. Falls Sie sich gerade über die beiden Spalten created_at Die komplette Dokumentation zum Umgang mit Formulaund updated_at wundern: Die beiden werden standardmäßig ren in Laravel finden Sie auf https://laravelcollective.com/ automatisch von Eloquent befüllt, sodass Sie sich nicht darum docs/5.3/html. kümmern müssen, zu protokollieren, wann Daten gespeiab in die Datenbank chert oder geändert wurden. Sagt Ihnen dieses Feature nicht Schicken Sie das Formular jetzt ab, erhalten Sie eine Fehlerzu, dann können Sie im Model die folgende Zeile hinzufügen, meldung, weil die Route nicht existiert. Bisher habe ich nämum es abzuschalten: lich nur eine Route für die GET-Methode angelegt. Zwar würpublic $timestamps = false; de der URL der neuen Route dem URL der bestehenden Route entsprechen, aber es handelt sich um einen POST-Request. Die Methode, die ich im Controller ergänzt habe, ist sehr simNatürlich wäre es auch möglich, beide Methoden mit derselpel aufgebaut. Sie liest einfach nur die Daten aus und überben Route zu behandeln, aber dann müsste ich in der Methogibt sie an das Model, das sie dann speichert (Listing 3). de unterscheiden, ob das Formular ausgegeben werden soll Die Methode bekommt das Request-Objekt übergeben. oder die Daten gespeichert werden sollen. Zunächst ergänze Somit kann ich die Daten direkt auslesen und dem Model zuich also die folgende Route: weisen. Die View, die ich am Schluss nutze, ist einfach nur ei▶ Route::post('data/input' , 'DataController@save'); ne statische HTML-Datei. Wie Sie hier sehen können, wird bei Aufruf dieser Route eine andere Methode aufgerufen. Bevor ich nun aber zum Controller komme, stellt sich noch die Frage, wie Sie überhaupt auf die Datenbank zugreifen können. Dazu bietet Laravel mehrere Ansätze. Mit Eloquent steht Ihnen ein ORM-Layer zur Verfügung. Damit können Sie für jede Datenbanktabelle ein eigenes Model erstellen, über das Sie mit der Tabelle kommunizieren. Alternativ können Sie den Query Builder einsetzen, und zu guter Letzt können Sie auch direkt mit SQL-Code arbeiten, was gerade bei komplexeren Abfragen oft die einfachere Variante ist. Die Konfigurationsdaten für den Zugriff auf die Datenbank werden in der Datei config/database.php hinterlegt. Überarbeiten Sie das dort vorhandene Array einfach so, dass es Ihren Anforderungen entspricht.

www.webundmobile.de 3.2017

Listing 2: Beispieltabelle CREATE TABLE 'kunden' ( 'id' int(11) NOT NULL AUTO_INCREMENT, 'name' varchar(200) NOT NULL DEFAULT '', 'birthday' date NOT NULL DEFAULT '1981-1-1', 'phone' varchar(200) NOT NULL DEFAULT '', 'country' int(11) NOT NULL DEFAULT '0', 'created_at' datetime DEFAULT NULL, 'updated_at' datetime DEFAULT NULL, PRIMARY KEY (`id`) );

91


BaCKEnD

PHP

Der Query Builder Alternativ möchte ich Ihnen noch kurz die Nutzung des Query Builders vorstellen. Das Auslesen der Daten aus dem Request-Objekt funktioniert natürlich genauso, weswegen ich hier auf diesen Teil der Methode verzichtet habe:

Die einfachste Variante, um alle Daten auszulesen, ist die statische Methode all(), die in allen Eloquent-Models bekannt ist. Ohne Parameter liefert sie Ihnen den kompletten Inhalt der Tabelle zurück: So erfolgt die ausgabe der Daten der Anwendung (Bild 8)

public function show() { $data = KundenModel::all();

public function save(Request

return view ('show', ['data' =>

$request) { // Wie vorher

$data]); }

DB::table('kunden')->insert( ['name' => $name, 'birthday' => $birthday, 'phone' => $phone,

In der View können Sie die Daten nun mit einer @foreachSchleife ausgeben lassen. Nachfolgend sehen Sie den relevanten Teil der View (Bild 8):

'country' => $country] <body>

); return view ('save');

<table> <tr>

}

<td>Name</td>

Zusätzlich muss noch die folgende use-Anweisung ergänzt werden:

<td>Geburtstag</td> <td>Telefon</td> </tr>

use Illuminate\Support\Facades\DB;

@foreach($data as $set) <tr>

Im Unterschied zu Eloquent füllt der Query Builder nicht die beiden Spalten mit den Zeitstempeln aus. Sollte das für Sie wichtig sein, dann müssen Sie es manuell implementieren. Um sicherzustellen, dass es beim Speichern der Werte nicht zu Problemen kommt, arbeitet der Query Builder mit Prepared Statements. Natürlich können Sie die Daten mit diesen Mitteln auch wieder auslesen. Sobald die neue Route angelegt ist, können Sie im Controller eine neue Methode zum Auslesen und Anzeigen der Daten implementieren.

<td>{{ $set->name }}</td> <td>{{ $set->birthday }}</td> <td>{{ $set->phone }}</td> </tr> @endforeach </table> </body>

Damit sind Sie mit den Grundlagen von Laravel vertraut. Aber Laravel kennt natürlich noch einige Besonderheiten. Ei-

Listing 3: Daten auslesen public function save(Request $request) {

Links zum Thema

Allgemeine Beschreibung des MVC-Musters https://de.wikipedia.org/wiki/Model_View_Controller

Laravel-Homepage www.laravel.com

Vagrant zum Konvertieren von virtuellen Maschinen https://www.vagrantup.com

Virtual Box https://www.virtualbox.org

VMware www.vmware.com

Parallels https://www.parallels.com

Composer https://getcomposer.org

$name = $request->input('name', ''); $birthday = $request->input('birthday', ''); $phone = $request->input('phone', ''); $country = $request->input('country', ''); // Daten zuweisen $tabelle = new KundenModel(); $tabelle->name = $name; $tabelle->birthday = $birthday; $tabelle->phone = $phone; $tabelle->country = $country; // Daten speichern $tabelle->save(); return view ('save'); }

92

3.2017 www.webundmobile.de


PHP

BaCKEnD

namespace App\Http\Middleware; use Closure; class IpCheck { public function handle($request, Closure $next) { return $next($request);

übersicht über die bekannten Routen (Bild 9)

} }

ne davon ist die Möglichkeit, mit Middleware zu arbeiten. Eine Middleware bei Laravel ist ein Software-Layer, der vor beziehungsweise nach dem Controller ausgeführt werden kann. Es handelt sich also nicht um eine Middleware im Sinne des PSR-7-Standards, der ja momentan in aller Munde ist. Wozu aber ein Software Layer, der vor oder nach dem Controller ausgeführt wird? Die Idee ist recht einfach. Stellen Sie sich beispielsweise vor, dass Sie einen geschützten Bereich haben, auf den nur authentifizierte User zugreifen dürfen. Bei den meisten Frameworks müssen Sie dann im Controller eine Methode implementieren, die immer aufgerufen wird, um die Authentifizierung zu prüfen. Das macht den Code aber nicht unbedingt besser lesbar und man vergisst es auch schnell einmal, die Methode aufzurufen. Alternativ kann man eine solche Methode natürlich auch in den Konstruktor oder eine Basisklasse auslagern. Aber auch das ist auch nicht immer ideal.

Die Methode handle() bekommt das Request-Objekt und den Pointer auf die nächste Funktion beziehungsweise Methode übergeben. Durch das return $next($request) ist sichergestellt, dass die Referenz auf die nächste Methode ($next), also typischerweise die Methode des Controllers, aufgerufen wird und das Request-Objekt weitergegeben wird. Dadurch, dass die Methode das komplette Objekt übergeben bekommt, können natürlich auch Werte aus Formularen gefiltert oder validiert werden. Um die IP-Adresse des Clients zu prüfen, habe ich die Methode handle() um ein paar Zeilen ergänzt: public function handle($request, Closure $next) { if ($request->getClientIp() != '127.0.0.1' && // IPv4 $request->getClientIp() != '::1')

return redirect()->action('DataController@input');

Middleware Eine Middleware schafft da Abhilfe. Sie ist komplett autonom und bekommt das Request-Objekt übergeben, bevor es an den Controller weitergegeben wird. Eine Middleware wird bei der Deklaration der Route mit angegeben. Somit ist auch ein hohes Maß an Transparenz gewährleistet. Eine komplette Benutzerverwaltung würde leider den Rahmen des Artikels sprengen. Daher möchte ich hier nur eine kleine Middleware implementieren, die das Speichern von Daten nur zulässt, wenn die IP des Users der 127.0.0.1 entspricht. Natürlich können Sie die Middleware auch manuell anlegen, aber es ist einfacher, artisan zu nutzen:

// IPv6

{ } return $next($request); }

In der if-Abfrage wird in der IPv4- und IPv6-Variante geprüft, ob der Aufruf vom localhost stammt. Ist das nicht der Fall, dann erfolgt eine Weiterleitung auf die Methode input() des DataControllers. Diese Vorgehensweise ist für eine echte Anwendung zwar nicht zu empfehlen, hier aber ausreichend. Nun muss die Middleware noch angemeldet werden. Dazu wird sie zunächst in der Datei app/Http/Kernel.php registriert. Das geschieht dadurch, dass Sie im Array $routeMiddleware noch die Zeile

php artisan make:middleware IpCheck 'ip.check' => \App\Http\Middleware\IpCheck::class,

Die neue Klasse legt artisan dann in app/Http/Middleware ab, und sie sieht so aus:

Auf die richtige Version achten Wie schon erwähnt, benötigt Laravel 5.3 mindestens PHP 5.6.4. Sollte Ihr PHP-CLI in einer vorhergehenden Version vorliegen, dann installiert der Installer Version 5.2 von Laravel. Bitte prüfen Sie also vor der Installation mit php –v, welche Version Ihr CLI hat, oder achten Sie bei der Installation darauf, welche Version installiert wird.

www.webundmobile.de 3.2017

ergänzen. Damit kennt die Anwendung den Shortcut ip. check, der die Middleware referenziert. Nun muss sie nur noch der Route zugewiesen werden: Route::post('data/input' , 'DataController@save')-> middleware('ip.check');

Sobald das geschehen ist, prüft die Middleware vor jedem Speichern der Daten die IP des Clients. Ein wirklich einfaches, gutes System, wie ich finde. Sie können der Methode middleware() übrigens auch mehrere Middlewares übergeben, die dann nacheinander abgear- ▶

93


BaCKEnD

PHP

beitet werden. Und bevor ich es vergesse: Eine Middleware kann auch nach dem Ausführen einer Methode noch eine Aufgabe übernehmen. Wollen Sie also beispielsweise nach jeder Aktion, die ausgeführt wurde, temporäre Daten löschen oder Ähnliches, dann können Sie das auf diesem Weg machen. In dem Fall müsste die Methode handle() nur etwas anders aussehen:

Die anwendung im Wartungsmodus (Bild 11)

Zu guter Letzt möchte ich noch auf ein Problem eingehen, das immer wieder auftaucht. Wenn Ihre Anwendung regelmäßig bestimmte Aufgaben erfüllen soll, dann können Sie das mit Hilfe eines Cron-Jobs erledigen. Sind Sie aber nicht der Server-Administrator, dann sind Sie ständig darauf angewiesen, dass er Ihren Cron-Job einträgt oder ändert. Abhilfe schafft da php artisan schedule:run. Diesen Befehl gibt man eigentlich nicht direkt auf der Kommandozeile ein. Er wird üblicherweise als Cron-Job ausgeführt, indem die folgende Zeile in der crontab ergänzt wird:

Ein paar Zitate von artisan inspire (Bild 10)

* * * * * php /pfad/artisan

public function handle($request, Closure $next) { $response = $next($request); // Vorhergenden Code ausführen // Temporäre Dateien l̈schen

schedule:run >> /dev/null 2>&1

return $response; }

Sehr praktisch, wie ich finde – und sollten Sie Sorge haben, dass die web.php irgendwann zu undurchschaubar wird, können Sie sich mit php artisan route:list eine Übersicht der bekannten Routen ausgeben lassen, ohne den Code analysieren zu müssen (Bild 9).

Maintenance Mode mit artisan Den Befehl artisan haben Sie ja nun schon in einigen Zusammenhängen getroffen. Der Befehl kennt aber noch eine ganze Menge mehr Möglichkeiten, die ich hier nicht komplett vorstellen kann. Auf ein paar Kleinigkeiten möchte ich aber noch eingehen. Kommen Sie bei der Entwicklung Ihrer Applikation einmal gerade nicht weiter, dann ist php artisan inspire vielleicht hilfreich. Damit wird ein inspirierendes Zitat ausgegeben. Sicher nicht unbedingt das wichtigste Feature eines Frameworks, aber mal ganz nett (Bild 10). Vielleicht kennen Sie das auch: Sie wollen bei einer Anwendung, die live ist, ein Update einspielen. Dummerweise hat aber niemand daran gedacht, einen Wartungsmodus zu implementieren, damit die Applikation auch einmal offline geschaltet werden kann. Also versucht man mitten in der Nacht oder am Wochenende sein Glück und hofft, dass kein User verprellt wird. Laravel bringt hier schon von Haus aus eine Lösung mit: php artisan down schaltet die Anwendung in einen Maintenance Mode, und dem User wird eine entsprechende Meldung ausgegeben (Bild 11). Für eine Änderung der ausgegebenen Meldung ist übrigens nicht der Parameter --message zuständig. Der legt nur fest, welche Information im Logfile gespeichert wird. Möchten Sie die Meldung für die Nutzer ändern, dann müssen Sie das Template 503.blade.php in resources/views/errors überarbeiten. Mit php artisan up schalten Sie die Anwendung übrigens wieder live.

94

Damit wird Laravels Scheduler jede Minute ausgeführt. In Ihrer Applikation können Sie nun Aufgaben registrieren, die mit einer bestimmten Regelmäßigkeit ausgeführt werden. Dazu sieht Laravel ein recht einfaches Interface vor, das Methoden wie daily(), weekly() oder monthly() bereitstellt. Auf diesem Weg können Sie Ihre Cron-Jobs aus der Anwendung heraus verwalten und müssen nicht jedes Mal den Server-Administrator bemühen. Weitere Informationen zum Scheduler finden Sie unter https://laravel.com/docs/5.3/scheduling.

Fazit In einem solchen Artikel kann ein so mächtiges Framework natürlich nicht komplett vorgestellt werden, und daher musste ich eine ganze Menge Dinge unterschlagen. So schreibt Laravel automatisch ein Log, kennt einen Debug-Modus, bringt eine fertige User-Authentifizierung mit, hat vue.js als JavaScript-Bibliothek an Bord und vieles mehr. Laravel ist an vielen Stellen erfrischend anders als die Konkurrenten. Die Entwickler hinterfragen Dinge, die von anderen Frameworks als Dogma übernommen werden, und machen sie anders und meiner Ansicht nach oft besser. Laravel ist schnell zu erlernen, klar strukturiert und lösungsorientiert. Besonders positiv finde ich, dass Laravel im Vergleich zu anderen Frameworks einfach ein Stück weit bodenständiger und nicht so akademisch abgehoben ist. ◾

Carsten Möhrke arbeitet seit 15 Jahren professionell im EDV-Umfeld. Er ist Inhaber der netviser Internet Beratung e.K. und als Internet-Programmierer, Dozent sowie Consultant tätig. www.netviser.de

3.2017 www.webundmobile.de


Tr

T

aining

s

Updates für Ihr Know-How „Fortschritt heißt für mich vor allem, dass man fortschreiten will!“ Johannes Hoppe IT-Berater, Programmierer, Webdesigner

Cross-PlattformApps mit C# und Xamarin

Apps in Windopws 8/10 entwickeln

Trainer: Sebastian Seidel

2 Tage, 04.-05.05.2017, Köln Ab EUR 1.799,- zzgl. MwSt.

Trainer: Lars Heinrich

3 Tage, 25.-27.04.2017, München Ab EUR 2.199,- zzgl. MwSt.

Angular 2 mit TypeScript 2

Software testen im Java-Umfeld

Trainer: Johannes Hoppe

Trainer: Carsten Negrini

3 Tage, 08.-10.05.2017, München Ab EUR 2.199,- zzgl. MwSt.

3 Tage, 10.-12.05.2017, Köln Ab EUR 2.199,- zzgl. MwSt.

Ihr Ansprechpartner: Fernando Schneider – developer media Telefon: +49 (0)89 74117-831 – E-Mail: fernando.schneider@developer-media.de

developer-media.de/trainings


BaCKEnD

DevOps

DEVOPS In DER PRaXIS (TEIL 2)

DevOps-Dienste in der Cloud Microservices und Container-Plattformen haben die Software-Entwicklung um Fähigkeiten zur kontinuierlichen Bereitstellung erweitert.

D

ie Prozesse der Entwicklung (Dev) und der Bereitstellung (Ops) von Software müssen in modernen Unternehmen parallel zueinander und möglichst reibungslos ablaufen. Dieser neue Ansatz wurde auf den Namen DevOps getauft. DevOps vereint Continuous Integration (CI), Continuous Delivery (CD) und Continuous Deployment (CD) von Softwarecode zu einem System kontinuierlicher Codeverbesserung. Bei DevOps unter Gewährleistung kontinuierlicher Cyber-Sicherheit spricht man von DevSecOps (siehe Kasten). Nirgendwo ist dieses Ziel so wichtig wie in der Cloud.

Infrastruktur in Code erfasst Die führenden Cloud-Anbieter haben in dem Dev(Sec)OpsTrend eine Gelegenheit erkannt, Entwicklern neuartige, spezialisierte Dienste zu bieten, die speziell auf das neue Zeitalter zugeschnitten sind. Viele Unternehmen nutzen inzwischen bereits diverse Software-, Plattform- und Infrastrukturdienste des einen oder anderen Cloud-Anbieters, um die Agilität der hauseigenen ITAbteilung zu erhöhen, die Kosten der Software-Entwicklung und -Bereitstellung zu senken, die Kapitalbindung (dank Pay-as-you-go) zu minimieren, die Entwicklungszyklen von Software zu reduzieren und ihre Anwendungen nach der Bereitstellung bedarfsgerechter skalieren zu können. Doch sind

DevOps versus DevSecOps Der Begriff DevOps beschreibt einen Prozessverbesserungsansatz in den Bereichen der Software-Entwicklung (Dev) und -Bereitstellung (Ops). Das DevOps-Modell setzt auf kontinuierlichen Fluss von CodeVerbesserungen von der Planung bis hin zur Bereitstellung und Wartung. Die unmittelbare Bereitstellung von neuem Code gemäß dem DevOps-Paradigma hat ein neues Problem auf den Plan gerufen: die Sicherheit unternehmenskritischer Systeme. Die Antwort auf diese Herausforderung taufte die Industrie auf den Namen SecOps.

diese Deployments vergleichsweise portabel, und zwar sowohl zwischen On-Premise-Umgebungen als auch von Cloud zu Cloud. Den Anbietern der Infrastrukturdienste ist diese Mobilität ein Dorn im Auge. Binnen nur weniger Jahre haben Container-Frameworks wie Docker und Lösungen wie Vagrant den Ablauf der Software-Entwicklung (Dev) und -Bereitstellung (Ops) in Unternehmen grundlegend umgekrempelt und die Migration von Webanwendungen in die Cloud beschleunigt. Die Bereitstellung von Webanwendungen in Containern hatte aber auch einen anderen Effekt zur Folge: Sie hat zu einer erhöhten Portabilität von Anwendungen zwischen öffentlichen und privaten Clouds sowie On-Premise-Umgebungen geführt. Diese Portabilität von Anwendungen wird durch Initiativen der DevOps-Gemeinde wie das AppC-Projekt zusätzlich noch gefördert. Cloud-Betreiber wie Amazon mit AWS, Microsoft mit Azure, Google mit der Compute Engine oder IBM mit Bluemix DevOps Services buhlen um die Gunst der Entwickler mit neu erfunden: In seiner Keynote auf der diesjährigen AWS re:Invent in Las Vegas stellte spezialisierten Softwarediensten. Amazons CTO unter anderem 13 neue Dienste vor (Bild 1) Diese Cloud-Dienste bieten einen

96

3.2017 www.webundmobile.de


DevOps

aWS re:Invent 2016 in Las Vegas

Microservices auf der Basis von visuell konfigurierbaren Schritt-für-Schritt-Workflows zu erstellen, Lambda@Edge: ein Dienst, der es Entwicklern ermöglicht, JavaScript-Code zur Ausführung auf Edge-Servern von Amazon CloudFront zu schreiben, ohne die Notwendigkeit, diese Server zu provisionieren und zu administrieren, Blox: eine Sammlung von quelloffenen Tools für die Orchestrierung und Verwaltung von Docker-Containern auf Amazon ECS, aWS Personal Health Dashboard: Amazons Benachrichtigungen über Dienststörungen und -Ausfälle. Amazon möchte Unternehmen die mühsame Administration der Infrastruktur weitgehend abnehmen. Dies wird auch an Diensten wie AWS CodeBuild offensichtlich (einem Ersatz für konventionelle Build-Server). Wenn es nach Amazon ginge, würde die Administration von Servern und Diensten zugunsten der Entwicklung von Cloud-Lösungen und mobilen Apps komplett entfallen. Der Schwerpunkt bei den Cloud-Benut-

Auf der AWS re:Invent im November 2016 in Las Vegas legte der führende Cloud-Anbieter Amazon mit der Vorstellung von dreizehn neuen Diensten ein halsbrecherisches DevOpsInnovationstempo an den Tag. Zu den neu vorgestellten Lösungen zählen: aWS CodeBuild: ein verwalteter BuildDienst für Android, Java, Python, Ruby, Go, Node.js und Docker mit Unterstützung für GitHub, AWS CodeCommit, S3-Buckets und andere Source-Repositories, aWS OpsWorks für Chef automate: AWS OpsWorks mit Unterstützung für Chefs neue Lösung, Automate, amazon EC2 Systems Manager: ein Dienst zum Inventarisieren installierter Software auf EC2-Instanzen und auf Hosts in On-Premise-Umgebungen (Windows und Linux) mit Fähigkeiten zum Aufspielen von Punktgenau: Amazon Pinpoint identifiziert potenzielle Stolperfallen der Usability mobiler Aktualisierungen für eine verein- Apps sowie beliebte und unbeliebte Features dank der Datenanalyse in Echtzeit (Bild 2) fachte Einhaltung von ComplianceRichtlinien, aWS X-Ray: ein verwalteter Dienst zum Analysieren und Dezern verschiebt sich klar weg von der reinen Administration buggen von Applikationen durch Tracing, hin zur Software-Entwicklung. Für die Entwickler von Soft aWS Shield: ein vollständig verwalteter Dienst zum Schutz ware entsteht so ein Bedarf an neuen Kompetenzen im Bevon Webanwendungen vor DDoS-Attacken, reich der Cloud und Cyber-Sicherheit. amazon Pinpoint: ein Dienst für die Echtzeit-Analyse des BeAngesichts der meist angespannten Arbeitsverhältnisse nutzerengagements in mobilen Apps mit dem Ziel, Usabizwischen der Dev- und der Ops-Abteilung in vielen Unterlity-Hindernissen und anderen ähnlichen Problemen auf nehmen würde der eine oder andere Entwickler die De-facdie Spur zu kommen (Bild 2), to-Abschaffung der Ops-Abteilung möglicherweise sogar be aWS Glue: ein vollständig verwalteter ETL-Dienst für die grüßen. Doch ganz so einfach ist es nicht: Ein gewisses Maß automatisierte Handhabung von massiven Datenbeständen an Ops-Kompetenz ist auch im Cloud-Zeitalter unverzichtmit Fähigkeiten zum Konvertieren von Daten und zum bar. Mappen von verschiedenen Datenquellen aufeinander, aWS Batch: ein Dienst zum Durchführen von massiven StaDevOps-Workflows auf aWS Die AWS re:Invent 2016 in Las Vegas hat Amazon mit AWS pelverarbeitungsjobs (zum Beispiel im Rahmen der Datenals den weiterhin unangefochtenen Marktführer von cloudanalyse) ohne die Notwendigkeit, EC2-Instanzen zu verbasierten DevOps-Workflows in seiner Position bestätigt. walten, aWS Step Functions: ein Dienst für Entwickler, der es ermögAWS stellt den Entwicklern von Web- und mobiler Software licht, verteilte, automatisch skalierende Anwendungen und eine ganze Sammlung von DevOps-Tools und -Diensten ▶

www.webundmobile.de 3.2017

97

Quelle: Amazon

klaren Mehrwert, indem sie eine vollständig verwaltete Alternative zu rein quelloffenen Lösungen darstellen, die sich ansonsten auf dem Unterbau klassischer Infrastrukturdienste eines beliebigen Anbieters aufsetzen lassen. Diese CloudDienste sind unter anderem darauf ausgelegt, die langfristige Bindung der betroffenen Entwickler an das eigene Ökosystem des jeweiligen Cloud-Betreibers zu maximieren. Cloud-Anbieter sehen in der Portabilität von ContainerAnwendungen offenbar eine Bedrohung ihrer langfristigen Rentabilität. Dies war unter anderem auf Amazons jährlicher Konferenz AWS re:Invent in Las Vegas nicht zu übersehen (Bild 1). Amazon versucht, die Software-Entwickler unter seinen Benutzern auf Biegen und Brechen für neue, hochspezialisierte verwaltete Dienste zu gewinnen.

BaCKEnD


BaCKEnD

DevOps

zur Verfügung, die sich sowohl mit Amazons übrigen CloudDiensten als auch zum Teil mit konventionellen On-PremiseUmgebungen (etwa mit On-Premise-Jenkins-Installationen) und externen Diensten (etwa GitHub) integrieren lassen. AWS bietet inzwischen auch rein proprietäre und vollständig verwaltete DevOps-Dienste. Damit Coder und Administratoren in einem cloudbasierten DevOps-Workflow im Gleichschritt miteinander arbeiten können, müssen sie die verschiedenen AWS-Bauteile geschickt aneinander anbinden. Als die wichtigsten Stützpfeiler von DevOps-Workflows auf AWS gelten folgende Dienste: CodeCommit: ein Cloud-Dienst für die Versionskontrolle in privaten Repositories, CodePipeline: ein Cloud-Dienst für die kontinuierliche Bereitstellung und Release-Automatisierung, CodeDeploy: ein Cloud-Dienst zur Automatisierung der Übergabe von Code an eine beliebige Serverinstanz (sowohl On-Premise als auch in AWS EC2). Bereits mit Hilfe dieser drei Dienste lässt sich eine vollständige CI/CD-Pipeline (mit oder auch ohne Jenkins) auf AWS implementieren. Seit der AWS re:Invent kam auch noch AWS Code Build hinzu. Der Dienst CodeCommit stellt Entwicklern ein privates, vollständig verwaltetes und automatisch skalierendes Git-Repository mit Unterstützung für AWS-Identitäts- und AWS-Zugriffsmanagementdienste bereit. Der Dienst verwaltet sowohl öffentliche als auch private Repositories und ist auch bei den Letzteren – anders als GitHub – für die ersten fünf Entwickler rein kostenfrei. CodeCommit ist in der EU derzeit nur in der Region eu-west-1 verfügbar. Bei AWS CodePipeline handelt es sich um einen verwalteten Continuous-Delivery-Dienst (CD), der es erlaubt, den

Listing 1: buildspec.yml ... pre_build: commands: - echo Logging in to Docker Hub... - docker login --username="$DOCKER_HUB_USERNAME" -password="$DOCKER_HUB_PASSWORD" build: commands: - echo Build started on 'date' - echo Building the Docker image... - docker build -t $IMAGE_REPO_NAME:$IMAGE_TAG . - docker tag $IMAGE_REPO_NAME:$IMAGE_TAG $IMAGE_REPO_NAME:$IMAGE_TAG post_build: commands: - echo Build completed on `date` - echo Pushing the Docker image... - docker push $IMAGE_REPO_NAME:$IMAGE_TAG ...

98

Integral: CodeBuild integriert sich in den Build-Schritt der AWS Pipeline (Bild 3)

Softwarebereitstellungsprozess in der Cloud nachzubilden und zu orchestrieren. CodePipeline orchestriert jede Phase der Bereitstellung: Der Dienst befragt ein VersionskontrollRepository nach Code-Änderungen, sendet diese durch automatisierte Build- und Test-Zwischenstufen der Bereitstellungspipeline und initiiert anschließend den Release-Vorgang. In jeder Zwischenstufe lassen sich Werkzeuge von Drittanbietern hinzuschalten.

Elastic Compute Cloud Sie können CodeDeploy an eine CI/CD-Pipeline anbinden, um den resultierenden Anwendungscode auf Servern zu installieren. Dazu wird lediglich ein sogenannter Agent benötigt, der sowohl auf Elastic-Compute-Cloud-Instanzen (EC2) als auch auf On-Premise-Servern laufen darf. Wann immer sich neuer Code durch die Bereitstellungspipeline durcharbeitet, übernimmt CodePipeline die Ausgabe vom Buildprozess und übergibt diese zur Installation und Ausführung auf den Applikationsservern an CodeDeploy. AWS CodeBuild lässt sich unter anderem direkt in die Build-Stufe einer AWS CodePipeline integrieren, aber auch via AWS Management Console, über das AWS CLI, über ein HTTP-API und nicht zuletzt auch unter Verwendung von AWS SDKs ansprechen. Quellen für AWS CodeBuild können auf GitHub oder in Amazons Objektspeicher AWS EC3 liegen, aber auch via AWS CodeCommit bereitgestellt werden. Die unterstützten Sprachen beinhalten neben Python und Ruby unter anderem auch Node.js und Scala. Eine Übergabe der resultierenden Artefakte ist unter anderem an Amazon ECR, an Docker Hub (Listing 1) und an AWS Elastic Beanstalk (zum Beispiel unter Verwendung von Apache Maven) möglich. Die Dienste AWS Elastic Beanstalk (ein Anwendungscontainer für die beliebtesten Stacks) und AWS OpsWorks unterstützen die kontinuierliche Bereitstellung von Code- und Infrastruktur-Änderungen auf AWS. AWS Elastic Beanstalk reduziert die Komplexität durch eine automatische Handhabung der Kapazitätenbereitstellung, horizontale Skalierung, Lastverteilung und einen

3.2017 www.webundmobile.de


DevOps

BaCKEnD

DevOps in der Wolke: Beispiel eines Jenkins-Deployments auf Amazon AWS (Bild 4)

git push und fertig: Bereitstellung von containerisierten Anwendungen mittels Jenkins auf AWS ECS (Bild 5)

Health Check Ihrer Anwendungen. Der Dienst verwaltet die verschiedenen Versionen der betreffenden Applikation und diverse Varianten der Konfiguration der Infrastruktur, um Rollbacks zu gewährleisten. Darüber hinaus arbeitet der Dienst Hand in Hand mit Auto-Scaling-Gruppen zusammen, um die Hochverfügbarkeit Ihrer Webapplikation beim Versionswechsel zu gewährleisten. Beim Einsatz von AWS OpsWorks können Sie festlegen, welche Instanzen in welcher Reihenfolge aktualisiert werden sollen. AWS OpsWorks kann außerdem zusätzliche Befehle und Chef-Rezepte zur Laufzeit ausführen.

ein JSON-Dokument, das die Zusammenstellung der benötigten Ressourcen durch den Dienst CloudFormation ermöglicht. Um ein neues Repository mit Hilfe von AWS-CodeCommit zu erstellen, können Sie wahlweise das AWS CLI oder die AWS Konsole für CodeCommit (Bild 3) verwenden. Zum jetzigen Zeitpunkt haben Sie bei der Wahl der AWS-Regionen aber leider keine wirkliche Auswahl, denn Sie müssen bisher mit der Region EU (Ireland) oder mit der US-amerikanischen Ostküste (Region North Virginia oder Region Ohio) Vorlieb nehmen. In der deutschen Region Frankfurt wird der Dienst derzeit leider noch nicht unterstützt. Mit dem Befehl aws configure können Sie die Region überprüfen und gegebenenfalls anpassen. Die eigentliche Erstellung eines AWS CodeCommit-Repositorys mit den AWSTools ist ein Einzeiler:

asynchrone Updates Die Praxis asynchroner Updates wurde in der DevOps-Gemeinde auf den Namen rollendes Deployment (rolling deployment) getauft: Aktualisierungen einer Webanwendung werden nicht auf alle Instanzen gleichzeitig, sondern auf eine Instanz nach der anderen eingespielt; so lässt sich die kontinuierliche Betriebsbereitschaft einer gewissen Anzahl von Servern gewährleisten und jegliche Ausfallzeiten der eigenen Dienste verhindern. Die eigentliche Bereitstellung der benötigten InfrastrukturBauteile auf AWS erfolgt typischerweise unter Verwendung einer CloudFormation-Vorlage. Hierbei handelt es sich um

Listing 2: AWS CodeCommit { "repositoryMetadata": { "repositoryName": "neuesRepository", "repositoryDescription": "Kurzbeschreibung in HTML- oder Unicode-Zeichen", "repositoryId": "f3559e23-b31e-7523-aaef-950c0BEISPIEL", "accountId": "Ihre-Account-ID" } }

www.webundmobile.de 3.2017

aws codecommit create-repository --repository-name neuesRepository --repository-description "Kurzbeschreibung in HTML- oder Unicode-Zeichen"

Im Erfolgsfall gibt der Befehl ein repositoryMetadata-Objekt zurück (Listing 2). Sie können sich mit dem neuen Repository unmittelbar verbinden (wahlweise via SSH oder HTTPS) und Ihren Code committen sowie das Repository an die AWS CodePipeline anbinden. Mit Amazons proprietären AWS-Diensten CodeCommit, CodePipeline, Elastic Beanstalk, CodeDeploy und Cloud Formation erschöpft sich bei Weitem nicht das überaus vielfältige Repertoire von DevOps-Lösungen auf AWS. Eingeschworene Befürworter von Jenkins-zentrierten Workflows brauchen beim Einsatz von AWS auf ihre bevorzugte Lösung keinesfalls zu verzichten. Ganz im Gegenteil: Zahlreiche Jenkins-Plug-ins wurden mit dem Ziel entwickelt, DevOps auf AWS zu ermöglichen. Im Amazon Marketplace nehmen Jenkins-AMIs (Amazon Machine Images) einen prominenten Platz ein. Jenkins kommt auf AWS in zwei grundlegenden Einsatz▶ szenarien zum Einsatz:

99


BaCKEnD

DevOps

in Amazon EC2: Serverinstanzen mit Netzwerkspeicher (Bild 4), Container im Rahmen von Amazon ECS: verwaltete Docker-Container auf EC2-Clustern (Bild 5).

aWS Elastic Beanstalk: Bereitstellen und Skalieren von Java-, .NET-, PHP-, Node.js-, Python-, Ruby-, Go-Anwendungen und Docker-Containern auf NGINX-, Apache-, IIS- und Passenger-Servern.

Das Jenkins-Ökosystem unterstützt unter anderem die folgenden AWS-Dienste unter Verwendung von Jenkins-Plugins: amazon EC2 (Elastic Compute Cloud): Ausführung von beliebigen Serverinstanzen in virtuellen Maschinen, amazon ECR (Docker Container Registry): Speichern, Verwalten und Bereitstellen von Docker-Containern, amazon SnS (Simple notification Service): Versenden von Push-Benachrichtigungen, amazon ECS (EC2 Container Service): Ausführen von containerisierten Applikationen in Produktionsumgebungen, amazon S3 (Simple Storage Service): Aufbewahren von Daten im verwalteten Objektspeicher, aWS CloudFormation: Infrastrukturvorlagenverwaltung, aWS CodeDeploy: Automatisierung der Bereitstellung von Code, aWS CodePipeline: Code-Bereitstellung und Release-Automatisierung, aWS CodeCommit: Versionskontrolle in privaten oder öffentlichen Repositories, aWS Device Farm: Testen von mobilen Anwendungen auf mehreren Zielgeräten gleichzeitig,

Microsoft Azure und die Google Cloud Platform haben im Vergleich zu dem DevOps-as-a-Service-Platzhirsch AWS noch einen großen Nachholbedarf.

DevOps auf Microsoft azure Microsofts Aufholjagd in Sachen DevOps hat beim CloudRiesen ein umfassendes Umdenken ausgelöst. Nicht nur hat sich Microsoft entschieden, die eigene Cloud Azure für Linux zu öffnen, um den Betrieb von quelloffenen Lösungen wie Docker zu ermöglichen, sondern die Redmonder haben auch die hauseigenen Entwicklungswerkzeuge um die Unterstützung relevanter Technologien ausgebaut, das Betriebssystem Windows Server Container-fähig gemacht und die Datenbank SQL Server auf Linux portiert. Bereits mit der Ankündigung von Windows Server Containern, verschachtelbaren Hyper-V-Containern in Windows Server 2016 und dem Nano Server, einer leichtgewichtigen Windows-Variante, sorgte Microsoft seinerzeit für viel Aufregung. Docker läuft unter Windows Server 2016 auf einer virtualisierten Linux-Schicht in einer VM oder nativ auf Microsofts Hyper-V-Hypervisor (ohne eine virtuelle Maschine). Software-Entwickler auf Azure kommen zudem in den Ge-

Vagrant versus Docker Container-Frameworks wie Docker erleichtern die Bereitstellung von anwendungen und verbessern die auslastung der vorhandenen Hardware. Inzwischen sind alle relevanten Anbieter von IT-Diensten, darunter Betreiber von Mega-Datencentern, auf den Container-Zug aufgesprungen: von dem Ubuntu-Haus Canonical über Red Hat, Google, AWS, VMware und Pivotal bis hin zu Microsoft. Allein Google startet jede Woche eigenen Aussagen zufolge über 2 Milliarden Container. Die Container-Revolution wird primär von zwei Faktoren getrieben: dem explodierenden Bedarf nach einer höheren DevOps-Agilität dank möglichst kurzer Release-Zyklen und dem enormen Kostendruck der Software-Entwicklung und -Bereitstellung. Hinzu kommt die Herausforderung, eine hohe Portabilität von Anwendungen zwischen den verschiedenen ITUmgebungen – On-Premise und Clouds – zu gewährleisten. Bei Containern handelt es sich um ultraleichtgewichtige, hochportable Laufzeitumgebungen. Container-Frameworks wie Docker führen einzelne Anwendungen in dem Sandkasten der jeweiligen Laufzeitumgebung direkt auf dem Kernel des Host-Systems, also ohne einen Hypervisor, aus. Daraus ergibt sich der größte Vorteil von Containern gegenüber VMs, nämlich die Fähigkeit, einmalig bereitgestellte Ressourcen des Host-Systems gemeinsam zu gebrauchen, um auf derselben physischen Hardware eine höhere Nutzungsdichte zu erzielen. VMs haben eine längere

100

Start-up-Phase als Container, sind vergleichsweise ressourcenhungrig und generell etwas träge. Intelligente Orchestrierungslösungen für Container können daher eine bessere Auslastung der vorhandenen Hardware gewährleisten als virtuelle Maschinen. Container-Images können schichtenweise aufeinander aufbauen, um die Ressourcenanforderungen für die Datenübertragung nach einer Pull-Anfrage und somit die Latenz weiter zu minimieren. Alles in allem sind Container wesentlich schneller und um ein Vielfaches kosteneffizienter als VMs. Container erleichtern die Inbetriebnahme von virtualisierten Anwendungen. Vagrant zeichnet dagegen für die Erstellung leichtgewichtiger und gleichzeitig portabler Entwicklungsumgebungen verantwortlich (unabhängig von dem Systemunterbau). Es ermöglicht die Automatisierung portabler Entwicklungsumgebungen für DevOps und DevSecOps und erlaubt es, die Parität des technischen Unterbaus von Dev und Ops zu garantieren. Vagrant wurde von einem Entwickler namens Mitchell Hashimoto erstmals im Januar 2010 veröffentlicht. Die Lösung war auf Anhieb ein Selbstläufer. Durch das aktive Sponsoring von Fastly, Kiip, Typekit und Softlayer wurde dann im November 2012 das Unternehmen HashiCorp aus der Taufe gehoben. HashiCorp fokussiert primär darauf, kommerzielle Add-ons und professionellen Support und Training für Vagrant bereitzustellen; Vagrant an sich ist kostenfrei. Die treibende Kraft hinter Vagrant ist die lebhafte Open-Source-Gemeinde.

3.2017 www.webundmobile.de


DevOps

nuss eines umfassenden Satzes von Docker-spezifischen Tools für Visual Studio und ASP.NET Core von Microsoft. Darüber hinaus können Entwickler ein Docker-Image direkt aus dem Azure Marketplace beziehen und in Microsofts Cloud auf einer Ubuntu-Instanz starten. Mit der Azure-Docker-VMErweiterung für den Azure-Linux-Agenten können Sie unter Verwendung der CLI-Schnittstelle eine Docker VM mit jedem beliebigen unterstützten Linux-System als eine ContainerPlattform provisionieren. Die Unterstützung für Container hat Microsoft auch für Windows 10 fest verplant. Windows 10 bietet Entwicklern bereits das Linux-Subsystem einschließlich der CLI-Schnittstelle Bash von Ubuntu (portiert durch den Linux-Spezialisten Canonical). Doch damit nicht genug: .NET Core läuft inzwischen sogar unter Linux. Nach der Akquisition der beliebten plattformübergreifenden Entwicklungsumgebung Xamarin Studio stellte Microsoft das zugehörige SDK unter eine Open-Source-Lizenz und bündelt sie mit Visual Studio. Mitte April 2016 schaltete Microsoft die allgemeine Verfügbarkeit von Azure Container Service, einer gehosteten Lösung für Container, frei. Der Dienst bietet Entwicklern inzwischen die Wahl zwischen drei Orchestrierungs-Engines: Apache Mesos DC/OS, Docker Swarm und Google Kubernetes. Gleichzeitig beteiligt sich Microsoft an Mesosphere DC/OS, einem Datencenter-Betriebssystem für die Container-Orchestrierung, und ist kürzlich sogar ganz offiziell als ein Platinum-Mitglied der Linux Foundation beigetreten. Der Softwareriese hat sich diese Ehre eine halbe Million US-Dollar pro Jahr kosten lassen. Immerhin zählen zu dieser erlesenen Gruppe ja insgesamt nur elf Unternehmen, und diese dürfen die Richtung für so wichtige Initiativen wie das Hyperledger-Projekt vorgeben. Ohne eine enge Kooperation mit der Linux Foundation würde Microsoft in einer DevOpsdominierten Welt tatsächlich nicht allzu weit kommen. Zu den prominentesten DevOps-Benutzern von Microsoft Azure zählt der Shell-Konzern mit seinen circa 2800 Software-Entwicklern, die ihren Code in Visual Studio für Linux, Windows, Android und macOS entwickeln. Shell stellt seine Websoftware via Azure bereit. »Wir betreiben längst keine eigenen Server mehr«, sagt Johan Krebbers, CTO der IT-Sparte und stellvertretender Vorsitzender von Shell Global Solutions International. Der Trend, weg von der Administration (Ops) hin zur Software-Entwicklung (Dev) und Cybersicherheit (Sec) – von DevOps zu DevSecOps zu DevSec – ist somit auch im Fall von Microsoft Azure eindeutig erkennbar.

DevOps-automatisierung in der Google-Cloud Die Automatisierung von DevOps-Abläufen in der Google Compute Engine (GCE) dreht sich nicht ganz so stark um plattformspezifische Dienste wie im Fall von Amazon AWS. GCE trumpft im Hinblick auf die benutzerfreundliche Bedienung und wettbewerbsfähige Preise auf (unter anderem dank der minutenweisen Abrechnung), kann jedoch mit der Vielfalt von APIs und Diensten von AWS nicht mithalten. Dafür sind viele GCE-Dienste Open Source; das Risiko eines Vendor-Lock-ins fällt damit bei den beiden anderen An-

www.webundmobile.de 3.2017

BaCKEnD

Diensterkennung: Consul von HashiCorp, eine DNS-basierte Diensterkennungslösung, kommt auf GCE im Rahmen eines HAProxy-basierten Lastverteilers zum Einsatz (Bild 6)

bietern weitaus höher aus als bei der GCE. Dennoch sind sich die drei verschiedenen Clouds – AWS, Azure und GCE – im Prinzip recht ähnlich. So bietet Google beispielsweise verwaltete Instanzgruppen, das heißt, Vorlagen für die Bereitstellung identischer Instanzen mit der Fähigkeit zur automatischen Skalierung der Gruppe auf der Basis von Richtlinien für die optimale Auslastung. Das ist ein Feature, das sich in einer ähnlichen Form auf AWS vorfinden lässt, zum Beispiel in Form von Autoscaling Groups. Typische Aufgaben von DevOps-Teams, die GCE einsetzen, umfassen laut dem Anbieter: das aufsetzen neuer Systemarchitekturen (zum Beispiel Workloads rund um High-Availability-Datenbanken wie Apache Cassandra oder Redis), die Entwicklung von robusten, sicheren und Hacker-festen Anwendungen, das Bereitstellen von Webapplikationen und -Diensten in neuen geografischen Orten (zum Beispiel im Rahmen der Ausweitung der Geschäftstätigkeiten von Europa auf Nordamerika und Asien), Inbetriebnahme von leistungsfähigen, DDoS-resistenten Deployments. Was GCE von den anderen beiden Clouds – Amazon AWS und Microsoft Azure – unterscheidet, ist Googles klare Präferenz für quelloffene Lösungen, die sich in zahlreichen OpenSource-Projekten aus Googles eigener Feder und in den gebotenen Cloud-Diensten reflektiert. So bietet Google auf GCE unter anderem diverse Lösungen für die automatische Diensterkennung, um die Automatisierung von DevOps-Abläufen zu vereinfachen. Erfahrungsgemäß können sich scheinbar minimale Änderungen der Infrastruktur auf so viele verschiedene Aspekte des Deployments auswirken (zum Beispiel geänderte IP-Adressen, Passwörter und Schlüsselpaare et cetera), dass manuelle Nachbesserungen einfach nicht in Frage kommen. Erst der völlige Verzicht auf starre, hart codierte Konfigurationen und der konsequente Einsatz von Diensterkennung ▶ schaffen hier Abhilfe.

101


BaCKEnD

DevOps

Die GCE stellt DevOps-Anwendern für ebendiese Aufgabe eine Vielzahl von Werkzeugen zur Verfügung, darunter: Consul (http://consul.io): ein Diensterkennungswerkzeug von HashiCorp (Bild 6), etcd (http://coreos.com/etcd): ein verteilter Speicher von Schlüssel-Wert-Paaren, apache Zookeeper (http://zookeeper.apache. org): ein quelloffener Dienst für die Verwaltung von Konfigurationsdaten. Erst der Einsatz dieser Werkzeuge ermöglicht es DevOps-Teams auf GCE, eine hohe Verfügbarkeit ihrer Dienste zu gewährleisten.

IBM Bluemix DevOps Services IBM bietet mit Bluemix DevOps Services eine Kronjuwelen: IBM strickt seine DevOps-Dienste rund um kognitive Lösungen eigene DevOps-Plattform in der Cloud und herum (Bild 7) trumpft dabei mit kognitiven Diensten der Watson-Plattform auf (Bild 7). Zu den deutschen Anwendern von IBMs Lösungen zählen Organisationen wie die nuelle Zusammenstellen dieser Informationen ist nicht nur Technische Universität München, die Technische Universität mühsam und zeitraubend, es ergibt ja auch im DevOps-ZeitBerlin, Airbus Helicopters, die Deutsche Nationalbibliothek, alter einfach überhaupt keinen Sinn mehr. die DATEV eG, die Deutsche Rentenversicherung BadenUm dieses Beispiel einer Applikation zur Verwaltung von Württemberg und ThyssenKrupp Marine Systems. Lizenzbedingungen in einem DevOps-Workflow nachzuvollIn IBM-zentrischen Umgebungen ist quelloffene Software ziehen, benötigen Sie vier Komponenten: eine Node.js-Applikation, überaus willkommen. Anstelle von Jenkins kommen aber des die neueste Version von NPM, Öfteren IBMs hauseigene Bluemix DevOps Services in Kom eine IBM Bluemix DevOps Services Pipeline, bination mit Node.js und Grunt zum Einsatz. Die Nutzung Grunt, den JavaScript-Taskrunner ab der Version 0.45 (sodieser Werkzeuge lässt sich anhand einer Applikation zur wohl das Grunt CLI als auch das Node-Modul). Verwaltung von Lizenzbedingungen erläutern. Nichts ist einfacher, als im Eifer des DevOps-Gefechts die Zwar bringt Node.js NPM vorinstalliert mit, doch in der ReLizenzbedingungen der eingesetzten Bibliotheken zu vergel wird der Paketmanager deutlich häufiger aktualisiert als nachlässigen. Spätestens vor der Freigabe einer neuen Softdas Framework selbst. Aus diesem Grund empfiehlt es sich, wareversion müssen die Entwickler und Release-Manager siNPM-Aktualisierungen regelmäßig aufzuspielen, um die cherstellen, dass die verwendeten Bibliotheken den avisierSoftware auf dem neuesten Stand zu halten. ten Einsatz – zum Beispiel die kommerzielle Nutzung – expliUm Grunt zu installieren, führen Sie erst einmal aus dem zit zulassen. Wer etwa eine Node.js-Applikation baut, sollte root-Verzeichnis Ihres Projekts heraus folgenden Befehl aus: besondere Aufmerksamkeit den zahlreichen Dependencies und ihren jeweiligen Lizenzbedingungen widmen. Das manpm install -g grunt-cli

Eine Runtime-unabhängige Spezifikation Bei app Container handelt es sich um eine Spezifikation der DevOps-Gemeinde für portable anwendungscontainer (https://github.com/appc). Die Spezifikation definiert gewisse Aspekte des Betriebs von Anwendungscontainern, darunter das Image-Format, die Laufzeitumgebung und die Mechanismen zum Erkunden von Anwendungscontainern. Die Spezifikation ist nicht an eine Implementierung gekoppelt. Sie legt lediglich fest, wie die betreffende Applikation in ein App-Container-Image verpackt werden soll, wie sie aus dem Netzwerk heruntergeladen und schließlich als ein Container ausgeführt werden kann.

Jetzt benötigen Sie noch den Grunt-Taskrunner. Mittels npm install grunt --save-dev

fügen Sie der Datei package.json Grunt als eine der Abhängigkeiten Ihres Projekts hinzu. Als Nächstes benötigen Sie gruntfile.js; diese unbedingt gültige JavaScript-Datei gehört zusammen mit der Datei package.json in das root-Verzeichnis Ihres Projekts. Diese beiden Dateien sollten Ihrem Quellcode-Repository beigefügt werden. Ihre Datei gruntfile.js könnte zum Beispiel wie folgt aussehen: module.exports = function(grunt) { grunt.initConfig({ pkg: grunt.file.readJSON('package.json')

102

3.2017 www.webundmobile.de


DevOps

});

Running "example" task

grunt.registerTask('default');

Done, without errors.

BaCKEnD

};

Nachdem Sie Grunt in Ihrem Projekt eingerichtet haben, können Sie jetzt ein Grunt-Taskfile erzeugen, damit Grunt Ihren benutzerspezifischen Code ausführt. Erstellen Sie ein Verzeichnis mit dem Namen build_tasks im Wurzelverzeichnis Ihres Projekts und hierin eine Datei namens licenses.js. Diese beinhaltet Ihre Grunt-Tasks und kann zum Beispiel so aussehen:

Fügen Sie zu Ihrem Projekt das Node-Modul grunt-licensefinder hinzu, indem Sie im Wurzelverzeichnis Ihres Projekts den folgenden Befehl ausführen: npm install grunt-license-finder –-save-dev

Das soeben installierte Plug-in müssen Sie jetzt noch aktivieren, indem Sie der Datei gruntfile.js die folgende Zeile hinzufügen:

module.exports = function (grunt) { 'use strict';

grunt.loadNpmTasks(‘grunt-license-finder‘);

grunt.registerTask('example', 'Example task', function () { }); };

Fügen Sie dem Datenobjekt, das in der gruntfile.js-Datei Ihres Projekts an die Methode grunt.initConfig() übergeben wird, einen Abschnitt namens license_finder hinzu:

Dieser Code registriert einen Task, der mittels gruntfile.js aufgerufen werden kann. Hierzu müssen Sie diese Datei entsprechend anpassen:

grunt.initConfig({

npm install grunt --save-dev

});

pkg: grunt.file.readJSON('package.json'), license_finder: { }

module.exports = function(grunt) { grunt.initConfig({ pkg: grunt.file.readJSON('package.json') }); grunt.task.loadTasks('build_tasks'); grunt.registerTask('default', ['example']); };

Zum Testen Ihres Grunt-Tasks geben Sie in der Kommandozeile ganz einfach den Befehl grunt ein. Im Erfolgsfall erwartet Sie das folgende Resultat:

Listing 3: gruntfile.js für zwei Lizenzumgebungen grunt.initConfig({ pkg: grunt.file.readJSON('package.json'), license_finder: { dev: { options: { production: false, out: 'npm-dev-licenses.csv', csv: true } }, prod: { options: { production: true, out: 'npm-prod-licenses.csv', csv: true

In diesem Abschnitt legen Sie dann die gewünschten Optionen fest. Sie können bei Bedarf auch zwei Berichte für serverseitige Abhängigkeiten erzeugen: einen für die Produktionsumgebung und einen für die Entwicklungsumgebung. Bei den Abhängigkeiten der Entwicklungsumgebung handelt es sich um solche, die ausschließlich in der Phase der Entwicklung und Automatisierung zum Einsatz kommen (zum Beispiel grunt und grunt-license-finder), während es sich bei den Abhängigkeiten der Produktionsumgebung um solche handelt, die zur Laufzeit der Anwendung auf dem Produktionsserver zum Einsatz kommen. Wenn Sie in der Datei package.json eine neue Abhängigkeit definieren, können Sie diese entweder der Produktionsoder der Entwicklungsumgebung zuweisen. Erstellen Sie im Abschnitt license_finder für jede der beiden Kategorien der Abhängigkeiten jeweils eine eigene Zielumgebung (target). So können Sie die Produktions- und Entwicklungsumgebung sauber auseinanderhalten (Listing 3). Sie können die Optionen Ihren eigenen Bedürfnissen anpassen. Die Option production gibt an, ob es sich um die Produktions- oder die Entwicklungsumgebung handelt. Die Option out legt die Ausgabedatei fest. Mit der Option csv entsteht eine CSV-Datei. Weiterhin benötigen Sie einen sogenannten Target-Task, um die beiden Tasks von license_finder aufrufen zu können, also einen für den Bericht zur Produktions- und einen anderen für den Bericht zur Entwicklungsumgebung. Hierzu fügen Sie die folgende Zeile in Ihre gruntfile.js-Datei ein:

}}} });

grunt.registerTask('server-side-license', ['license_finder:dev', 'license_finder:prod']);

www.webundmobile.de 3.2017

103


BaCKEnD

DevOps

Das vollständige gruntfile.js-Skript nach dem Einbinden der serverseitigen Änderungen finden Sie in Listing 4. Nun können Sie den Task server-side-license auf die Probefahrt nehmen, indem Sie Folgendes in die Kommandozeile eingeben: grunt server-side-license

Ist alles glatt gelaufen, so erhalten Sie eine Erfolgsmeldung. Anstatt die clientseitigen Abhängigkeiten mühsam zu Fuß abzustecken, indem Sie alle benötigten Bibliotheksdateien herunterladen, können Sie diesen Prozess viel komfortabler mittels einer Bower-Konfigurationsdatei automatisieren. Nachdem Sie Bower auf Ihrem System installiert und für Ihr Projekt angepasst haben, werden alle clientseitigen Abhängigkeiten in einer Datei namens bower.json gespeichert. Achten Sie unbedingt darauf, dass alle clientseitigen Abhängigkeiten nicht direkt im Quelltext referenziert, sondern durchgängig von Bower eingebunden werden. Nur auf diese Weise können Sie sicherstellen, dass der dadurch generierte Bericht auch akkurat ist. Um alle benötigten Abhängigkeiten zu ermitteln, fügen Sie das Node-Modul bower-license Ihrem Projekt hinzu, indem Sie im Wurzelverzeichnis Ihres Projekts den folgenden Befehl eingeben: npm install bower-license --save-dev

Nachdem das Plug-in installiert ist, sollten Sie dieses innerhalb der Datei license.js mit einer Zeile JavaScript-Code wie folgt aktivieren:

Nach dem erfolgreichen Laden des Node-Moduls bowerlicense coden Sie jetzt Ihren benutzerdefinierten Task, der dieses Modul aufruft. Erzeugen Sie einen Task namens run_bower_license, um alle Abhängigkeiten zu ermitteln und in eine Datei auszugeben. Den hierfür benötigten Code können Sie Listing 5 entnehmen. Der Code registriert einen Grunt-Task namens run_bower_ license, der zwei Parameter entgegennimmt. Der eine Parameter legt das Verzeichnis fest, in dem die Bower-Komponenten abgelegt werden sollen. Der zweite Parameter definiert den Namen der Ausgabedatei. Um Verwechslungen zu vermeiden, löscht der Task zudem bereits existierende Ausgabedateien und ruft die bower-license-Bibliothek auf, um alle clientseitigen Abhängigkeiten zu ermitteln. Für jede Abhängigkeit, die der Grunt-Task run_bower_license findet, versucht die Software, die folgenden Informationen zu ermitteln und, falls vorhanden, in der Ausgabedatei zu notieren: den Namen der Bibliothek, die Versionsnummer, den URL des Git-Repository, die Lizenz, die Homepage. Registrieren Sie jetzt in der Datei gruntfile.js einen neuen sogenannten Target-Task, der den run_bower_license-Task aufrufen soll, und nennen Sie ihn client-side-license: grunt.registerTask('client-side-license', ['run_bower_license:all']);

var license = require('bower-license');

Lassen Sie den neuen Task client-side-license von der GruntKommandozeile aus ablaufen:

Listing 4: gruntfile.js grunt client-side-license module.exports = function (grunt) { grunt.initConfig({ pkg: grunt.file.readJSON('package.json'),

Im Erfolgsfall sollte die Ausgabe in der Grunt-Kommandozeile folgendermaßen aussehen:

license_finder: { Running "run_bower_license:all" (run_bower_license) task

dev: { options: {

Executing run_bower_license task

production: false, out:

Output file already exists. Will delete it

'npm-dev-licenses.csv', csv: true }},

End of run_bower_license task

prod: { options: {

Done, without errors.

production: true, out: 'npm-prod-licenses.csv', csv: true }}} });

Erzeugen Sie jetzt einen Task namens get-licenses, der sowohl die clientseitigen als auch die serverseitigen Versionen der Tasks aufruft:

grunt.task.loadTasks('build_tasks'); grunt.loadNpmTasks('grunt-license-finder');

grunt.registerTask('client-side-license',

grunt.registerTask('server-side-license',

['run_bower_license:all']);

['license_finder:dev', 'license_finder:prod']); };

104

Nach all diesen Erweiterungen sollte Ihre voll ausgebaute ▶ Datei gruntfile.js dem Inhalt von Listing 6 entsprechen.

3.2017 www.webundmobile.de


DevOps

BaCKEnD

Listing 5: PrĂźfen der Bower-Lizenz var license = require('bower-license'),

if (prop === 'licenses') {

fs = require('fs');

item.licenses = data[entry][prop];

module.exports = function (grunt) {

} else if (prop === 'repository') {

'use strict';

item.repository = data[entry][prop];

grunt.registerMultiTask('run_bower_license',

if (item.repository.constructor ===

'Gather bower license report', function () {

Object) {

var options = this.options({

item.repository = item.repository.url;

directory: 'bower_components',

}

output: 'bower-license.csv'

} else if (prop === 'homepage') {

}),

item.homepage = data[entry][prop];

entry, item, prop, done, dependency;

}}

done = this.async(); item.version = entry.substring(entry. console.log('Executing run_bower_license task');

indexOf('@') + 1, entry.length); item.name = entry.substring(0,

// Wurde eine Datei bereits ausgegeben,

entry.indexOf('@'));

// wird sie jetzt gelĚˆscht. dependency = item.name + ',' + item.version +

if(grunt.file.exists(options.output)) {

',' + item.repository + ',' + item.licenses;

console.log('Output file already exists. Will delete it');

if(item.homepage) {

grunt.file.delete(options.output);

dependency += ',' + item.homepage;

} }

fs.appendFileSync(options.output, dependency

license.init(options, function (data) {

+ '\r\n');

for (entry in data) { }

item = {licenses: "",

console.log('End of run_bower_license task');

repository: "",

done();

homepage: ""

});

};

}); for (prop in data[entry]) {

};

Listing 6: Die voll ausgebaute Datei gruntfile.js module.exports = function (grunt) {

run_bower_license: { all: {

grunt.initConfig({

options: {

pkg: grunt.file.readJSON('package.json'),

directory: 'bower_components',

license_finder: {

output: 'bower-license.csv'

dev: {

}}}

options: {

});

production: false, out: 'npm-dev-licenses.csv',

grunt.task.loadTasks('build_tasks');

csv: true

grunt.loadNpmTasks('grunt-license-finder');

}}, grunt.registerTask('server-side-license', prod: {

['license_finder:dev', 'license_finder:prod']);

options: {

grunt.registerTask('client-side-license',

production: true,

['run_bower_license:all']);

out: 'npm-prod-licenses.csv',

grunt.registerTask('get-licenses',

csv: true }}},

www.webundmobile.de 3.2017

['server-side-license', 'client-side-license']); };

105


BaCKEnD

DevOps

Indem Sie den Task get-licenses von der Grunt-Kommandozeile aus aufrufen, können Sie sowohl den clientseitigen als auch den serverseitigen Bericht abrufen: grunt get-licenses

Zu guter Letzt folgt noch die Anbindung an die IBM Bluemix DevOps Services. Navigieren Sie zur Ansicht Build & Deploy Ihres Projekts im Dashboard von IBM Bluemix DevOps Services. Aktivieren Sie das Pipeline-Feature und erstellen Sie eine neue Pipeline. Sie besteht aus zwei Phasen: In der einen Phase (Build Stage) wird der Build ausgeführt, in der anderen (Deploy Stage) wird er via Bluemix bereitgestellt. Nach dem Erstellen der Pipeline konfigurieren Sie diese wie folgt: Input Type: Build Artifacts, Stage: Build Stage, Job: Build, Stage Trigger: Run jobs when the previous stage is completed.

AWS CodeCommit in DevOps-Workflows Kaum jemand möchte im laufenden Betrieb von seinem bisherigen Git-Repository-Server direkt auf eine neue Lösung wie den Dienst aWS CodeCommit umstellen. Der Grund: Bereits die kleinsten Abweichungen der Funktionsweise dieser beiden Lösungen können den Workflow ernsthaft ins Stottern bringen. Sollten Sie ohnehin bereits in der AWSCloud arbeiten, möchten Sie sicherlich nur ungern an einem laufenden, wichtigen Projekt experimentieren. Doch hier gibt es Abhilfe. Sie können sich leicht aus dieser Situation herausmanövrieren, indem Sie die Push-Commits an zwei Git-Repositories gleichzeitig senden.

Fazit

Die Entwicklung und die Bereitstellung von Software sind heutzutage zwei Seiten derselben Münze. Eine kontinuierliche und reibungslose Bereitstellung inkrementeller, zuverErstellen Sie eine neue Job-Instanz vom Typ Build. Im Ablässiger Software-Upgrades (Continuous Delivery) im Rhythschnitt Execute License tasks wählen Sie im Menü Builder mus vollautomatisierter Build-, Test- und Deploy-Abläufe gehört heutzutage ins Pflichtenheft der Entwicklung von Web- wie auch mobilen Anwendungen. Moderne Dev-Abteilungen müssen sich den dynamischen Anforderungen eines DevOps-Workflows mit Agilität anpassen, und nirgendwo gelingt es einfacher als in der Cloud. Die Fähigkeit, Ressourcen flexibel und bedarfsgerecht in der virtualisierten Umgebung einer Cloud elastisch zu provisionieren und umgehend zu konfigurieren, um skalierbare Applikationen möglichst kosteneffizient bereitzustellen, hat zu einer neuen Grundeinstellung geführt. überschaubar: Eine Ausführungspipeline auf IBM Bluemix Services (Bild 8) Erstmals arbeiten Entwickler, CybersecurityExperten und die Betreiber der resultierenden Anwendungen kontinuierlich Hand in Hand Type den Eintrag Grunt und tragen dort die folgenden CLIzusammen. Crossfunktionale Teams sorgen für einen Zufluss Befehle ein: von Querdenkern und eine größere Vielfalt von Kompetenzen – zwei Merkmale, die sich auf die resultierenden Soft◾ #!/bin/bash warelösungen generell sehr positiv auswirken. npm install node_modules/bower/bin/bower install grunt get-licenses

Speichern Sie die so erstellte Konfiguration der PipelineStage ab und führen Sie diese aus (Bild 8). Mit einem Klick auf View Logs and History können Sie die Logs und die Liste der Artefakte einsehen. Die Ausführung der Skripts in der Bluemix-Pipeline ist natürlich sehr IBM-spezifisch. Die Bower-Tasks können Sie jedoch auch sehr leicht anpassen, sodass diese in entsprechender Weise in Gulp oder in einem anderen Task-Automatisierungsframework funktionieren.

106

Filipe Pereira Martins und anna Kobylinska sind international anerkannte IT-Berater mit Schwerpunkt auf CloudLösungen. Sie stehen den Lesern der web & mobile developer gern per Twitter via @D1gitalPro und @D1gitalInfo zur Verfügung.

3.2017 www.webundmobile.de


Tr

T

aining

s

Updates für Ihr Know-How „Erfolgreiche Entwickler vermeiden Komplexität – durch einfache und nachhältige Architekturen und Lösungen.“ Stefan Priebsch PHP-Consultant und Trainer

Node.js & Co. Trainer: Golo Roden 3 Tage, Ort & Termin nach Absprache Ab EUR 2.199,- zzgl. MwSt.

Deployment und Systemarchitektur für PHP-Projekte Trainer: Arne Blankerts 2 Tage, Hamburg, Termin nach Absprache Ab EUR 1.799,- zzgl. MwSt.

Qualitätssicherung in PHP-Projekten Trainer: Sebastian Bergmann 2 Tage, Köln, Termin nach Absprache Ab EUR 1.799,- zzgl. MwSt.

Effiziente Softwarearchitekturen mit PHP Trainer: Stefan Priebsch 2 Tage, München, Termin nach Absprache Ab EUR 1.799,- zzgl. MwSt.

Ihr Ansprechpartner: Fernando Schneider +49 (0)89 74117-831 – fernando.schneider@developer-media.de

developer-media.de/trainings


BaCKEnD

Datenbank

SQL SERVER 2016 (TEIL 1)

architektur und Konzepte Nach nur zwei Jahren erneuert Microsoft den SQL Server zur Version 2016.

M

icrosoft hat im Sommer des vergangenen Jahres die Version 2016 seines SQL Servers freigegeben. Seit der ersten Version zu Beginn der 1990er Jahre wurde das Datenbankmanagementsystem beständig erweitert und erneuert. Aufgrund der langjährigen Entwicklung des Produkts darf man eine ausgereifte Software erwarten. Daher sind die Änderungen in der Version 2016 meist nicht mehr so einschneidend, wie dies bei früheren Versionen der Fall war. Dennoch gibt es eine Reihe an Detailverbesserungen und innovativen Konzepten. In diesem ersten Teil unseres Berichts zum SQL Server 2016 wollen wir Sie vor allem über Architektur und Konzepte und deren Neuerungen informieren. Im Teil 2 in der nächsten Ausgabe gehen wir auf die Installation, die Verwaltung und weitere Besonderheiten ein (Bild 1).

Der SQL Server 2016 ist das Flaggschiff der Microsoft-Datenbanksysteme (Bild 1)

Der SQL Server und seine Entwicklung Der SQL Server zählt zu jenen Produkten von Microsoft, die auf eine langjährige Historie zurückblicken können. Im Jahr 1993 lieferte Microsoft die erste Version des SQL Servers. Dieser gründete auf eine Kooperation mit Sybase. Anschließend folgten die Versionen 4.2, 6.0 und 6.5, dann die Version 7. Seit der Version 2000 hat die Jahreszahl Einzug in die Bezeichnung des SQL Servers (Version 2000) gehalten. Dem folgten die Versionen 2005, dann 2008, 2012, 2014 und nun schließlich 2016. Vom alten Sybase-Code ist wohl längst nichts mehr übrig. Die Verbesserungen der Version 2016 finden sich vor allem in den Analysefunktionen, wie sie für Business Intelligence oder Massenverarbeitung benötigt werden. Darüber hinaus hat Microsoft die In-Memory-Verarbeitung von Massendaten optimiert. Hierbei werden die häufig verwendeten Tabellen direkt im Arbeitsspeicher des Rechners abgelegt und müssen nicht immer erst von der Platte geladen werden. Da der Zugriff auf den Arbeitsspeicher um ein Vielfaches schneller ist als Plattenzugriffe, wird die Verarbeitung erheblich beschleunigt. Gleichzeitig ist der Arbeitsspeicher im Verhältnis zum Plattenplatz natürlich eingeschränkt. Das Verfahren kann also nur für die am häufigsten verwendeten Tabellen genutzt werden. Ferner hat Microsoft nach eigenen Angaben die Sicherheit und die Anbindung an die Cloud verbessert. Wie schon die Vorgängerversionen wird auch der SQL Server 2016 in mehreren Editionen angeboten. Microsoft unter-

108

scheidet dabei nach Server-Editionen und den speziellen Editionen. Diese beiden Versionen sind kostenpflichtig. Daneben stehen mit der Developer Edition und Express Edition zwei weitere Varianten des SQL Servers zur Verfügung, die kostenlos abgegeben werden. Sie wenden sich vor allem an Entwickler. Ab 2017 soll es den SQL Server auch für das Betriebssystem Linux geben. Unter dem folgendem Link ist ein E-Book zum SQL Server 2016 abzurufen: https://www.microsoft.com/germany/tech net/news/show.aspx?id=msdn_de_61272. Das Buch führt in die Änderungen in SQL Server 2016 ein, die bereits in der Community Preview 3.2 enthalten sind. Eingeschlossen sind die Verbesserungen der DatenbankEngine und der Reporting Services inklusive Datenvirtualisierung. Die vollständige technische Dokumentation findet man unter https://www.microsoft.com/de-de/server-cloud/ products/sql-server/overview.aspx (Bild 2).

neuerungen in den Konzepten des SQL Servers Die Neuerungen, die Microsoft beim SQL Server 2016 angebracht hat, betreffen sowohl die Software-Entwicklung als auch die Administration. Dies gilt, weil der SQL Server ja auch diese beiden Bereiche der IT berührt. Der Programmentwickler verwendet den SQL Server zur Speicherung der Applikationsdaten, während der Administrator für den reibungslosen Betrieb sorgen muss. In Hinblick auf die Verwaltung hat Microsoft, wie auch bei den vergangenen Versionen, die Automatisierung weiter vorangetrieben. So manche Tätigkeit, die der Administrator bis-

3.2017 www.webundmobile.de


Datenbank

BaCKEnD

lang noch manuell durchführen musste, ist nun automatisiert worden. Damit schreibt Microsoft eine Strategie fort, die schon seit mehreren Versionen des SQL Servers eingeführt wurden. Die prinzipielle Stoßrichtung dabei ist eine weitgehend selbstoptimierende IT, in der sich die Systeme stärker als heute selbst verwalten und optimieren. Zerlegt man den SQL Server in seine Bestandteile, so präsentiert er sich in Form von mehreren Diensten. Microsoft spricht dabei von Services. Ein Service gruppiert eine zusammengehörende Menge an Diensten oder Hilfen für einen bestimmten Nutzen. Der SQL Server umfasst alle Funktionsmodule zur Datenspeicherung und Auswertung (Bild 2) Die wichtigsten Services im Überblick: Datenbankmodul: Den Kern des Datenbanksystems stellt die Datenbank-Engine pieren und Verteilen von Daten und Datenbankobjekten dar. In diesem Modul wurden zahlreiche Änderungen vorgenommen. Sie betreffen beispielsweise jene Aspekte, die aus einer Datenbank in eine andere und das anschließende Synchronisieren zwischen den Datenbanken. Das letztfür eine kürzere Antwortzeit und höhere Verfügbarkeit sorendliche Ziel ist fast immer, einem möglichen Datenverlust gen. R Services: Die R Services sind neu im SQL Server 2016. Sie vorzubeugen. Replikation kann aber auch zwischen unterumfassen die Statistiksprache R und weitere in diesem Konschiedlichen Server-Standorten stattfinden. Dabei werden text hilfreiche Werkzeuge. Die Sprache R und R Services die Daten an Remote-Benutzer oder mobile Benutzer an dienen vor allem zur Datenanalyse. verschiedenen Standorten über lokale Netzwerke und Integration Services: Sie übernehmen die ZusammenfühWANs, Funkverbindungen oder über das Internet verteilt. rung unterschiedlichster Datenquellen in den Datensenken In diesem Fall sorgt die Replikation für eine erhöhte Verund fungieren als Grundlage für die Werkzeuge der Busifügbarkeit der Daten. Eine Alternative zur Replikation ist ness Intelligence (BI). Sie werden die Synchronisation der Daten mit dem Mimitunter auch als Analysewerkzeucrosoft Sync Framework. Es schließt Kompoge bezeichnet. Sie sind damit vernenten und ein intuitives und flexibles gleichbar mit den ETL-Werkzeugen, API ein, die es erleichtern, zwischen SQLdie man gemeinhin im BI-Umfeld Server-, SQL-Server-Express-, SQL-Servervorfindet. Compact- und SQL-Azure-Datenbanken zu analytical Services: Die Analytical synchronisieren (Bild 3). Data Quality Services: Mit den SQL Server Services stellen die OLAP-Dienste Data Quality Services (DQS) soll die Datendes SQL Server 2016 dar. Sie gehöQualität erhöht werden. Dies geschieht ren bereits seit der Version SQL Serdurch eine Wissensdatenbank. Sie kann ver 2000 zum Umfang des Datenbeim Ausführen von Maßnahmen zur Verbankprodukts. Die Änderungen hier besserung der Datenqualität herangezobetreffen vor allem eine einfachere gen werden. Dazu gehören beispielsweise Programmierung. Ferner wurden didie Korrektur, Erweiterung, Standardisieverse Hilfsmittel zum Aufbau der rung und Deduplizierung der Daten. DQS Datenmodelle und Auswertungen ermöglicht es außerdem, eine Datenbereihinzugefügt. Reporting Services: Die Funktionen nigung mit cloudbasierten Verweisdatender Reporting Services erlauben umdiensten auszuführen, die von speziellen fangreiche Berichte samt Integration Verweisdatenanbietern bereitgestellt werzusätzliche Komponenten und unden. SQL Server Management Studio: Das Materstützen bei der Einbindung der nagement Studio stellt die zentrale VerBerichte in weitere Applikationen. waltungskonsole für den SQL Server und Ferner übernehmen sie eine Reihe alle oben genannten Dienste dar. Es fasst weitergehender VerwaltungsfunkDurch Transaktionsreplikation werden die unterschiedlichen Werkzeuge der Vortionen. Replication: Als Replikation bezeichÄnderungen an der Datenbank weitergängerversion zusammen und ergänzt die▶ net man all die Techniken zum Ko- gereicht (Bild 3) se um weitere Funktionen.

www.webundmobile.de 3.2017

109


BaCKEnD

Datenbank

Die notification Services: Sie ermöglichen eine schnelle Übermittlung der in den Analytical Services gewonnenen Ergebnisse an die Empfänger und zielen damit in Richtung Realtime Monitoring auf der Grundlage von analytischen Auswertungen.

Manche der erwähnten Funktionsblöcke, wie etwa die R Services, sind völlig neu, andere wiederum wurden bereits in den vergangenen Jahren als Add-ons oder Servicepacks dem bestehenden SQL Server hinzugefügt.

Das Datenbank-Modul des SQL-Servers Das Datenbankmodul (die Database Engine) des SQL Servers ist mittlerweile seit Jahren erprobt und bei unzähligen Kunden im Einsatz. Die frühen Kinderkrankheiten sind ausge-

einem Abfrageplanoperator zu einem anderen übertragen werden. Der Abfragespeicher ist eine neue Funktion, die über DBAs Einblick in die Auswahl und die Leistung des Abfrageplans bietet. Er vereinfacht das Beheben von Leistungsproblemen, indem er das schnelle Auffinden von Leistungsabweichungen durch Änderungen an Abfrageplänen ermöglicht. Ein wesentlicher Bereich der Änderungen betrifft neben den allgemeinen Optimierungen hinsichtlich der Performance und den Erweiterungen für die Programmierung den Zweig der Business Intelligence. Das Microsoft BI-Angebot besteht aus den Komponenten der Integration Services, der Analytical Services, der Reporting Services und neu in 2016 der R Services. Die Analytical Services umfassen OLAP-Server zur Datenauswertung und Analyse. Die Reporting Services fassen all jene Werkzeuge zusammen, die mit der Erstellung und Verwaltung von Berichten zu tun haben (Bild 4).

Die Sprache R

Power BI ermöglicht umfangreiche Analysen der Daten (Bild 4)

standen, gravierende Fehler sind hier nicht mehr vorhanden. Infolgedessen gibt es auch keine besonders herausragenden Neuerungen. Eine Tabelle kann nun auf maximal 253 andere Tabellen und Spalten als Fremdschlüssel (ausgehende Referenzen) verweisen. SQL Server 2016 erhöht außerdem den Grenzwert für die Anzahl der anderen Tabellen und Spalten, die auf Spalten in einer einzelnen Tabelle (eingehende Referenzen) verweisen können, von 253 auf 10.000. Ferner unterstützt der neue SQL Server nun auch temporale Tabellen mit Versionsverwaltung.

automatische aktualisierung Die automatische Aktualisierung der Statistik erfolgt jetzt aggressiver für große Bestände. Der Schwellenwert zum Auslösen der automatischen Aktualisierung der Statistik beträgt 20 Prozent. Die INSERT-Anweisung in einer INSERT-SELECTAnweisung erhält mehrere Threads oder kann einen parallelen Plan aufweisen. Das neue Management Studio bietet die Möglichkeit, den Live-Ausführungsplan einer aktiven Abfrage anzuzeigen. Dieser Live-Abfrageplan bietet Echtzeit-Einblicke in den Abfrage-Ausführungsprozess, während die Steuerelemente von

110

Die Implementierung der Dienste der Sprache R ist neu im SQL Server 2016. Die Dienste basieren auf der Analysesprache R und sollen bei der Auswertung der Daten helfen. Die Grundlage für die R Services bildete die Übernahme des Unternehmens Revolution Analytics im Frühjahr 2015. R wird von mehr als 2,5 Millionen Data Scientist und Statistikern genutzt und im Rahmen vieler Statistik-Studiengänge an Hochschulen gelehrt. Es ist eine Sprache von Statistikern für Statistiker. Die Anwender erstellen in R ihre Analysemodelle. Einmal erstellte R-Modelle kann man mit SQL Server 2016 uneingeschränkt weiterverwenden. Darüber hinaus sind über 8000 RPakete frei verfügbar. Skripts, die auf der Sprache R basieren, lassen sich über den Microsoft Azure Marketplace herunterladen und können so in den in SQL Server 2016 integriert werden. Umgekehrt können die Entwickler ihre eigenen R-Skripts auch über den Marktplatz vertreiben. Unternehmen, die eigene Analysen mit R erstellen, können einheitliche Oberflächen und Verwaltungshilfen aufbauen. Die Verknüpfung der relationalen Datenbanken und der Bibliotheken für Analysen erfolgt durch T-SQL.

analyse von Daten Angeboten werden die Analysen in R in zwei Formen, als Dienst (Services) im Kontext des SQL Servers und als eigeständiger Server. Das Ziel ist in jedem Fall die Integration der Source-Sprache R in den Kontext des SQL Servers. R Services unterstützen die Analyse von Daten. Die R Services können daher in das Datenbanksystem des SQL Servers

3.2017 www.webundmobile.de


Datenbank

integriert werden (In-Database). Hierbei unterstützen sie die schnelle Entwicklung, Bereitstellung und Operationalisierung von R-Lösungen, die auf der Grundlage der SQL-Server-Plattform und zugehöriger Dienste erstellt werden. Ferner gehört zu den R Services ein Datenbankdienst, der außerhalb des SQL Servers mit den Diensten des R-Systems kommuniziert. Die Modellierung der Analysen erfolgt als R-Modelle. Sie lassen sich dabei vielfältig bearbeiten und an die Nutzeranforderungen anpassen. Die fertigen Analysen lassen sich in gespeicherten Prozeduren (Stored Procedure) des SQL Servers einbetten. R Plots helfen bei der Bewertung der Analysen (Bild 5). Auswertungen lassen sich zwischen den R-Services und dem SQL Server austauschen. Der Test und die Entwicklung von Anwendungen können auch remote von einem entfernten Computer aus erfolgen. R Services (In-Database) werden die COMPUTE-Klausel auf die Daten in R auf dem gleichen Computer wie die Datenbank ausführen können. Der Microsoft R Server wird als eigenständiges Serversystem angeboten. Er unterstützt verteilte, skalierbare R-Lösungen auf mehreren Plattformen und verwendet mehrere

BaCKEnD

Integration Services all jene Funktionen ab, die man früher den ETL-Tools zugeschrieben hatte. Die Definition und der Integrationsablauf werden in einem Integrationspaket beschrieben, das als Projekt im Designer definiert wird. Die Daten sind somit in den Rahmen von Visual Studio eingeklinkt. Die Integration Services bieten dabei mehrere Editoren, die das Projekt hinreichend beschreiben und spezifizieren. Sie ermöglichen die Definition des Kontrollflusses, des Datenflusses und der Ereignissteuerung. Definiert wird der Integrationslauf der Daten in grafischer Notation, unterstützt durch die notwendigen Attribute in den Eigenschaftsdialogen der Editoren. Dabei werden Schleifenverarbeitung, Fehler-Handling und eine Protokollierung des Integrationslaufs unterstützt. Ferner gehören Debug-Hilfen sowie Werkzeuge zur Untersuchung und Spezifikation der Pakete zum Umfang des Integration-Services-Toolsets. Als Datenquellen kommen all jene in Betracht, die über die gängigen Windows-Mechanismen wie etwa OLE DB, ODBC oder FTP angebunden werden können, und natürlich auch Flat Files. Möglich sind auch Umsetzungen von Daten oder etwa das Nachschlagen von weiteren Daten (das Lookup) in anderen Quellen. Das Ergebnis eines Integrationslaufs sind die zusammengeführten Daten in einem Data Warehouse oder Data Mart. Darauf setzen dann die nachgeschalteten Prozesse und Toolsets des SQL Server 2016 auf. Dies sind die Analytical Services und die Reporting Services.

Die Reporting Services Mit den Reporting Services lassen sich Berichte erstellen, veröffentlichen und verwalten. Diese können dann auf unterschiedliche Weise an die gewünschten Benutzer übermittelt werden, etwa durch Anzeigen Durch den Einsatz von R-Bibliotheken lassen sich vielerlei ansprechende Diagramme der Berichte im Webbrowser, auf erstellen (Bild 5) mobilen Geräten oder als E-Mails in den Postfächern. Im ersten Schritt wird dabei ein Report definiert. Die Definition eines Reports wird in RDL (Report Definition LanEnterprise-Datenquellen, einschließlich Linux, Hadoop und guage), einem XML-Dialekt, vorgenommen. Teradata. Zur Laufzeit wird die RDL-Datei an die Reporting Service Die Integration Services Engine des SQL Servers übergeben. Dort erfolgt das AusleDie Integration Services umfassen all die Dienste zur Zusamsen der benötigten Daten aus den Datenquellen ebenso wie menführung (Integration) von einzelnen Datenquellen zu eider Aufbau des Reports. ner Einheit. Damit sind sie im Prozessablauf auch vor den Da dieser auf RDL basiert, können Reports prinzipiell auch Analytical Services und den Reporting Services anzutreffen. mit einem Editor erstellt werden. Dies ist natürlich ein aufBei den Integration Services handelt es sich um eine Sammwendiges Unterfangen. Der bessere und sicherlich einfachelung von Werkzeugen und programmierbaren Objekten, mit re Weg ist der Aufbau eines Berichts durch einen grafischen denen Daten aus unterschiedlichen Quellen extrahiert und Editor, der dann auch den WYSIWYG-Modus unterstützt. transformiert werden können. Korrespondierend dazu steht ein Self-Service für EndbeDiese gesammelten Daten können dann in ein einzelnes nutzer bereit, der eine vereinfachte Berichterstellung für ▶ Ziel oder in mehrere Ziele geladen werden. Damit decken die Analyse-Umgebungen ermöglicht.

www.webundmobile.de 3.2017

111


Datenbank

Durch seine Einfachheit soll der Report Manager auch ein Ad-hoc-Reporting für den Benutzer ermöglichen. Durch die Offenlegung der Schnittstelle können zudem Drittanbieter eigene Werkzeuge zur Definition von Berichten in das Toolset einbinden. Hinterlegt werden die Report-Definitionen als RDL-File wiederum im SQL Server. Durch rollenbasierte Mechanismen werden dabei weitreichende Zugriffslogiken implementiert. Deren Grundlagen sind das Active Directory und der SQL Server. Der Funktionsumfang der Reporting Services beschränkt sich eindeutig auf das Reporting.

Quelle: Microsoft

BaCKEnD

Die von SQL Server Reporting Services bereitgestellten Dienste helfen beim Aufbau von Berichten für unterschiedliche Geräte (Bild 6)

Data-Mining-Verfahren In Kontext des SQL Server 2016 bezieht sich das Reporting meist auf die Massendaten für das Tagesgeschäft. Die Auswertungen sind im Vergleich zu den Analysen und Data-Mining-Verfahren meist von einfacher Natur. Dazu zählen etwa Listen mit Zwischensummen oder Durchschnittswerten. Als Datenquelle dafür kommen relationale oder OLAP-Daten in Betracht. Das sind neben dem schon erwähnten Data Warehouse auch davon unabhängige Datenquellen. Sollten die Daten aus unterschiedlichen Datenhaltungssystemen aggregiert werden müssen, so geschieht auch das über

Zum Umfang der analytical Services gehören die Funktionen des Data Mining (Bild 7)

die unterschiedlichen Schnittstellen. Und da diese Interfaces für nahezu alle Datenquellen verfügbar sind, sollte hierbei auch kein Engpass auftreten. Bezüglich der zeitlichen Steuerung sind verschiedene Verfahren anwendbar. Sie werden durch eine Scheduling-Funktion unterstützt. Bleibt nur noch die Verteilung und Ausgabe der Berichte auf die Zielgeräte, die durch Erweiterungen der Reporting Services vorgenommen werden. Diese Erweiterungen kümmern sich um die Verteilung der Berichte mittels E-Mail oder als Dateiablagen. Hierbei unterstützt das Dienstpaket alle gängigen Formate, einschließlich HTML und PDF, aber auch die Übergabe an weitere Portale oder Dienste.

112

Aus der Verbindung der Zeitsteuerung für die Erstellung der Berichte und den Abonnementfunktionen lassen sich dabei regelmäßige Berichtsläufe erzeugen, deren Ergebnisse auch automatisch an die Empfänger übertragen werden. Ferner ist eine Integration der Berichte in bestehende Anwendungen programmierbar (Bild 6).

Die analytical Services Erweiterungen gibt es zudem hinsichtlich der Analytical Services. Ähnlich wie bei den Reporting Services stellen die Analytical Services in erster Linie eine Entwicklungsplattform dar. Für die eigentliche Analyse der Daten können die Anwender auf verschiedene Tools und Hilfen zurückgreifen. Verglichen mit dem Vorgänger hat man vor allem daran gearbeitet, die Entwicklung dieser Anwendungen zu vereinfachen. Die Entwicklung dieser Anwendungen kann auch aus Visual Studio heraus erfolgen. Hierfür werden eine Reihe von Assistenten und Design-Tools bereitgestellt. Assistenten helfen bei der Erstellung von Datenanalysen. Eingeschlossen sind auch Hilfen zur Modellierung. Diese vereinfachen den Aufbau von Datenmodellen und den Relationen der Daten zueinander. Sie stellen außerdem auch die Grundlage für die weitere Analyse dar. Für die Analyse steht der Data Mining Assistent zur Verfügung (Bild 7). Der Assistent sammelt eigenständig die Daten und bringt sie in Abgleich mit dem verwendeten Mining-Algorithmus. Hierzu gehört die selbstständige Integration sowohl von demografischen Daten als natürlich auch von trans◾ aktionalen Datenbeständen.

Johann Baumeister hat Informatik studiert und verfügt über langjährige Erfahrung in der Entwicklung, der Anwendung und dem Rollout von IT-Systemen. Außerdem ist er als Autor für zahlreiche ITPublikationen tätig. redaktion@webundmobile.de

3.2017 www.webundmobile.de


Jetzt kostenlos testen!

Das Fachmagazin fĂźr IT-Entscheider 2 Ausgaben kostenlos testen. Mit exklusivem Zugang zu unseren Digitalausgaben. Business-Newsletter inklusive.

www.com-magazin.de/gratis


BEyOnD DEV

Grafik für Entwickler

GRaFIK FüR EnTWICKLER

Bilder, die Geschichten erzählen Ob nonverbale Kommunikation oder Schlüsselreiz: Bilder, die Geschichten erzählen, sind nicht nur in der Werbung wichtig.

W

eihnachten 2016 bei Coca-Cola: Zu sehen ist der Weihnachtsmann mit weißem Rauschebart und seiner Colaroten Kutte. Im nächtlichen Schneegestöber trinkt er in genießerischen Zügen seine nach der anstrengenden Vorweihnachtszeit wohlverdiente Coke. Außer dem Coca-ColaSchriftzug ist auf der Titelseite ein Weihnachtsgruß zu lesen,

Doch wie funktioniert Werbung? Zunächst sind die reinen Informationen zum Produkt nebensächlich. Gut gemachte Werbung soll Neugierde wecken und somit den potenziellen Käufer beeinflussen. Neugierig geworden möchte der Betrachter erfahren, was das Produkt „mit ihm macht“, was es bewirkt. Die eigentlichen Fakten zum Produkt sind zunächst unwichtig. Werbung funktioniert bei nahezu allen Produkten deutlich besser, wenn sie mit Bildern arbeitet, die eine Geschichte erzählen. Selbst wenn bestimmte Eckdaten für das Produkt wichtig sind. Beispiel Auto: Natürlich möchte jeder Käufer exakte Informationen zur Leistung des gewählten Fahrzeugs, dem Benzinverbrauch oder dem Preis haben. Zunächst bestimmt jedoch das Lebensgefühl oder das Image, das durch das neue Auto vermittelt wird, welche Modelle in die nähere Auswahl gelangen. Gerade für alle potenziellen Käufer, die noch keiner bestimmten Marke treu sind, tragen dann die passenden Bilder auf der Herstellerseite mit dazu bei, dass der gezeigte

Weihnachten bei Coca-Cola: Ein einziges Bild erzählt eine ganze Geschichte (Bild 1)

weiter unten wird auf den Weihnachtsfilm verwiesen. Doch bereits das Bild erzählt eine Geschichte, die den Betrachter sofort anspricht – und damit das Produkt nahebringt (Bild 1). Anders bei Wikipedia: »Coca-Cola, kurz Coke, ist ein geschütztes Warenzeichen für ein kohlensäurehaltiges Erfrischungsgetränk der Coca-Cola Company«. Daneben das Coca-Cola-Emblem. Unterhaltsamer und deutlich werbewirksamer ist jedoch die Site des Herstellers. Mit dem Konsumieren des koffeinhaltigen Getränks möchte der Verbraucher nicht nur genießen, er hofft auch dadurch neue Energie zu gewinnen – was der Coke-trinkende Weihnachtsmann besser vermittelt als die nüchterne Aufzählung der Inhaltsstoffe in dem OnlineLexikon. Um den Betrachter zu erreichen, ist es also hilfreich, eine Geschichte zu erzählen. Ob Erfrischungsgetränk, Auto oder Versicherung – alle Produkte oder Dienstleistungen müssen sich auf dem Markt positionieren und gegen die Konkurrenz abheben, um so potenzielle Kunden zu gewinnen.

114

Der Mini Countryman und der Porsche Cayman sprechen völlig unterschiedliche Zielgruppen an (Bild 2)

3.2017 www.webundmobile.de


Grafik für Entwickler

BEyOnD DEV

Wagen in die engere AusBild zu sehen, hilft es, die wahl gelangt. Bild 2 zeigt entsprechende Mimik, Gesoben die Seite zu dem Mini tik oder eine zum Anliegen Countryman, unten ist der passende Körperhaltung abPorsche Cayman zu sehen. zubilden. Beide Fahrzeuge sind sozuZum Beispiel die frühere sagen in Action vor der pasWerbung der Zigarettenmarsenden Kulisse abgebildet – ke Marlboro: Hier gab es den und visualisieren sehr geeinsamen Cowboy, der sich konnt zwei ganz verschiedenach getaner Arbeit eine Zine Träume: Der Mini schafft garette ansteckt. Lässig saß auch die engste Bergstraße er vor dem Lagerfeuer, ein im staubigen Gelände. Ein freier Mann, der mit allen Fahrzeug, das »Mehr Aben- Schwäbisch Hall greift mit dem Titelbild den Wunsch nach einer Widrigkeiten gut zurechtteuer« verspricht. Der Por- glücklichen Familie im Eigenheim auf (Bild 3) kommt, der handelt: »Don’t sche hingegen suggeriert seibe a maybe«. Eine solche nem zukünftigen Fahrer, Idealisierung von Zigaretten »Mitten im Sport« zu sein. Schnell und dabei sicher flitzt er ist heute nicht mehr erlaubt, seit Januar 2017 flimmern ähnauf der Schnellstraße um die Kurve, so schnell, dass er nur liche Werbefilme auch nicht mehr über deutsche Kinoleinnoch von hinten zu sehen ist. wände. In dieser Art gestaltete nonverbale Kommunikation Ein weiteres Beispiel: Bausparen bei Schwäbisch Hall. Hier funktioniert hervorragend; bestimmt auch mit ein Grund dareicht der junge Vater – nicht die Mutter! – seinem Baby die für, dass immer mehr Menschen auf Werbebildern zu sehen Flasche. Unterstützt wird dieses Bild durch den Schriftzug sind – gerade bei der Werbung von Genussmitteln oder Lu»Bausparen macht glücklich: Top-Darlehenszinsen sichern.« xusgütern. Nonverbale Kommunikation muss jedoch nicht zwangsläuDer günstige Bausparvertrag rückt das ersehnte Eigenheim fig ein bestimmtes Produkt verherrlichen. Ein passendes Bild um gefühlte Jahrzehnte näher – und verspricht damit Platz kann auch kritische Aspekte an den Mann bringen. Als Beiund Zeit für die eigene Familie (Bild 3). spiel ein Artikel aus dem Magazin Brigitte: »6 Lebensmittel, nonverbale Kommunikation die tabu sein sollten, wenn du jenseits der 25 bist!« Ein Bild Zunächst verspricht Werbung also die Erfüllung unserer der sechs verbotenen Lebensmittel würde keine Geschichte Träume und Wünsche. Um das zu erreichen, muss eine gut erzählen. Diese kommt erst durch den Gesichtsausdruck zugestaltete Werbebotschaft gezielt die unterschiedlichen Sinstande, der beim Verzehr des bunten Sahnetörtchens zu sene ansprechen. Wird das Produkt rein digital dargestellt, falhen ist. Zwar verspricht die Süßigkeit einen nahezu himmlilen Fühlen und Riechen weg; umso mehr müssen die Bilder schen Genuss, dem die Dame kaum widerstehen kann; herzstimmen. Und diese stimmen haft beißt sie ab. Ihre ganze dann, wenn sie eine GeMimik verrät jedoch, dass sie schichte erzählen. durchaus weiß, wie ungesund Bilder, die Geschichten erdas Törtchen ist. Vermutlich zählen, sind nicht nur auf wird sie der Versuchung troteinschlägigen Verkaufsseizen und das Objekt ihrer Beten zu finden. Wie bei der gierde vernünftig beiseiteWerbung sorgen beispielslegen (Bild 4). weise auch in einem OnlineSchlüsselreize Magazin gerade die Bilder Neben Mimik, Gestik und dafür, die Aufmerksamkeit Körperhaltung bestimmen des Lesers zu erreichen. verschiedene Schlüsselreize Gleiches gilt für jede digitale wie wir auf bestimmte DarAnwendung, ob es sich nun stellungen mehr oder wenium die neueste Wetter-App ger automatisch reagieren. handelt oder um das hippe Ein Schlüsselreiz ist ein, in Online-Spiel. der Regel angeborener Reiz, Die Geschichte, die in eider ein bestimmtes Verhalten nem Bild steckt, muss von auslöst. Sexuelle Schlüsseldem angesprochenen Zielreize beispielsweise wecken publikum in kürzester Zeit Begehrlichkeiten verschiedeentschlüsselt werden kön- nonverbale Kommunikation: Auch wenn es noch so lecker ist, ner Art. Auf der Online- ▶ nen. Sind Menschen auf dem sie wird das Törtchen nicht essen (Bild 4)

www.webundmobile.de 3.2017

115


BEyOnD DEV

Grafik für Entwickler

Präsenz des Magazins Mens’s Health, das sich offensichtlich eher an Männer richtet, ist meistens ein männlicher muskulöser Körper mit breiten Schultern und flachem Bauch zu sehen – männliche sexuelle Schlüsselreize. Hier soll der eigene Körper mit den entsprechenden Mitteln in dieser Art geformt werden (Bild 5). Andere Wünsche und Träume wecken die Schlüsselreize bei der Spiele-App Lara Croft Relic Run: Hier turnt eine digitale Schönheit halsbrecherisch in schwindelnden Höhen, um auch dem gruseligsten Feind zu entkommen und letztendlich »die Wahrheit ans Licht zu bringen«. Auch hier der sexuelle Schlüsselreiz: ein schlanker Körper mit wohlproportionierten Rundungen – in eher wenig sittsame, eng anliegende Hüllen gepackt. So verfehlt hier auch die digitale Darstellung einer attraktiven Frau nicht ihre Wirkung: Dank ihrer Schlüsselreiz-besetzten Figur mit Körbchengröße D erfüllt Lara das Rollenklischee perfekt. Schließ-

Men’s Health liefert Muskeln und Sixpack als Ziel aller Begehrlichkeit (Bild 5)

Versteckter sexueller Schlüsselreiz: Digitalmädchen Lara Croft mit wohlgeformten Kurven (Bild 6)

lich richtet sich das Spiel wohl eher an (große) Jungs und Männer, die dann ihre Geschichte leben, zusammen mit der attraktiven Lara (Bild 6). Ein weiterer Schlüsselreiz, der nicht nur in der Werbung sehr häufig bemüht wird, ist das Kindchenschema: Zeigt ein Körper einen zum Körper verhältnismäßig großen Kopf, große Augen und dabei eine kleine Nase, löst dieses Bild unseren Beschützerinstinkt aus. Diese instinktive Reaktion erfolgt nicht nur beim Anblick eines Babys, sondern auch bei jungen Tieren oder bei Säugetieren, die entsprechende Körpermerkmale aufweisen. So zeigt beispielsweise auch ein ausgewachsener Pandabär Körperproportionen, die dem Kindchenschema entsprechen (Bild 7). Wie die sexuellen Schlüsselreize bei Lara Croft funktioniert auch das Kindchenschema besonders gut bei entsprechend gezeichneten oder dreidimensional gestalteten Comic-Charakteren. Bekannt dafür sind etwa die Figuren von Walt Disney, der ihnen die reizgebenden Körpermerkmale in übersteigerter Form verliehen hat: Ob es nun Micky Maus, Donald

Wirkung durch Formen Die Wirkung eines Bildes beruht auch auf der entsprechenden Formgebung. So kann bereits ein einzelner Punkt durch seine Anordnung auf einer definierten Fläche unterschiedliche Eindrücke hinterlassen, etwa beweglich oder fixiert, leicht oder schwer. Dabei ist die Größe des Punktes unwesentlich, alleine die Position schafft diesen Eindruck. Kommen weitere Formen hinzu, wird die Bildaussage deutlicher. So kann beispielsweise eine Linie neben ihrer Position noch eine Drehung zeigen. Sie gibt – anders als der Punkt – eine bestimmte Richtung an. Diese Richtung kann durch die Kombination mit weiteren Formen bestimmt werden, etwa durch einen Punkt, der quasi als Verlängerung der Linie dient: So wird der Punkt zum Ziel.

116

Liegt der Punkt jedoch nicht auf der Verlängerung der Linie, wird die Linie zur Grenze; sie teilt die Fläche in zwei Bereiche, von denen einer durch den Punkt besetzt ist – ein erster Eindruck von Raum entsteht. Kommen weitere Linien hinzu, entstehen Muster, sofern die Linien in einem bestimmten System angeordnet werden. Zudem können mehrere Linien eine räumliche Wirkung erzeugen. Ein solches System kann auch Perspektive beinhalten. Viele einzelne Formen können dann konkrete Bilder erzeugen. So ist letztendlich jedes Bild nichts anderes als ein Zusammenspiel vieler Punkte. Funktioniert in einem Bild auch die abstrakte Zusammenstellung wichtiger Kernpunkte, wird die Aussage deutlicher. Das Bild erzählt eine Geschichte.

Die Platzierung von Punkten und Linien können die Geschichte im Bild unterstützen

3.2017 www.webundmobile.de


Grafik für Entwickler

BEyOnD DEV

Schlüsselreiz Kindchenschema: Baby, Katzenjunges und ausgewachsener Panda zeigen die gleichen Merkmale (Bild 7)

Duck (Bild 8) oder auch die aktuell bei allen Kindern beliebte Prinzessin Elsa aus dem Computeranimationsfilm von Walt Disney Pictures ist. Alle Figuren zeigen in ihren im Verhältnis zum Körper riesigen Köpfen große Augen, eine hohe Stirn, kleine Nasen sowie die Frauen einen zierlichen Unterkiefer. Die aus Japan kommenden Manga-Figuren funktionieren ebenfalls nach dem Kindchenschema. Die Merkmale dieser Comic-Gestalten sind überzogen kindliche Gesichter mit großen Augen und kleine schmächtige Körper (Bild 9).

mangafox.me

Disneys Figuren, hier etwa in einer Spiele-App zur Schneekönigin, orientieren sich am Kindchenschema (Bild 10)

nach Micky Maus schuf Walt Disney Donald Duck, die liebenswerte Chaosente, nach dem Kindchenschema (Bild 8)

Japanische Mangas haben neben Walt Disneys Figuren das Kindchenschema in der Comicwelt etabliert (Bild 9)

Dabei verfehlen solche Figuren ihre Wirkung nicht. Der durch das Kindchenschema geweckte Beschützerinstinkt erzeugt positive Gefühle, die wiederum die Bereitschaft zum Kauf verschiedener Produkte steigert, die sich Bilder dieser Figuren zu eigen machen. Als Beispiel sei die Spiele-App »Die Eiskönigin – Free Fall« genannt: Hier zeigt der Startscreen verschiedene Figuren aus dem Disney-Film »Die Eiskönigin – Völlig unverfroren« (Bild 10).

Bild-Betrachter-Beziehung Bleiben wir beim zuvor genannten Beispiel »Die Eiskönigin Free Fall«. Zwar läuft der Film dazu bereits seit 2013 in den deutschen Kinos, Figuren daraus, wie etwa Prinzessin Elsa, Anna oder der Schneemann Olaf, sind in deutschen Kinder-

www.webundmobile.de 3.2017

gärten und Grundschulen aber immer noch allgegenwärtig und bestimmen dort maßgeblich das gemeinsame Spiel. Das Kindchenschema spricht also nicht nur Erwachsene an, Bilder dieser Art versetzen vielmehr auch Kinder in eine emotional positive Grundstimmung. Doch spielt hier ein weiterer Faktor eine entscheidende Rolle: die Erfahrung des Betrachters. Wohl jedes Kind ab einem bestimmten Alter wird Prinzessin Elsa kennen. Hat es den Film nicht gesehen, so kennt es zumindest die Handlung aus Erzählungen und Spielen der anderen Kinder. Das Startbild der besagten Spiele-App der Eiskönigin ruft also voraussichtlich bei Kindern die komplette Geschichte ins Gedächtnis. Sicher werden sich darauf die meisten von ihnen sehnlichst das digitale Spiel wünschen – ohne etwas vom Spieleablauf zu wissen. Das Bild funktioniert also nicht nur aufgrund seines Kindchenschemas: Es lässt eine bekannte Geschichte neu aufleben und weckt somit Wunschträume bei den kleinsten Anwendern digitaler Geräte.

Fazit Erst durch einen gezielten Einsatz von passenden Bildern wird die Aufmerksamkeit des Betrachters erreicht. Dabei sollten verschiedene Aspekte berücksichtigt werden. So sollte die Bildfläche so aufgeteilt sein, dass die Linien-und Flächenführung die Bildaussage unterstützt. Hinzu kommen Überlegungen zur Zielgruppe und dazu, welche Grundvoraussetzungen diese zum Thema mitbringt. Davon abhängig ist dann ◾ auch der Einsatz von visuellen Schlüsselreizen.

Katharina Sckommodau arbeitet als freiberufliche Autorin, Grafikerin und Dozentin, unter anderem für die Akademie der Bayerischen Presse und für Macromedia. redaktion@webundmobile.de

117


BEyOnD DEV

Fire TV Stick

SMaRT-TV-aPPLIKaTIOnEn FüR FIRE TV

Unter Feuer Fire TV von Amazon möchte existierende Fernsehgeräte in Smart TVs umwandeln.

F

ür Entwickler bieten sich hier fast unbegrenzte Möglichkeiten. Neben der Entwicklung von Casual Games (Schema: Mario Party), die man am Fernseher spielen kann, ist Amazon auch an Produkten interessiert, die vorhandene Medieninhalte auf eine bequemere Art und Weise bereitstellen. Die Erstellung derartiger Applikationen wird durch ein SDK erleichtert, das Amazon als Fire App Builder bezeichnet. Dieser Artikel möchte neben einer Vorstellung von Fire App Builder auch einige allgemeine Hinweise zur Erzeugung von attraktiven Smart-TV-Applikationen geben. Zum Zeitpunkt der Drucklegung umfasst die Fire-TV-Produktfamilie einige Mitglieder. Wir wollen in den folgenden Schritten auf dem für rund 40 Euro erhältlichen Fire TV Stick zurückgreifen (Bild 1). Die Inbetriebnahme des Fire TV ist im Großen und Ganzen einfach: Amazon liefert neben dem in Bild 2 gezeigten Controller ein Adapterkabel, mit dem man den Stick auch an Workstation-Monitore mit nach unten zeigendem HDMI-Port anschließen kann. Zudem gehört noch ein Netzteil mit MicroUSB-Anschluss zum Lieferumfang, dessen Nutzung empfehlenswert ist. Neben der Fernbedienung des Basispakets gibt es auch eine Version des Fire TV Sticks, die stattdessen einen an PlayStation und Xbox erinnernden Controller mitbringt. Für Entwickler, die an Medienanwendungen arbeiten, ist dies nicht relevant. Wer hingegen ein Spiel programmiert, sollte die rund 30 Euro Mehrpreis in Kauf nehmen. Aufgrund eines kleinen Fehlers im Bereich des Industriedesigns von Amazon ist es empfehlenswert, zum Öffnen der Fernbedienung einen Flachschraubenzieher zu verwenden und den Deckel damit nach unten zu schieben. Bild 3 zeigt die Fernbedienung in zerlegtem Zustand. Folgen Sie sodann den am Bildschirm eingeblendeten Hinweisen, um WLAN und Co. einzurichten. Ein interessantes Detail ist, dass die Hardware des Fire TV Sticks automatisch das Konto ergreift, das zum Erwerb eingesetzt wurde. Berücksichtigen Sie dies insbesondere dann, wenn Sie den Fire TV Stick für einen Kollegen kaufen.

Funktioniert auch mit Display Der Autor nutzt seinen Fire TV Stick mit einem HP-Monitor. Fernseher sind für die Arbeit im Labor zu unhandlich. Achten Sie allerdings darauf, Inhalte vor der Auslieferung auch mit einem echten Fernsehgerät zu prüfen – der wesentlich höhere Betrachtungsabstand stellt Ansprüche an das GUI-Design. Das im Rahmen des ersten Starts verpflichtend eingeblendete Werbevideo lässt sich durch mehrfaches Drücken der Nach-vorn-Taste überspringen. Nach getaner Arbeit fin-

118

Der Fire TV Stick ist nicht sonderlich groß (Bild 1)

Eingaben nimmt Fire TV über eine an ältere iPods erinnernde Fernbedienung entgegen (Bild 2)

den Sie sich im Homescreen wieder, der als Ausgangsbasis für weitere Erkundungen des Fire TV Sticks dienen wird (Bild 4). Nach der erfolgreichen Einrichtung der Hardware stellt sich die Frage, wie Sie optimal mit dem Fire TV arbeiten. Der USB-Anschluss lässt sich theoretisch auch zum Debuggen verwenden. Dies ist insofern nicht ratsam, als der Fire TV Stick wegen seines hohen Stromverbrauchs viele Workstations überfordert und einige Features wie das Anschließen von externen Speichermedien in diesem Fall nicht zur Verfügung stehen. In den folgenden Schritten arbeiten wir deshalb über WLAN. Ist das verwendete Netzwerk schnell, so geht die Fehlersuche nicht allzu unkomfortabel von der Hand. Wechseln Sie in die Rubrik Einstellungen, wo Sie daraufhin in die

3.2017 www.webundmobile.de


Fire TV Stick

BEyOnD DEV

connected to 192.168.0.102:5555 tamhan@TAMHAN14:~/Android/Sdk/platform-tools$ ./adb devices List of devices attached 192.168.0.102:5555

nach dem Zerlegen der Fernbedienung kann man die beiden AAA-Batterien einbauen (Bild 3)

device

Dabei weist das erste Kommando die Android Debug Bridge (ADB) darauf hin, dass sie eine Verbindung zu einem Netzwerkgerät aufbauen muss. Im zweiten Schritt prüfen wir durch Nutzung des devices-Parameter, ob die Verbindung auch wirklich aufgebaut wurde. Damit ist die Einrichtung des Fire TV auch schon abgeschlossen. Zumindest so lange, bis ADB die Verbindung zum Stick aufgrund eines Neustarts oder aus anderen Gründen verliert. Ab diesem Zeitpunkt verhält sich der Fire TV Stick aus Sicht von Android Studio wie ein gewöhnliches, per USB mit der Workstation verbundenes Telefon.

Kampf den Medien Unterrubrik System und dann in die Unterrubrik Entwickleroptionen wechseln. Aktivieren Sie dort die Optionen ADBDebugging und Apps unbekannter Herkunft. Die Option für das USB-Kabel wird nur dann eingeblendet, wenn der Fire TV Stick mit einer Workstation verbunden ist. Im nächsten Schritt müssen Sie die IP-Adresse des Sticks herausfinden. Die MAC-Adresse des Fire TV des Autors lautet 81:77:E5:A8:6D:DA. Halten Sie nach einer ähnlichen Adresse Ausschau, wenn Sie nach dem Stick im Router-Backend recherchieren. Als Alternative dazu bietet sich die Auswahl der Menüoption System, Info und Netzwerk an. Der Fire TV Stick zeigt dort seine IP-Adresse an (Bild 5). Als erfahrener Entwickler ist Ihnen natürlich klar, dass an dieser Stelle Android Studio erforderlich ist. Starten Sie die IDE wie gewohnt und öffnen Sie danach ein Terminalfenster, in dem Sie in das Installationsverzeichnis Ihres SDK navigieren. Dort geben Sie folgende Befehlssequenz ein: tamhan@TAMHAN14:~/Android/Sdk/platform-tools$ ./adb connect 192.168.0.102 * daemon not running. starting it now on port 5037 * * daemon started successfully *

Über die Vorteile von Kommunalität müssen wir an dieser Stelle nicht berichten: Verhält sich ein Programm so wie alle anderen Programme auf demselben System, so kommen die

Dieser Dialog erspart Ihnen das Herumfuhrwerken im Backend Ihres Routers (Bild 5)

Benutzer schneller damit zurecht. Das gilt in besonderem Maße für Applikationen, die zur Unterhaltung dienen. Wer eine Abspielsoftware für unterhaltsame Videos erst nach langem Handbuchstudium bedienen kann, sucht sich ein anderes Programm. Im Fall des Fire TV bietet Amazon mit dem in der Einleitung erwähnten Fire App Builder eine Erweiterung an, die Android Studio um eine Art Projektgenerator ergänzt. Dieser ist auf die Erzeugung von Streaming-Media-Anwendungen optimiert. Es handelt sich dabei um den wohl häufigsten Anwendungsfall von Smart-TV-Produkten überhaupt. Die Beschaffung des Codes muss über GitHub erfolgen. Wechseln Sie in ein Verzeichnis Ihrer Wahl und führen Sie unter Windows-Workstations folgendes Kommando aus: git config –global core.symlinks true

Ähnlichkeiten zum Menü der Xbox sind rein zufällig (Bild 4)

www.webundmobile.de 3.2017

Das Setzen der Umgebungsvariable ist erforderlich, weil der Builder symbolische Links voraussetzt, die von Windows von Haus aus nicht unterstützt werden. Fehlen diese, so scheitert die Kompilation mit diversen Fehlermeldungen. Im nächsten Schritt können Sie das eigentliche Herunterladen des Codes folgendermaßen anstoßen. Beachten Sie ▶

119


BEyOnD DEV

Fire TV Stick

dabei, dass Git die angewiesenen Daten automatisch im Arbeitsverzeichnis ablegt:

package="com.amazon.android.calypso"> <application android:allowBackup="true" android:label="@string/app_name"

tamhan@TAMHAN14:~/firetvbuilder$ git

android:name="com.amazon.android.tv.

clone https://github.com/amzn/

tenfoot.base.TenFootApp"

fire-app-builder.git

...>

Cloning into 'fire-app-builder'...

Neben der Möglichkeit zum Anpassen des Paketnamens finden Sie hier auch die Quelle der Strings, die für den Programmnamen zuständig sind. Falls Sie sich wundern: Die zum Applikationsprojekt gehörende Manifest-Datei findet sich in der Projektstrukturansicht ganz unten (Bild 7). App-Builder-Projekte bestehen aus einer Vielzahl verschiedener Module. Je nach Ausbau können Sie schon mal zwei Dutzend Ordner auf dem Bildschirm haben.

remote: Counting objects: 1275, done. remote: Total 1275 (delta 0), reused 0 (delta 0), pack-reused 1275 Receiving objects: 100% (1275/1275), 7.79 MiB | 1.59 MiB/s, done. Resolving deltas: 100% (334/334), done. Checking connectivity... done. tamhan@TAMHAN14:~/firetvbuilder$

Quelle: Amazon

Für die Arbeit mit dem Builder ist eine Vielzahl von SDK-Komponenten erforderlich. Wer diese nicht im Rahmen der alles in XML Kompilation Schritt für Schritt herunterNach dem erfolgreichen Kompilieren des laden möchte, kann dies via Amazon Projekts ist es an der Zeit, zu schauen, auch en bloc tun (Bild 6). was wir hier bekommen haben. Führen Das GitHub-Repository enthält unter Sie das Projektskelett auf dem Stick aus, anderem einen Ordner namens Applicaum sich am Startbildschirm zu erfreuen. tion, der eine komplette BeispielapplikaDie vom Fire App Builder bereitgestelltion bereitstellt. Da Amazon im Lauf der te Applikation ist im Grunde genommen Zeit Updates anbieten wird, ist es nicht ein klassischer Media Viewer, der die in empfehlenswert, den Inhalt direkt zu verForm eines XML-Feeds anzuliefernden ändern. Wer es trotzdem tut, muss beim Medieninhalte auf eine attraktive Art nächsten Update mit manuell aufzulöund Weise grafisch aufbereitet (Bild 8). senden Konflikten rechnen. Das gesamte Produkt ist eine Gruppe Öffnen Sie stattdessen das Hauptvervon Klassen, deren Verhalten vom Entzeichnis der heruntergeladenen Inhalte alle gelb unterlegten Komponenten wickler über JSON-Dateien beeinflusst und kopieren Sie den Applications-Ord- können bei der Arbeit erforderlich sein wird. Als Erstes wollen wir uns der Frage ner mit dem Dateimanager Ihrer Work- (Bild 6) zuwenden, wo die Konfiguration der Dastation. In den folgenden Schritten gehen tenquelle erfolgt. Die Antwort darauf wir davon aus, dass das Verzeichnis den liegt im Verzeichnis assets/configurations, wo die Datei DataNamen NMGFireApplication trägt. Öffnen Sie das VerzeichLoadManagerConfig.json folgenden Inhalt aufweist: nis mit der bekannten Option des Willkommensbildschirms von Android Studio (Open Existing Android Studio Project). { Stoßen Sie an dieser Stelle eine Rekompilation des Projekts "data_downloader.impl": "com.amazon.dataloader. an, um weitere notwendige Abhängigkeiten herunterzuladatadownloader.BasicHttpBasedDataDownloader", den. Wundern Sie sich nicht, wenn mehrere Durchläufe er"is_cache_manager_enabled": true, forderlich sind: Das Buildsystem hat die unangenehme Ei"data_updater.duration": 14400 genschaft, bei jedem Durchlauf nur eine fehlende Kompo} nente zu monieren. Beachten Sie zudem, dass ein eventuell schon vorhandenes build-Verzeichnis unter Umständen ausAmazon bietet seinen Entwicklern in vielen Fällen mehrere geräumt werden muss, um Gradle das erfolgreiche ZusamImplementierungen desselben Prozesses an. Im Fall der Bemenbauen der Applikation zu ermöglichen. schaffung von Inhalten gibt es beispielsweise mehrere mögIm nächsten Schritt müssen Sie die Manifest-Datei ein weliche Quellen. nig anpassen. Die für uns relevanten Passagen sehen folgenDie Auswahl der zu verwendenden Version der Logik erdermaßen aus: folgt im gesamten Produkt durch Übergabe des Klassenna<manifest xmlns:android="http://schemas.android.com/apk/ mens der gewünschten Variante. Hier nutzen wir einen prires/android" mitiven HTTP-Downloader, der einfach einen URL aberntet.

120

3.2017 www.webundmobile.de


Fire TV Stick

BEyOnD DEV

Interessanterweise erfolgt das eigentliche Festlegen der Quell-URLs in der Datei assets/urlFile.json. Zum Zeitpunkt der Drucklegung liefert Amazon hierbei folgende Inhalte aus – der Grund für das Vorhandensein mehrerer Adressen erschließt sich im weiteren Verlauf des Artikels: { "urls": [ Quelle: Amazon

"http://www.lightcast.com/api/firetv/channels. php?app_id=263&app_key=4rghy65dcsqa&action= channels_videos", "http://www.lightcast.com/api/firetv/channels. php?app_id=249&app_key=gtn89uj3dsw&action= channels_videos",

Zum Zeitpunkt der Drucklegung entführt Amazon seine Entwickler nach Jamaica (Bild 8)

"http://www.lightcast.com/api/firetv/channels. php?app_id=267&app_key=6tgbfr4edc2x&action= channels_videos",

"ContentContainerTranslator",

"http://www.lightcast.com/api/firetv/channels.

"modelType": "array",

php?app_id=273&app_key=u8jnsaq2rfgy&action=

"query": "$..categories[*]",

channels_videos"

"queryResultType": "[]$", "matchList": [

]

"StringKey@name"

} ],

Amazon bietet Entwicklern mehrere Wege zum Herunterladen von Feedinformationen an. Die unter der Adresse https:// developer.amazon.com/public/solutions/devices/fire-tv/docs /fire-app-builder-load-media-feed#types-of-feeds bereitstehende Übersicht bietet Informationen zu hier nicht behandelten exotischeren Methoden. Das Anliefern der darzustellenden Medien erfolgt sodann über zwei als Rezept bezeichnet Konfigurationsdateien: Die eine ist für das Festlegen der Kategorien zuständig, während die andere dafür sorgt, dass die angelegten Gruppen mit Medieninhalten bevölkert werden. Diese für den Entwickler etwas umständliche Vorgehensweise erweist sich in der Praxis insofern als sinnvoll, als auf diese Weise die Struktur des resultierenden Programms schnell und unbürokratisch an beliebige Feed-Formate angepasst werden kann. Die insbesondere in größeren ContentUnternehmen nur schwer realisierbaren Anpassungen des Feed-Layouts können durch Adjustierung der verwendeten Query-Strings umgangen werden. Amazons App Builder nimmt Informationen sowohl als JSON- als auch als XML-Feld entgegen. Das von Amazon bereitgestellte Beispiel benutzt JSON, weshalb das Kategorienrezept assets/recipes/LightCastCategoriesRecipe.json in folgender Weise aufgebaut ist:

"keyDataType": "StringKey@keyDataPath" }

cooker legt zunächst fest, welche Klasse für die Verarbeitung der angelieferten Informationen zuständig ist. Wichtig ist in diesem Kategorienrezept eigentlich nur format, das die Nutzung von JSON oder XML anweist. Der Query-String bestimmt sodann, welche Anfrage gegen die Datenquelle gestellt werden muss, um eine Liste der in ihr enthaltenen Kategorien zu bekommen. Über das matchList-Attribut erfolgt schließlich die Zuweisung zwischen den angelieferten Informationen und den Feldern des App Builders. Im Moment schreiben wir hier nur den String mit den Kategorie-Informationen ins Backend. Das hier verwendete Categories-Rezept lässt sich leicht verstehen, wenn wir folgenden Ausschnitt aus dem von Amazon bereitgestellten Feed betrachten: [ { "id":"136211", "title":"Legends Beach Resort, Negril Jamaica", ... "categories":[ "Jamaican Attractions" ], "channel_id":"13671"

{

}, "cooker": "DynamicParser",

{

"format": "json",

"id":"136216",

"model": "com.amazon.android.model. content.ContentContainer", "translator":

www.webundmobile.de 3.2017

"title":"Falmouth Jamaica

Das Beispielprojekt bringt eine Vielzahl von Komponenten mit (Bild 7)

Nature's Lullaby ", ...

121


BEyOnD DEV

Fire TV Stick

"categories":[ "The Country Jamaica" ], "channel_id":"13672"

Das hier gezeigte – und stark gekürzte – Snippet druckt die von Amazon verwendeten Video- und Thumbnail-URLs aus Platzgründen nicht ab. Beachten Sie, dass die Kategorien inline, also im Rahmen der Deklaration der einzelnen Videos entstehen. Es gibt normalerweise kein separates CategoriesArray, in dem die Felder angelegt werden. Duplikate sind hierbei übrigens kein Problem: Der String-Parser erkennt mehrfach vorkommende Einträge in der Kategorienliste und eliminiert sie automatisch. Wer JSON nicht mag, kann in den folgenden Schritten stattdessen auf XML setzen. Aus diesem Grund müssen wir im ersten Schritt einen Feed anlegen, dessen Struktur beispielsweise folgendermaßen aussehen könnte: <?xml version="1.0" encoding="utf-8"?> <rss version="2.0"xmlns:media="http://www.example.com"> <channel> <title>Willkommen bei Tamoggemon </title> <description>Alles über Elektronik</description> <lastBuildDate>Mon, 28 Dec 2016 22:55:16 GMT </lastBuildDate> <ttl>5</ttl>

JSON-basierte Feeds werden unter Nutzung der JsonPathSyntax formuliert, die unter https://developer.amazon.com/ public/solutions/devices/fire-tv/docs/fire-app-builder-query ing-json im Detail beschrieben ist. Bei der Arbeit mit XML nutzen Sie stattdessen XPath. Weitere Informationen dazu

Listing 1: Aufbau des Feeds <item> <title>Video Nummer Eins</title> <description>Es ist lehrreich!</description> <guid isPermaLink="false">1</guid> <pubDate>Mon, 08 Dec 2014 22:55:16 GMT</pubDate> <category>News</category> <media:content url="http://www.tamoggemon.com/ test/2016/nmgfiretv/clip1.mp4" type="..."> <media:title type="plain">1080x1920 - English with caption</media:title> <media:credit>Tamoggemon Holding k.s. </media:credit> </media:content> <thumbnail url="http://www.tamoggemon.com/ test/2016/nmgfiretv/thumb1.jpg" ></thumbnail> <background url="http://www.tamoggemon.com/ test/2016/nmgfiretv/bg1.jpg" ></background> </item>

122

Quelle: Amazon

...

Die Kartenbilder dienen als eine Art Thumbnails, während der Hintergrund nur zeitweise eingeblendet wird (Bild 9)

finden sich unter https://developer.amazon.com/public/solu tions/devices/fire-tv/docs/fire-app-builder-querying-xml. Es ist empfehlenswert, sich beim Aufbau des Feeds an klassischem RSS zu orientieren und tiefe Verschachtelungen nach Möglichkeit zu vermeiden. Zudem sollten Sie darauf achten, alle Elemente mit einem vollwertigen End-Tag zu terminieren. Die Nutzung von /> führt zuweilen zu schwer debuggbaren Parserfehlern. Wir beginnen die Arbeit an unserem Feed mit dem Angeben eines Titels, einer Beschreibung des Kanals und einem Datum, das die letztmalige Neugenerierung der im Feed enthaltenen Informationen angibt. Im Zusammenspiel mit den TTL-Feldinformationen kann der Client so feststellen, ob eine Aktualisierung der lokal vorgehaltenen Datenbasis erforderlich ist. Die Festlegung des XML-Namespaces für Media ist primär zur Befriedigung des Verifikationswerkzeugs relevant, das sonst die Abarbeitung von Anfragen mit einem Verweis auf die fehlende Namespace-Deklaration einstellt.

Einfache Struktur wählen Als Nächstes deklarieren wir die anzuzeigenden Elemente durch Item-Tags. Wie bei den Kategorien gilt auch hier, dass die Struktur des XML im Großen und Ganzen dem Entwickler überlassen bleibt. Es ist allerdings empfehlenswert, eine möglichst einfache Struktur zu wählen, um beim Zusammenbau der Query nicht allzu viel Arbeit zu haben. In unserem Beispiel wollen wir den Aufbau in Listing 1 nutzen. Wichtig ist, dass Amazons Bibliotheken zur korrekten Abarbeitung eines Medien-Feeds einige Informationen über die enthaltenen Multimedia-Inhalte benötigen. Neben einem Titel und einer Feed-weit einzigartigen ID sind ein Beschreibungstext und ein URL erforderlich, unter dem der Fire TV Stick die eigentliche Mediendatei herunterladen kann. Interessant sind zudem zwei als CardImage und BackgroundImage bezeichnete Bilder. Sie werden im Benutzer-Interface an verschiedenen Stellen benutzt, um den User zu informieren, was ihn in der jeweiligen Datei erwartet (Bild 9). Wer den Aufwand zur Erzeugung von zwei Bilddateien einsparen möchte, kann Background und CardImage mit ein und demselben URL befüllen. Die Klasse legt nur auf das Vorhandensein des Motivs Wert und führt bei Bedarf selbst Skalierungen und Crops durch.

3.2017 www.webundmobile.de


Fire TV Stick

Die englisch als CardImage bezeichneten Kartenbilder sollten dabei eine Größe von 548 x 452 Pixel aufweisen, während die Hintergründe im Idealfall im Format 1920 x 1080 vorliegen. Als nächste Aufgabe müssen wir uns der Deklaration der Rezepte zuwenden. Kehren Sie zur Datei assets/recipes/ LightCastCategoriesRecipe.json zurück, wo folgende Änderungen notwendig sind:

BEyOnD DEV

Listing 2: GenericMediaDataRecipe { "cooker": "DynamicParser", "format": "xml", "model": "com.amazon.android.model.content. Content", "translator": "ContentTranslator",

{

"modelType": "array", ...

"query": "rss/channel/item",

"format": "xml",

"matchList": [

...

"title/#text@title",

"query": "//category/text()",

"guid/#text@id",

...

"description/#text@description", "media:content/#attributes/url@url",

Neben dem Setzen des Format-Attributs auf XML müssen wir einen Query-String festlegen, der dem Parser das Beschaffen der Kategorie-Informationen ermöglicht. Zum Testen der Korrektheit bietet sich der unter www.freeformatter.com/ xpath-tester.html bereitstehende XPath-Tester an. Wer ihn mit dem Inhalt der Modelldatei füttert, kann die Ergebnisse – wie in Bild 10 gezeigt – verifizieren. Achten Sie zudem darauf, den Wert "queryResultType": "[]$" zu entfernen: Er spielt nur bei der Verarbeitung von JSON eine Rolle und führt beim Parsen von XML zu NullPointerExceptions. Die Verarbeitung der Content-Items ist insofern schwieriger, als wir es hier mit einer Gruppe von Attributen zu tun haben. Öffnen Sie die unter /assets/recipes bereitstehende Datei GenericMediaDataRecipe und passen Sie ihren Inhalt wie in Listing 2 gezeigt an. Der Query-String liefert diesmal ein Array zurück, das die Inhalte der einzelnen Media-Elemente bereitstellt. Die matchList ist für die Zuweisung der Attribute zuständig. Sie teilt den Speicherklassen mit, welche Query-Strings auf das Array angewendet werden müssen, um die jeweiligen Attribute zu erhalten. Amazon verwendet dabei eine etwas eigenwillige Syntax. Der links vom @ stehende Teil ist ein Abfrage-String, der das

"thumbnail/#attributes/url@cardImageUrl", "background/#attributes/url@backgroundImageUrl" ] }

Listing 3: Navigator.json "globalRecipes": [ { "categories": { "dataLoader": "recipes/ LightCastDataLoaderRecipe1.json", "dynamicParser": "recipes/ LightCastCategoriesRecipe.json" }, "contents": { "dataLoader": "recipes/ LightCastDataLoaderRecipe2.json", "dynamicParser": "recipes/ GenericMediaDataRecipe.json" } } ],

Der XPath-Tester spart beim Umgang mit XML-Queries Zeit und schont die Nerven (Bild 10)

www.webundmobile.de 3.2017

nach dem @ befindliche Feld bevölkert. In unserem Fall würde die Abfrage title/#text beispielsweise in das Feld title wandern, das sodann von der Engine weiterverwendet wird. Die in der matchList zu verwendende Syntax ist ein Selbstlaborat aus dem Hause Amazon, das mit keinem anderen Standard kompatibel ist. Beachten Sie, dass der XPath-Tester diese Bindungs-Strings nicht prüfen kann. Auf dem Fire TV gültige Strings werden vom Tester mit einem Syntaxfehler quittiert. Laden Sie die Datei im nächsten Schritt auf einen öffentlich zugänglichen Webspace hoch und fügen Sie den betreffenden URL anstelle der von Amazon vorgegebenen Adressen in urlFile.json ein. Der Autor dieses Artikels stellt – für einige Zeit – eine XML-Datei mit einigen Videos seines hausei- ▶

123


BEyOnD DEV

Fire TV Stick

genen Elektronik-YouTube-Channels bereit – ein schneller Test würde folgenden Inhalt voraussetzen:

Die schwarzen Quadrate entstehen, wenn der Feed Bild-URLs enthält, die mit Error 404 aufgelöst werden (Bild 11)

{ "urls": [ "http://www.tamoggemon.com/test/2016/nmgfiretv/ feed.htm" ] }

Wer das Programm in der vorliegenden Form ausführt, wird mit einer Exception konfrontiert. Dies liegt daran, dass die Abkürzung der url-Datei zu Fehlfunktionen führt. Zum Verständnis der Problemquelle müssen wir uns Navigator.json zuwenden. Amazon nutzt diese Datei als eine Art Einsprungpunkt, der unter anderem die zu initialisierenden Rezeptkombinationen beschreibt. Von besonderem Interesse ist hier das Feld globalRecipes, dessen Inhalt wie in Listing 3 gezeigt angepasst werden muss. Jedes Element des Arrays beschreibt dabei eine Inhaltsquelle, die aus je einem Kategorien- und einem Contentrezept

besteht. Diese werden wiederum durch einen Inhaltslader und einen Parser konfiguriert. Gemeinsam entsteht eine Art Toolchain, die das Entgegennehmen von Content ermöglicht. In der Datei LightCastDataLoaderRecipe2.json findet sich sodann folgender Code: { "task": "load_data", "url_generator": { "url_index": "1" } }

Tabelle 1: Verfügbare Schriftarten amazon Ember

Roboto

Verdana

Sonstige

Amazon Ember

Roboto Black

Verdana

AndroidClock Regular

Amazon Ember Bold

Roboto Black Italic

Verdana Bold

AndroidClockLargeRegular

Amazon Ember Bold Italic

Roboto Bold

Verdana Bold Italic

Carrois Gothic SC

Amazon Ember Italic

Roboto Bold Italic

Verdana Italic

Clockopia

Amazon Ember Light

Roboto Condensed Bold

Code2000

Amazon Ember Light Italic

Roboto Condensed Bold Italic

Coming Soon

Amazon Ember Medium

Roboto Condensed Italic

Cutive Mono

Amazon Ember Medium Italic

Roboto Condensed Light

Dancing Script

Amazon Ember Thin

Roboto Condensed Light Italic

Dancing Script Bold Droid Sans Mono

Amazon Ember Thin Italic

Roboto Condensed Regular

Kindle Symbol

Roboto Italic

MotoyaLMaru W3 mono

Roboto Light

MT Chinese Surrogates

Roboto Light Italic

NanumGothic

},

Roboto Medium

Source Code Pro Medium

Das Config-Array erlaubt Entwicklern, das Verhaltens des Gesamtsystems festzulegen: Sie können die Amazon-Engine

124

Zur Erleichterung des Debuggings empfiehlt es sich, während des Tests zwei identische Kopien des Feeds unter verschiedenen URLs anzulegen. Erweitern Sie die URL-Datei sodann um einen zweiten Eintrag – die url_index-Attribute der beiden DataLoader-Rezepte erlauben Ihnen das Zuweisen der URLs an die einzelnen Rezepte. Der Lohn dieser Mühe ist eine Ausgabe in der Debuggerkonsole. Fire TV lädt die Rezepte nacheinander und quittiert dies mit dem Auswerfen des URL. Bei der Suche nach der Absturzursache haben Sie in diesem Fall nur ein Rezept zu analysieren. Damit ist diese Version des Programms einsatzbereit. Schicken Sie sie auf den Fire TV Stick, um sich an den Resultaten Ihrer Arbeit zu erfreuen. Interessant ist, dass der Fire TV Stick bei nicht vorhandenen Bilddateien automatisch einen Platzhalter einfügt (Bild 11). Beachten Sie in diesem Zusammenhang, dass dies nur für formattechnisch gültige URLs gilt.

Erweiterung nach Maß Amazon stellt Entwicklern mehrere Stellschrauben zur Anpassung der Benutzerschnittstelle zur Verfügung. Beginnen wir mit der schon weiter oben erwähnten Datei Navigator. json, in der sich folgende Struktur befindet: "config": { "showRecommendedContent": true, "categoryDefaultRecommendation": true, "searchAlgo": "basic"

3.2017 www.webundmobile.de


Fire TV Stick

beispielsweise davon abhalten, den Benutzer mit Vorschlägen für weitere Medieninhalte zu konfrontieren. In der Rubrik Branding finden sich Stellschrauben, die das Auswählen der Schriftarten erlauben. Damit können Sie aus den in Fire OS enthaltene Fonts mehr oder weniger beliebig wählen, um Ihrem Programm zu einem eigenen Aussehen zu verhelfen. Tabelle 1 bietet eine Übersicht aller zum Zeitpunkt der Drucklegung verfügbaren Schriftarten:

BEyOnD DEV

zelnen Formulare beeinflussen. Ein Beispiel dafür ist die folgende Struktur: <resources> <!-- Splash Screen Customization --> <!-- Background to display on Splash Screen --> <drawable name="splash_background"> @drawable/bg_generic_nopreview</drawable> <!-- Company logo to show on Splash Screen -->

"branding":

<drawable name="splash_logo">

{

@drawable/fire_app_builder_white</drawable> "globalTheme": "AppTheme",

<!-- Copyright string text color -->

"lightFont" : "Roboto Light ",

<color name="copyright">#E6FFFFFF</color>

"boldFont" : "Roboto Bold" "regularFont" : "Roboto Regular" },

Ein weiterer interessanter Aspekt ist die Datei terms_of_use. html. Ihr Inhalt wird von der Fire-TV-Applikation zur Laufzeit im Nutzungsbedingungen-Fenster angezeigt. Achten Sie dabei darauf, dass die von Amazon vorgegebenen Lizenzbedingungen der verwendeten Open-Source-Komponenten nicht entfernt werden dürfen, weil Sie sonst gegen GPL und andere Lizenzvereinbarungen verstoßen und Abmahnungen provozieren könnten. Zu guter Letzt gibt es die Datei custom.xml. Sie ist in eine Gruppe von Parametern unterteilt, die das Aussehen der ein-

Die von Amazon mit Kommentaren versehene Datei bietet diverse Parameter an, die das Aussehen verschiedener Komponenten beeinflussen. Der hier abgedruckte Teil befasst sich mit dem Splash-Screen: Sie können unter anderem einen hauseigenen Hintergrund und eine Bitmap-Datei einbinden, die das Firmenlogo enthält. Größere Veränderungen am Layout der Formulare können auf diese Art und Weise allerdings nicht vorgenommen werden. Amazon bietet in der unter https://developer.amazon. com/public/solutions/devices/fire-tv/docs/fire-app-buildercustomize-look-and-feel bereitstehenden und lesenswerten Dokumentation allerdings eine Gruppe von Alternativlayouts an, die sich nach folgendem Schema einbinden lassen: "com.amazon.android.tv.tenfoot.ui.activities. ContentBrowseActivity": {

Tabelle 2: Interfaces

"verifyScreenAccess": false,

Interface

Funktion

Fertige Implementierungen

IAds

Ermöglicht die Einbindung von Werbeanzeigen zur Monetisierung von Applikationen

FreeWheelAdsComponent

Liefert diverse Ereignisse an, die vom Entwickler an Logging-Subsysteme weitergeleitet werden können

CrashlyticsComponent

IAnalytics

PassThroughAdsComponent

FlurryAnalyticsComponent GoogleAnalyticsComponent OmnitureAnalyticsComponent

Komponente, die für die Identifikation von Benutzern und das Freischalten von Medienelementen zuständig ist

AdobepassAuthComponent

IPurchase

Interface zur Implementierung von In-App-Käufen

AmazonInAppPurchasingComponent

UAMP

Dienste zum Abspielen von Multimedia-Inhalten

AMZNMediaPlayerComponent

www.webundmobile.de 3.2017

"onAction": "CONTENT_HOME_SCREEN" }

VastAdsComponent

LoggerAnalyticsComponent IAuthentication

"verifyNetworkConnection": true,

FacebookAuthComponent LoginWithAmazonComponent

Auch wenn der Quellcode nur teilweise zur Verfügung steht: Das Programm kann um in Java gehaltene Intelligenz erweitert werden. Amazon bedient sich dabei einer Gruppe von Interfaces, die das Implementieren bestimmter Verhalten ermöglichen. Tabelle 2 zeigt die zum Zeitpunkt der Drucklegung verfügbaren Varianten. Interessant ist hierbei, dass die Komponenten für Benutzeridentifikation und Analytics nicht erforderlich sind. Für Werbung, In-App-Käufe und Medienplayer hingegen muss je eine Komponente vorhanden sein, weil das Programm sonst nicht ausführbar ist. Amazon bietet mit LoggerAnalyticsComponent, AmazonInAppPurchasingComponent und AMZNMediaPlayerComponent hier Standardimplementierungen an, die von Haus aus aktiv sind. In der Dokumentation finden sich widersprüchliche Informationen dazu, ob eine LoggingKomponente erforderlich ist. Zur Vermeidung von Problemen können Sie die Klasse LoggerAnalyticsComponent einsetzen, die Meldungen in die Debugger-Konsole emittiert.

Realisierung eigener Komponenten Da die von Amazon selbst bereitgestellten Beispielkomponenten unter https://developer.amazon.com/public/solutions/ ▶

125


BEyOnD DEV

Fire TV Stick

devices/fire-tv/docs/fire-app-builder-in mentierung der Klasse und der Beheterfaces-and-components mehr als ausbung der Compilerfehler zuwenden. reichend dokumentiert sind, wollen wir Erzeugen Sie im ersten Schritt eine uns hier mit der Realisierung einer kleineue Klasse im Codeverzeichnis, die nen eigenen Komponente befassen. Das als Mater-Interface IAnalytics eingeZiel ist hierbei nicht die Erzeugung schrieben bekommt. Nach dem autoeiner funktionsfähigen Applikationslomatischen Einbinden der benötigten gik, sondern vielmehr die Vorstellung Die passende Version von settings.gradle Pakete bietet Android Studio die ebender dazu notwendigen Prozesse und Ar- wird mit der Annotation (Project Settings) falls automatische Generierung eines versehen (Bild 12) beitsschritte. Klassenkorpus an, was zu folgendem Module für den Fire App Builder müsCode führt: sen prinzipiell über die Gradle-Modulpublic class NMGAnalytics implements funktion erzeugt werden. Klicken Sie im IAnalytics ersten Schritt in Android Studio auf File, { New und New Module, um den Assis@Override tenten zur Erzeugung eines neuen Mopublic void configure(Context duls auf den Bildschirm zu holen. context) { } Die von Haus aus ausgewählte Op@Override tion Phone and Tablet Module kann public void collectLifeCycleData dabei ausgewählt bleiben. Klicken Sie (Activity activity, boolean dann auf Next, um die Einstellung zu active) { } quittieren und zum nächsten Schritt zu @Override gelangen. Als applikationsbezogenen public void trackAction Bibliotheksnamen wollen wir für die fol(HashMap<String, Object> data) genden Schritte NMGAnalytics aus{ } wählen. Beachten Sie, dass der App@Override Builder beim Paketnamen vergleichs- Wer sich hier vertippt, handelt sich eine public void trackState(String weise empfindlich ist: Im Fall von Ana- irreführende Fehlermeldung ein (Bild 13) screen) { } lytics-Komponenten muss das Paket @Override zwangsweise im Namespace com.amapublic void trackCaughtError zon.analytics liegen. (String errorMessage, Throwable t) { } Dies lässt sich durch Anklicken des Edit-Links im Assisten} ten bewerkstelligen, der Ihnen das Eingeben von beliebigen Paketnamen ermöglicht. Das Hinzufügen einer Activity ist an Amazons offizielle Dokumentation weicht an dieser Stelle dieser Stelle nicht notwendig, weil unser Modul ja keine gravon der in den anderen Modulen gelebten Praxis ab. Empfohfische Darstellung vorhat. len wird, den Code von Listing 4 in die Manifestdatei einzuNach der mit einem Fehler endenden Resynchronisation bauen. des Gesamtprojekts können wir uns der eigentlichen ImpleWer dies probiert stellt fest, dass das Produkt nicht funktionsfähig ist, weil die BroadcastReceiver-Implementierung in NMGAnalytics fehlt. Die Betrachtung des unter https://git Listing 4: Zusatzcode für Manifest-Datei hub.com/amzn/fire-app-builder/tree/master/GoogleAnaly <application ticsComponent bereitstehenden Moduls für Google Analytics android:allowBackup="true" führt stattdessen zu folgender Manifestdatei: android:label="@string/app_name" android:supportsRtl="true">

<manifest xmlns:android="http://schemas.android.com/apk/

<receiver android:name=

res/android"

"com.amazon.analytics.nmganalytics.NMGAnalytics"

package="com.amazon.analytics.nmganalytics">

android:enabled="true"

<application ...>

android:exported="false"> <intent-filter> <action android:name= "android.amazon.module.init"/> </intent-filter>

<meta-data android:name="AMZNAP@NMGAnalytics" android:value="IAnalytics@com.amazon.analytics. nmganalytics.NMGAnalyticsImplCreator"/> </application> </manifest>

</receiver> </application>

126

Die von Hand anzulegende Klasse NMGAnalyticsImplCreator ist eine Art Adapter, der dem SDK das Beschaffen einer

3.2017 www.webundmobile.de


Fire TV Stick

Listing 5: Projektverweis

BEyOnD DEV

liothek lässt sich durch Anpassung der betreffenden Zeile erzwingen:

/* Implementations */ project(':AMZNMediaPlayerComponent').projectDir =

apply plugin: 'com.android.library'

new File(rootProject.projectDir, '../AMZNMediaPlayerComponent') ... project(':NMGAnalytics').projectDir = new File(rootProject.projectDir, '../NMGAnalytics') // In der build.gradle-Datei muss eine Kompilations// Dependanz hinzugefügt werden: dependencies { compile fileTree(include: ['*.jar'], dir: 'libs')

In der Dokumentation findet sich zudem ein Verweis auf das Utils-Modul. Während unseres Tests war diese Änderung allerdings nicht notwendig. Damit ist das Projekt zur Einbindung in die Hauptapplikation bereit. Öffnen Sie die zum Hauptprojekt gehörende settings.gradle. Sie erscheint in Gradle am unteren Ende der Gradle-Skriptliste (Bild 12). Das vom Fire App Builder realisierte Klassensystem unterstützt nur eine Implementierung für jede Logikklasse. Daher muss die von Haus aus eingebaute Analytics-Klasse nach folgendem Schema durch NMGAnalytics ersetzt werden:

... compile project(':nmganalytics')

include ':app', ':nmganalytics',

// Uncomment when using CrashlyticsComponent

/* Frameworks */

/*compile('com.crashlytics.sdk.

...

android:crashlytics:2.6.1@aar') {

/* Implementations */

transitive = true; }*/

':PassThroughAdsComponent', ':AMZNMediaPlayerComponent', ':FacebookAuthComponent',

}

':AmazonInAppPurchaseComponent', ':NMGAnalytics'

Instanz von NMGAnalytics ermöglicht. Amazon stellt ein zu implementierendes Interface zur Verfügung, was zu folgender Struktur führt: public class NMGAnalyticsImplCreator implements IImplCreator<IAnalytics> { @Override public IAnalytics createImpl() { return new NMGAnalytics(); } }

Damit bleibt die Fehlermeldung der Bauart Manifest merger failed : uses-sdk:minSdkVersion 19 cannot be smaller than version 21 declared in library ungelöst. Die Arbeit mit Gradle sorgt hier insofern für Ärger, als Nutzer von Android Studio die Mindestversion des Android SDK nicht in der Manifestdatei festlegen. Öffnen Sie stattdessen die zum Modul nmganalytics gehörende Datei build.gradle und ändern Sie den minSdkWert auf 21:

Zudem ist ein Projektverweis erforderlich, um Gradle darüber zu informieren, wo es die betreffenden Komponenten findet (Listing 5). Gradle zeigt sich an dieser Stelle von der bissigen Seite: Fehler der Bauart Gradle sync failed: Configuration with name ‚default‘ not found weisen darauf hin, dass der an compile project übergebene String nicht korrekt ist. Der richtige String findet sich neben der build.gradle-Datei des Analytics-Moduls und ist Case-sensitiv (Bild 13). Damit ist das Programm zur Ausführung bereit. Wer in NMGAnalytics.java Breakpoints setzt, stellt fest, dass der vom App Builder generierte Code die in unserem Modul implementierten Funktionen regelmäßig aufruft. Alternativ dazu bietet sich das Platzieren von Log-Kommandos an.

Fazit Amazons Fire App Builder kann seine Stärken immer dann ausspielen, wenn die zu realisierende Applikation in das vorgegebene Template passt. Der zugegebenermaßen nervtötende Aufwand mit der hauseigenen Abfragesyntax amortisiert ◾ sich in der Praxis binnen kurzer Zeit.

android { compileSdkVersion 24 buildToolsVersion "24.0.3" defaultConfig { applicationId "com.amazon.analytics.nmganalytics" minSdkVersion 21 targetSdkVersion 24

Das von Android Studio erzeugte Projekt arbeitet von Haus aus mit dem Applikations-Plug-in – das Erzeugen einer Bib-

www.webundmobile.de 3.2017

Tam Hanna ist Autor, Trainer und Berater mit den Schwerpunkten Webentwicklung und Webtechnologien. Er lebt in der Slowakei und leitet dort die Firma Tamoggemon Holding k.s. Er bloggt sporadisch unter: www.tamoggemon.com

127


BEyOnD DEV

Customer Relationship Management

PER nET PROMOTER SCORE DIE ZUFRIEDEnHEIT DER KUnDEn MIT DIGITaLEn PRODUKTEn MESSEn

Zufriedene Kunden Die beste Werbung geht von zufriedenen Kunden aus.

I

st der Kunde zufrieden und äußert er diesen Umstand, dann ist das ein unbezahlbarer Werbeeffekt. Es gilt jedoch auch das Gegenteil. Ein negatives Produkturteil zerstört die zarte Pflanze des Vertrauens zwischen Kaufinteressenten und Hersteller. Der Indexwert Net Promotor Score fasst die Stimmungslage in einer einzigen Kennzahl zusammen. Sie ist nicht unumstritten, aber dennoch eine wichtige Messgröße. Beginnen wir mit der Beschreibung von typischen Situationen aus der Praxis. Täglich trifft man als Konsument eine Reihe von großen und kleinen Entscheidungen. Die meisten davon fällt man intuitiv und ohne längere Zeit darüber nachzudenken. Bei anderen Entscheidungen tut man sich vergleichsweise schwer. Welchen Aufwand man jeweils bei Kaufentscheidungsprozessen betreibt, ist nicht ausschließlich vom Preis des Produkts abhängig. Entscheidend ist vielmehr das Ausmaß der persönlichen Betroffenheit, das auch als Involvement bezeichnet wird. Im Internet werden nahezu alle Angebote und Dienstleistungen bewertet. Typische und bekannte Beispiele sind Pauschalreisen oder Produkte in den Online-Shops. Dabei kann die Bewertung formal in dafür vorgesehenen Plattformen wie zum Beispiel https://www.holidaycheck.de erfolgen. Bewertet werden inzwischen aber auch ärztliche Dienstleistungen sowie digitale Produkte wie Programme und Apps. Formale Bewertungsplattformen bündeln die Kundeneinschätzungen zu einem Produkt. Informale Bewertungen werden über Foren und die sozialen Netzwerke geäußert. Aus den Bewertungen kann direkt oder indirekt ein Stimmungsbild über das Produkt oder Dienstleistung gewonnen werden. Sehr oft wird dabei implizit die Frage beantwortet, ob bereits bestehende Kunden das Produkt weiterempfehlen. Fest steht, dass Dienstleistungen und Waren, die von den Kunden weiterempfohlen werden, erfolgreich sind. Umgekehrt gilt aber auch, dass Warnungen vor einem Produkt oder einer Produktpalette eines Herstellers dessen Chancen auf einen erfolgreichen Absatz erheblich einschrän-

ken. Eine öffentlich geäußerte Meinung von Kunden wiegt also schwer. Insbesondere jüngere Generationen lassen sich in ihren Kaufentscheidungen durch Online-Produktbewertungen und Internetforen beeinflussen. Noch stärker als öffentliche Bewertungen wirken persönliche Empfehlungen oder Einschätzungen von Personen, die man kennt und auf deren Meinung man vertraut. Konkrete Situationen, die dieses Verhaltensmuster beschreiben, kennt jeder. Ein Beispiel: Sie sitzen beim Zahnarzt und dieser berät Sie über alternative Behandlungsoptionen, die verhältnismäßig kostenintensiv sind. Will der Zahnarzt eine Dienstleistung verkaufen oder handelt es sich wirklich um die beste Leistung? Dem Zahnarzt vertraut man im Regelfall. Eine zur Entscheidung führende Frage könnte lauten: »Würden Sie die Leistung auch Ihren nahen Angehörigen oder sich selbst empfehlen?« Kehren wir zurück zu den digitalen Produkten: Für Apps und Angebote im Web sieht es nicht anders aus. Apps für mobile Endgeräte können direkt in den Stores gelobt, abgestraft und mit Kommentaren versehen werden. Mit zunehmender Anzahl an Bewertungen stellt sich für den Hersteller zunehmend die Frage nach einer Gesamteinschätzung der Nutzerbewertungen.

net Promoter Score Wie viele Kunden sind dem Produkt gegenüber positiv, neutral oder negativ eingestellt? Nach den obigen Ausführungen ergibt es offensichtlich wenig Sinn, lediglich den Durschnitt der Bewertungen zu errechnen, denn Produkte mit ausschließlich mittelmäßigen Bewertungen würden in etwa einen gleichen durchschnittlichen Punktwert erhalten wie Produkte, die die Kunden polarisieren und sowohl eine Menge positiver als auch negativer Bewertungen erfahren. Ebenso stellen sich zum Beispiel die folgenden Fragen: Was sind die Trennungsmerkmale innerhalb der Bewertungsklassifikation im Store? Üblicherweise gibt es fünf

Das Konzept des Net Promoter Score in der Übersicht (Bild 1)

128

3.2017 www.webundmobile.de


mögliche Sterne. Sind ein oder zwei Sterne dann negativ, drei Sterne neutral, und kann man vier oder mehr Sterne als positive Bewertung sehen? Wie hoch müsste eine positive Bewertung aussehen, damit es zu einer Produktempfehlung kommt? Ein interessanter Ansatz zur Beantwortung dieser Fragen ist das Konzept des Net Promoter Score (NPS). Ursprünglich wurde der NPS zur klassischen Produktbewertung verwendet. Zunehmend wird der NPS jedoch auch für digitale Produkte wie Apps eingesetzt. Unter dem NPS versteht man einen Index zur Berechnung beziehungsweise Messung der Wahrscheinlichkeit für die Weiterempfehlung eines Produkts. Gleichwohl werden auch die Konstrukte Kundenzufriedenheit und Kundenbindung gemessen. Die Methode wurde von Satmetrix Systems, Inc., Bain & Company und Fred Reichheld entwickelt. Wir erläutern zunächst, wie man den NPS berechnet (https://www.vocatus.de/files/pdf/Feedback -2007-01_Die_Aussagekraft_des_Net_Promoter_Score.pdf).

WDC Web Developer Conference 2017 10. - 11. Oktober 2017 München

Berechnung des nPS Der Ausgangspunkt ist die Frage: »Wie wahrscheinlich ist es, dass Sie Unternehmen X einem Freund oder Kollegen weiterempfehlen werden?« Diese Frage wird einer repräsentativen Gruppe der Kunden gestellt. Die Antworten werden auf einer Skala von 0 bis 10 bewertet. Dabei bedeutet ein Wert von 0 unwahrscheinlich und ein Wert von 10 äußerst wahrscheinlich. Abhängig von der gegebenen Antwort werden die Befragten in drei Gruppen eingeteilt (Bild 1). Die übliche Einteilung dabei lautet: Promotoren: Diese Kunden haben die oben genannte Frage mit 9 oder 10 beantwortet. Das heißt, dass sie zufrieden sind, und es ist sehr wahrscheinlich, dass sie das Produkt beziehungsweise die Dienstleistung weiterempfehlen werden. ▶

Konferenz & Workshops für Web-Entwickler zu den JavaScript- Frameworks

• Angular JS • React JS

Involvement Unter Involvement versteht man das Ausmaß der Ich-Beteiligung, das heißt, den Grad der subjektiv empfundenen Wichtigkeit des Verhaltens. Mit steigendem Involvement wird eine wachsende Intensität des kognitiven und emotionalen Engagements eines Individuums angenommen, beispielsweise bei der Durchführung von wichtigen Kaufentscheidungsprozessen (http://wirtschaftslexikon.gabler.de/Archiv/8445/involvementv8.html). Die Stärke des Involvements ist subjektiv unterschiedlich. Auch die jeweilige Situation spielt eine Rolle. Ein typisches Beispiel: Für den Wocheneinkauf von Lebensmitteln im Wert von 130 Euro braucht eine Person nur 45 Minuten. Die einzelnen Güter werden ohne großes Abwägen gekauft. Später geht die gleiche Person in ein Bekleidungsgeschäft und möchte sich ein T-Shirt kaufen. Zur Auswahl stehen Modelle zwischen 20 und 30 Euro. Nach mehr als einer Stunde ist die Entscheidung gefallen, keines der angebotenen Produkte zu kaufen. Eine weitere Produktauswahl wird folgen.

www.webundmobile.de 3.2017

web & mobile DEVELOPER Leser erhalten

15 % Rabatt mit Code

WDC17wmp

Veranstalter:

wdc-conference.de


BEyOnD DEV

Customer Relationship Management

Indifferente beziehungsweise Passive: Diese Gruppe bilden die Kunden, die die oben genannte Frage mit 7 oder 8 beantwortet haben. Sie sind zufrieden, aber nicht enthusiastisch genug für eine Weiterempfehlung. Sie verhalten sich passiv, das heißt, sie äußern sich weder negativ noch positiv über das Produkt. Kritiker: Zu dieser Gruppe zählen die Kunden, die die Frage mit 0, 1, 2, 3, 4, 5 oder 6 beantwortet haben. Es sind unzufriedene Kunden, die ihre negative Einstellung propagieren und rufschädigend wirken.

Was fällt unmittelbar auf? Die Verteilung zwischen zufrieden, neutral und unzufrieden ist nicht gleichmäßig. Bis zu einer Bewertung von 6 (auf einer Skala von 0 bis 10) geht man von Unzufriedenheit aus. Nur die beiden besten Bewertungen führen gegebenenfalls zu einer Weiterempfehlung. Bei einer anderen Skaleneinteilung, zum Beispiel 0 bis 5 oder 0 bis 7, müsste man von einer ähnlichen ungleichmäßigen Verteilung ausgehen. Wie wird die Kennzahl NPS berechnet? Der NPS ergibt sich, indem man von der Zahl der Promoter die Zahl der Kritiker abzieht: NPS = Promoter (%) – Kritiker (%)

Somit liegt der Wertebereich des NPS zwischen +100 Prozent und -100 Prozent. Was ist denn angesichts dessen ein guter Wert des NPS? Der NPS kann positiv oder negativ sein. Grundsätzlich gilt, dass Unternehmen mit einem deutlich zweistelligen positivem NPS profitabel wachsen. Zu beachten ist, dass die Gruppe der Indifferenten (Passive) nicht in die Berechnung einfließen. Ein konkretes Rechenbeispiel: Wenn jeweils 22 Prozent der Kunden Promotoren und 38 Prozent Kritiker sind, beträgt der Net Promoter Score minus 16. Neutral eingestellte Kunden, werden also keinen Beitrag für den künftigen Absatz leisten. Dabei sind niedrige oder negative Werte für die Motivation der Mitarbeiter nicht unbedingt förderlich. Ebenso ist der NPS sehr stark von externen Faktoren wie der Branche und der Konjunktur abhängig. Ein NPS von 0 gilt im Bereich der Banken bereits als ein hervorragender Wert. Der NPS wird immer öfter verwendet. Der Gründe dafür sind trivial: Die für die Berechnung notwendigen Daten lassen sich einfach erheben und anhand derer kann der Index eindeutig und unkompliziert berechnet werden. Ebenso ist der Wert leicht zu verstehen und es bedarf keiner umfassenden Erklärungen. Dennoch muss man den NPS differenzierter betrachten, darauf kommen wir später noch zurück.

Hinter den Score blicken NPS wird oft kritisch gesehen. Das Konzept erweckt den Eindruck, dass die gesamte Marktforschung auf eine einzelne Kennzahl reduziert werden kann – die Weiterempfehlungsrate. Diese ist jedoch nicht richtig. Der NPS selbst ist ein Index, der nur dann richtig interpretiert werden kann, wenn man ein Verständnis für die Treiber dieser Kennzahl entwickelt hat. Diese wiederum müssen anhand weitgehender Untersuchungen festgestellt werden. Man muss also ergründen,

130

Sender- und empfängerbezogene Erfolgskette der Weiterempfehlung (Bild 2)

warum Kunden auf einer Skala von 0 bis 10 nur 3 oder 4 wählen. Was sind die Gründe für die geäußerte Unzufriedenheit? In Bezug auf Apps kann man einige Gründe direkt aus den Kommentaren ableiten. Kennt man die Ursachen der Kundenbewertung, dann kann man auch die Kennzahl NPS richtig interpretieren. Aus den obigen Ausführungen zum Thema Involvement kann man entnehmen, dass die entscheidenden Faktoren stets diejenigen Größen sind, die für die Kunden die größte Wichtigkeit haben. Bei einer Veränderung dieser Größen besteht das höchste Potenzial, etwas zu bewirken. Der Erfolg und der große Vorteil des NPS liegt in seiner Einfachheit. Im Vergleich zu komplexeren Kundenzufriedenheitsstudien und Analysen kann der NPS sehr schnell und ohne viel Aufwand berechnet werden. Jedoch ist der NPS auch mit einigen Nachteilen verbunden. Man erhält nur Auskunft über die vorliegende Situation und somit keine Zukunftsprognose. Ebenso gibt der NPS keine Auskunft über ein individuelles Kundenverhalten. Welche Faktoren für den Wert des NPS ausschlaggebend sind, muss ergänzend ermittelt werden. Handlungsempfehlungen zur Verbesserung können also nur aus der Kombination von NPS und Ursachenanalyse (Treiberanalyse) abgeleitet werden.

Die Bedeutung von Empfehlungen Der Wert einer Produktempfehlung von Kunden für Kunden äußert sich letztendlich im wirtschaftlichen Erfolg. Konkretisieren wir dies an einem Beispiel: Apps, die überragende Bewertungen haben und die allgemein in aller Munde sind, weisen hohe Downloadzahlen auf. Über sie wird gesprochen, sie werden verwendet und sie sind auf unzähligen Smartphones installiert. Für den Hersteller bietet sich jetzt die Chance auf wirtschaftlichen Erfolg, beispielsweise über die Generierung von Werbeeinnahmen. Diese Wirkungs- und Erfolgskette der Weiterempfehlung ist in Bild 2 dargestellt. Dabei ist der wichtigste Einflussfaktor auf den Erfolg der oben genannten Kette die Kundenzufriedenheit. Positive Empfehlungen sind der beste, schnellste und kostengünstigste Weg, neue Kunden zu gewinnen. Die Bedeutung des Empfehlungsmarketings ist in den vergangenen

3.2017 www.webundmobile.de


W

W

e bin ar

e

Jahren stark gestiegen; eine Folge der Übersättigung der Märkte mit Werbung. Einem Bericht eines zufriedenen Kunden, beispielsweise in den sozialen Medien, schenkt man mehr Glauben als einer Produktwerbung des Herstellers. Auch dies lässt sich unmittelbar nachvollziehen. Schauen Sie sich die installierten Apps auf Ihrem Smartphone an! Welche davon nutzen Sie täglich? Warum haben Sie diese installiert? Richtig: Man hat davon gehört, Freude und Bekannte haben Sie Ihnen empfohlen oder die App ist allgemein ein Gesprächsthema. Zufriedene, begeisterte und vom Produkt überzeugte Kunden sind die besten Promoter. Das Geniale dabei: Sie machen es unentgeltlich, freiwillig und gern. Man sagt auch: Ein empfohlenes Geschäft ist schon gewissermaßen vorverkauft. Empfehlungsmarketing zielt darauf, eine möglichst große Anzahl von positiven Empfehlungen zu stimulieren und auf diese Weise Neukunden zu gewinnen und den wirtschaftlichen Erfolg zu steigen. Aktive Empfehler sind somit die Treiber einer positiven Umsatzentwicklung. Mit der Empfehlung geht die betreffende Person ein Risiko ein, somit ist es wichtig, dass diese Person dem Unternehmen vertraut. Im Gegensatz zum Produktverkäufer kommt die empfehlende Person im weiteren Zeitablauf mit den von ihr angesprochenen Personen immer wieder in Kontakt. Eine Produktempfehlung wird daher nur ausgesprochen werden, wenn man wirklich vom Produkt überzeugt ist.

Neue LiveWebinare für Entwickler JavaScript-Testing Referent: Sebastian Springer 16.02.2017, ab 16:00 Uhr

TypeScript Referent: Marius Schulz 15.03.2017, ab 16:00 Uhr

Entity Framework Core Referent: Christian Giesswein 20.03.2017, ab 11:00 Uhr

Mund-zu-Mund-Propaganda Wie werden Produkte von Kunden für potenzielle neue Kunden empfohlen? Es passiert ganz informal über Mund-zuMund-Propaganda. Die Weitererzähler können Produkte zu Verkaufshits machen! Die Bedeutung von Mund-zu-MundPropaganda ist jedoch von Branche zu Branche sehr unterschiedlich. Besonders effektiv ist dieses Instrument, wenn der potenzielle Konsument sich mit der Produktkategorie nicht auskennt. Als Hersteller muss man wissen: Eine negative Mundpropaganda wird stärker bewertet als eine positive Äußerung. Die Studie des White House Office of Consumer Affairs hat gezeigt, dass jeder unzufriedenen Kunde seine negative Erfahrung an mindestens neun andere Personen weitergibt. Vor allem bei neuen Produkten ist das der Fall. Negative Bewertungen im Internet spielen somit eine entscheidende Rolle. Die kommerzielle Nutzung der Mund-zu-Mund-Propaganda in Zeiten des Internets bezeichnet man als virales Marketing. Man darf nicht glauben, dass die Erkenntnisse des Empfehlungsmarketings vollständig neu sind. Bereits in den 1930er Jahren hatten Unternehmen professionelle Gerüchtemacher beschäftigt. Diese haben die eigenen Produkte intensiv weiterempfohlen und die Produkte der Konkurrenz schlechtgemacht. Heute nutzt die Mundpropaganda andere Tools. Die schwersten Waffen sind soziale Netzwerke und YouTube. Ein aktives Beobachten und Auswerten der Kundenaktivitäten in sozialen Netzwerken ist notwendig. Schauen Sie sich die Bewertungsseiten der erfolgreichen Apps in den Stores an. Die Nutzer kommentieren eine neue Version umfangreich. ▶

Event Storming Referent: Marco Heimeshoff 12.04.2017, ab 16:00 Uhr

Datenvalidierung mit WPF Referent: Christian Giesswein 21.04.2017, ab 11:00 Uhr

Codequalität bewerten Referent: Hendrik Lösch 09.05.2017, ab 16:00 Uhr

Migration zum Zend Framework 3 Referent: Ralf Eggert 11.05.2017, ab 16:00 Uhr

Weitere Informationen und Anmeldung unter www.webundmobile.de 3.2017

www.developer-media.de/webinare


BEyOnD DEV

Customer Relationship Management

Der Support lässt Fehlermeldungen und Probleme in der Regel nicht unkommentiert. Die Reaktionen der Nutzer werden aufgegriffen, Hilfe wird angeboten und man bedankt sich für gemeldete Probleme. Dieses Verhalten der Hersteller sorgt für Vertrauen bei den Kunden. Der Net Promoter Score wird gelegentlich um weitere Aspekte zum Net Promoter System erweitert. Dazu gehören: Die Kritiker werden kontaktiert und es wird versucht, die Ursachen für schlechte Bewertungen zu klären und diese zu beseitigen. Die Promotoren werden identifiziert und gefördert. Oft werden diese in den Produktentwicklungsprozess miteinbezogen. Die Indifferenten/Passiven werden ebenso angesprochen mit dem Ziel, diese in Promotoren umzuwandeln (https:// www.lamapoll.de/cms/files/files/Net%20Promoter%20Score %20(NPS).pdf).

Virales Marketing Virales Marketing beschreibt die Strategie, Informationen, zum Beispiel über ein Produkt, an Freunde weiterzuleiten, damit noch mehr Menschen Kenntnis von dem Produkt erhalten. Kernelemente sind oft unterhaltsame oder seltsame digital präsentierte Inhalte (Solomon, M.: Konsumentenverhalten, Pearson, 2013). Der Grundgedanke ist, dass sich die digitalen Botschaften rasant und effizient wie ein Virus verbreiten. Der Inhalt der Botschaft hat dabei eine große Bedeutung, diese soll für Sender und Empfänger emotional ansprechend oder nutzenstiftend sein. Virales Marketing basiert auf dem Prinzip der Mund-zu-Mund-Propaganda. Grundsätzlich kann zwischen dem aktiven und passiven viralen Marketing unterschieden werden. Beim passiven Marketing wird der Nutzer allein durch die Nutzung des Produkts zum Verbreiter der Botschaft. Beim aktiven viralen Marketing soll der Nutzer aktiv an der Verbreitung der Nachricht teilnehmen. Ein Beispiel: Der Samsung Truck macht die Straßen sicherer. In Argentinien stirbt beinahe stündlich jemand im Straßenverkehr. 80 Prozent der tödlichen Unfälle passieren auf öffentlichen Straßen, die meisten davon bei Überholmanövern. Und in der Tat sind Überholmanöver, besonders auf den kleineren Landstraßen, wie sie in Argentinien üblich sind, oft sehr riskant. Wenn es sich bei dem voranfahrenden Fahrzeug dabei noch um einen Lastwagen handelt, scheint ein Überholen oft unmöglich. Das koreanische Unternehmen Samsung hat sich dieses Problems angenommen und mit dem Safety Truck eine Lösung präsentiert. Auf der Rückenwand des LKW wurden große Samsung-Displays montiert, die ein Live-Kamerabild vom Verkehrsgeschehen vor dem Laster zeigen. Auf diese Weise sollen nachfolgende Autofahrer klar erkennen, was sich vor dem LKW abspielt beziehungsweise ob ein sicheres Überholmanöver möglich ist. Die Kamerabilder werden per Funk an die vier Heck-Displays übertragen und sollen auch bei Nacht aussagekräftige Bilder liefern (http://ideenwunder.at/category/viral).

132

Abschließend stellen wir noch die Berechnung des NPS an einem Beispiel vor. Es wird gezeigt, wie der NPS für ein digitales Produkt berechnet wird. Wir lehnen uns mit der Darstellung an den Beitrag auf der Seite www.klickibunt.de/app-bewertungen-pernet-promoter-score-nps an, auf der die Berechnung für unterschiedliche Webanwendungen beziehungsweise Apps demonstriert ist. Folgende Schritte werden durchlaufen: anpassung der Skala: Üblicherweise liegt der Berechnung des NPS eine Skala von 0 bis 10 zugrunde. In den Stores kann nur zwischen 1 und 5 Sternen gewählt werden. Daher wird folgende Einteilung festgelegt: 1 bis 3 Sterne: Detraktoren, 4 Sterne: Neutral und 5 Sterne: Promotoren. Ermittlung der Kundenbewertungen: Es muss ermittelt werden, wie viele Kunden welche Bewertungen abgeben haben. Zum Beispiel: 1 Stern: 21 (78 Prozent), 2 Sterne: 1 (4 Prozent), 3 Sterne: 1 (4 Prozent), 4 Sterne: 2 (7 Prozent) und 5 Sterne: 2 (7 Prozent). Insgesamt also 27 Bewertungen. Berechnung des nPS: Gemäß den dargestellten Werten ergibt sich: NPS (-79 Prozent) = Promotoren (7 Prozent) – Detraktoren (86 Prozent). Benchmark: Der NPS ist auch für direkte Konkurrenzprodukte zu bestimmen. Mit den vorliegenden Werten können Vergleiche vorgenommen werden. analyse der nutzerkommentare: Ableitung erster Schlussfolgerungen für den relativ schlechten Wert des NPS. Der NPS fasst die Stimmungslage der Kunden in einer Kennzahl zusammen. Dabei stellt dieser Index auf den wichtigen Umstand der Weiterempfehlungsrate ab. Berechnen Sie für Ihre Apps im Store den NPS anhand der abgegeben Kundenbewertungen. Machen Sie dies auch für die direkten Konkurrenzprodukte. Die dafür notwendigen Daten sind schnell beschafft und die Berechnung ist kein Hexenwert. Ist der errechnete Wert noch nicht zufriedenstellend, so gilt es weitergehende Analysen durchzuführen. Die entscheidende Frage lautet: Warum empfehlen bestehende Kunden das Produkt nicht vorbehaltlos weiter? Die möglichen Ursachen sind vielfältig: Treten Fehler auf? Stürzt die App ab? Ist das Design nicht ansprechend? Hinweise dazu finden Sie in den verbalen Kommentaren. Haben Sie die möglichen Ursachen gefunden, gilt es diese anzugehen und zu beseitigen. Eine spätere Messung des NPS sollte dann zu einem besseren Ergebnis führen. Jetzt kann man davon ausgehen, dass das Produkt auch verstärkt weiterempfohlen wird. ◾

Olena Bochkor studierte Betriebswirtschaftslehre mit dem Schwerpunkt Wirtschaftsinformatik. Weitere Informationen zu diesen und anderen Themen der IT finden Sie unter: http://larinet.com

3.2017 www.webundmobile.de


26.-29. Juni 2017, Messe Nürnberg

if

href

Jetzt Aussteller {} werden!

01000100 0101011101 011000

href

{} string

div • Treffen Sie Ihre Zielgruppe auf einer der größten Entwickler-Konferenzen Europas • Profitieren Sie von umfangreichen Marketingaktivitäten • Gestalten Sie das Progamm selber mit und nehmen Sie am Call for Papers teil

developer-week.de/Ausstellung Diese Kunden vertrauen uns:

developer-week.de

#dwx17

DeveloperWeek


IT-Jobs

Foto: Fotolia / md3d

BEyOnD DEV

nEUE JOBS IM ZEICHEn DER DIGITaLISIERUnG

Die Digital-Profis Gefragt sind Digital-Profis mit wirtschaftlichem Denken.

D

nehmens sorgen und sich darum kümmern, dass man über die sozialen Netzwerke wie Facebook, Instagram und Co. die richtigen Kunden erreicht. »Die Digitalisierung führt zu einem historischen Wandel in der Arbeitswelt«, resümiert Thorsten Dirks, Präsident des ITBranchenverbands Bitkom und CEO von Telefónica Deutschland, die Veränderungen in der digitalisierten Arbeitswelt. Seiner Einschätzung nach entstehen mit der Digitalisierung neue, aufregende und anspruchsvolle Jobs, die eine gute Ausbildung voraussetzen und im Gegenzug viel Gestaltungsspielraum und Verantwortung bieten. Chief Digital Officer, Chief Disruption Manager, Data Scientist, Data Strategist oder Social Media Manager – web & mobile developer stellt die bedeutendsten neuen Digitalberufe vor, die immer häufiger auf den Suchlisten der Unternehmen in allen Bereichen der Wirtschaft zu finden sind. Über keine neue Jobbezeichnung wird derzeit so viel berichtet – und auch diskutiert – wie über den Chief Digital Officer. Doch was genau macht ein CDO? Kurz gesagt: Der CDO

134

3.2017 www.webundmobile.de

ie digitale Transformation ist in aller Munde, kaum ein Unternehmen kommt mehr um dieses Thema herum. Dabei verändert die Digitalisierung nicht nur die IT-Landschaft, Geschäftsmodelle und Wertschöpfungsketten – die Umwälzungen betreffen auch die Arbeitswelt. Vom Pförtner bis zum Vorstand – die Digitalisierung erfordert von jedem Mitarbeiter neue Digitalkompetenzen. Auf der einen Seite macht die Digitalisierung zahlreiche Jobs überflüssig, etwa weil intelligente Roboter die Arbeit kostengünstiger erledigen, zum Beispiel das Reinigen von Gebäuden. Auf der anderen Seite schafft die Digitalisierung Arbeitsplätze und bringt ganz neue Jobprofile hervor. Gefragt sind Digital-Profis, die wirtschaftliches Denken und digitale Fachkenntnisse vereinen und so Unternehmen bei der Digitalisierung voranbringen. So werden zum Beispiel vielerorts Experten für Big Data gesucht, die im Wust der Daten den Überblick behalten, diese analysieren und daraus neue Geschäftsmodelle entwickeln. Oder Social-Media-Profis, die online für die perfekte Außendarstellung des Unter-


BEyOnD DEV

IT-Jobs

ist für die gesamte digitale Wertschöpfungskette eines Unternehmens zuständig. Er erarbeitet eine Strategie zur Digitalisierung und gewährleistet deren Umsetzung. Dazu gehören neue Geschäftsmodelle, Produkte und Services, aber auch das Hinterfragen vorhandener Geschäftsmodelle. Konkret geht es darum, wie sich durch die Digitalisierung beispielsweise interne Prozesse optimieren lassen, wie sich das Marketing in Zeiten von sozialen Netzwerken ändert oder welche digitalen Produkte sich neu einführen lassen. Hinzu kommt das große Thema Big Data – welche Daten sind im Unternehmen verfügbar und wie lassen sich diese optimal auswerten und nutzen. Um entsprechend handlungsfähig zu sein, hat der CDO einen Sitz im Vorstand. Der Chief Digital Officer ist also eine Art IT-Manager. Er braucht nicht unbedingt einen IT-Hintergrund mitzubringen, sondern kann auch über einen kaufmännischen Background verfügen. Denn für die abteilungsübergreifende Querschnittsaufgabe ist vor allem betriebswirtschaftliches Wissen und Denken gefragt. Für die technische Umsetzung ist dann der Chief Information Officer (CIO) zuständig, der mit dem CDO idealerweise Hand in Hand zusammenarbeitet. Doch wieso wird überhaupt so viel über den Sinn eines solchen Chief Digital Officers diskutiert? Häufig wird in Unternehmen nicht klar formuliert, was der neu eingeführte CDO genau machen soll. Und damit wird der neue Chef-Digitalisierer dann häufig alleingelassen – ohne Rückhalt durch das übrige Top-Management. Nicht selten sind damit dann auch die Erfolge eines CDO überschaubar. Daher ist es unerlässlich, dass sich Unternehmen genau überlegen, was die unternehmerischen Ziele eines Chief Digital Officers sind und welche operativen Spielräume er für die Umsetzung dieser Ziele erhalten soll. Nur so verhindert man etwaige Grabenkämpfe zwischen dem Chief Digital Officer und den anderen Abteilungen im Unternehmen. Solche Grabenkämpfe sind nicht unbedingt selten: Einer Untersuchung der Digitalagentur Etventure mit Unterstützung der Marktforscher von GfK ergab, dass in deutschen Großunternehmen mit 65 Prozent das mit Abstand meistgenannte Problem bei der Umsetzung der Digitalisierung die Verteidigung bestehender Strukturen ist. Derzeit ist der Chief Digital Officer übrigens noch ein ziemlicher Exot: Laut Bitkom gibt es lediglich in zwei Prozent der deutschen Unternehmen einen CDO – allerdings mit stark steigender Tendenz.

Chief Disruption Manager In vielen Unternehmen gibt es statt eines Chief Digital Officers einen Chief Disruption Manager. Mitunter sieht man den Chief Digital Officer und den Disruption Manager auch in Personalunion als sogenannten Chief Disruption & Digital Officer (CDDO). Was aber ist der Unterschied zwischen dem Digital Officer und dem Disruption Manager? Disruptiv bedeutet so viel wie zerbrechend, zerreißend, Disruption heißt Erschütterung oder auch Störung. Im Zusammenhang mit der digitalen Transformation bedeuten diese Begriffe, dass eine neue Idee, eine neue Technologie auf einen Schlag alles weitreichend verändert.

www.webundmobile.de 3.2017

Ein Chief Disruption Manager macht also eigentlich nichts anderes als der CDO: die digitale Transformation eines Unternehmens vorantreiben und es für die Herausforderungen des digitalen Zeitalters rüsten. Disruption ist jedoch offenbar derzeit einfach das schickere Wort: Laut der Frankfurter Allgemeinen Zeitung war Disruption das Wirtschaftswort des Jahres 2015 unter Deutschlands Geschäftsleuten. Neu ist die Verwendung des Begriffs übrigens nicht: Bereits vor rund 20 Jahren schrieb der Harvard-Professor Clayton Christensen über disruptive Technologien.

Data Scientist Die beiden Wörter Big Data geistern ebenfalls schon seit ein paar Jahren durch die IT-Welt. Und inzwischen fangen auch immer mehr deutsche Unternehmen etwas damit an: Sie treffen wichtige Geschäftsentscheidungen auf der Basis von Datenanalysen, etwa der detaillierten Auswertung von Kundenoder Wirtschaftsdaten. Laut dem IT-Branchenverband Bitkom ist Big Data vor allem im Maschinen- und Anlagenbau sowie in der Automobilbranche populär, während öffentliche Verwaltungen dem Datensammeln und -auswerten noch eher skeptisch gegenüberstehen. Eine Studie der Unternehmensberater von KPMG ergab, dass hierzulande ein gutes Drittel der Unternehmen auf Big-Data-Analysen setzt. Die Unternehmen haben also verstanden, dass das Auswerten von Daten für den wirtschaftlichen Erfolg zunehmend von Bedeutung ist und es sich dabei um eine Voraussetzung für die erfolgreiche Digitalisierung handelt. Doch in vielen Firmen fehlen Mitarbeiter, die bei den riesigen Datenmengen den Überblick behalten und die relevanten Daten richtig aufbereiten können. Diese Lücke schließt der Data Scientist. Er steuert die Datenprojekte und nutzt die Analyse-Ergebnisse, um den Unternehmenserfolg zu sichern und zu steigern. Dazu findet der Data Scientist im erstem Schritt heraus, wo überall im Unternehmen wichtige Daten anfallen. Diese Daten trägt er zusammen und verarbeitet sie mit Hilfe diverser Analyse-Tools. Was sich einfach anhört, ist eine komplexe ▶

Nutzung von Big Data Wir haben Big-DataLösungen in Einsatz

35 %

Wir planen, diese zukünftig zu nutzen

24 %

Wir diskutieren, diese zukünftig zu nutzen

18 %

Big-Data-Lösungen sind für uns derzeit kein Thema Wir haben uns bisher noch nicht mit dem Thema Big Data beschäftigt

22 % 1%

Inwieweit setzt Ihr Unternehmen bereits Big-DataLösungen ein? Gut ein Drittel der deutschen Unternehmen betreibt bereits Datenanalyse. web & mobile developer 3/2017

Quelle: KPMG

135


BEyOnD DEV

IT-Jobs

Angelegenheit. So benötigt ein Data Personelle Verantwortung für die Digitalisierung Scientist ein hohes Maß an Fachwissen in den Bereichen Informatik und MaAngaben in Prozent thematik, zum Beispiel zum ProgramGeschäftsführung bzw. mieren der Datenabfragen. Hinzu 25 36 16 Vorstand/COO 34 kommen idealerweise fundierte KenntLeiter Digitalisierung/ 0 0 0 nisse über die Produkte und Dienste, Chief Digital Officer (CDO) 0 die das Unternehmen vertreibt. Und Leiter Informations46 technik/Chief Information 36 33 60 auch über die rechtlichen Grundlagen Officer (CIO) des Datenschutzes muss ein Data SciKeine bereichsübergreifende Koordinierung 28 28 27 19 entist Bescheid wissen. Je nach Unterder Digitalisierung nehmensgröße sorgt der Data Scientist gesamt 20–99 Mitarbeiter 100–499 Mitarbeiter ab 500 Mitarbeitern nicht nur dafür, die wichtigen Daten heranzuschaffen und aufzubereiten, Wer koordiniert bereichsübergreifend die Digitalisierung im Unternehmen? Hier sondern er entwickelt aus den gewonspielt der Chief Digital Officer (CDO) in deutschen Unternehmen noch keine Rolle. nenen Daten auch selbst neue Geschäftsmodelle und Businesskonzepte Quelle: Bitkom web & mobile developer 3/2017 für das Unternehmen. Wie neu der Beruf des Data Scientists ist, zeigt eine Studie des Softwarenächste Gewinnspiel für die Facebook-Freunde des Unterherstellers SAS: 62 Prozent der Data Scientists in Deutschnehmens ist, in welchem Intervall die Fotos neuer Produkte land, Österreich und der Schweiz haben nur bis zu drei Jahauf Instagram gepostet werden sollten oder wie man mit nörre Berufserfahrung. gelnden Kunden auf Twitter umgeht. Ein Ausbildungsberuf ist Data Scientist nicht. Vielmehr bieDer Experte für soziale Medien muss aber auch mit Zahlen ten zahlreiche Organisationen, zum Beispiel die Fraunhofer umgehen können: Er wertet Statistiken zu Zugriffszahlen und Academy oder die Bitkom Akademie, entsprechende WeiterKundenreaktionen aus, entwickelt neue Konzepte für Aktiobildungen für IT-Profis an. Dort werden unter anderem Ananen und hält nach neuen Online-Kanälen Ausschau. Dabei lysetechniken und Statistikmethoden gelehrt. geht es beim Social Media Manager nicht nur um die exterData Strategist ne Kommunikation. Genauso wichtig ist die interne KommuEine Begleiterscheinung von Big Data ist, dass die vielen Danikation im Unternehmen selbst. ten irgendwann überall liegen: auf den Servern des UnterDer Job des Social Media Managers ist augenscheinlich nehmens – inhouse oder ausgelagert in der Cloud – oder auf hauptsächlich etwas für junge Menschen: Einer Studie des den Servern diverser Big-Data-Analyse-Tools. Das wirft Bundesverbands Community Management für digitale Komzwangsläufig die Frage auf, welche Daten das Unternehmen munikation & Social Media (BVCM) zufolge sind zwei Drittel eigentlich in welchem Zusammenhang nutzen darf. Vor allem der Social Media Manager in Deutschland zwischen 25 und wenn es um Kundendaten geht, sind zahlreiche rechtliche 35 Jahre alt. Die Verteilung zwischen Frauen und Männern Vorgaben einzuhalten. Hier kommt der Data Strategist zum ist im Gegensatz zu sonstigen Berufen im IT-Umfeld erfreuliZug: Er behält den Überblick und gibt die Leitlinien für den cherweise ziemlich ausgewogen: 49,4 Prozent der deutschen Umgang mit den einzelnen Datenarten vor. Social Media Manager sind weiblich. Ein Data Strategist benötigt ein hohes technisches VerMobile Developer ständnis. Nur damit lässt sich nachvollziehen, an welchen Rund 80 Prozent der deutschen Mobilfunknutzer verfügen Stellen überall Daten erhoben und in welcher Weise diese bei über ein Smartphone – eine riesige Zielgruppe, die Unternehder Auswertung verarbeitet werden. Für die Aufgabe des Damen über mobiloptimierte Inhalte und Apps erreichen könta Strategists eignen sich also vor allem Informatiker, Mathenen. Wie wichtig das Thema Mobile mittlerweile ist, beweist matiker oder Physiker. Darüber hinaus vereinfachen jurisauch der Suchmaschinengigant Google. Er wird seinen Index tische Kenntnisse die Einhaltung von Unternehmensrichtliin den kommenden Monaten auf »mobile first« umstellen und nien und rechtlichen Vorgaben. mobile Inhalte in den Suchergebnissen bevorzugen. Kein Social Media Manager Wunder, dass immer mehr Unternehmen auf der Suche nach Auch Social Media Manager ist keine offizielle BerufsbeSpezialisten für mobile Systeme sind. zeichnung. Vielmehr hat sich dieser Begriff für diejenigen Mobile Developer sind neben Entwicklern für die MobilMitarbeiter etabliert, die sich um die Internetgemeinde eines Betriebssysteme Android oder iOS auch Entwickler im Unternehmens kümmern. Salopp gesagt bekommt der Social HTML-, CSS- und JavaScript-Umfeld. Der Mobile Developer Media Manager Geld fürs Surfen im Netz. Er ist in den sokümmert sich um die Konzeption, die Programmierung und zialen Medien wie Facebook, Instagram, Twitter und Co. zu die Gestaltung von mobilen Inhalten und Apps. Laut den Hause und weiß zum Beispiel genau, welches das perfekte Marktbeobachtern von Evans Data gibt es weltweit bereits

136

3.2017 www.webundmobile.de


rund 12 Millionen Mobile Developer. In den kommenden vier Jahren soll deren Zahl auf bis zu 20 Millionen anwachsen. Bei einer geschätzten Gesamtzahl von rund 21 Millionen Entwicklern weltweit konzentriert sich damit derzeit schon mehr als die Hälfte auf mobile Inhalte.

Security Manager In Zeiten zunehmender Vernetzung und immer raffinierterer Angriffe durch Cyberkriminelle wird das Thema IT-Sicherheit immer wichtiger. Die folgende Zahl ist alarmierend: Laut einer aktuellen Bitkom-Studie verfügen nur 51 Prozent der deutschen Unternehmen über einen Notfallplan, um innerhalb kurzer Zeit auf den Abfluss sensibler Daten, digitale Wirtschaftsspionage oder Sabotage zu reagieren. Die übrigen haben im Fall der Fälle das Nachsehen. Sich erst dann um die IT-Sicherheit zu kümmern, wenn es zu spät ist, ist kein planvolles Vorgehen. Aufgabe eines Security Managers ist das Vermeiden von Datenlecks und das Entwickeln einer Strategie für die IT-Sicherheit – früher nannte sich der Security Manager häufig einfach IT-Sicherheitsbeauftragter. Der Security Manager befasst sich jedoch auch mit den Sicherheitsrichtlinien des Unternehmens im Alltag: Er schult Mitarbeiter im Umgang mit Daten, er legt fest, ob und welche Mitarbeiter zum Beispiel private Daten auf FirmenSmartphones nutzen dürfen und welche externen Dienstleister welche Zugriffe auf die Unternehmens-IT erhalten. Einen Chief Information Officer (CIO) ersetzt der Security Manager übrigens nicht. Während Letzterer dafür zuständig ist Richtlinien, Strategien und Notfallpläne für die Unternehmens-IT zu entwickeln, ist die IT-Abteilung des CIO letztlich dafür verantwortlich, diese Richtlinien umzusetzen.

Real-Time advertising Manager Im Bereich des Marketings hat die digitale Transformation vor allem für mehr Tempo gesorgt. Die Zeiten langfristig geplanter Anzeigenkampagnen im Internet sind vorbei. Heute lautet das Stichwort im Marketing Echtzeit. Nur so lassen sich auf den Werbeplattformen in Sachen Sichtbarkeit Wettbewerbsvorteile schaffen. Real-Time Advertising ist die neueste Disziplin im Online-Marketing, und der Real-Time Advertising Manager erzielt die besten Anzeigenergebnisse, indem er Strategien und Kampagnen umsetzt, die Interessenten zu Kunden machen. Der neue Anzeigen-Manager analysiert dazu kontinuierlich die Aktivitäten und die Performance der ◾ einzelnen Kampagnen.

SMART DATA Developer Conference Developer Conference Big Data & Smart Analytics

Für Softwareentwickler + IT-Professionals 27. Juni 2017, Nürnberg Themenauswahl:

• Smart Data Analytics • Datenqualität • Visualisierung • Tools & Frameworks web & mobile DEVELOPER Leser erhalten

15 % Rabatt mit Code

SMART17wmd Konstantin Pfliegl ist Redakteur bei der Zeitschrift com! professional. Er hat mehr als fünfzehn Jahre Berufserfahrung als Redakteur verschiedener Print- und Online-Medien. www.xing.com/profile/Konstantin_Pfliegl

www.webundmobile.de 3.2017

Veranstalter:

smart-data-developer.de


BEyOnD DEV

Online-Recht

STöRERHaFTUnG

Ohne selbst Täter zu sein Hierzulande kann man für Urheberrechtsverstöße zur Verantwortung gezogen werden, auch wenn man die Tat nicht selbst begangen hat.

W

er selbst zum Beispiel Musik, Filme oder Software ohne die dazu erforderliche Berechtigung aus dem Internet herunterlädt, verstößt als Täter gegen fremdes Urheberrecht. Hierzulande besteht jedoch die Besonderheit, dass man auch dann für Urheberrechtsverstöße zur Verantwortung gezogen werden kann, wenn man die Tat nicht selbst begangen hat – und zwar auch dann, wenn man nachweislich im Urlaub, im Krankenhaus et cetera war. Grund dafür ist das Instrument der sogenannten Störerhaftung. Störer ist, wer mit seinem Handeln dazu beiträgt, dass Rechtsverletzungen geschehen, ohne selbst Täter zu sein. Im Fall einer Abmahnung wegen illegalen Filesharings ist das beispielsweise der Anschlussinhaber.

Grundlagen Eine weitere und in der Praxis viel diskutierte Voraussetzung für die Haftung als Störer ist die Verletzung von bestehenden, zumutbaren Prüfpflichten. Nach Maßgabe der Rechtsprechung des Bundesgerichtshofs (BGH) kann also nicht jeder automatisch als Störer herangezogen werden, sondern nur derjenige, der eine Pflichtverletzung begeht (vergleiche die BGH-Urteile vom 26. November 2015, Aktenzeichen: I ZR 174/14, vom 30. April 2008, Aktenzeichen: I ZR 73/05, und vom 12. Mai 2010, Aktenzeichen: I ZR 121/08). Wer also etwa ein Internetforum betreibt, in dem ohne Registrierungspflicht Dritte uneingeschränkt Inhalte und/oder Dateien posten können, ist ebenso potenzieller Störer wie derjenige, der andere seinen Internetanschluss mitbenutzen lässt. In diesen Fällen sollte der Betreffende vorab darüber belehren, dass im Forum beziehungsweise über den Internetanschluss keine Rechtsverstöße begangen werden dürfen. Es ist oftmals sogar sinnvoll, zumindest stichprobenartig zu kontrollieren. Kinder und Jugendliche, die im eigenen Haushalt leben und das Internet nutzen dürfen, sollten besonders eindringlich ermahnt und eventuell sogar unter Aufsicht gestellt werden, wenn sie online gehen. Eine gewisse Kontrolle ist insbesondere dann erforderlich, wenn man in der Vergangenheit bereits eine Abmahnung aufgrund von Urheberrechtsverstößen erhalten hat oder man weiß, dass einschlägige Peer-to-Peer-Software auf dem Computer vorhanden ist. In solchen Fällen kann es ratsam sein, die Belehrung des Nachwuchses zu protokollieren oder einen Eltern-Kind-Vertrag abzuschließen. Derartige Schriftstücke können später in einem etwaigen Rechtsstreit als Beweis herangezogen werden. Die Rechteinhaber benötigen als Grundlage für eine Abmahnung Name und Anschrift des Anschlussinhabers. Hier-

138

zu werden regelmäßig die IP-Adressen der Nutzer von Tauschbörsen-Software protokolliert. Vor den meisten deutschen Gerichten gelten die Ergebnisse dieser Ermittlungen als gerichtsfester Beweis, auch wenn es nicht wenige IT-Experten gibt, die aus dem Stegreif gleich mehrere Fehlerquellen benennen können.

Ermittlung des Verantwortlichen Steht fest, von welcher IP-Adresse zu einem bestimmten Zeitpunkt Downloads ausgeführt wurden, so lässt sich in einem zweiten Schritt recht simpel der dazugehörige Inhaber des Internetanschlusses ermitteln – die entsprechenden Informationen erhalten die Rechteinhaber per Auskunftsverfahren von den Telekommunikationsanbietern. Nach Ermittlung des Anschlussinhabers steht allerdings lediglich fest, um welchen Anschluss es geht. Weder ein konkreter Täter noch ein bestimmtes Tatwerkzeug kann auf diese Weise ermittelt werden. War es der pubertierende Sohn oder doch der Ehegatte? Wurde auf einem PC heruntergeladen oder mittels Periscope beziehungsweise vergleichbarer Software Videos via Peer-to-Peer-Technik auf ein Tablet oder

Praxis-Tipp Der Chaos Computer Club (CCC) hat im letzten Jahr als Reaktion auf die nach wie vor sehr aktive AbmahnSzene den sogenannten Abmahnbeantworter ins Netz gestellt (https://ab mahnbeantworter.ccc.de). Dieses Tool soll allen wegen Filesharings Abgemahnten helfen, ein gepfeffertes Antwortschreiben zu formulieren – einfach in der Handhabung, unentgeltlich und ohne Der abmahnbeantworter des Speicherung von persoChaos Computer Clubs (CCC) nenbezogenen Daten. Inhaltlich ist dieses Werkzeug jedoch unter Juristen nicht unumstritten, eine individuelle Rechtsberatung scheint noch immer der bessere Weg zu sein.

3.2017 www.webundmobile.de


Online-Recht

Smartphone gestreamt? Genau hier setzt die Störerhaftung an. Denn selbst dann, wenn der Anschlussinhaber den behaupteten Verstoß selbst nicht begangen hat, kann ihm vorgeworfen werden, keine ausreichenden Sicherungsmaßnahmen getroffen zu haben.

Links zum Thema

Video-Trainings des Autors www.video2brain.com/de/trainer/michael-rohrlich

Blog des Autors zum Thema Online-Recht für Webmaster http://webmaster-onlinerecht.de

Blog des Autors zum Verbraucherrecht online http://verbraucherrechte-online.de

So sieht es Europa Infolge der Entscheidung des Europäischen Gerichtshofs (EuGH) vom 15. September 2016 (Aktenzeichen: C-484/14, McFadden gegen Sony) blieb die Störerhaftung insbesondere für die Betreiber von WLAN-Netzwerken weiterhin faktisch bestehen. Die EuGH-Richter setzen vergleichsweise hohe Anforderungen an die Entlastung von potenziellen Störern. So ist beispielsweise dafür zu sorgen, dass Dritte nur mit individueller Zugangskennung, also Benutzername und Passwort, Zugang erhalten. Damit aber nicht genug: Nutzer eines öffentlichen Netzwerkzugangs, zum Beispiel in Gaststätten, Hotels oder Kaufhäusern, sollen zum Erhalt einer Zugangsberechtigung ihre Identität offenlegen müssen. Zwar folgt der EuGH in seinem Urteil der Auffassung des BGH, dass zumindest keine Schadensersatzansprüche auf den Anschlussinhaber zukommen können. Allerdings besteht nach wie vor das Risiko, jedenfalls die Abmahnkosten tragen zu müssen.

… und so Deutschland Wer auch nur ab und zu aus beruflichen Gründen mit Filesharing-Abmahnungen zu tun hat, weiß, dass es bisweilen so wirkt, als sei Deutschland aufgeteilt. Es gibt im Norden, Süden, Westen und Osten jeweils zwei bis drei sehr aktive Anwaltskanzleien, die regelmäßig verschiedene Inhaber von Urheber- beziehungsweise Lizenzrechten vertreten und deren Forderungen geltend machen. Bisweilen kann man sich des Eindrucks nicht erwehren, dass es in erster Linie nicht mehr um die (durchaus legitime) Verfolgung von Urheberrechtsverstößen geht, sondern schlicht um Geld. Die deutsche Bundesregierung hat in den letzten Jahren mehrere Versuche unternommen, durch Gesetzesänderungen dem Rechtsmissbrauch in diesem Bereich einen Riegel vorzuschieben. Zunächst kam 2008 die sogenannte 100-Euro-Abmahnung, dann – wegen des großen Erfolgs – 2013 eine weitere Änderung des einschlägigen Paragrafen. § 97a Abs. 3 des Urheberrechtsgesetzes (UrhG) lautet inzwischen: »Soweit die Abmahnung berechtigt ist […], kann der Ersatz der erforderlichen Aufwendungen verlangt werden. Für die Inanspruchnahme anwaltlicher Dienstleistungen beschränkt sich der Ersatz der erforderlichen Aufwendungen hinsichtlich der gesetzlichen Gebühren auf Gebühren nach einem Gegenstandswert für den Unterlassungs- und Beseitigungsanspruch von 1.000 Euro, wenn der Abgemahnte 1. eine natürliche Person ist, die nach diesem Gesetz geschützte Werke oder andere nach diesem Gesetz geschützte Schutzgegenstände nicht für ihre gewerbliche oder selbständige berufliche Tätigkeit verwendet, und 2. nicht bereits wegen eines Anspruchs des Abmahnenden durch Vertrag, auf Grund einer rechtskräftigen gerichtlichen Entscheidung oder einer einstweiligen Verfügung zur Unterlassung verpflichtet ist. […]«

www.webundmobile.de 3.2017

BEyOnD DEV

Beabsichtigt war also, Privatpersonen bei einmaligen Verstößen insoweit zu schützen, als die Kosten der anwaltlichen Tätigkeit nur ungefähr 150 Euro betragen dürfen. Faktisch finden die Abmahner aber auch hierbei regelmäßig Ausnahmetatbestände, um dennoch höhere Kosten geltend zu machen. Im Jahr 2016 kam es wiederum zu einer Gesetzesänderung, nämlich zu einer Anpassung des Telemediengesetzes (TMG) durch die Änderung von § 8. Leider wird nur in der Gesetzesbegründung und nicht im Gesetzestext selbst erwähnt, dass Betreiber von offenen WLAN-Netzwerken nicht als Störer haften sollen. Im BGH-Urteil vom 12. Mai 2010 (Aktenzeichen: I ZR 121/ 08) haben die Karlsruher Richter festgelegt, dass eine tatsächliche Vermutung dafür spricht, dass der Anschlussinhaber auch für die Rechtsverletzung verantwortlich ist. Diesen treffe daher eine sekundäre Darlegungslast, wenn er geltend macht, dass nicht er, sondern ein Dritter die Rechtsverletzung begangen hat. Außerdem soll der Betreiber eines WLAN-Anschlusses als Störer haften, wenn er es unterlässt, die zum Kaufzeitpunkt des Routers marktüblichen Sicherungen anzuwenden, sofern Dritte seinen Anschluss für Urheberrechtsverstöße nutzen. Generell sind also folgende Sicherungsmaßnahmen zu empfehlen: Aktivierung der WPA2-Verschlüsselung, Vergabe eines individuellen Passworts, sichere Gestaltung des Passworts, Freigabe nur für bestimmte Endgeräte (MAC-Filter), Aktivieren der Firewall im Router, Deaktivierung der WLAN-Funktion bei längerer Abwesenheit im Urlaub et cetera. Ob und wie sich diese Maßnahmen zur Absicherung des eigenen Netzwerks später dann auch nachweisen lassen, das ◾ steht auf einem anderen Blatt.

Michael Rohrlich ist Rechtsanwalt und Fachautor aus Würselen. Seine beruflichen Schwerpunkte liegen auf dem Gebiet des Online-Rechts und des gewerblichen Rechtsschutzes. www.rechtssicher.info

139


aRBEITSMaRKT

Trends am Arbeitsmarkt

ARBEITSMARKT TRENDS UND JOBS FÜR ENTWICKLER

Digitale arbeitsplätze

Wirtschaft ist schlecht vorbereitet Arbeitnehmer in Deutschland stellen ihren Chefs ein schwaches Zeugnis aus, wenn es um den digitalen Arbeitsplatz der Zukunft geht. Befragt nach den größten Stolpersteinen am IT-Arbeitsplatz bemängeln knapp 60 Prozent einen schlechten Datenzugriff von unterwegs, 58 Prozent kritisieren einen zu langsamen IT-Störungsdienst und 55 Prozent erleben die IT der eigenen Firma als zu unflexibel, um neue Anforderungen einzubinden (Bild 1). Insbesondere die mobilen Einsatzgebiete der IT werden als Baustelle beschrieben. So bewertet knapp jeder zweite Arbeitnehmer die IT-Ausstattung der eigenen Firma mit befriedigend oder schlechter, wenn er beispielsweise auf Geschäftsreisen in Deutschland unterwegs ist. Bei Auslandsreisen sind es rund 60 Prozent. Neben mobi-

lem Arbeiten wird auch das Homeoffice wichtiger. Die technische Anbindung für den Arbeitsplatz zu Hause lässt der Umfrage zufolge allerdings zu wünschen übrig: 42 Prozent der Befragten geben hier dem IT-Arbeitsplatz die Schulnote befriedigend oder schlechter. Zehn Prozent erteilen sogar eine glatte Sechs. Um für das digitale Business besser gerüstet zu sein, hält es eine überwältigende Mehrheit der Mitarbeiter für wichtig (89 Prozent), dass die Firmen mobiles Arbeiten künftig professioneller unterstützen. Claus Schünemann, Vorsitzender der Geschäftsführung von CSC in Deutschland: »Die anstehende Modernisierung der Arbeitsplätze sichert nicht nur künftige Marktanteile, sondern dient gleichzeitig als Visitenkarte des Arbeitgebers. 81 Prozent der Arbeitnehmer halten einen modernen, digitalen IT-Arbeitsplatz für wichtig, um als Unternehmen für Mitarbeiter attraktiv zu sein.«

Hemmnisse für digitale Arbeitsplätze 60 %

Langsamer ITStörungsdienst

56 %

Unflexible Firmen-IT

55 %

140

Fast die Hälfte der deutschen Büroangestellten gab in der internationalen Studie Mobile Multiplier der British Telecom (BT) an, dass flexibles Arbeiten die höchste Priorität bei der Suche nach dem idealen Arbeitgeber hat. Lediglich für 13 Prozent steht ein Firmenwagen ganz oben in der Liste. Vielen Unternehmen fällt es jedoch noch immer schwer, diese Anforderungen umzusetzen. Sie kämpfen teilweise mit technischen Schwierigkeiten und limitierten Budgets. Für 88 Prozent der Befragten in Deutschland gehört flexibles Arbeiten zu den drei Top-Prioritäten bei der Wahl des idealen Arbeitgebers. Effektive Kommunikation mit den Kollegen zu gewährleisten stellt Unternehmen allerdings nach wie vor vor Herausforderungen. Die Befragten gaben an, dass sie beim

Flexibles Arbeiten ist eine der Top-3-Prioritäten

88 %

Flexibles Arbeiten hat höchste Priorität

49 %

Zugriff auf Unterlagen von außerhalb ist schwierig

49 %

Keine privaten Endgeräte bei der Arbeit erlaubt 52 %

Die mobile anbindung muss besser werden. Zudem wird der langsame IT-Störungsdienst beklagt (Bild 1) web & mobile developer 3/2017

Wichtiger als ein Firmenwagen

Arbeiten außerhalb des Büros viel Zeit benötigen, ihre Kollegen zu erreichen. Den Zugriff auf Unterlagen und Dateien von unterwegs empfinden 49 Prozent als schwierig (Bild 2). Die Ergebnisse deuten auf einen Bedarf für smartere Technologien hin. Zwei Drittel der Angestellten gaben an, dass eine bessere Kommunikation ihr Unternehmen erfolgreicher machen würde. Die Mitarbeiter wünschen sich vor allem die Möglichkeit, mehr Tätigkeiten mit dem Smartphone erledigen zu können. Andrew Small, Vice President Unified Communications, Mobile and Contact Centre Portfolio bei BT: »Für Unternehmen ist es wichtig, ihr Geschäft zukunftssicher aufzustellen, indem sie in Technologie für mobile Zusammenarbeit investieren, die flexibles Arbeiten unterstützt. Je mehr Mitarbeiter positive Erfahrungen mit dem Arbeiten von unterwegs machen, desto stärker profitieren auch ihre Unternehmen.«

Mobil und flexibel arbeiten

Schlechter mobiler Datenzugriff

Lahme Anbindung des Home-Office

Mobiles arbeiten

Quelle: CS-Studie, Mehrfachnennungen

47 %

Chefs vertrauen auf effektive Arbeit außerhalb des Büros Arbeite niemals außerhalb des Büros web & mobile developer 3/2017

45 %

17 %

Flexibles arbeiten gehört zu den TopPrioritäten bei der Auswahl eines neuen Arbeitsplatzes (Bild 2)

Quelle: BT-Studie Mobile Multiplier, Mehrfachn.

3.2017 www.webundmobile.de


aRBEITSMaRKT

Trends am Arbeitsmarkt

Zahl des Monats

657

619

Auf 100.000 Erwerbstätige kommen in Baden-Württemberg und in Bayern Stellenanzeigen – im Durchschnitt verzeichnen die Bundesländer hingegen 243 Anzeigen. Am häufigsten nachgefragt werden IT-Spezialisten. Bereits jede sechste Stellenzeige ist eine Ausschreibung für IT-Profis. Quelle: StepStone.de

Hasso-Plattner-Institut (HPI)

HPI Connect: SpeedDating für die Karriere Sieben Minuten haben Studierende und Unternehmen beim IT-Speed-Dating für ein erstes Kennenlernen und Beschnuppern – dann werden die Partner gewechselt. Bereits zum achten Mal organisiert das HassoPlattner-Institut (HPI) am 18. Mai 2017 die Karrieremesse HPI Connect, bei der sich Studierende und Unternehmen besser kennenlernen können. Das Hasso-Plattner-Institut bildet seit 1999 international wettbewerbsfähige IT-Nachwuchskräfte aus. »Ein früher Kontakt der Studierenden zu Unternehmen ist ausdrücklich gewünscht und für beide Seiten von Vorteil«, so HPI-Institutsdirektor Professor Christoph Meinel. »Viele Studentinnen und Studenten können so bereits im Rahmen ihres Studiums Praxiserfahrungen in Unternehmen sammeln und wissen dann im Anschluss an ihr Studium

schon sehr genau, in welche Richtung sie gehen möchten.« Das Hasso-Plattner-Institut für Softwaresystemtechnik GmbH an der Universität Potsdam ist Deutschlands universitäres Exzellenzzentrum für IT-Systems Engineering. Neben der einmal jährlichen stattfindenden Connect Messe bietet das Hasso-Plattner-Institut mit seinem Karriereportal HPI Connect ganzjährig eine Plattform für Unternehmen, um in Kontakt mit talentierten Studierenden und Alumni zu treten und sich als attraktiver Arbeitgeber zu präsentieren. ROC-Studie

Digitales Lernen Immer mehr deutsche Betriebe leben bereits den digitalen Fortschritt: Jeder dritte Arbeitnehmer gibt an, in seiner Firma sei es explizit erwünscht, Lerninhalte über soziale Medien zu nutzen. Dies zeigt die Studie »Arbeitswelt der Zukunft« der Unternehmensberatung ROC.

nen fände in seiner Firma vor allem im Zusammenhang mit größeren Veränderungen statt. Und 64 Prozent erlernen neue Fähigkeiten in konventionellen Formen, wie etwa Seminaren. Prof. Dr. Armin Trost, wissenschaftlicher Begleiter der Studie: »Auch wenn viele Unternehmen noch auf konventionelle Lernmethoden setzen, sind sie aufgeschlossen gegenüber der digitalen Transformation«. arbeit 4.0

Selbstbestimmt und flexibel Mit der Digitalisierung verändern sich auch die Ansprüche an den Arbeitsplatz. Vier von fünf Unternehmen berichten, dass sich ihre Mitarbeiter eine flexible Arbeitsgestaltung wünschen, wie Homeoffice, Familienzeit und Sabbaticals. Fast jeder zweite Chef sagt aber auch, dass die Gesetze dafür noch gar nicht reif sind: Demnach sehen ▶ sich die Unternehmen ge-

Flexibles Arbeiten

Digitales Lernen Täglicher Wissenserwerb spielt eine wichtige Rolle

67 %

Standard-Weiterbildung in Seminaren

Arbeitnehmer wünschen sich flexible Arbeitsplätze

79 %

64 % Auch in 10 Jahren überwiegen normale Arbeitsverhältnisse

Erhalten zeitliche Freiräume für eigenverantwortliche Fortbildung Lernen über virtuelle Netzwerke

Ein Arbeitnehmer lernt einen neuen Vorgang nicht im Seminarraum, sondern über ein Webinar oder YouTube-Video. Er diskutiert darüber im Gruppenchat mit Kollegen und dem jeweiligen Experten. Beim Pauken über soziale Medien in Unternehmen sind viele Varianten denkbar. Und sie werden praktiziert, wie die ROC-Studie zeigt: 36 Prozent der Beschäftigten sagen, bei ihren Arbeitgebern sei das Nutzen von Lerninhalten über virtuelle Netzwerke ausdrücklich erwünscht (Bild 3). Zudem gewähren die Firmen nahezu jedem zweiten Arbeitnehmer zeitliche Freiräume für eigenverantwortliches Fortbilden und Wissensaustausch. Oliver Back, Global COO der ROC Group: »Das Lernen hat eine zentrale Funktion für die Arbeit 4.0. Deshalb werden sich neue, digitale Lernformen langfristig in sämtlichen Unternehmen etablieren.« Dennoch halten etliche deutsche Unternehmen an alten Gewohnheiten fest. So sagt jeder zweite Befragte, Ler-

69 %

45 %

36 %

Chefs: Gesetze sind nicht reif für flexible Arbeitsplätze

48 %

Mehr als ein Drittel lernt schon in virtuellen Netzwerken. Bei 64 Prozent läuft die Weiterbildung noch über herkömmliche Seminare (Bild 3)

Die meisten arbeitnehmer wünschen sich flexible Arbeitsplätze. Viele Chefs finden, die Gesetze sind noch nicht reif dafür (Bild 4)

web & mobile developer 3/2017

web & mobile developer 3/2017

www.webundmobile.de 3.2017

Quelle: ROC-Studie

Quelle: Bitkom

141


aRBEITSMaRKT

zwungen, an klassischen Arbeitsverhältnissen festzuhalten, anstatt flexiblere Formen anzubieten. Die Wirtschaft erwartet, dass sich das auf absehbare Zeit kaum ändern wird. Auch in zehn Jahren würden normale Arbeitsverhältnisse überwiegen, erklären 69 Prozent der Unternehmen (Bild 4). BitkomHauptgeschäftsführer Dr. Bernhard Rohleder: »Eigenverantwortliches und projektorientiertes Arbeiten wird künftig immer wichtiger. Neue Technologien machen das heute schon möglich.« Kienbaum, StepStone

Umgangsformen In einer Befragung durch StepStone und Kienbaum gaben nur drei Prozent der Befragten an, dass sich an ihrem Arbeitsplatz alle Mitarbeiter siezen. »Das Du ist ein Ausdruck der Revolution, die gerade in der deutschen Wirtschaft stattfindet«, sagt Dr. Sebastian Dettmers, Geschäftsführer StepStone.de. Knapp zwei Drittel (63 Prozent) der befragten Fachkräfte sind mit einigen Kollegen per Du, während sie die Führungsebene mit Sie ansprechen. Tendenziell ist diese gemischte Umgangsform in größeren Unternehmen häufiger üblich als in kleineren. Bei Arbeitgebern mit mehr als 500 Mitarbeitern steigt der Wert sogar auf 70 Prozent. »Im Zuge der Digitalisierung müssen sich auch Großunternehmen und Konzerne wandeln. Sie stehen mit erfolgreichen Start-ups im Wettbewerb um die besten Köpfe. Starre Strukturen abzubauen ist daher für viele Arbeitgeber sinnvoll«, sagt Walter Jochmann, Geschäftsführer bei Kienbaum. Während im Gesamtschnitt der Befragten jeder Dritte alle Kollegen und Vorgesetzten duzt, ist es in Unternehmen mit weniger als 50 Mitarbeitern die Hälfte

142

Trends am Arbeitsmarkt

aller Fachkräfte. In der IT & Internet-Branche sind mehr Fachkräfte mit allen Kollegen per Du als in anderen Branchen (70 Prozent). Schlusslicht ist der öffentliche Dienst (15 Prozent). Wrike Digital Work Report

Digitaler Alltag in deutschen Büros Deutsche Unternehmen sind im Digitalisierungs-Fieber. Wie die Digitalisierung bei den Büroangestellten, die letztlich mit neuen Software-Tools arbeiten, ankommt, ist die Fragestellung im aktuellen Digital Work Report von Wrike. Der Experte für Arbeitsmanagement untersucht, wie sich Büroarbeiter in Deutschland, Frankreich und Großbritannien organisieren und welche Werkzeuge sie dafür einsetzen (Bild 5). Im Durchschnitt jongliert jeder deutsche Büroarbeiter mit etwa fünf verschiedenen ITTools. Etwa sieben Prozent der Befragten nutzt sogar mehr als zehn digitale Hilfsmittel. Und ihre Anzahl scheint tendenziell zu steigen: 45 Prozent der Befragten nehmen gegenüber dem Vorjahr einen leichten Zuwachs der digitalen Hilfsmittel wahr. 15 Prozent bemerken sogar eine signifikante Steigerung. Dabei sind E-Mails zwar das

meistgenutzte Tool, doch gleichzeitig sehen 40 Prozent der Befragten darin ein Hemmnis, um ihre Arbeit produktiv erledigen zu können. Der Ländervergleich zeigt, dass Frankreich in Sachen Digitalisierung weiter zu sein scheint als Deutschland: Bei unseren Nachbarn im Westen nutzen nur 59 Prozent E-Mail regelmäßig für die Organisation ihrer Aufgaben, handschriftliche Notizen führt nur noch jeder vierte. Im Gegensatz dazu kommen in französischen Büros CRM-Tools (32 Prozent) häufiger zum Einsatz. Auch Collaboration-Software, die die Organisation gemeinsamer Projekte und Aufgaben erleichtert, hat sich in Frankreich bereits stärker durchgesetzt: Sie werden von nahezu jedem Vierten (24 Prozent) genutzt, in Deutschland sind es erst 17 Prozent. Vielleicht ein Grund, warum die Franzosen trotz stärkerem Arbeitsanstieg (77 Prozent versus 72 Prozent) weniger gestresst sind (60 Prozent versus 65 Prozent)? Nur 14 Prozent der Befragten des Digital Work Reports gaben an, ihre eigenen Tools nutzen zu dürfen. Demgegenüber haben 84 Prozent keine Möglichkeit, selbst über die Werkzeuge, die sie für ihre Aufgaben benötigen,

IT-Werkzeuge deutscher Büroarbeiter 75 %

E-Mail 62 %

Tabellenprogramme 44 %

Handschriftliche Notizen Konferenzsysteme (Audio, Video, Web)

28 %

ERP-Systeme

26 %

Instant-Messaging-Dienste

26 %

ProjektmanagementSoftware

25 %

CRM-Software

24 %

Collaboration-Software web & mobile developer 3/2017

17 %

Die meistgenutzten Tools zur Arbeitsorganisation in deutschen Büros (Bild 5) Quelle: www.wrike.com

zu entscheiden. In über 60 Prozent der Fälle bestimmt die ITAbteilung, in 24 Prozent der Bereichs- oder Teamleiter, welche Tools auf dem Rechner oder dem beruflich genutzten Smartphone landen. Gehalt.de

Trendberufe 2017 Laut einer Untersuchung von Gehalt.de gehören zu den Trendberufen 2017 neben dem Dauerbrenner Ingenieur für Luft- und Raumfahrt auch eSports-Manager, Software Entwickler für Virtual-RealityAnwendungen, Robotik-Ingenieure sowie Lehrer für Naturwissenschaften. Die Gaming-Branche boomt und die Umsätze im eSportSegment sind am Explodieren. Live-Events werden aufgrund der hohen Zuschauerzahlen in Fußballstadien ausgetragen und die Einschaltquoten im Internet sind ein Traum für jeden Werbetreibenden. Ein Trendberuf für 2017 ist damit der eSports-Manager, der vom Community- bis zum Projektmanagement als Allrounder eingesetzt wird. Mit Virtual Reality-Brillen blicken wir in eine neue Welt. Spiele und Anwendungen geschehen um den Nutzer herum. Diese Technologie ermöglicht ein ganz neues Erlebnis. Der Trend geht in Richtung computergesteuerter Prozesse. Fließbandroboter gehören längst zum Repertoire modernen Industrieunternehmen. Doch die Robotik geht weiter: Kassier- und Kanalarbeiten oder das Amt des Gerichtsschreibers könnten laut neuesten Studien in Zukunft von Robotern übernommen werden. Dies wiederum erfordert spezialisierte Ingenieure, die sich dem Fach Robotik widmen und die Arbeitskräfte von morgen erschaffen.

3.2017 www.webundmobile.de


IMPRESSUM

Mitarbeiter dieser Ausgabe

Impressum Verlag Neue Mediengesellschaft Ulm mbH Bayerstraße 16a 80335 München Telefon: (089) 741 17-0 Fax: (089) 741 17-101 (ist zugleich Anschrift aller Verantwortlichen)

Leitung Herstellung / Vertrieb

Herausgeber Dr. Günther Götz

E-Mail: leserservice@nmg.de

Telefon: (089) 741 17-111 E-Mail: thomas.heydn@nmg.de Leserservice Hotline: (089) 741 17-205 Fax: (089) 741 17-101

Kooperationen Denis Motzko Telefon: (089) 741 17-116 E-Mail: kooperationen@nmg.de Druck

Schlussredaktion Ernst Altmannshofer

L.N. Schaffrath Druckmedien

Redaktionelle Mitarbeit Philip Ackermann, Johann Baumeister, Christian Bleske, Olena Bochkor, Tam Hanna, Anna Kobylinska, Bernhard Lauer, Filipe Martins, Florence Maurice, Carsten Möhrke, Konstantin Pfliegl, Michael Rohrlich, Jochen Schmidt, Katharina Sckommodau, Thomas Sillmann, Frank Simon

47608 Geldern

art Directorin Maria-Luise Sailer

Bezugspreise

Grafik & Bildredaktion Alfred Agatz, Dagmar Breitenbauch, Verena Greimel, Hedi Hefele, Manuela Keller, Simone Köhnke, Cornelia Pflanzer, Karoly Pokuta, Petra Reichenspurner, Ilka Rüther, Sebastian Scharnagl, Christian Schumacher, Nicole Üblacker, Mathias Vietmeier Mediaberatung und Content-Marketing-Lösungen Thomas Wingenfeld Telefon: (089) 741 17-124 E-Mail: sales@nmg.de Klaus Ahlering Telefon: (089) 741 17-125 E-Mail: sales@nmg.de Stellenanzeigen / Anbieterverzeichnisse / Guides Juliane Roschke Telefon: (089) 741 17-283 E-Mail: sales@nmg.de

Marktweg 42–50

Vertrieb DPV Vertriebsservice GmbH Objektvertriebsleitung Lothar Kosbü Süderstraße 77 20097 Hamburg Telefon: (040) 34724857

web & mobile developer ist das ProfiMagazin für Web- und Mobile-Entwickler und erscheint zwölfmal im Jahr. Der Bezugszeitraum für Abonnenten ist jeweils ein Jahr. Der Bezugspreis im Abonnement beträgt 76,20 Euro inklusive Versand und Mehrwertsteuer im Halbjahr, der Preis für ein Einzelheft 14,95 Euro. Der Jahresbezugspreis beträgt damit 152,40 Euro. In Österreich sowie im übrigen Ausland kostet das Abonnement 83,70 Euro im Halbjahr. Der Jahresbezugspreis beträgt somit 167,40 Euro. In der Schweiz kos-

W

W

e bin ar

e

Chefredakteur Max Bold – verantwortlich für den redaktionellen Teil – E-Mail: redaktion@webundmobile.de

Thomas Heydn

Jetzt Ihre web & mobile developer auf dem iPad lesen

Jetzt online weiterbilden! „Fortschritt heißt für mich vor allem, dass man fortschreiten will.“ Johannes Hoppe IT-Berater, Programmierer, Webdesigner

tet das Abonnement 152,00 Franken im Halbjahr. Der Jahresbezugspreis in der Schweiz beträgt 304,00 Franken. Das Abonnement verlängert sich automatisch um ein Jahr, wenn es nicht sechs Wochen vor Ablauf der Bezugszeit schriftlich beim Verlag gekündigt wird. Studenten erhalten bei Vorlage eines

Disposition Marita Brotz Telefon: (089) 741 17-281 Fax: (089) 741 17-269 E-Mail: sales@nmg.de

www.webundmobile.de 3.2017

Nachweises einen Rabatt von 50 Prozent. ISSN: 2194-4105 © 2017 Neue Mediengesellschaft Ulm mbH

developer-media.de/webinare

143


dotnetpro Newsletter Top-Informationen fĂźr den .NET-Entwickler. Klicken. Lesen. Mitreden.

Jetzt kostenlos anmelden: dotnetpro.de

twitter.com/dotnetpro_mag

facebook.de/dotnetpro

gplus.to/dotnetpro


ANBIETER

Anbieterverzeichnis für Deutschland, Schweiz und Österreich.

Consulting / Dienstleister

ANEXIA Internetdienstleistungs GmbH Feldkirchner Straße 140 9020 Klagenfurt / AUSTRIA T +43-50-556 F +43-50-556-500 info@anexia-it.com

ANEXIA wurde im Juni 2006 von Alexander Windbichler als klassischer Internet Service Provider gegründet. In den letzten Jahren hat sich ANEXIA zu einem stabilen, erfolgreichen und international tätigen Unternehmen entwickelt, das namhafte Kunden rund um den Globus mit Standorten in Wien, Klagenfurt, München, Köln und New York City betreut. ANEXIA bietet ihren Kunden hochwertige und individuelle Lösungen im Bereich Web- und Managed Hosting, sowie Individualsoftware und App Entwicklung.

prodot GmbH Schifferstraße 196 47059 Duisburg T: 0203 - 346945 - 0 F: 0203 - 346945 - 20 info@prodot.de https://prodot.de

prodot - Software für Marktführer Intelligente Software für internationale Konzerne und mittelständische Unternehmen: prodot stärkt seit über 15 Jahren namhafte Kunden im weltweiten Wettbewerb – mit effizienten, stabilen und kostensenkenden Lösungen. Kunden schätzen unsere Kreativität. Mit Sorgfalt und Enthusiasmus entwickeln wir hochwertige Software. Digitale Prozesse und innovative Technologien sind unser Antrieb, Fortschritt und Kontinuität unser Anspruch. ALDI SÜD, Microsoft und Siemens vertrauen uns bereits viele Jahre. Gerne zeigen wir Ihnen warum! Sprechen Sie mich an. Pascal Kremmers.

Payone GmbH & Co. KG Fraunhoferstraße 2-4 24118 Kiel T: +49 431 25968-400 F: +49 431 25968-1400 sales@payone.de www.payone.de

PAYONE ist einer der führenden Payment Service Provider und bietet modulare Lösungen zur ganzheitlichen Abwicklung aller Zahlungsprozesse im E-Commerce. Das Leistungsspektrum umfasst die Zahlungsabwicklung von allen relevanten Zahlarten mit integriertem Risikomanagement zur Minimierung von Zahlungsausfällen und Betrug. Standardisierte Schnittstellen und SDKs erlauben eine einfache Integration in bestehende IT- und mobile Systemumgebungen. Über Extensions können auch E-Commerce-Systeme wie Magento, OXID eSales, Demandware, Shopware, plentymarkets und viele weitere unkompliziert angebunden werden.

eCommerce / Payment

Web- / Mobile-Entwicklung & Content Management

digitalmobil GmbH & Co. KG Bayerstraße 16a, 80335 München, T: +49 (0) 89 7 41 17 760, info@digitalmobil.com, www.digitalmobil.com

In allen Fragen rund um das Dienstleisterverzeichnis berät Sie Frau Roschke gerne persönlich!

Juliane Roschke ▪ 089 / 7 41 17 - 283 ▪ juliane.roschke@nmg.de

www.webundmobile.de

3.2017

145


VORSCHAU

4/2017

Die Ausgabe 4/2017 erscheint am 16. März 2017 Webhosting in der Cloud Permanente Veränderungen, neue Technologien und Methodologien prägen die IT-Welt seit jeher. Eines dieser Themen, die unser Denken und Handeln hinsichtlich Hosting-Lösungen in den letzten Jahren nachhaltig beeinflusst haben, ist das Cloud Computing. Unzählige internationale Unternehmen haben in den vergangenen Jahren ihre IT-Infrastruktur von traditionellen Rechenzentren und Inhouse-Serverräumen in die Cloud umgezogen. Aber viele Firmen ignorieren diesen globalen Trend bisher. Woran liegt das und sind die Vorbehalte berechtigt? Cloud-Anbieter, wie beispielsweise Amazon Web Services (AWS), Microsoft Azure oder Google, steigern ihre Gewinne in diesem Sektor seit Jahren kontinuierlich und übertreffen sich mit der Einführung neuer Angebote gegenseitig.

Amazon Machine Learning

Swift und Objective-C im Einklang

Im Gartner Hype Cycle von 2016 platziert sich Machine Learning als absolutes Technologie-Trendthema für die nächsten Jahre. Kaum verwunderlich – will man doch eigentlich keine plumpe Mustererkennung mehr haben, sondern ein lernendes System. Der Einstieg in diese Technologie ist meist recht schwer – es sei denn, man verwendet die Infrastruktur von Amazon. Maschinelles Lernen ist ein wichtiger Bereich der künstlichen Intelligenz.

Apple liefert diverse Möglichkeiten, das Zusammenspiel von Swift- und Objective-C-Code zu optimieren. Die Programmiersprache Swift hat sich seit ihrer erstmaligen Vorstellung 2014 massiv weiterentwickelt und erfreut sich unter Apple-Entwicklern sehr großer Beliebtheit. Die gelungene Syntax und mächtige Sprachmerkmale wie Optionals oder Generics gestalten für viele die Arbeit mit Swift deutlich angenehmer als mit Objective-C.

dotnetpro

Nicht für alle Anwendungen, in denen vom Server Daten an den Client gesendet werden, sind Web Sockets die beste Wahl. In vielen Fällen sind Server-Sent Events, kurz SSEs, besser. Der Unterschied: Im Gegensatz zu Web Sockets erfolgt die Kommunikation unidirektional, und zwar vom Server in Richtung Client. Hinzu kommt, dass SSEs ganz normal über HTTP versendet werden, während Web Sockets ein eigenes Protokoll verwenden.

Unsere digitalen Angebote Ausgabe 3/2017 ab 16. Februar 2017 am Kiosk Künstliche Intelligenz ist keine Zukunftsmusik, sondern schon seit Längerem gängige Praxis. Wie Sie künstliche Intelligenz in Ihren Anwendungen einsetzen, ohne sie selbst entwickeln zu müssen, lesen Sie im Schwerpunkt dieser Ausgabe. www.dotnetpro.de

146

Das Server-Sent Events API

Wöchentlicher Newsletter www.webundmobile.de/newsletter Shop http://shop.webundmobile.de YouTube https://youtube.com/user/developermedia Facebook https://facebook.com/webundmobile Google + https://plus.google.com/103648199036371702595 Twitter https://twitter.com/webundmobile

3.2017 www.webundmobile.de


Ihr Partner fĂźr mehr Online-Wachstum Wir planen, entwickeln und steuern Websites, Apps und Kampagnen.

Unsere Ziele sind Ihre Ziele: Mehr Sichtbarkeit Mehr TrafďŹ c Mehr Leads Mehr Conversions Mehr Kunden

Besuchen Sie uns unter www.digitalmobil.com


26.-29. Juni 2017, Messe Nürnberg

Die Konferenz für Entwickler • Für Entscheider und Entwickler in IT- und Entwicklungsabteilungen

• Know-how für Praxis und Innovation • 200 Sessions mehr als 150 Experten, diversen Abendprogrammen, Specials, Internationale

Keynotesprecher

Mit Very Early Bird

€ 200,– sparen* *bis 27.02.2017

developer-week.de Aussteller und Sponsoren:

#dwx17

DeveloperWeek


Issuu converts static files into: digital portfolios, online yearbooks, online catalogs, digital photo albums and more. Sign up and create your flipbook.