Interface Builder
# Interface Builder

Der Interface Builder ist eine Software von Apple, mit der grafische Benutzeroberflächen für Programme für macOS und iOS erstellt werden.

Bereits in den Developer Tools für NeXTStep war der Interface Builder enthalten. Auch bei Project Builder (2001–2003) und Xcode (2003 bis heute) war bzw. ist der Interface Builder ein wichtiger Bestandteil der Entwickler-Tools. Bis einschließlich Xcode 3.x war der Interface Builder eine eigenständige Anwendung, mit Xcode 4.0 wurde er jedoch in die IDE integriert.

Die Dateien, die der Interface Builder erzeugt, haben die Dateiendung .nib (von NeXT Interface Builder; die Dateien werden von Entwicklern oft "nib-Dateien" genannt) oder .xib.

Das GNUstep-Projekt hat einen Klon von Interface Builder namens Gorm geschrieben.

## Geschichte

### NeXTStep

Die erste Version von Interface Builder erschien 1986 und war in Lisp geschrieben. Der Entwickler des Tools wurde noch im gleichen Jahr von NeXT übernommen, und bereits 1988 war Interface Builder Teil von NeXTStep 0.8. Es war die erste kommerzielle Anwendung, mit der man eine Benutzeroberfläche mithilfe einer Maus zusammenstellen konnte.

### Project Builder (2001–2003)

NeXTStep diente als Basis für Mac OS X, und als Mac OS X 10.0 erschien, veröffentlichte Apple auch eine neue Version der Developer Tools. Teil davon war, neben einer komplett neu geschriebenen Version von Project Builder, auch Interface Builder zum Erstellen von Oberflächen für Carbon- und Cocoa-Anwendungen (in C++ bzw. Objective-C.)

ResEdit, das unter Mac OS 9 und davor zum Erstellen von Oberflächen verwendet wurde, konnte unter Mac OS X nicht mehr eingesetzt werden, da das neue System Bundles (Code und Ressourcen in verschiedenen Dateien, aber zusammen in einem Ordner mit einer bestimmten Struktur) statt Code Forks und Resource Forks verwendete.

### Xcode (ab 2003)

Ab Mac OS X Panther wurde Project Builder nicht mehr unterstützt, stattdessen setzte Apple auf die Xcode Tools mit Xcode als IDE. Interface Builder wurde beibehalten. Da das Datenformat nicht geändert wurde, sind Programme und NIB-Dateien, die mit Panther erstellt wurden, auch auf älteren Systemen ausführbar.

Mit Panther wurden die Cocoa Bindings eingeführt, die UI-Elemente und Code miteinander verbinden.

Interface Builder wurde mit jedem Betriebssystem-Release verbessert und erweitert, sodass es die neuen UI-Elemente einer neuen Systemversion unterstützte (z. B. die HUD-Panels in 10.5.)

Mit Erscheinen des iPhone SDK 2.0 und Xcode 3.1 wurde auch der Interface Builder aktualisiert, um Oberflächen von iPhone-Apps designen zu können.

Mit Xcode 4.0 wurde Interface Builder direkt in Xcode integriert. Das bot einige Vorteile: Entwickler mussten nicht mehr zwei Anwendungen geöffnet haben, sie mussten nicht mehr den Code speichern um ihn mit dem UI zu verbinden, und sie konnten per Drag und Drop die UI-Elemente direkt mit dem Quellcode verbinden.

## Funktionsweise

### Erstellen der Oberfläche

Objekte für eine Oberfläche sind in sogenannten Paletten gruppiert. Im AppKit-Framework existiert eine Palette für die vom System vorgegebenen UI-Elemente wie Fenster, Knöpfe, Listen, Bilder oder Textfelder.

In der Regel dient als Grundelement ein Fenster (NSWindow) oder eine Fläche (NSView). Jede .nib-Datei ist mit einer Klasse verbunden, die auch die Outlets und Aktionen deklariert (siehe nächster Abschnitt); diese Klasse ist oft eine Unterklasse von NSWindow oder NSView, seltener auch NSObject.

Auf diesen Flächen können dann weitere Elemente platziert werden, ihre Eigenschaften können verändert werden, und sie können mit dem Code verbunden werden.

### Verbinden von UI und Code

UI-Elemente werden über Outlets mit dem Code verbunden. Die Deklaration erfolgt in der jeweiligen Header-Datei etwa wie folgt:

Viele Objekte können bei bestimmten Aktionen ("Actions" genannt) (z. B. gedrückt oder verändert) eine Nachricht an ein Ziel ("Target") senden. Die Deklaration im Header sieht z. B. so aus:

Im eigentlichen Quellcode befindet sich eine Methode mit gleicher Deklaration, die dann bei Bedarf ausgeführt wird. Der generische Datentyp id ermöglicht es hierbei, dass die Methode von verschiedenen Objekten aufgerufen werden kann, z. B. von einem Knopf und einem Schieberegler.

Objekte, Outlets, Actions und Targets werden per Drag und Drop miteinander verbunden.

### Speichern und Ausführen

Die fertige Datei mit ihren Verbindungen zum Code wird in einer Property-List-Datei mit der Dateiendung .nib gespeichert (während der Entwicklung meist als XML, im fertigen Produkt als Binärdatei). Wenn das Programm ausgeführt und die NIB-Datei "aufgeweckt" wird, wird sie geladen und mit dem Binärcode verbunden.

Mit Interface Builder 3.0 wurde ein neues Dateiformat eingeführt, das die Dateiendung .xib trägt. Es hat genau die gleichen Funktionen wie .nib-Dateien, ist jedoch aufgrund seiner Datenstruktur einfacher in Tools wie Versionsverwaltungen und diff zu handhaben. Die Dateien werden von den meisten Entwicklern jedoch immer noch nib-Dateien genannt.

Es wird seitens Apple dazu geraten, verschiedene Fenster (sofern sie nicht zu einer Klasse gehören) in verschiedene NIB-Dateien zu packen. Hauptgründe dafür sind Übersichtlichkeit und Effizienz (es dauert länger eine große Datei in den Speicher zu laden und zu verbinden als drei kleine.)

### Lokalisierung

Elemente mit Text können entweder per Code oder direkt im Interface Builder lokalisiert werden. Für die Lokalisierung werden Ordner mit dem Sprachkürzel und der Endung .lproj angelegt, darin sind dann die lokalisierten NIB-Dateien gespeichert. Bei der Ausführung wird dann nur die Datei, die im Ordner mit der aktuellen Systemsprache liegt, geladen und ausgeführt. Die Lokalisierung per Code erfolgt per .strings-Dateien und der Methode NSLocalizableString.

Es gibt auch einige Programme von Drittherstellern, mit denen man entweder die String- oder NIB-Dateien lokalisieren kann.

## Oberflächen ohne Interface Builder

Es ist ohne Weiteres möglich, UIs für Anwendungen nicht per Interface Builder, sondern per Code zu schreiben. Besonders um die Portierbarkeit zu gewährleisten, wird gerade bei Libraries und Frameworks in der Regel mit programmatisch erstellten Views gearbeitet. Ein weiterer Vorteil ergibt sich, wenn mehrere Entwickler an einer App arbeiten. Nur minimale Änderungen der .storyboard- oder .xib-Datei können dazu führen, dass sich die zugrundeliegende XML-Datei deutlich verändert, was relativ schnell zu Konflikten führt, wenn die verschiedenen Änderungen gemerged werden sollen. Bei manuell programmierten Views gibt es dieses Problem nicht, da sich die Struktur der Klasse nicht willkürlich ändern kann. Außerdem sind die einzelnen Teile der App besser gekapselt. Bei einem Storyboard ist in der Regel die komplette Benutzeroberfläche einer App in einer Datei, beim programmatischen Ansatz wird jede View in einer eigenen Klasse erstellt.

Programmatisch erstellte Views sind zudem performanter, da hier keine zusätzliche XML-Datei vom Speicher geladen und geparst werden muss, und deutlich mächtiger, da beispielsweise nur im Code weitere Eigenschaften wie Schatten oder Rahmen gesetzt werden können. Der Performanceverlust des Interface Builders macht sich zudem nicht nur zur Laufzeit, sondern bereits zur Entwicklungszeit bemerkbar. Gerade bei komplexen Storyboards (hier werden mehrere Views in einer Datei verwaltet) kommt es dazu, dass das Öffnen der Datei im Interface Builder spürbar lange dauert.

Nachteilig ist der erhöhte Zeitaufwand beim programmatischen Erstellen der View. Zum einen dauert es länger, die einzelnen Code-Zeilen zu schreiben, zum anderen ist es schwerer, die Elemente genau auszurichten. Da das grafische Ergebnis erst zur Laufzeit – und nicht wie beim Interface Builder zur Übersetzungszeit – betrachtet werden kann, sind Änderungen erst nach dem Kompilieren und Starten der App sichtbar. Das Überprüfen einer jeden Änderung benötigt daher deutlich mehr Zeit als bei einem WYSIWYG-Editor wie dem Interface Builder. Diese erhöhte Komplexität ist sowohl für Neulinge als auch für schnelles Prototyping ungeeignet.

