Tutorials

Swift-Grundlagen – Die Objektorientierung in Swift

Das heutige Tutorial wird sich mit den Grundlagen der allgemeinen Objektorientierung und dessen Implementierung in Swift befassen. Auch der Bereich objektorientierte Programmierung ist etwas üppiger geraten, als das, was man von anderen Programmiersprachen kennt. Und es ist durch die prozedurale Auslegung deutlich anders als das von Objective-C, die durch Message Passig realisiert ist. Diese bringt sehr große Vorteile in der leichteren Übertragbarkeit von Codeteilen aus anderen Programmiersprachen, aber auch in der Ausführungsgeschwindigkeit der erzeugten Programme gegenüber Objective C.

Aber erst einmal die Frage: wozu den eine Objektorientierung und wie geht man damit um. Durch die Objektorientierung kann man besser die Vorgänge und Objekte der realen Welt auf einem Rechner nachbilden.

Von Records und Strukturen zu Klassen

Die Ursprünge der Objektorientierung liegen ganz weit zurück in den 60er Jahren des vorherigen Jahrhunderts in der Programmiersprache Cobol. Dort wurden einzelne Daten zu Gruppen zusammengefasst, die dann gemeinsam auf einem Band oder später auch einer Festplatte gespeichert wurden. So konnte man z.B. eine Adresse aus dem Vornamen, Nachnamen, der Straße und dem Ort bilden. Dieses Feature wurde dann in die Sprachen Algol und Pascal übernommen und auch die damals aufkommende Programmiersprache C hat unter der Bezeichnung Struktur etwas Analoges integriert.

Bereits recht früh kamen Forscher auf die Idee, nicht nur Daten, sondern auch Programmcode in einer Einheit zu bündeln. Solche Konzepte gab es in den Sprachen Pascal und Modula, wo sie Unit und Modul hießen. Parallel dazu kam man auf die Idee, die Einheiten aus Code und Daten mehrfach verwenden zu können, mit jeweils unterschiedlichen Inhalten. Damit war das Objekt / die Klasse geboren. Fast parallel entstanden zwei voneinander abweichende Konzepte und verbunden damit – Programmiersprachen. Sie unterschieden sich hauptsächlich über die Art, wie der Programmcode von außen angesprochen wird. Es entstanden die Sprachen Prolog und Simula, deren Nachfolger Objective C und C++ / Swift sind.

Damit konnte man bereits sehr gut in der realen Welt vorkommende und im Rechner abzubildende Dinge modellieren und dieses auch testbar machen.

Strukturen in Swift

In Swift gibt es ähnlich wie in C++ einen Unterschied zwischen Strukturen und Klassen. Jedoch sind C++ Strukturen einfach nur zusammengefasste Datentypen ohne Logik, wenn Logik dazu kommt, muss es als Klasse definiert werden. In Swift ist der Unterschied zwischen Klasse und Struktur ein anderer. Eine Struktur kann sowohl Code als auch Properties beinhalten. Aber eine Struktur ist ein Wertetyp und wird bei der Zuweisung kopiert. Eine Klasse ist ein Referenztyp und bei der Zuweisung wird nur eine neue Referenz erzeugt, die auf das gleiche Objekt zeigt. Auch kann sie nicht von anderen Strukturen abgeleitet werden und genauso wenig kann von ihr eine weitere Struktur ableiten. Strukturen dürfen auch nicht gecastet werden, das heißt, der Typ eines Ausdrucks kann nicht an einen anderen, verwandten angepasst um dann zugewiesen zu werden. Darüber hinaus gibt es keine Deinitiliser-Methoden (vergleichbar mit den Destruktiven, siehe Objektorientierung, zweiter Teil).

Daher werden wir nach einer kurzen Einführung nur noch von Klassen reden, da diese den vollständigen Umfang an Möglichkeiten gewährleisten.

struct Point {
    var x = 0
    var y = 0
}

class Square {
    var origin : Point?
    var length = 0
    var height = 0
}

struct Point3d {
    var x : Int?
    var y : Int?
    var z : Int?
}


Wie man im obigen Beispiel sieht, ist eine Struktur / Klasse in Swift grundsätzlich bereits bei der Memberdefinition ein wenig anders aufgebaut als die Klassen in Java/C++ oder auch Objective C.

Ein Unterschied fällt dabei sofort auf: Im Gegensatz zu den oben benannten Sprachen müssen alle Variablen bereits bei der Definition initialisiert werden. Das ist eine Folge dessen, dass normale Variablen keinen Wert NULL aufnehmen können. Sollte dieses der Fall sein, muss man mit der Nullable- (Optional-) Variante mit angehängten Fragezeichen arbeiten. Wie man bei der Definition der Rechteck-Klasse gut sehen kann, gilt das nicht nur bei den vordefinierten Klassen, sondern auch bei den eigenen. Von der Regel, dass alle Variablen von vornherein definiert sein müssen, wird abgewichen, wenn die Klasse Konstruktoren besitzt.

Es gibt noch einen zweiten Unterschied, der nicht direkt bemerkt wird. Die Variablen, die in der Klasse definiert werden, sind keine direkten Variablen, wie in den übrigen Sprachen, sonder per se Auto-Properties. Der Unterschied zwischen einer Variablen und einer Property ist technischer Natur und dient der Kapselung der Daten. Eine Variable bedeutet den direkten Zugriff auf die Speicherstelle(n), in der die Variable gespeichert wurde. Eine Property speichert zwar letztendlich auch den Wert in einer Variablen ab, jedoch ist dem jeweils ein Stück Code vorangestellt (ein Getter und ein Setter) der bei Autoproperties automatisch generiert wird. Man kann somit, wenn man die Getter und Setter selbst programmiert, ggf. bestimmte Konvertierungen aber auch Prüfungen auf Vollständigkeit und Korrektheit durchführen.

Instantieren und Initialisieren von Strukturen und Klassen

In objektorientierten Sprachen nennt man eine spezielle Ausprägung (also das, was man einer Variablen zuweist) einer Klasse, eine sogenannte Instanz. Diese Instanz beinhaltet individuelle Werte der einzelnen Memberproperties. Bei der Initialisierung von Strukturen kann man wahlweise eine vorgelegte Instanz mit den Standard-Werten verwenden oder eine mit eigenen Werten initialisierte Variante benutzen. Man kann aber nur eine der beiden Möglichkeiten wählen – oder einfach keinen Parameter angeben (nur dann, wenn alle Membervariable Standardwerte besitzen) oder alle Werte müssen initialisiert werden.

var point = Point()
point.x = 15
point.y = 20

var point1 = Point(x: 20, y: 30)

Bei Klassen sieht es ein wenig anders aus. Hier gibt es wahlweise die konstruktorlose Variante, die im Gegensatz zu Strukturen auch optionale Member haben darf.

var sq = Square()
sq.origin = point
sq.radius = 10

Alternativ gibt es eine Version mit Konstruktoren, wie man sie aus anderen objektorientierten Programmiersprachen kennt. Ein Konstruktor wird immer mit dem Wort init eingeleitet, dem die (optionalen) Parameter folgen. Anschließend folgt eine Implementierung, bei der die Parameter den Memberproperties zugewiesen werden und ggf. auch eine andere Initialisierung durchgeführt wird.

class Circle {
    var origin : Point
    var radius : Int

    init (origin: Point, radius: Int) {
        self.origin = origin
        self.radius = radius
    }


    init (fromAnotherCircle circle: Circle) {
        self.origin = circle.origin;
        self.radius = circle.radius;
    }

    init (_ x: Int,_ y: Int,_ radius: Int) {
        self.origin = Point(x: x, y: y)
        self.radius = radius
    }
}

let circle = Circle(origin: point, radius: 12)

let circle1 = Circle(fromAnotherCircle: circle)

let circle1 = Circle(5, 5, 15)

Hier sieht man gleich zwei Besonderheiten – das Fragezeichen für die optionalen Typen darf auch fehlen. Allerdings darf das nur gemacht werden, wenn alle Konstruktoren alle nichtoptionale Member mit Werten befüllen.

Zweitens kann man hierbei den Zugriff auf die Member einerseits über die im Konstruktor-Body verwendeten Variablen-Namen verfolgen. Alternativ kann man sprechende Parameter-Namen verwenden, die von dem im Body verwendeten abweichen. Die dritte Möglichkeit verwendet anstelle von optionalen Parameter-Namen einen Underscore (Unterstrich). Damit muss beim Konstruktoraufruf kein Parametername mehr angegeben werden, der Aufruf sieht wie in einer konventionellen Programmiersprache aus.

Zugriff auf Klassenproperties

Will man auf die Klassenproperties einer Instanz von einer Klasse oder Struktur zugreifen, dann geschieht das über den Namen der Instanz und dem Namen der Property, unterteilt durch einen Punkt. Im Normalfall kann man so auch den Inhalt einer Property setzen. Allerdings geht das nur dann, wenn die Property keine Konstante ist (dann kann sie allerdings entgegen seiner Eigenschaft als Konstante im Konstruktor dennoch beschrieben werden. Ist eine Struktur-Instanz einer Konstanten zugewiesen, kann man auch hier keine Properties von außen ändern. Dieses gilt aber nur bei Strukturen.

Bei Klassen, die ja Referenztypen sind, gibt es keinen Unterschied ob eine Instanz einer Variablen oder einer Konstanten zugewiesen wird. Man kann bei beiden Arten alle Properties, die selbst nicht konstant sind, ändern. Einzig kann man einer Klassen-Konstanten keine neue Referenz (also eine andere Instanz) zuweisen.

struct Triangle {
    var origin : Point()
    let base : Int
    var height : Int

    init (origin : Point, base: Int, height: Int) {
        self.origin = origin
        self.base = base // Ist möglich
        self.height = height

    }
}

var t1 = Triangle()
t1.base = 12 // Fehlermeldung

let t2 = Triangle()
t2.height = 12 // genauso Fehlermeldung

let c1 = Circle(5, 5, 10)
c1.radius = 20 // funktioniert

Ein weiterer Unterschied zwischen Strukturen und Klassen offenbart sich bei der Zuweisung oder beim Aufruf von Funktionen, bei denen eine Instanz als Parameter übergeben wird.

Wird eine Struktur-Instanz einer anderen Variablen oder Konstanten zugewiesen, erhält diese eine Kopie der Instanz. Daher wirken sich Änderungen bei der neuen Instanz nicht auf alte aus. Bei einer Klasse wird die gleiche Instanz nur einer anderen Referenz zugewiesen. Daher wirken sich hier die Änderungen wohl aus.

var pt1 = Point(x: 10, y: 10)
var pt2 = pt1
pt2.x = 20 // pt1.x = 10, pt2.x = 20

var c1 = Circle(5, 5, 10)
var c2 = c1
c2.radius = 20 // c1.radius = 20, c2.radius = 20

In der nächsten Folge werden wir uns weiterhin mit den Klassen beschäftigen: und zwar mit Properties, bei denen aber eine Implementierung des Verhaltens ins Spiel kommt.

Hier findet man eine Übersicht von sämtlichen Swift-Tutorials auf unserem Blog.

Fragen zu diesem Tutorial können in den Kommentaren oder in der Swift Community gestellt werden.

Read More

Automator Tutorials – Eine Textdatei aus der Zwischenablage erstellen

Heute möchten wir einen weiteren Automator-Workflow vorstellen, der ein paar Handgriffe am Computer abnehmen kann. Als Beispiel-Szenario möchten wir den Erwerb einer Software heranziehen. Nach dem Kauf bekommt man häufig eine Mail mit der Seriennummer zugeschickt. Diese Nummer soll nun in einer Textdatei archiviert werden. Das übliche Vorgehen ist hier den Text zu markieren, in die Zwischenablage zu kopieren, einen Texteditor zu öffnen, den Text dort einzufügen und die Datei zu speichern. An dieser Stelle kommt unser Automator-Script ins Spiel, welches automatisch aus dem Inhalt der Zwischenablage ein Textfile erstellt.

Nach dem Start des Automators wählen wir “Programm” aus und fahren fort.

Clipboad2TXT-01

Im Bereich Dienstprogramme finden wir die Aktion “Get Contents of Clipboard”, welche wir nach rechts in den Workflow ziehen.

Clipboad2TXT-02

Die zweite Aktion, die wir benötigen heißt “New Text File”. Auch diese ziehen wir in den Ablauf und nehmen noch ein paar kleine Modifikationen vor. Als Dateiformat ist “Reiner Text” zu wählen. Direkt darunter können wir einen Dateinamen vorgeben, den das File bekommen soll. Optional kann auch der Punkt “Diese Aktion beim Ausführen des Arbeitsablaufes anzeigen” aktiviert werden. Dann nämlich erscheint immer ein Dialog zum ändern des Speichernamens. Als letztes sollte noch der Speicherort bestimmt werden.

Clipboad2TXT-03 Der Workflow ist nun fertig und braucht nur noch gespeichert zu werden.

Clipboad2TXT-04Auch diesmal bietet dieses Script viel Raum, um noch weitere Veränderungen oder Verbesserungen vorzunehmen. In erster Linie denken wir an die Möglichkeit, das Programm mit einer Tastenkombination aufzurufen. Aber auch die Umsetzung als Dienst, statt als Programm wäre möglich gewesen. Hier muss jeder für sich entscheiden, was für ihn am sinnvollsten ist. Wir wünschen auf jeden Fall viel Spaß beim experimentieren.

Hier findet man eine Übersicht aller Automator Tutorials.

Weitere Tutorial-Reihen auf apfelcheck! – SynologyFusion DriveOS X Terminal

Fragen zu diesem Automator Tutorial können in den Kommentaren oder in der Community gestellt werden. 

Read More

Swift Grundlagen – Unterprogramme (Methoden / Funktionen)

Swift ist eine objektorientierte prozedurale Sprache. Das prozedurale Paradigma ist deutlich älter als das objektorientierte und dient in erster Linie der Wiederverwendbarkeit vom Code. Dieses bedeutet, dass man ein Stück Code, das man an mehreren Stellen verwenden kann, nicht mehrmals schreiben muss, sondern man unterbringt diesen Code in einer Prozedur und ruft diese von verschiedenen Stellen im Code auf.

Sie ist aber auch ein integraler Bestandteil der Objektorientierung, damit werden die verschiedenen Aktionen eines Objektes angesprochen. An dritter Stelle soll das Verwenden von Methoden und Funktionen die Lesbarkeit des Programmes verbessern und die Wartbarkeit erhöhen, indem man lange Codestücke in kleine, logisch getrennte Einheiten unterteilt.

Um diese Ziele zu erreichen, soll ein Unterprogramm logisch zusammenhängenden Code zu einer Einheit zusammenfassen. Dies ist wichtig, damit dieser einerseits von verschiedenen Stellen aufgerufen werden kann, aber auch um den Code logisch von anderen Teilen des Programmes abzugrenzen. Um eine Methode flexibel an verschiedene Anforderungen anzupassen, kann man einer Methode Parameter übergeben. Eine solche Methode kann auch einen Wert zurückliefen. In dem Fall würde man früher von einer Funktion sprechen. In Swift gibt es keinen praktischen Unterschied zwischen Prozeduren und Funktionen, beide liefern einen Wert zurück, wobei dieser im Falle einer Prozedur auch nichts “void” sein kann. Wie bereits oben angewandt, reden wir auch in C-verwandten objektorientierten Programmiersprachen nicht von Prozeduren und Funktionen sondern nur von Methoden.

Um die Code-Dokumentation zu optimieren, sollten Methoden und Parameter, wie zuvor die Variablen, sprechende Namen tragen. Sinnvoll ist auch bei etwas komplexeren Methoden ein Kommentar vor dem Methodenanfang zu setzen, aus dem die Funktion und die Rolle der Parameter und des Rückgabewertes hervorgeht.

/*
* Methode zeichnet ein Rechteck
* als Parameter werden die Koordinaten der linken oberen
* sowie der rechten unteren Ecke und die Farbe übergeben
*/
func draw (x1:int16, y1: int16, x2: int16, y2: int16, Color color): void {
  .....
}

Eine Methode wird aufgerufen, indem man ihren Namen sowie die notwendigen Parameter in Klammern schreibt. Liefert die Methode einen Wert zurück, kann man diesen an eine Konstante oder Variable zuweisen.

// Aufruf der im vorherigen Beispiel verwenden Draw-Methode
draw (10, 10, 50, 50)

// Definition einer Methode, die zwei Zahlen multipliziert
func multiply (first: Double, second: Double) -> Double {
  return first * second;
}

let result = multiply (first, double)

// Definition einer Facultät-Methode
func faculty(value : Int64) -> Int64 {
    var result = 1;
    var i:Int64;

    for i=1; i<value; i++ {
        result *= i;
    }
    return result;
}

// 21 ist der höchste Wert für die Fakultät, damit noch ein 64-bit Integer-Wert als Ergebnis kommt.
var facresult = faculty(21)

Im letzten Beispiel sieht man gut, dass man innerhalb einer Methode auch Variable und Konstante definieren kann. Diese werden dann “lokale Variablen / Konstanten” genannt und ihre Lebensdauer (“Wirkung”) ist nur auf den Bereich der Methode beschränkt. Will man außerhalb der Methode auf eine solche Variable zugreifen, erhält man eine Fehlermeldung, dass diese Variable nicht definiert sei. Umgekehrt jedoch kann man in einer Methode auf Variablen zugreifen, die außerhalb definiert wurden. Der Name einer lokalen Variablen / Konstanten ist, kann aber auch gleichlautend mit einer Variablen / Konstanten außerhalb sein. Der Zugriff erfolgt dann stets auf die lokale Variable. Im nächsten Teil werden wir dann sehen, dass sich die Methode innerhalb einer umschließenden Klasse befindet. Man kann dennoch in einer Methode auf eine gleichnamige Klassenvariable / Klassenkonstante zugreifen, hierfür bedient man sich des Schlüsselwortes “self”.

Innerhalb einer Methode kann man natürlich andere Methoden aufrufen. Ein besonderer ist der Aufruf nach der Methode durch sich selbst. Diese besondere Form nennt sich Rekursion und es gibt viele Einsatzgebiete für den rekursiven Aufruf einer Methode. Als Beispiel dient hier eine andere Schreibweise des letzten Beispiels.

func faculty1 (value: Int64) -> Int64 {
  if value <= 1 {
      return 1
  } else {
      return value * faculty1(value-1)
  }
}

facresult = faculty1(20

Da ein Return den Programmfluss unterbricht (an dieser Stelle kehrt der Programmfluss zurück an den Aufrufer) können wir den “else”-Zweig weglassen. In den Anfängen der prozeduralen Programmierung war ein solches Verhalten verpönt bzw. sogar nicht möglich (z.B. in der Standard-konformen Schreibweise in Pascal), wird es in heutigen Zeiten bevorzugt eingesetzt, da es die Verschachtelungstiefe drastisch reduziert.

func faculty2 (value: Int64) -> Int64 {
    if value <= 1 {
        return 1
    }
    return value * faculty2 (value-1)
}

facresult = faculty2(19)

In diesem einfachen Fall können wir es über das inline-if nochmals etwas kürzer schreiben:

func faculty3 (value: Int64): Int64 {
    return value <= 1 ? 1 : value * faculty3(value-1)
}

facresult = faculty3 (18)

Eine Besonderheit der Methoden stellt bei den meisten objektorientierten Programmiersprachen das Überladen (Overloading). Dieses bedeutet, dass man bei ähnlicher Funktionalität aber unterschiedlichen Parametern eine Methode mehrmals definieren kann und der Compiler sorgt dafür, dass die richtige Methode aufgerufen wird. Es gibt noch einen zweiten Aspekt des Überladens, den werden wir dann bei der fortgeschrittenen objektorientierten Programmierung besprechen.

func test (value: Int64) -> String {
    return "Parameter Int64"
}

func test (value: String) -> String {
  return "Parameter String"
}

let stringResult = test ("Test")

Im nächsten Artikel werden wir uns mit Aspekten der objektorientierten Programmierung mit Swift beschäftigen, also der Definition von Strukturen und daraus hervorgehenden – Klassen.

Hier findet man eine Übersicht von sämtlichen Swift-Tutorials auf unserem Blog.

Fragen zu diesem Tutorial können in den Kommentaren oder in der Community gestellt werden.

Read More

Swift Grundlagen – Kontrollstrukturen Teil 2 (if, case)

In diesem Beitrag werden wir uns mit den Entscheidungs-Kontrollstrukturen befassen. Diese weichen kaum von den bekannten Strukturen der C-angelehnten Sprachen ab. Allerdings haben wir auch hier ein paar erweiterte Möglichkeiten sowie Besonderheiten zu erwarten.

Das if-Statement dient dazu, Entscheidungen zu treffen, die nur zwei Möglichkeiten kennen. Das If-Statement birgt keine neuen Möglichkeiten gegenüber C-ähnlichen Sprachen. Genauso wie bei der while-Schleife wird hier die Bedingung nicht in Klammern gesetzt.

let x = 10
var y = 5

if y < x {
    println ("Kleiner")
} else {
    println ("Größer")
}

Die Switch-Anweisung dient dazu, je nach dem Inhalt einer Variablen, eine von vielen möglichen Verzweigungen zu nutzen. Ggf. kann auch eine zusätzliche Verzweigung für den Fall hinzugefügt werden, dass keine der anderen Möglichkeiten zutrifft.

var z : 8

switch z {
    case 0: println ("Null")
    case 2,4,6,8: println ("Eine gerade Zahl kleiner als 10")
    case 10..19: println ("Eine Zahl innerhalb der Bereiches 10 bis 19")
    default: println ("Nichts aus der obigen Auswahl")
}

Wie man sieht, kann man im Gegensatz zu C auch mehrere Werte innerhalb einer Case-Anweisung behandeln, genauso gut kann man mit einem Bereich viel Arbeit sparen.

Wichtig: Das default – Statement ist im Gegensatz zu einigen anderen Programmiersprachen Pflicht. Und es gibt, wiederum im Gegensatz zu C-ähnlichen Sprachen kein implizites fallthrough. In C sollte jede Verzweigung mit einem break abgeschlossen werden. Ist dies nicht der Fall, wird der Code aus dem nächsten Case mit ausgeführt. Dieses ist bei Swift nicht der Fall: hier wird standardmäßig nur der Code, der dem Case unmittelbar folgt, ausgeführt. Will man dennoch das C-Verhalten, kann man das fallthrough-Schlüsselwort verwenden.

let x = 5

switch x {
    case 0...5: println("Bereich 0...5")
                fallthrough
    case 6...9: println("Bereich 0...9")
    default:    println ("außerhalb des Bereichs 0..9")
}

Zum Üben wollen wir mal ein komplexeres Beispiel programmieren. Dazu löschen wir unser Playground und versuchen uns an einem Programm, das die Primzahlen in einem Bereich von und bis angibt.

var from = 4
var to = 300
var notPrime:Bool

for i in from...to {
    notPrime = false
    var half = Int(i / 2)
    for j in 2...half  {
        var remainder = i % j
        if remainder == 0 {
            notPrime = true
            continue
        }
    }
    if notPrime {
        continue
    }
    print (i)
    print (" ")
}

Eine etwas optimiertere Version verwendet anstelle der Hälfte, nur die Wurzel des Wertes von i und ist bei einem größeren Bereich deutlich schneller

var from = 4
var to = 300
var notPrime:Bool

for i in from...to {
    notPrime = false
    var sq = sqrt(Double(i))
    for j in 2...Int(sq)  {
        var remainder = i % j
        if remainder == 0 {
            notPrime = true
            continue
        }
    }
    if notPrime {
        continue
    }
    print (i)
    print (" ")
}

Als nächstes werden wir uns die Prozeduren/Methoden und Funktionen näher anschauen.

Hier findet man eine Übersicht von sämtlichen Swift-Tutorials auf unserem Blog.

Fragen zu diesem Tutorial können in den Kommentaren oder in der Community gestellt werden.

Read More

Automator Tutorials – Öffnen von Webseiten

Wer kennt das nicht? Man fährt morgens den Rechner hoch und ruft immer die gleichen Webseiten auf, um sich erst einmal einen Überblick über die Welt zu verschaffen. Welche Mails hat man bekommen? Was wurde in der Twitter-Timeline geschrieben? Welche neuen Reviews gibt es bei apfelcheck?

Unnötig zu sagen, dass dieser Vorgang unnötig Zeit verschlingt, und das noch vor dem ersten Kaffee! Wie so oft kann auch hier der Automator weiter helfen. Erfahrene Nutzer vom Automator dürften diesen Workflow in unter zwei Minuten zusammen klicken können. Später aber kann er viele Stunden Zeit im Safari Webbrowser einsparen.

Zunächst wird ein neues Programm ausgewählt.

Automator-Websites01 Im Bereich “Internet” zieht man die Aktion “Angegebene URLs abfragen” nach rechts ins Fenster. Danach werden alle Adressen in gewünschter Reihenfolge hinzugefügt.Automator-Websites02 Die abgefragten URLs müssen nur noch angezeigt werden. Dazu dient die Aktion “Webseiten anzeigen”, die Ebenfalls im Bereich “Internet” zu finden ist.Automator-Websites03 So, fast fertig. Jetzt wird das Programm noch abgespeichert. Zum Beispiel auf dem Schreibtisch, von wo es schnell aufgerufen werden kann.Automator-Websites04

Hier findet man eine Übersicht aller Automator Tutorials.

Weitere Tutorial-Reihen auf apfelcheck! – SynologyFusion DriveOS X Terminal

Fragen zu diesem Automator Tutorial können in den Kommentaren oder in der Community gestellt werden. 

Read More

Tutorial – OS X Terminal – Verzeichnisoperatoren

Im vierten Teil unserer Reihe wollen wir uns eingehender mit Verzeichnisoperatoren beschäftigen, bevor wir dann in den kommenden Wochen dazu übergehen mehr und mehr am praktischen Beispiel zu lernen. Man kann mit Abschluss dieser Folge dann zwar nicht annähernd behaupten wir hätten alle Basics erklärt, aber es werden die nötigen Grundlagen geschaffen, um den kommenden Tutorials zu folgen.

Zwei Verzeichnisoperatoren haben wir schon kennengelernt und daher sei an dieser Stelle nur auf die jeweiligen Artikel verwiesen. In Folge zwei war das der Befehl cd (Change Directory), mit dem das Arbeitsverzeichnis gewechselt werden kann, und in Folge drei der Befehl rm (Remove). rm dient zwar hauptsächlich dem Löschen von Dateien, aber durch Verwendung des Schalters -R können damit auch Ordner entfernt werden.

pwd

Wenn es um Verzeichnisse geht, ist es wichtig zu wissen, an welchem Ort man sich gerade befindet. Genau hierzu dient pwd (Print Working Directory), das nach Eingabe den absoluten Pfad liefert.

apfelcheck@iMac:~$ pwd
/Users/apfelcheck

Zwar ist schon oft am Prompt der Ort zu erkennen, das ist dieser Teil apfelcheck@iMac:~$, aber je nach Konfiguration kann dort auch nur ein Teil des Pfades stehen. Damit  der Prompt auch verstanden wird, müssen wir ihn etwas aufdröseln. Das @ trennt den Benutzernamen (apfelcheck) vom Computernamen (iMac). Danach folgt hinter dem Doppelpunkt die Angabe des aktuellen Ortes. Die wellige Linie nennt man Tilde und kann mit der Tastenkombination Wahl + n eingegeben werden. Die Tilde ist dabei eine Abkürzung für das Heimatverzeichnis des aktuellen Benutzers (/Users/apfelcheck). Gerne wird die Abkürzung mit dem Befehlt cd verwendet um sich Tipparbeit zu sparen. Die beiden folgenden Eingaben sind vom Ergebnis also identisch.

apfelcheck@iMac:/$ cd /Users/apfelcheck/

apfelcheck@iMac:/$ cd ~

mkdir

Am Namen wird man schon erraten können, was man mit diesem Befehl anstellen kann – mkdir erstellt neue Ordner.

apfelcheck@iMac:~$ mkdir Tutorial/Teil-4

Hier wird im Ordner Tutorial der Unterordner Teil-4 erstellt. Alternativ hätten wir auch erst in das Verzeichnis Tutorial rein gehen können bevor wir ein mkdir absetzen.

apfelcheck@iMac:~$ cd Tutorial/
apfelcheck@iMac:~/Tutorial$ mkdir Teil-4

Wenn wir mkdir Tutorial/Teil-4 eingeben, muss es den Ordner Tutorial zu dem Zeitpunkt schon geben, damit es zu keiner Fehlermeldung kommt. Sollte das nicht der Fall sein, gibt es diese beiden Möglichkeiten.

apfelcheck@iMac:~$ mkdir Tutorial
apfelcheck@iMac:~$ mkdir Tutorial/Teil-1

Oder man spart sich etwas Tipparbeit und verwendet stattdessen nur einmal mkdir mit dem Schalter -p.

apfelcheck@iMac:~$ mkdir -p Tutorial/Teil-1

Hier werden dann beide Ordner auf einmal angelegt.

rmdir

Was erstellt wird, kann auch wieder entfernt werden. Zwar können Verzeichnisse auch mit dem oben erwähnten rm gelöscht werden, aber eigentlich ist diese Aufgabe diesem Befehl zugedacht.

apfelcheck@iMac:~$ rmdir Tutorial/Teil-4/

Auch hier kann der Schalter -p verwendet werden, wenn Tutorial und Teil-4 gelöscht werden sollen.

apfelcheck@iMac:~$ rmdir -p Tutorial/Teil-4/

Damit es beim Löschen zu keinen Fehlermeldungen kommt, müssen die zu entfernenden Ordner leer sein. Es dürfen sich also weder Unterordner noch irgendwelche Dateien darin befinden. Dieser Befehl kann jedoch auch volle Ordner löschen.

apfelcheck@iMac:~$ rm -R Tutorial

Achtung!!!  Hier passiert es schnell, dass mehr gelöscht wird, als man eigentlich vor hatte. Besser ist es hier interaktiv zu löschen und jedes Löschen noch einmal mit Yes oder No (y oder n) zu bestätigen.

apfelcheck@iMac:~$ rm -Ri Tutorial
examine files in directory Tutorial? y
examine files in directory Tutorial/Teil-4? y
remove Tutorial/Teil-4? y
remove Tutorial? y

Hier findet man eine Übersicht von unseren OS X Terminal Tutorials.

Fragen zum OS X Terminal Tutorial können in den Kommentaren oder in der Community gestellt werden.

Read More

Swift Grundlagen – Kontrollstrukturen 1 (Schleifen)

Auch bei den Schleifen hat Swift unter den meisten Programmiersprachen einiges voraus. Die Schöpfer haben sich einiges Neues ausgedacht aber auch dadurch, dass sie Altbewährtes beibehalten haben und somit für die recht einfache Übertragung von bestehendem Code gesorgt haben. Dieser Artikel beschäftigt sich mit den Schleifen unter Swift.

Schleifen bei Swift

For-Schleife

Bei der For-Schleife gibt es die meisten Neuerungen. Hier sind drei sehr unterschiedliche Formen vorhanden. Es sind der Reihenfolge nach:

Die klassische C-For-Schleife

Diese Schleife wird allen C- und Java-Kennern bekannt vorkommen. Sie besteht aus der Initialisierung, einem Vergleich sowie einer Operation auf der Schleifenvariablen. Im Gegensatz zu der C-Notation werden keine Klammern benötigt.

Für alle, die mit der C-Notation nicht vertraut sind, sei hier gesagt, dass es in der for-Schleife drei Bereiche gibt, die durch Semikola unterteilt sind. Im ersten Teil befindet sich der sogenannte Initializer, d.h. die Festlegung eines Startwertes. Darauf folgt im zweiten Bereich die Bedingung. Diese wird vor jedem Ausführen des Schleifenkörpers geprüft. Nur wenn sie stimmt, also den Wert true zurückgibt wird der Schleifenkörper zum wiederholten Mal durchgelaufen. Als letzten Part haben wir hier den Aktualisierungsausdruck. Diese wird, nachdem der Schleifenkörper durchgelaufen ist, ausgewertet und verändert. Im Normalfall ist die Schleifenvariable die, die im ersten Teil der for-Schliefe initialisiert wurde.

for var i = 0; i < 10; i++ {
    println(i)
}

var j:Int16;

for j = 1; j < 100; j*=2 {
    println(j)
}

Man kann, wiederum genauso wie in den anderen C-Abkömlingen nicht benötigte Teile auslassen, sodass in letzter Instanz eine leere Schleife entsteht, die bei systemnaher Programmierung gerne verwendet wird, um einen Eventloop zu programmieren, also eine Schleife, die über die gesamte Lebenszeit der Anwendung ausgeführt wird und in der bei bestimmten Ereignissen der passende Programmcode ausgeführt wird.

for ;; {
    //hier jede Menge Code einfügen
]

Genauso kann man aber auch in einer Schleife mehrere Werte initialisieren und / oder mehrere Werte aktualisieren.

for var i=0, j=10; i<10; i++, j-- {
    print(i)
    print("   ")
    println(j)
}
 Die For Each-Schleife

Diese Schleife kennt man auch seit einiger Zeit als C++ oder C#-Programmierer. Auch Objektive C, Java und viele andere moderne Sprachen kennen solche Konstrukte. Hier wird jeder Wert aus einer Sammlung von gleichartigen Objekten einmal der Variablen, die vor dem Schlüsselwert in steht, zugewiesen und damit der Schleifenkörper komplett durchlaufen.

let freunde = ["Frank", "Andreas", "Thomas", "Michael", "Niels"]
for freund in freunde {
  println ("Mein Freund heißt: \(freund)")
}

Diese Art von Schleifen kann man mit allen Typen, die mehrere gleichartige Werte aufnehmen können, aufbauen. Es wären z.B. Listen, Dictionatries und wie hier Arrays. Man kann nicht nur über Sammlungen aus einzelnen Werten, sondern auch aus Tupeln iterieren.

let tiereUndBeine = ["Spinne": 8, "Ameise": 6, "Katze": 4, "Spatz": 2, "Karpfen": 0]
for (tiername, anzahlBeine) in tiereUndBeine {
    println("\(tiername) hat \(anzahlBeine) beine")
}

Auch ein String ist eine Sammlung von Zeichen, also kann man auch durch die einzelnen Buchstaben eines Strings iterieren.

let greeting = "Hallo Welt"
var reverse = ""
for character in greeting {
    reverse = String(character) + reverse
}
println (reverse)

Einen Sonderfall der For … in – Schleife bildet die

Schleife mit einem Bereich (Range)

Sprachen wie Basic und Pascal boten einen einfachen Schleifentyp, mit dem man über einen bestimmten Bereich von aufsteigenden Integer-Werten durchiterieren konnte. In Basic wurde sie z.B. unter Zuhilfenahme der Schlüsselwörter FOR … TO …. NEXT programmiert. In Swift dient dazu eine for … in – Schleife, wobei der Bereich, durch den iteriert werden soll, über eine Range beschrieben wird. In Swift wird es wesentlich eleganter unter der Zuhilfenahme der Range-Typen gelöst, wobei die Schleifen nur einer der Einsatzfälle für Range-Typen sind.

Es gibt zwei grundsätzliche Range-Typen: den geschlossenen und den halb offenen Typen

Ein geschlossener Bereich wird durch die Angabe der Grenzen definiert. Dazwischen werden drei Punkte platziert. So beinhaltet die Range 1…4 die Werte 1, 2, 3 und 4. Ein halb offener Bereich wird ähnlich dem geschlossenen Bereich definiert, nur an Stelle des letzten Punktes befindet sich ein “kleines als”-Zeichen (<). Analog zu vorhin beinhaltet der Bereich 1..<4 nur die Werte 1,2 und 3.

// Beispielprogramm druckt eine ein-mal-eins-Tafel von 1 bis 10

print ("     ")

for i in 1...10 {
    print (String(format: "%5i", i))
}

println()

for i in 1...10 {
    print (String(format: "%5i", i))
    for j in 1...10 {
        print (String(format: "%5i", i*j))
    }
    println()
}
Die while-Schleife

Als weitere Schleifenform können wir im Swift die while-Schleife benutzen. Sie funktioniert analog zu den Pendants in den C-ähnlichen Sprachen. Auch hier haben die Swift-Väter auf die geschweiften Klammern verzichtet.

var count = 10

while count > 0 {
    println(count--)
}

Auch die Form mit der Prüfung am Ende des Schleifenkörpers kennt Swift in einer ähnlichen Form, wie auch C oder Java.

var count1 = 10

do {
    println(count1--)
} while count1 > 0

Der Unterschied zwischen beiden Schleifen ist nur der, dass die zweite Form der Schleife mindestens ein mal durchlaufen wird, bei der ersten kann die Prüfung am Anfang sofort das Überspringen der Schleife verursachen.

Die Schlüsselwörter break und continue

Mithilfe dieser Wörter ist es inmitten einer Schleife möglich, das Verhalten zu ändern. Meist passiert dieses dann in einer Bedingung, von daher werden wir dies im nächsten Teil behandeln. Allerdings sei hier so viel gesagt, dass break bedingungslos die Schleife unterbricht und continue sofort wieder an Anfang der Schleife zurückkehrt. Bei der continue-Anweisung wird bei einer while-Schleife die Bedingung ausgewertet, bei einer for-Schleife zusätzlich die Aktualisierungs-Operation ausgeführt.

Hier findet man eine Übersicht von sämtlichen Swift-Tutorials auf unserem Blog.

Fragen zu diesem Tutorial können in den Kommentaren oder in der Community gestellt werden.

Read More

Swift Grundlagen – Operatoren

Swift verfügt über den üblichen Satz an Operatoren, jedoch sind diese bei Swift durch die Möglichkeit diese zu überschreiben wesentlich universeller einsetzbar. Darüber hinaus gibt es auch ein paar neue, nützliche Operatoren, wie den Bereichs und den Coalesce (Ersetzungs-) Operator.

In diesem Beitrag wollen wir die Swift-Operatoren klassifizieren und erläutern. Die Operatoren einer Programmiersprache kann man nach zwei verschiedenen Kriterien unterteilen: nach der Anzahl der Operanden also der mit dem Operator verbundenen Werte sowie nach dem Typ des Ergebnis / der Verwendung des jeweiligen Operators. Die erste Klassifizierung unterscheidet nach unären (also mit einem Operanden verbundenen Operatoren), binären (also die üblichen, mit zwei Operanden verbunden Operatoren) sowie trinären, speziellen Operatoren, die für 3 Werte zuständig

Der Zuweisungsoperator

Der wichtigste aller Operatoren ist der Zuweisungsoperator (assignment). Er weist der linken Seite n Wert der rechten Seite zu. Im Gegensatz zu den von C abstammenden Sprache gibt eine Zuweisung keinen Wert zurück, d.h. man kann die Zuweisungen nicht verketten.

let a = 10
var b = 12
b = a
let d = b = a + 1 // es erscheint eine Warnung, dass die Konstante d vom Typ () angelegt wird, d.h. dass die Konstante d vollkommen leer ist

 Die artithmetische Operatoren

Swift verfügt über den Standardsatz an arithmetischen Operatoren. Diese können sowohl für Integer- wie auch für Float-Typen angewandt werden.

let a = 5 + 6 // a = 11
let b = 6 - 9 // b = -3
let c = 4 * 8 // c = 32
let d = 9 / 2 // d = 4 da das Ergebnis auf Grund der Einzelwerte als Int berechnet wird
let e = 9.0 / 2.0 // e = 4.5, da jetzt das Ergebnis den Double-Typ hat
let f = 9.0 / 2 // f = 4, hier unterscheidet Swift nach dem Typ des Divisors
let g = 9 / 2.0 // g = 4.5, hier ist der Divisor Double, daher ist auch das Ergebnis Double

Das Pluszeichen hat eine besondere Funktion bei String oder Char-operanden. Bei Strings führt der Operator zum Hinzufügen des zweiten Operanden an den Ersten (konkatinieren, concationation).

let aa = "Hello" + " " + "world" // Hello world

let chr: Char = 'A';
let second_chr: Char = 'b'
let c = chr + second_chr // String "AB"
let space = ' '
let bb = "Hello" + space + "world" // Hello world

Dazu kommt der Rest- (remainder) Operator. Dieser kann nur bei Integer und Long-Zahlen angewandt werden und gibt den Restbetrag aus  Diesen Operator kann man zum Besipiel sehr gut in Schleifen verwenden, um z.B. bei jeder x-ten Durchlauf eine besondere Aktion auszulösen, z.B. den Bildschirm upzudaten.

let i = 14 % 3 // 2
let j = 18.2 % 5 // 3

Weitere zwei arithmetische Operatoren können den unären Operatoren zugezählt werden. Es sind die Vorzeihen “+” und “-“. “-” bewirkt eine Vorzeichen-Umkehr, “+” hat hingegen keinerlei Wirkung und wird dazu angewandt, um die positive Zahl besonders hervorzuheben.

let a = -2 // -2
let b = +5 // 5
let c = -a // 2
let d = +a // -2
let e = +b // 2

Für Ganzzahlvariablen gibt es noch weitere zwei Operatoren – increment und decrement. Sie erhöhen oder erniedrigen um eins den Wert der Variablen, bei der sie sich befinden. Je nach Lage der Operatoren, links oder rechts der Variablen beträgt der zurückgegebene Wert dem Inhalt der Variablen vor- oder nach dem increment/decrement.

var a = 5
let b = a++ // b = 5, a = 6
a--         // a = 5
let c = ++a // c = 6, a = 6

Wie man sieht, kann man den Increment/Decrement-Operator sowohl in einem Ausdruck verwenden wie auch außerhalb.

Vergleichsoperatoren

Vergleichsoperatoren dienen dazu, zwei Werte miteinander zu vergleichen. Also Operanden werden zwei Werte eines vergleichbaren Typus erwartet. Diese werden dann verglichen und ein boolescher Wert zurückgegeben. In den meisten Fällen werden die Vergleichsoperatoren zusammen mit den nachfolgend erläuterten logischen Operatoren in Kontrollstrukturen verwendet.

Folgende Operatoren gibt es:

  • < vergleicht ob der linke Wert kleiner als der rechte sei
  • > vergleicht, ob der linke Wert größer als der rechte sei
  • == vergleich, ob beide Werte (exakt) gleich sind
  • <= vergleicht, ob der linke Wert kleiner oder gleich dem rechten ist
  • >= vergleichet, ob der rechte Wert größer oder gleich dem rechten ist
let a = 5 < 6 // a = true
let b = 6 < 5 // b = false
let c = 6 == 5 // c = false
let d = 5 <= 5 // d = true

Logische Operatoren

verknüpfen Vergleiche und boolesche Variablen miteinander. Es gibt einen unären Operator sowie zwei binäre:

  • ! ist analog zum “-” Vorzeichen zu sehen und liefert den exakt entgegengesetzten Wert zurück.
  • && ist die logische Und-Operation und sie liefert ein true zurück, wenn beide Operanden true sind
  • || ist die logische Oder-Operation und sie liefert ein true zurück wenn zumindestens einer der Operanden true ist

Wichtig: die Operatoren arbeiten grundsätzlich “short circuit”. Short circuit bedeutet, dass wenn bei der Ausführung festgestellt wird, dass die eine weitere Auswertung nicht mehr notwendig ist, dieses auch unterlassen wird. Es hat eine beschleunigte Auswertung zufolge, jedoch wird womöglich Code der im rechten Teil der Operation vorhanden ist, nicht ausgeführt. Daher sollte man grundsätzlich in logischen Ausdrücken auf increment/decrement-Ausdrücke sowie auf den Aufruf von Funktionen, die Nebeneffekte Aufweisen, verzichten. Eine alternative wie bei Java das einfache “&” oder “|”, die jeweils beide Seiten auswertet, bevor es einen Wert liefert, gibt es nicht.

Es gibt keinen von einigen Sprachen bekannten XOR (Exklusiv-Oder)-Operator.

let a = true
let b = !a            // b = false
let c = a & 5 == 5    // c = true
let d = a && b        // false
let e = a || b        // true
var x = 5
let f = a && x++ == 5 // f = true
println (x)           // x = 6
x = 5                 // x wieder auf 5 setzen
let f = b && x++ = 5  // g = false
println (x)           // x = 5, da durch short circuit-Auswertung die rechte Seite nicht ausgeführt wurde

Bitoperatoren

Bitoperatoren wirken auf die einzelnen Bits also Nullen und Einsen, aus denen die Ganzzahl-Werte zusammengebaut sind.  Dieses wird sehr intensiv einerseits in der Hardware-nahen Programmierung eingesetzt, aber auch die Bildbearbeitung, Spiele-Programmierung, Verschlüsselung, Komprimierung und einige Tricks aus der normalen Programmierpraxis sind hier als Beispiele anzugeben. Um die Bitoperatoren zu verstehen, sollte man sich ein wenig mit dem Binärsystem auseinandersetzen. Hier sei nur soviel gesagt, dass das Binärsystem eine andere Darstellungsweise für Zahlen ist bei der nur Einsen und Nullen vorkommen. D.h. analog zu unserem 10er-System, bei dem nach der 9 die 10 folgt, kommt beim Binärsystem (auch Dualsystem genannt) nach der 1 die 10. Darauf folgt die 11 und danach dann 100. Somit steht die 10 für 2 im Dezimalsystem, 11 für 3 und 100 für 4. Manchmal wird auch die HL-Schreibweise verwendet, bei der H(igh) für 1 und L(ow) für 0 steht.

Somit haben wir folgende Operatoren zu Verfügung: zwei Shiftoperatoren, eine unäre Negation sowie drei logische Bitoperatoren.

  • << schiebt den Inhalt des linken Operanden um die Anzahl der Stellen, die im rechten Operanden angegeben ist nach links. Es entspricht damit der Multiplikation mit des linken Wertes mit einer 2er Potenz um den rechten Operanden.
  • >> schiebt den Inhalt des linken Operanden um die Anzahl der Stellen, die im rechten Operanden angegeben ist nach rechts. Es entspricht damit der Division mit des linken Wertes mit einer 2er Potenz um den rechten Operanden
  • ~ – der Negationsoperator schaltet alle Bits in einem Wert in den jeweiligen Kehrwert um.
  • & – der Und (and) Operator ergibt an einer Stelle eine 1 nur dann, wenn beide Werte an dieser Stelle eine 1 aufweisen. Man kann also sagen das bitweise Und kann Bits löschen.
  • | – der Oder Operator ergibt an einer Stelle eine 1 dann, wenn mindestens einer der Werte an dieser Stelle eine 1 aufweist. Man kann somit sagen, das Oder kann Bits setzen.
  • ^ – der Xor oder Exclusiv-Oder-Operator ergibt an einer Stelle eine 1 nur dann, wenn exakt bei beiden Operatoren an dieser Stelle nur eine 1 auftritt. Man kann somit sagen, das Xor kann ein Bit switchen / umschalten.
let a: UInt8 = 0b00001111 // 0xF oder 15
let b = ~a // b = 0b11110000 oder 0xF0 oder 240
let c = 0b00000001 & 0b00000011 // c = 0b00000001 oder 1
let d = 0b11111111 & 0b11011100 // d = 0b11011100, die Nullbits des zweiten Operanden haben die 1er des ersten gelöscht.
let e = 0b00000001 | 0b00000011 // e = 0b00000011 oder 3
let f = 0b00000000 | 0b11010101 // f = 0b11010101, die 1er des zweiten Operanden haben im Endergebnis die korrespondierenden Bits gesetzt.
let g = 0b00000001 ^ 0b00000011 // g = 0b00000010 oder 2
let h = 0b11110000 ^ 0b10101010 // h = 0b01011010, die 1 des zweiten Operanden haben die 1 oder 0er des ersten Operanden jeweils umgedreht

 Verkettung von dem Zuweisungsoperator mit binären Operatoren

Alle oben aufgeführte binäre Operatoren (eine Ausnahme sind die logischen Operatoren, was ich nicht verstehe) kann man mit dem Zuweisungsoperator verketten. Dieses hat zufolge, dass der Wert links des Zuweisungsoperators zugleich als Ziel der Zuweisung als auch als der linke Operator benutzt wird. Dieses verkürzt die Schreibweise und vereinfacht die Ausdrücke, sodass diese einfacher verstanden werden können.

var a = 5
a += 6          // a = 11
a -= 1          // a = 10
a /= 2          // a = 5
var b: UInt8 = 0b00001111
b ^= 0b01010101 // b = 0b01011010 oder 90

Den trinären Operator, die Bereichsoperatoren sowie den Ersetzungsoperator werden wir in dem nachfolgenden Beitrag zusammen mit den Kontrollstrukturen behandeln.

Hier findet ihr eine Übersicht von sämtlichen Swift-Tutorials auf unserem Blog.

Bei Fragen zu diesem Tutorial kann man uns in den Kommentaren oder in der Community schreiben.

Read More

Automator – Den OS X Bildschirmschoner mit einem Shortcut starten

Leider kann der Bildschirmschoner von OS X nicht mit einem Kurzbefehl gestartet werden. Wenn man diese Funktion vermisst, sollte man sich das heutige Tutorial unbedingt genauer anschauen. Bei diesem Workaround hilft uns mal wieder der vielseitige Automator, über den wir hier im Blog schon einige Tutorials veröffentlicht haben.

Einstellungen zum Bildschirmschoner werden auch nach diesem Tutorial wie gewohnt in den Systemeinstellungen vorgenommen. Der Automator kümmert sich nämlich nur um den Start des Screensavers aber nicht um die Konfiguration. Alle, die ihren Mac am Arbeitsplatz nutzen, verwenden vermutlich eine Passwortsperre in Verbindung mit dem Bildschirmschoner. Für diese Zielgruppe ist dieses Tutorial sicher auch eine nützliche Hilfe.

Als Erstes Öffnen wir den Automator unter Programme und wählen “Dienst” aus.
Automator-Bildschirmschoner-1

Nun muss im Suchfeld “Bildschirmschoner” eingegeben werden. Aus den Ergebnissen  wählen wir die Aktion “Bildschirmschoner ein” und ziehen diese nach rechts. Bei “Dienst empfängt” muss noch “keine Eingabe” ausgewählt werden. Hier kommen wir später drauf zurück.
Automator-Bildschirmschoner-2

Jetzt wird das Automator-Script abgespeichert, wir haben uns für den Namen “Bildschirmschoner starten” entschieden. Nun Öffnen wir die “Systemeinstellungen” und gehen auf “Tastatur”. Im Bereich “Kurzbefehle” wählen wir “Dienste aus” und scrollen im Feld nebenan ganz nach unten. Unter “Allgemein” sollte man nun das fertige Automator-Script finden können. Hier klicken wir in das Feld hinter dem Namen und vergebe einen Kurzbefehl, zum Beispiel Ctrl + Wahl + Cmd + B. Natürlich kann hier jeder seinen eigenen Kurzbefehl nach Wunsch erstellen.

Automator-Bildschirmschoner-3

Jetzt können die Systemeinstellungen verlassen werden und der neue Kurzbefehl kann ausgetestet werden.

Hier findet ihr eine Übersicht aller Automator Tutorials.

Weitere Tutorial-Reihen auf apfelcheck!

SynologyFusion DriveOS X Terminal

Bestehen noch Fragen zu diesem Automator Tutorial? Schreibt einfach in den Kommentaren oder in der Community

Read More

Swift Grundlagen – Das Typ-System von Swift

Typen sind ein sehr wichtiger Bestandteil jeder Programmiersprache. Wir unterschieden zwischen den primitiven Typen, also welchen, die tief in der Sprache verankert sind sowie den benutzerdefinierten Typen, die oder bereits in den Systembibliotheken mitgeliefert werden oder vom Programmierer selbst geschaffen werden. Hier haben die Schöpfer den Umfang, der von anderen Sprachen normalerweise geboten wird weit übertroffen.

Tupel

Alle Programmierer, die bisher mit einer der üblichen Programmiersprachen programmiert hat, haben sich oft gewünscht, mehr als einen Wert beim Aufruf einer Funktion zurückzuliefern. Das ist zwar über diverse Konstrukte auch in herkömmlichen Programmiersprachen möglich, aber oder unschön oder kompliziert. In Swift geschieht das sehr elegant und einfach. Man definiert ganz einfach eine Variable oder Konstante und fügt die Typen der einzelnen Komponenten dahinter in Klammern zu.

let punkt2D: (Double, Double) = (10, 20)

var amount: (Double, String) = (10.20, "EUR")
amount = (30.10, "DM");

Natürlich kann man auch zuvor definierte Variablen, Konstanten oder Ausdrucke an den einzelnen Stellen des Toupels verwenden.

let x = 2.3
let y = 3.4
let shiftedPoint = (x + 6.6, y)

Um auf die einzelnen Werte eines Toupels zuzugreifen, verwendet man die Punkt-Schreibweise: nameOfTouple.index, wobei index die Position des Wertes auf den man zugreifen will angibt. Die Position ist bei von C abstammenden Sprachen null-basiert, d.h. das erste Element hat die Position 0, das zweite 1 usw.

var xCoord = shiftedPoint.0
var yCoord = shiftedPoint.1
var currency = amount.1

Ein Toupel muss aus mindestens zwei Werten bestehen. Ist nur ein Wert wandelt es der Compiler in eine einfache Variable / Konstante um. Man kann aber auch eine beliebige einfache Variable oder eine Konstante über den Index 0 zugreifen.

var notATouple: (Int) = (10)
var simpleVar = notATouple // simpleVar = 10
var isPossible = notATouple.0 // es ist möglich

Eine Zuweisung eines Toupel-Wertes ist leider nicht möglich.

amount.1 = "USD" // error: cannot assign to '1' in 'amount'

 Enums

Um den Wertebereich auf eine Menge von einzelnen Werten zu beschränken, werden Aufzählungstypen verwendet. Dieses Vorgehen hat zwei angenehme Eigenschaften: Erstens kann man einer Variablen nur Werte zuweisen, die auch im gegebenen Kontext sinnvoll sind. Zweitens haben die zugewiesenen Werte (hoffentlich) sprechende Namen, sodass sich auch ein anderer ohne große Erläuterung im Programmcode zurechtfindet. Enums werden einem vorangestellten Word enum definiert.

enum Colors {
    case Black
    case White
    case Red
    case Green
    case Blue
    case Brown
    case Purple
}

Eine platzsparendere Variante ist das aneinanderreihen von den möglichen Werten getrennt durch Kommata in einer Zeile

enum Planets {
    case Mercury, Venus, Earth, Mars, Jupiter, Saturn, Uranus, Neptune
}

enum Currencies {
  case Euro,
       Dollar,
       Pound,
       Peseta,
       Deutschmark
}

Um den Wert einer Konstanten oder Variablen zuzuweisen, gibt es zwei Möglichkeiten. Man kann den Enum-Typ bei der Zuweisung explizit angeben oder, wenn die Variable bei der Definition bereits typisiert wurde, kann man die explizite Typenangabe auch weglassen, dann beginnt der Wert mit einem Punkt.

let earthNeighbour = Planet.Mars

var currentCurrency: Currencies
currentCurrency = .Euro

Im Gegensatz zu anderen Sprachen können einzelnen Werte der Aufzählung wiederum selbst einen Wert besitzen.

enum BookSearchCriteria = {
/tease Title(String)
/tcase ISBN(Int)
/tcase Author(String, String)
}

let titleToSearch = BookSearchCriteria.Title("Einführung in Swift")
let IsbnToBeFound = BookSearchCriteria.ISBN(123456789)
let authorForSeek = BookSearchCriteria.Author("Walter", "Meyer")

Wie man die Enums und vor allem die erweiterte Variante davon im Programmcode nutzen kann, werden wir in dem Grundlagen-Abschnitt über Bedingungen und Fallunterscheidungen zeigen.

Arrays

Felder werden verwendet, wenn man viele gleichartige Werte im Programm verwenden muss. Im Gegensatz zu herkömmlichen Sprachen ist ein Array in Swift auch von der Anzahl der Elemente veränderbar. Somit entspricht es einem NSMutableArray in Objektive C oder einer ArrayList in Java. Felder können auch mehrere Dimensionen haben, um z.B. eine zwei- oder dreidimensionale Spielwelt oder auch ein von mehreren Grundwerten abhängiges Ergebnis in einer kommerziellen Anwendung darstellen zu können. Ein Feld wird definiert, indem man den Grundtyp in rechteckige Klammern einschließt. Eine weitere Definitionsart verwendet die sogenannte Generics, die wir im weiteren Verlauf der Reihe kennenlernen werden.

let mates: [String] = ["Stefan", "Tom", "Andy", "Rob", "Mike"]
var boys: Array<String>; // andere Art der Definition
let girlfriends: = ["Jane", "Betty", "Babs", "Hillary"] // die Typisierung kann auch implizit erfolgen
var gameField: [[[Int]]] = [[[]]] // ein dreidimensionales Feld wird vorerst leer initialisiert
var array3D: [[[Int]]] = [[[1, 2], [3, 4]], [[5, 6], [7, 8]]] // die Re

Der Zugriff auf die einzelnen Felder wird wie bei den Toupels null basiert über in rechteckigen Klammern eingeschlossenen Index vorgenommen. Bei einer unvollständigen Indexierung eines multidimensionalen Feldes erhält man wiederum ein Feld als Ergebnis.

let friend = mates[0] // ergibt "Stefan"
let pointValue = array3d [0][1][1| // ergibt 4
let partArray = array 3d [1][1] // ergibt [7, 8]

Die Arrays in Swift haben viel mehr Funktionalität eingebaut, als die in herkömmlichen Sprachen. Von daher werden wir ihnen zur gegebenen Zeit einen eigenen Beitrag in den Grundlagen widmen.

Dictionaries

Dictionaries oder Wörterbücher sind als eine Erweiterung zum eindimensionalen Array zu sehen. Hierbei erfolgt der Zugriff auf die einzelnen Werte über einen beliebigen Schlüssel. Leser, die bereits mit Java oder ähnlichen Sprachen gearbeitet haben, kennen eine Dictionary unter dem Begriff “Map”. Hierbei wird immer ein Paar gleichzeitig behandelt – den ersten Wert davon nennt man den Schlüssel (Key), der zweite ist der eigentliche Wert.

Um eine Dictionary zu definieren gibt es wieder zwei Möglichkeiten: Eine erweiterte Array-Schreibweise sowie die Generics-Schreibweise.

let salary: [String: Double] = ["Alex": 45000.00, "Jan": 35199.22, "Joggy": 1200000]
let age: Dictionary<String, Int> = ["Mandy": 24, "Wilma": 99, "Veronica":13]
let taxStages = [0:0.0, 7500: 7.0, 12000: 14.0, 25000: 21.0] // auch hier ist eine implizite Definition möglich

Der Zugriff erfolgt wiederum über in rechteckigen Klammern eingeschlossenen Schlüsselwert. Wird kein entsprechender Wert in der Dictionary gefunden, bekommt man den speziellen Wert nil zurückgeliefert.

let salary = salaries["Jan"] //
let age = ages["Mandy"] //
let salary1 = salaries["Bernd"] //
let taxPercentage = taxStages[12000] //

Hier sieht man die Vorteile gegenüber dem Array: man kann nicht nur über einen ganzzahligen Wert, sondern über jedes nur erdenkliche Objekt (es gibt da eine Einschränkung, auf die wir später eingehen werden) auf den korrespondierenden Wert zugreifen. Und man benötigt bei einer großen Spannweite der Werte, auch wenn man über einen Integer als Schlüsselwert auf die Dictionary zugreift viel weniger Platz. So bräuchten wir im letzten Fall bei einer Felddefinition ein Array mit 25000 Integers. Bei einer Dictionary braucht man nur die wirklich benötigten Paare – bei uns 4. Dieses erkauft man aber durch eine allgemein schlechtere Performance und bei einer guten Befüllung des Arrays – mit deutlich höherer Speicherbelegung. Daher sollte man genau abwiegen, welches Konstrukt man für welchen Einsatzzweck verwendet.

Im nächsten Artikel werden wir uns den ersten Programmkonstrukten widmen. Dazu gehören Zuweisungen, Schleifen, Entscheidungen und Funktionen. Auch der Dictionary werden wir einen eigenen Beitrag widmen

Hier findet ihr eine Übersicht von sämtlichen Swift-Tutorials auf unserem Blog.

Bei Fragen zu diesem Tutorial kann man uns in den Kommentaren oder in der Community schreiben.

Read More

Swift Grundlagen – Kommentare, Variablen, Konstanten und grundlegende Datentypen

Nach einer kleinen Einleitung zu Swift, möchten wi nun mit den Grundlagen beginnen. In unserem ersten Teil, der Swift-Tutorials, geht es um die Grundlagen: Playground und das Konsolenfenster, Kommentare, Variablen, Konstanten sowie die grundlegenden Datentypen.

Erste Schritte mit Swift

Swift hat einen großen Vorteil gegenüber den meisten anderen Programmiersprachen. Für die ersten Schritte kann man dort den sogenannten Playground benutzen. Wie der Name bereits sagt, ist es ein Platz, wo man zwar keine großen Apps schreiben kann, aber wo man etwas ausprobieren kann und sich ein wenig austoben kann.

Um den Playground zu öffnen, starten wir Xcode und wählen den Punkt “Get started with Playground”.

Xcode Willkommen

Es erscheint eine Fläche, auf der man links Swift-Befehle und Programmstücke eingeben kann. Rechts befindet sich ein Bereich, in dem sofort das Ergebnis der auf der linken Seite eingegebenen Befehls erscheint.

Playground

Das Playgroundfenster

Compiler und Interpreter

Der Computer als solcher versteht nur die Maschinensprache. Diese besteht aus einer Aneinanderreihung von Zahlen. Jeder Prozessortyp verwendet auch noch eine vollkommen von den anderen abweichende Maschinensprache. Um also den für den Menschen lesbaren Programmcode in den vom Rechner ausführbaren Maschinencode zu übersetzen, benötigt man einen Übersetzer, einen Compiler oder Interpreter. Ein Interpreter liest den Programmcode während der Ausführung und übersetzt ihn wie ein Simulatanübersetzer nach und nach in den Maschinencode. Der Compiler übersetzt den Programmcode einmalig und der Benutzer bekommt bereits ein fertig übersetztes Programm, das nur aus Maschinencode besteht.

Wie man sich vorstellen kann, benötigt ein Interpreter viel mehr Zeit für die Ausführung des gleichen Programms, da er jeweils jeden Befehl lesen, übersetzen und ausführen muss. Beim Compiler wird das Lesen und Übersetzen einmalig durch den Programmierer durchgeführt und somit ist das Programm viel schneller. Nach dem Übersetzen wird der Code dann sogar noch optimiert, damit die Ausführungszeiten noch weiter sinken.

Typische Interpreter-Sprachen sind so gut wie alle Skripts-Sprachen, wie Java Script, PHP (zumindest in den Anfangszeiten), Ruby und das ursprüngliche Basic z.B. auf dem Apple II oder dem C64. Hingegen typische Compiler-Sprachen sind unter anderem C mit den Abkömmlingen C++ und Objektive C, Java, C#, Pascal und natürlich Swift.

Hallo, Swift

In den verschiedensten Programmiersprachen ist es üblich, mit einem “Hello World”-Projekt anzufangen. Das wollen wir auch tun, also geben wir in den geöffneten Playground folgende Zeile ein.

println("Hallo, Swift!")

Xcode Assistant Editor

Um die Ausgabe in der Konsole zu sehen, muss der Assistant Editor geöffnet werden.

Der Playground ist so entwickelt, dass er fortlaufend den für den Menschen lesbaren Code in Maschinencode übersetzt und ausführt. Dieser Übersetzungsvorgang nennt man Kompilieren und ist in der Entwicklung von Programmen und Apps sehr wichtig.

Kommentare

Kommentare sind ein wichtiger aber unterschätzter Teil des Programmcodes. Damit können wir Erläuterungen dem Code hinzufügen oder auch schwierig zu verstehende Konstrukte erklären. Speziell, wenn ein anderer den Code lesen und verstehen soll, kann ein sinnvoller Kommentar Wunder wirken.

Kommentare können am Anfang einer Zeile stehen, aber auch im Anschluß an den Programmcode positioniert werd

// Dies ist ein Kommentar. Sollte dieser Kommentar
// mehrzeilig sein, so brauchen wir mehrfach ein //

var i = 2 * j // i ist das doppelte von j

Bei längeren Kommentaren ist es mühsam jeweils mit  // zu beginnen. Es ist dann besser, die Kommentare jeweils am Anfang und am Ende mit  /* */ zu umschließen, um einen ganzen Block als Kommentar zu deklarieren. Anderseits kann aber damit auch ein Kommentar mitten in einer Zeile eingefügt werden.

/*
Dies ist ein mehrzeiliger Kommentar. Ich kann hier so lange schreiben,
bis der Block beendet wird.
*/

var u /* der Umfang */ = pi * r

Variablen & Konstanten

Um ein Programm auszuführen, werden Daten benötigt. Um auf die Daten zuzugreifen und auch diese zu beschreiben, werden in Swift Konstanten und Variablen verwendet. Konstante sind über die gesamte Laufzeit der Applikation unveränderter im Gegensatz zu Variablen, die bei Bedarf geändert werden können.

Die Variablen und Konstanten müssen vor der Verwendung dem Compiler bekannt gemacht werden. Das geschieht in der Deklaration. Abweichend von vielleicht anderen bekannten Sprachen, in denen Konstanten nur durch ein sogenannten Modifier also Zusatz zur Deklaration kenntlich gemacht werden (z.B. const bei C# oder final bei Java) verwendet Swift für Variablen und Konstanten zwei unterschiedliche Schlüsselwörter: var für Variablen und let für Konstanten.

let answerForAllQuestions = 42
var answerForNearAllQuestions = "unknown"

Die Namen der Variablen und Konstanten können alle möglichen Zeichen beinhalten, aber es ist üblich, einen sprechenden Namen zu verwenden. Die Namen sollten mit einem kleinen Buchstaben beginnen. Sollten die Namen aus mehreren Wörtern bestehen, werden diese ohne Pause aneinandergereiht, wobei ab dem zweiten Wort jeweils der erste Buchstabe groß geschrieben wird. Diese Schreibweise kommt aus der Programmiersprache Java und wird üblicherweise mit “Camel-Case” bezeichnet. Üblich ist auch für die Benennung ausschließlich Englisch zu verwenden.

Da in unserem Beispiel die Antwort auf alles nicht verändert werden muss, wurde eine Konstante und somit let verwendet. Die Antwort auf fast alles ist zum Definitionszeitpunkt noch nicht bekannt ist und erst im Verlauf des Programmes bekannt wird, wird hier var verwendet, um den Wert variabel zu halten. Sollte man anschließend versuchen die Konstante zu ändern erhält man die Fehlermeldung Cannot assign to ‘let’ value ‘answerForNearAllQuestions’. Durch gezielte Verwendung von Konstanten erspart man sich einige Fehler, die durch ein ungewolltes Überschreiben passieren können.

Sobald das Ergebnis bekannt wurde, kann man es der Variablen zuweisen:

answerForNearAllQuestions = "magic"

Datentypen

Wie auch im echten Leben gibt es beim Programmieren die Notwendigkeit mit verschiedenen Typen von Daten zu arbeiten. Es kann z.B. eine Zahl, einen Text oder ein Zeichen sein, aber auch etwas wesentlich komplexeres, z.B. eine Liste, eine Personenbeschreibung, eine (geometrische) Form oder auch die komplette Spielewelt eines Computerspieles. Ein Teil der Datentypen ist bereits Bestandteil der Programmiersprache selbst, ein Teil wird in verschiedenen Bibliotheken mitgeliefert und ein Teil entsteht auf verschiedene Art und Weise während der Programmerstellung durch den Programmierer.

Die Datentypen, die bereits ein Teil der Programmiersprache sind, nennt man primitive Typen. Swift kennt im Gegenteil zu anderen Programmiersprachen sehr viele primitive Datentypen, was manchmal sehr hilfreich sein kann aber manchmal auch verwirrt.

Zu den primitiven Datentypen gehören:

  • Integer also Ganzzahlwerte. Benötigt man ausschließlich ganze Zahlen (was beim Programmieren entgegen ursprünglichen Annahmen sehr oft passiert) verwendet man Integer-Typen. Die Integertypen können je nach Bedarf feingliedrig gewählt werden. Es gibt sie als Int8, Int16, Int32 und Int64, wobei die Zahl hinter Int die Anzahl der verwendeten Bits angibt. Mit einem Int8 kann man Werte zwischen -128 und 127 darstellen, mit einem Int16 bereits von -32.768 bis 32.767, mit Int32 dann von -2.147.483.648 bis 2.147.483.647 und mit Int64 von -263 bis 263-1. Jede dieser Varianten gibt es noch in einer Version, die nur positive Zahlen speichern kann (vorzeichenlos, unsigned). Diese werden mit eine U vorneweg gekennzeichnet, also UInt8, UInt16, UInt32 und UInt64. Der Wertebereich fängt dann bei 0 an und geht bis 2n – 1. Zur schnelleren Programmierung gibt es jeweils ein Int und ein UInt-Datentyp, die dem Int64 und UInt64 entsprechen.
  • Fließkommawerte. Diese gibt es in zwei Genauigkeiten als Float mit ca. 6 Nachkommastellen und Double mit ca. 15 Nachkommastellen. Man sollte jeweils die für die Anwendung ausreichende Variante benutzen, nicht immer benötigt man die genauere.
  • Zeichen. Dieser Typ stellt ein einzelnes Zeichen dar. Das Schlüsselwort für diesen Datentypen lautet Character.
  • Zeichenkette. In einer Zeichenkette können Texte beliebiger Länge gespeichert werden. Der Typ für eine Zeichenkette ist der String.

Swift unterstützt die implizite Typisierung, wie es z.B. C# seit der Version 3.5 auch tut. Dieses bedeutet, dass man bei der Deklaration den Datentypen nicht aufführen muss, sondern der Compiler stellt diesen an Hand des zugewiesenen Wertes fest.

var anInteger = 70 // Integer

Gleichzeitig ist Swift aber auch typensicher, im Unterschied z.B. zu Javascript. Das bedeutet, dass eine Variable den zugewiesenen Typen über die gesamte Lebenszeit behält. Somit schlägt der Versuch einem Integer ein Fließkommawert zuzuordnen zwar nicht fehl, aber der Teil der nach dem Komma kommt, geht verloren.

anInteger = 80.5 // funktioniert nicht, Nachkommastelle geht verloren
anInteger = "Hallo Welt" // Schlägt fehl, da keine Möglichkeit existiert Strings an ein Integer zuzuweisen
anInteger = "123" // auch das funktioniert nicht, es ist dank der Hochkommas ein String

Im Gegensatz dazu erweitert die Zuweisung eines Integers an eine Double-Variable diesen zu einem Fließkommawert.

var aDouble = 70.5 // Double
aDouble = 80 // funktioniert, der Wert der Variablen beträgt 80.0
var aSecondDouble = 5 + 1.5 // eine Summe eines Integres und eines Fließkommawertes ist immer ein Fließkommawert

Über eine explizite Typisierung kann man dem Compiler im Zweifelsfalle genau sagen, welchen Typ die Variable haben soll. Bestimmte Datentypen (z.B. die Integer-Varianten oder Character) sind gar nicht implizit definierbar. Man kann so auch Variablen definieren, die anfangs keinen Wert zugewiesen bekommen haben.

var aDouble: Double = 70 // Double
var anInt16: Int16 = 12 // Die implizite Variante verwendet immer Int also Int64
var char : Character // vorerst kein Wert zugewiesen

Ausblick: Im zweiten Teil werden die Operationen, die mit den Standardtypen möglich sind, vorgestellt.

Hier findet ihr eine Übersicht von sämtlichen Swift-Tutorials auf unserem Blog.

Bei Fragen zu diesem Tutorial kann man uns in den Kommentaren oder in der Community schreiben.

Read More

Swift – Die Entstehungsgeschichte Apples neuster Programmiersprache

Die Programmiersprache von OS-X und dessen Vorgänger NeXTStep war seit Anbeginn an Objective-C. Der eigentliche Compiler (Übersetzer) hat jedoch eine Evolution durchgemacht. Nach der Lizenzierung von Objective-C durch NeXTStep wurde der ursprüngliche Compiler nach kurzer Zeit durch die Open-Source-Compilier-Suite von GNU ersetzt. GNU ist ein Akronym und bedeutet GNU not Unix was darauf anspielen soll, dass es eine freie Software im Gegensatz zum lizenzbasierten Unix ist. Die GNU-Compiler-Suite war zwar relativ gut, aber nicht optimal.

Im Jahre 2000 fing ein Student namens Chris Lattner sein Master of Science-Studium. Das Studium wurde 2002 mit einer Master-Arbeit zum Thema LLVM (Low Level Virtual Machine) beendet. LLVM war ein brandneues Konzept zum Bau schneller und sehr gut optimierender Compiler. Es folgte 2005 das Doktorat, bei dem er sich weiter in das Thema vertiefte und spezielle Algorithmen für die Optimierung von Pointer-intensiven Programmen entwickelte. Diese Erkenntnisse wurden kontinuierlich in die LLVM integriert und in einem Blog nach außen getragen.

Dabei wurde die Softwareabteilung bei Apple auf ihn aufmerksam und bot ihm eine Stelle an. Seine erste Aufgabe war es die LLVM so stabil und sicher zu machen, damit sie die GNU-Suite ersetzen konnte. Ein spezieller C-Compiler namens clang wurde aus der Traufe gehoben und ersetzte den C-Compiler der GNU-Suite. Seit Xcode 3.1 kann LLVM parallel zur GNU-Compiler-Suite zum Übersetzen von Programmen eingesetzt werden. In der aktuellen Xcode-Version kann an den GNU-Compiler nicht mehr zur Übersetzung verwenden.

Seit 2010 leitete dann Lattner ein Programmierer-Team, die in einem streng geheimen Projekt Swift entwickelten. Das Geheimnis wurde erst auf der WWDC 2014 gelüftet und sorgte für ein Aufschrei in der Entwicklergemeinde. Allerdings wurde die Programmiersprache sehr wohlwollend aufgenommen und gewann bereits nach kurzer Zeit eine Vielzahl an Fans.

Im nächsten Artikel werden wir mit den Grundlagen von Swift beginnen. Wenn ihr zu dem heutigen Artikel Fragen habt, könnt ihr uns gerne in den Kommentaren oder in der Community schreiben.

Read More

Von Basic bis Swift – Apples Programmiersprachen und unsere neue Swift Tutorial Reihe

In der zweiten Hälfte der 70er, als Steve Wozniak und Steve Jobs anfingen den ersten Apple-Computer zusamenzubasteln befand sich die digitale Welt gerade im Umbruch. Anstelle der damals meist gehäuselosen, oft als Bausatz gelieferten kleinen Rechner mit meist nur einer LED-Zeile und einer Taschenrechnertastatur kamen Geräte mit vollständiger Tastatur und Monitor (sehr oft integriert, aber mitunter auch freistehend). Die „alten“ Geräte wurden in Maschinensprache programmiert, was sehr mühsam war. Somit musste eine neue Programmiersprache für diesen Gerätetypen her, etwas Interaktives, etwas, was einfach zu erlernen ist. Die Wahl fiel auf die Programmiersprache Basic, da sie einerseits lizenzfrei war, aber auch durch ihren Interpreter-Charakter keine komplizierten Übersetzungs- und Link-Prozeduren benötigte.

Also wurden Apple I sowie Apple II mit dem von Wozniak implementierten Integer-Basic ausgeliefert. Wie der Name schon verrät, konnte man damit keine Fließkommaberechnungen durchführen. In 1979 erschien dann Apple IIe, der mit einer neuen Basic-Variante ausgestattet wurde, die auch Fließkommaberechnungen ermöglicht hatte. Diese stammte nicht mehr von Wozniak sondern von einer recht kleinen Firma, die angepasste Basic-Interpreter lieferte und damit ihr erstes Geld verdiente. Diese Firma hieß Microsoft und der Programmierer Bill Gates. Fast den gleichen Basic-Interpreter lizenzierte sie in einer fast unveränderten Form auch an die Firma Commodore, wo dieser in der PET, CBM-Geräte sowie im legendären C64 eingebaut wurde.

pascal_apple

Parallel zu Basic wurde auf dem Apple II sehr oft das UCSD-Pascal benutzt, das eine komplett eigene Umgebung inklusive Programmeditor mitbrachte. UCSD-Pascal benutzte eine eigene Umgebung und übersetzte die Programme nicht in Maschinensprache, sondern in den sogenannten P-Code (Zwischencode). Dieser war hardwareunabhängig und wurde dann von einem Interpreter ausgeführt. Dieser P-Code war ein Vorbild für den ByteCode von Java respektive die CIL (Common Intermediate Language) von .NET. Eine besondere Version von USCD-Pascal wurde selbst von Apple weiterentwickelt und als Apple-Pascal vertrieben.

Der Beginn der Mac-Ära

Mit der Entwicklung von Apple Lisa sowie dem Macintosh wurde Zeit für eine neue Programmiersprache. Die Anregungen zum Betriebssystem haben sich die Herren Jobs und Wozniak bei XEROX Parc geholt. Dort wurde Smalltalk als Programmiersprache verwendet. Diese Programmiersprache war leider zu mächtig für den Mac-Vorgänger Lisa wie auch für den ersten Mac. Die Wahl fiel auf die damals aufkommende Programmiersprache Pascal, die einen guten Ruf im universitären Bereich hatte und mit der man bereits auf dem Apple II Erfahrungen gesammelt hatte. Dieses war schon eine bemerkenswerte Entscheidung, da eigentlich alle Wettbewerber die Programmiersprache C einsetzten. Eine Kuriosität hatte diesbezüglich Microsoft zu bieten. Ab der ersten Windows-Version wurde zwar mit C programmiert, jedoch wurden alle Betriebssystem-Aufrufe auf Pascal-Art aufgerufen (daher hatten die Microsoft-C-Compiler ein Schlüsselwort „pascal“ um dieser Aufrufart gerecht zu werden.

Das System Pascal, dass auf dem Macintosh verwendet wurde, war trotz der damals bereits aufkommenden objektorientierten Programmierung eine reine prozedurale Programmiersprache. Allein die Betriebssystemaufrufe (die s.g. API) bot bereits ein paar objektorientierte Ansätze. In 1986 versuchte Apple dann, dass vorhandene Pascal in Richtung Objektorientierung, mit dem Objekt Pascal-Entwurf zu bugsieren. Dieses war aber mit keinem sonderlichen Erfolg gekrönt gewesen. Hingegen fing ein anderer die Idee dazu auf: ein gewisser Anders Hejlsberg, der mit der Programmiersprache Turbo Pascal bereits recht erfolgreich auf dem Markt war. Die Ideen wurden in seine Programmiersprache integriert und es entstand die Programmiersprache Delphi, die sehr große Erfolge in der Windows-Welt feierte.

Sollte jemand Interesse haben sich ein umfangreicheres Projekt aus damaliger Zeit anschauen: Adobe hat den Source-Code seiner ersten Version von Photoshop freigegeben. Diese ist komplett in Pascal geschrieben.

CodeWarrioi

Langsam setzte sich parallel zu Pascal auch die Programmiersprache C++ auf dem Mac durch, um in den 90er dann die Vorherrschaft zu übernehmen. Dieses war vor allem der Programmierumgebung von Metrowerks, CodeWarrior zu verdanken, aber auch der Apple-eigenen Programmierumgebung MacApp, sozusagen dem Vorläufer von XCode. Allerdings war damals CodeWarrior das meist verwendete Werkzeug bei den professionellen Programmierern. Die Geschichte der Entstehung des Namens ist schon recht abenteuerlich. Zu dieser Zeit gab es zum Apples Developer-Account periodisch CDs, die jeweils die aktuellen Updates, Tools und Artikel enthielt. Diese CDs hatten jeweils einen Namen, der eine Verballhornung eines Film-Namen entsprachen. So gab es „The Hexorcist” (The Exorcist, Der Exorzist), „Lord of the Files” (Lord of the Flies, Herr der Fliegen), „Gorillas in the Disc” (). Nummer 9 hier Code Warrior (Mad Max 2: The Road Warrior, Mad Max 2: Der Vollstrecker). Der Chef von Metrowerks fand den Titel so gut, dass er ihn als Name für seine Programmentwicklungs-Umgebung wählte.

Von NeXTSTEP zu OS-X

Zur gleichen Zeit gründet der von Apple ausgeschiedene Steve Jobs eine neue Firma, NeXTSTEP. Dort wurde auf Basis des BSD-Unix-Systems das Betriebssystem NeXTSTEP für eine Workstation namens NeXT entwickelt. Als Programmiersprache wählt der die Softwareentwicklung leitende Avie Tevanian nicht das bereits sehr populäre C++ und auch nicht das bereits wachsende Java, sondern eine von Smalltalk beeinflusste objektorientierte C-Variante mit dem Namen Objective C. Eigentlich war sie älter als C++, jedoch gefielen ihm die von Smalltalk geerbten Konzepte des Message Passing anstelle des direkten Aufrufs von Methoden. Unter ihm wurde Objektive-C so angepasst, dass es mit der quelloffenen Compiler-Suite von GNU lief. In den späten 90ern kehrte Jobs wieder zurück zu Apple, da die Firma NeXTSTEP erwarb. Nach ein paar Ergänzungen und Umbauten wird aus NeXTSTEP über einen im Jahre 2000 OS-X (zuvor mit dem Code-Namen Rhapsodie) – und damit heißt die neue Programmiersprache von Apple Objective C. Da Objektive C aber eigentlich nur ein Aufsatz auf die Programmiersprache C ist (genau genommen ein Precompiler) und der eigentliche Compilerarbeit die GNU- und später die LLVM-Suite verrichtet wird, kann natürlich auch in C++ programmiert werden – der Mix wird dann Objektive C++ genannt.

Als neuste Alternative zum Objektive C wurde auf der WWDC 2014 als Neuentwicklung Swift vorgestellt und soll ab Herbst dann für die Entwicklung von Anwendungen für OS-X und iPhone/iPad vereinfachen und beschleunigen.

Welche Programmiersprachen können heutzutage im Apple Universum noch eingesetzt werden?

Die Apple-Richtilinien für die Entwicklung auf mobilen Geräten erlaubt den ausschließlichen Einsatz von Objektive C und Javascript, demnächst ergänzt um Swift. Allerdings haben findige Entwickler Möglichkeiten gefunden, um auch Programme in diversen anderen Sprachen für die mobilen Geräten in den Appstore von Apple zu schmuggeln. Es sind bei Spielen vor allem reines C++ und Ruby vertreten, bei Business-Anwendungen wird Pascal (Delphi), C# (Xamarin) und Java (RoboVM, Oracle Jdeveloper) eingesetzt. Unter OS-X ist die Sprachauswahl  durch die Unix-Abstammung so gut wie unbegrenzt, will man jedoch seine Programme über den AppStore verkaufen, muss man schon den von Apple herausgegebenen Anforderungen genügen und die App in einer der vorgeschriebenen drei Sprachen schreiben.

Wir beschäftigen uns seit Anfang an mit der neuen Programmiersprache Swift. Deswegen wird es für unsere Leser eine neue Tutorial-Reihe zu Swift geben. Wir werden sämtliche Grundlagen behandeln und eine App Entwicklung, Schritt für Schritt in Tutorials erklären.

Habt ihr noch Fragen zu diesem Artikel? Dann schreibt uns einfach in den Kommentaren oder in der Swift Community.

Read More

Synology – Installation der Cloud Station

Auch wenn der Speicher bei Diensten wie Dropbox, OneDrive, iCloud und Konsorten immer günstiger wird, ist es doch eine Überlegung wert seinen eigenen Cloud Dienst zu betreiben. Die viel zitierte Kontrolle über die eigenen Daten wollen wir jetzt mal nicht bemühen, auch wenn es nicht ganz von der Hand zu weisen ist. Nein, diesmal berufen wir uns ganz auf den Mehrwert unserer DiskStation, wenn sie auch noch diese Aufgabe übernimmt. Wer also eine ordentliche Internetverbindung hat, und das bezieht sich vor allem auf die Uploadgeschwindigkeit, die in der Regel der limitierende Faktor ist, der sollte sich ein paar Minuten Zeit nehmen und sich dieses Tutorial zu Gemüte führen.

Die Software der Cloud Station muss erst noch vom Internet runter geladen und auf dem NAS installiert werden. Das geht ganz bequem über das Paket Zentrum. Im Abschnitt “Unternehmen” werden wir fündig und starten den Prozess über den Installieren-ButtonCloud-Station01 Wenn die Firewall aktiv ist, und diese Verbindungen blockiert für die es keine Regel gibt, kommt eine Benachrichtigung, um Port 6690 frei zu schalten. Sollte bei euch eine derartige Meldung nicht erscheinen, so solltet ihr noch mal über euer Sicherheitskonzept nachdenken. Vor allem dann, wenn über das Internet auf euer NAS zugegriffen werden kann.

Cloud-Station02

Die Cloud Station befindet sich zwar nun auf dem NAS, jedoch sind noch ein paar Vorbereitungen zu treffen. In der Systemsteuerung muss noch der “Benutzer-Home-Dienst” aktiviert werden. Zu finden ist die Einstellung im Bereich “Benutzer”.

Cloud-Station03 Da eine Cloud Station vor allem dann Sinn macht, wenn sie über das Internet erreichbar ist, muss QuickConnect konfiguriert sein. Sollte ein MyDS Account  schon vorhanden sein, trägt man einfach die Email-Adresse und das dazugehörige Kennwort in die betreffenden Felder ein. Andernfalls klickt man auf den Button “Jetzt registrieren” und legt sich einen neuen Account an. Im Feld “QuickConnect ID” kann man eine frei zu wählende ID eingeben. Das System meldet es schon, wenn diese nicht verwendet werden kann. Generell muss die ID mit einem Buchstaben beginnen und darf zusätzlich noch Zahlen und Bindestriche enthalten.

Cloud-Station04 Jetzt sind die Vorbereitungen abgeschlossen und wir können das erste mal die Cloud Station starten.

Cloud-Station05 Zur Begrüßung sollte ein freundliches “Aktiviert” erscheinen. Auf der gleichen Maske sehen wir auch, welche Geräte mit der Cloud Station verbunden werden können. Da sind einmal Computer, Mobile Geräte und andere DiskStations. In diesem Tutorial wollen wir uns erst mal nur auf die Einrichtung eines Clients am Computer beschränken und so klicken wir auf den Button “Computer” in dem neu aufgehenden Fenster finden wir einen Link, über den wir die Client-Software runter laden können. Während der Download läuft machen wir mit der Einrichtung auf dem NAS weiter.

Cloud-Station06 Unter Berechtigungen werden alle User aktiviert, die die Cloud Station benutzen dürfen.

Cloud-Station07 Ein nettes Feature der Cloud Station ist die Versionierung von Dateien – per default sind es 32, Wem das zu viel ist kann das in den Einstellungen ändern.

Cloud-Station08 Auf der DiskStation gibt es nun nichts mehr zu tun und wir können uns dem Client auf dem Mac zuwenden. Das zuvor runter geladene DMG-File öffnet man dazu und führt das darin enthaltene Paket aus. Wenn die App nun endlich ihren Weg auf die Platte gefunden hat, starten wir sie und werden von einem Assistent begrüßt.

Cloud-Station09 Als erstes müssen die Verbindungsparameter eingetragen werden. Der Name des Computers ist individuell wählbar und kann nach eigenem Geschmack angepasst werden. Im zweiten Feld trägt man seine QuickConnect ID ein und in den folgenden Feldern einen auf dem NAS konfigurierten Benutzer-Account. Die SSL-Datenverschlüsselung sollte auf jeden Fall aktiviert werden, auch wenn man nur ein selbst signiertes Zertifikat auf der DiskStation hat.

Cloud-Station10Wenn zuvor SSL aktiviert wurde und kein signiertes Zertifikat vorhanden ist, kommt der Hinweis das dieses nicht vertrauenswürdig sei.  Für Fremde mag das so sein, wir wissen jedoch woher das Zertifikat kommt und können daher problemlos fortfahren.


Cloud-Station11 Die zu synchronisierenden Ordner sind schon voreingestellt und müssen nicht unbedingt geändert werden. Wenn dann kommt vor allem das Verzeichnis auf dem Mac in Frage. Wichtig ist lediglich die gemeinsamen Ordner zu aktivieren, bevor man fortfährt.

Cloud-Station12Die Einrichtung ist jetzt fertig gestellt und wir können zum testen übergehen.
Cloud-Station13Um die Synchronisierung zu testen, legen wir im Cloud Ordner ein neues Verzeichnis an. Wer mag kann dort auch eine Datei ablegen. Diese sollte aber nicht zu groß sein, damit wir das Ergebnis ohne Verzögerung auf der DiskStation überprüfen können.
Cloud-Station014 Zurück auf dem NAS öffnen wir die FileStation und navigieren zu den Home-Verzeichnissen. Unter dem Betreffenden User sollte nun ein neuer Ordner sichtbar sein.

Cloud-Station15

 

Read More

Tutorial – OS X Terminal – Dateioperatoren

Im ersten Teil unserer Tutorial-Reihe habe wir ein paar Verschönerungen vorgenommen, um die Shell etwas “cooler” aussehen zu lassen. Das war jedoch nur die Kür. Zur Pflicht wurde der zweite Artikel, in dem die wohl am häufigsten benutzten Befehle vorgestellt wurden. Daher empfehlen wir allen neuen Lesern zumindest letzteren Beitrag durchzulesen, bevor es hier mit ein paar essenziellen Dateioperatoren weiter geht.

cp

Die allgemeine Syntax von cp (copy) sieht wie folgt aus:

cp [OPTIONEN] QUELLE ZIEL

Die Optionen müssen nur bei Bedarf angegeben werden, wenn zum Beispiel ein Verzeichnis mit allen Unterordnern kopiert werden soll oder wenn vor dem Überschreiben einer Datei eine Rückfrage beim Anwender erfolgen soll. Welche Möglichkeiten es hier genau gibt, werden wir gleich noch sehen. Unbedingt notwendig ist die Angabe einer Quelle (was kopiert werden soll) und einem Ziel (wohin etwas kopiert werden soll. Quelle und Ziel können entweder eine Datei oder ein Ordner sein, wobei sich bestimmte Kombinationen ausschließen. Eine Datei kann sehr wohl in ein Ordner kopiert werden, umgekehrt ein Ordner in eine Datei kopieren macht dagegen nur wenig Sinn.

Um eine Datei zu kopieren würde man folgendes eingeben:

cp Telefonnummern.txt Telefonnummern.txt.backup

In diesem Beispiel erstellen wir eine Sicherheitskopie einer Textdatei. Hier sei noch mal erwähnt das OS X zwischen Groß- und Kleinschreibung unterscheidet. Telefonnummern.txt und telefonnummern,txt sind zwei unterschiedliche Dateien. Wer aus der Windows-Welt kommt, dem mag der Dateiname Telefonnummern.txt.backup komisch vorkommen. Unix Betriebssysteme sind jedoch viel cleverer als Windows und benötigen keine Dateiendung (.doc, .txt, .jpg), um einen Dateityp zu erkennen. Daher könnte das File auch nur Telefonnummern heißen und würde dennoch mit dem richtigen Programm geöffnet werden. Auch dürfen mehrere Punkte im Dateinamen vorkommen, um es optisch zu unterteilen.

Verzeichnisse können ebenfalls samt Inhalt kopiert werden:

cp -R GeekTool Backup

Der Schalter -R (rekursiv) bewirkt das alle Dateien und Unterordner vom Verzeichnis GeekTool nach Backup kopiert werden. Falls es den Ordner Backup nicht gibt, wird er vollautomatisch angelegt. Alternativ hätte der Befehl auch so aussehen können:

cp GeekTool/* Backup

Der Befehl macht fast das Gleiche, nur das keine Unterordner mit kopiert werden und das der Ordner Backup nicht automatisch angelegt wird – dieser muss schon vorhanden sein. Der Stern (*) hinter GeekTool/ ist wiederum ein Platzhalter und steht für alle Dateien.

Unser letztes Beispiel soll etwas Sicherheit beim Kopieren bringen:

cp -i Adressen.txt Adressen.backup

-i startet den interaktiven Modus. Sollte es die Zieldatei Adressen.backup schon geben, wird sie nicht automatisch überschrieben. Zuvor wird der User vom System gefragt, ob der Kopiervorgang fortgesetzt werden soll.

mv

mv (move) verschiebt Dateien und Ordner. Alternativ könnte man auch die Befehle cp (copy) und den noch nicht vorgestellten Befehl rm (remove) verwenden. In Kombination machen sie genau das Gleiche wie mv, nur das mehr Tipparbeit nötig ist. Die Syntax ist wie beim Kopier-Befehl:

mv [OPTIONEN] QUELLE ZIEL

mv kann aber noch mehr. Mit dem Befehl können auch Dateien und Verzeichnisse umbenannt werden.  Das geschieht immer dann, wenn es das angegebene Ziel noch nicht gibt. Dann nimmt das System an, dass die Quelle entsprechend umbenannt werden soll.

Bei den Optionen gibt es wieder den von cp bekannten Schalter -i. Auch er fragt vorher beim Anwender nach, ob ein Ziel überschrieben werden soll. Ein Beispiel sähe wie folgt aus:

mv -i Adressen.txt Adressen_Stand_2014.txt

rm

Mit rm (remove) lernen wir den dritten Dateioperator kennen. Er kann Dateien und Ordner vom Datenträger löschen. Wer die Befehle cp und mv kennt, für den birgt die Syntax keine Überraschungen mehr. Um Dateien zu löschen ist folgende Eingabe nötig:

rm Datei1 Datei2 Datei3

Auch hier kann der Schalter -i wie gewohnt verwendet werden. Die Optionen sind bei mehreren Befehlen zwar nicht immer identisch, aber eine gewisse Konsistenz ist häufig zu entdecken.

Verzeichnisse können ebenfalls gelöscht werden:

rm -R Verzeichnis

Die Option -R (rekursiv) wird benötigt, wenn ein Verzeichnis samt Inhalt gelöscht werden soll, ansonsten kommt es zu einer Fehlermeldung.

Hier findet ihr eine Übersicht von unseren OS X Terminal Tutorials.

Habt ihr noch Fragen zu diesem OS X Terminal Tutorial? Schreibt uns in den Kommentaren oder in der Community.

Read More