Dezember 21, 2025
12 Min. Lesezeit

Junior-iOS-Entwickler Interviewfragen: Swift, UIKit, SwiftUI

interview
career-advice
job-search
entry-level
Junior-iOS-Entwickler Interviewfragen: Swift, UIKit, SwiftUI
Milad Bonakdar

Milad Bonakdar

Autor

Üben Sie Junior-iOS-Interviewfragen zu Swift, UIKit, SwiftUI, Networking, Persistenz und asynchronem Code mit klaren Antworten für Einstiegsrollen.


Einführung

In einem Junior-iOS-Interview wird meist geprüft, ob Sie Swift-Grundlagen erklären, einfache Oberflächen mit UIKit oder SwiftUI bauen, Daten laden und decodieren, passende lokale Speicherung wählen und typische Speicher- oder Threading-Fehler vermeiden können. Gute Antworten sind kurz, konkret und zeigen, wie Sie eine kleine App bauen würden.

Nutzen Sie diesen Leitfaden, um die wahrscheinlichsten Fragen für den Einstieg zu üben: was ein Konzept bedeutet, wann Sie es verwenden würden und welches Risiko Junior-Entwickler beachten sollten.


Swift-Grundlagen (6 Fragen)

1. Was ist der Unterschied zwischen var und let in Swift?

Antwort:

  • var: Deklariert eine veränderliche Variable. Ihr Wert kann nach der Initialisierung geändert werden.
  • let: Deklariert eine unveränderliche Konstante. Einmal festgelegt, kann ihr Wert nicht mehr geändert werden.
  • Bewährte Methode: Verwenden Sie standardmäßig let für Sicherheit und Klarheit. Verwenden Sie var nur, wenn Sie wissen, dass sich der Wert ändern wird.
let name = "John"  // Kann nicht geändert werden
var age = 25       // Kann geändert werden
age = 26           // Gültig
// name = "Jane"   // Fehler: Kann keinem Wert zugewiesen werden

Seltenheit: Sehr häufig Schwierigkeit: Leicht


2. Erklären Sie Optionals in Swift. Was ist Optional Binding?

Antwort: Optionals stellen einen Wert dar, der nil sein kann (Fehlen eines Werts).

  • Deklaration: Verwenden Sie ? nach dem Typ: var name: String?
  • Entpackmethoden:
    • Forciertes Entpacken: name! (gefährlich, stürzt ab, wenn nil)
    • Optional Binding: Sicheres Entpacken mit if let oder guard let
    • Nil Coalescing: name ?? "Default"
    • Optional Chaining: user?.address?.city
var email: String? = "[email protected]"

// Optional Binding
if let unwrappedEmail = email {
    print("Email: \(unwrappedEmail)")
} else {
    print("Keine E-Mail")
}

// Guard-Anweisung
guard let email = email else { return }
print(email)

Seltenheit: Sehr häufig Schwierigkeit: Leicht


3. Was ist der Unterschied zwischen einer class und einer struct in Swift?

Antwort:

  • Class: Referenztyp (im Heap gespeichert). Unterstützt Vererbung. Wird als Referenz übergeben.
  • Struct: Werttyp (im Stack gespeichert). Keine Vererbung. Wird als Kopie übergeben.
  • Wann verwenden:
    • Struct: Für einfache Datenmodelle, wenn Sie Wertsemantik wünschen (unabhängige Kopien)
    • Class: Wenn Sie Vererbung, Referenzsemantik oder Deinitialisierer benötigen
struct Point {
    var x: Int
    var y: Int
}

class Person {
    var name: String
    init(name: String) { self.name = name }
}

var p1 = Point(x: 0, y: 0)
var p2 = p1  // Kopie erstellt
p2.x = 10    // p1.x ist immer noch 0

var person1 = Person(name: "John")
var person2 = person1  // Gleiche Referenz
person2.name = "Jane"  // person1.name ist auch "Jane"

Seltenheit: Sehr häufig Schwierigkeit: Mittel


4. Was sind Closures in Swift?

Antwort: Closures sind in sich geschlossene Funktionsblöcke, die in Ihrem Code herumgereicht und verwendet werden können. Sie ähneln Lambdas oder anonymen Funktionen in anderen Sprachen.

  • Syntax: { (Parameter) -> Rückgabetyp in Anweisungen }
  • Erfassen von Werten: Closures können Referenzen auf Variablen aus ihrem umgebenden Kontext erfassen und speichern.
  • Häufige Verwendung: Completion-Handler, Rückrufe, Array-Operationen.
// Einfacher Closure
let greet = { (name: String) -> String in
    return "Hallo, \(name)!"
}
print(greet("Alice"))

// Trailing-Closure-Syntax
let numbers = [1, 2, 3, 4, 5]
let doubled = numbers.map { $0 * 2 }
print(doubled)  // [2, 4, 6, 8, 10]

Seltenheit: Sehr häufig Schwierigkeit: Mittel


5. Erklären Sie den Unterschied zwischen weak und unowned Referenzen.

Antwort: Beide werden verwendet, um Retain Cycles (Speicherlecks) in Referenztypen zu verhindern.

  • weak: Optionale Referenz, die automatisch nil wird, wenn das referenzierte Objekt freigegeben wird. Verwenden Sie diese, wenn die Referenz das Objekt möglicherweise überlebt.
  • unowned: Nicht-optionale Referenz, die davon ausgeht, dass das Objekt immer existieren wird. Stürzt ab, wenn nach der Freigabe darauf zugegriffen wird. Verwenden Sie diese, wenn Sie sicher sind, dass die Referenz das Objekt nicht überleben wird.
class Person {
    var name: String
    weak var apartment: Apartment?  // weak, um Retain Cycle zu verhindern
    init(name: String) { self.name = name }
}

class Apartment {
    var unit: String
    unowned let tenant: Person  // unowned - Apartment hat immer einen Mieter
    init(unit: String, tenant: Person) {
        self.unit = unit
        self.tenant = tenant
    }
}

Seltenheit: Häufig Schwierigkeit: Mittel


6. Was sind Protokolle in Swift?

Antwort: Protokolle definieren einen Entwurf von Methoden, Eigenschaften und anderen Anforderungen, die für eine bestimmte Aufgabe oder ein bestimmtes Funktionsteil geeignet sind. Klassen, Strukturen und Enums können Protokolle übernehmen.

  • Ähnlich wie: Schnittstellen in anderen Sprachen
  • Protokollerweiterungen: Können Standardimplementierungen bereitstellen
  • Protokollorientierte Programmierung: Swifts bevorzugtes Paradigma
protocol Drawable {
    func draw()
}

struct Circle: Drawable {
    var radius: Double
    
    func draw() {
        print("Zeichne Kreis mit Radius \(radius)")
    }
}

struct Rectangle: Drawable {
    var width: Double
    var height: Double
    
    func draw() {
        print("Zeichne Rechteck \(width)x\(height)")
    }
}

Seltenheit: Sehr häufig Schwierigkeit: Leicht


UIKit-Grundlagen (5 Fragen)

7. Was ist der Unterschied zwischen UIView und UIViewController?

Antwort:

  • UIView: Stellt einen rechteckigen Bereich auf dem Bildschirm dar. Behandelt das Zeichnen und die Ereignisbehandlung. Beispiele: UILabel, UIButton, UIImageView.
  • UIViewController: Verwaltet eine View-Hierarchie. Behandelt den View-Lebenszyklus, Benutzerinteraktionen und Navigation. Enthält eine Root-View und verwaltet ihre Subviews.
  • Beziehung: Ein View-Controller verwaltet Views. Ein View-Controller kann viele Views haben.

Seltenheit: Sehr häufig Schwierigkeit: Leicht


8. Erklären Sie die Lebenszyklusmethoden des View-Controllers.

Antwort: View-Controller haben spezifische Lebenszyklusmethoden, die in der folgenden Reihenfolge aufgerufen werden:

  1. viewDidLoad(): Wird einmal aufgerufen, wenn die View in den Speicher geladen wird. Einrichtung, die einmalig erfolgen muss.
  2. viewWillAppear(_:): Wird aufgerufen, bevor die View auf dem Bildschirm erscheint. Kann mehrmals aufgerufen werden.
  3. viewDidAppear(_:): Wird aufgerufen, nachdem die View auf dem Bildschirm erscheint. Starten Sie hier Animationen.
  4. viewWillDisappear(_:): Wird aufgerufen, bevor die View verschwindet.
  5. viewDidDisappear(_:): Wird aufgerufen, nachdem die View verschwindet. Bereinigen Sie Ressourcen.
override func viewDidLoad() {
    super.viewDidLoad()
    // Einmalige Einrichtung: UI konfigurieren, Daten laden
}

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    // Daten aktualisieren, Benachrichtigungen abhören
}

Seltenheit: Sehr häufig Schwierigkeit: Leicht


9. Was ist Auto Layout und wie verwenden Sie Constraints?

Antwort: Auto Layout ist ein Constraint-basiertes Layoutsystem, mit dem Sie adaptive UIs erstellen können, die auf verschiedenen Bildschirmgrößen und -ausrichtungen funktionieren.

  • Constraints: Definieren Beziehungen zwischen Views (Breite, Höhe, Abstand, Ausrichtung)
  • Methoden:
    • Interface Builder: Visueller Editor in Xcode
    • Programmatisch: NSLayoutConstraint- oder NSLayoutAnchor-API
    • Visual Format Language: String-basiert (heutzutage weniger verbreitet)
let button = UIButton()
button.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(button)

NSLayoutConstraint.activate([
    button.centerXAnchor.constraint(equalTo: view.centerXAnchor),
    button.centerYAnchor.constraint(equalTo: view.centerYAnchor),
    button.widthAnchor.constraint(equalToConstant: 200),
    button.heightAnchor.constraint(equalToConstant: 50)
])

Seltenheit: Sehr häufig Schwierigkeit: Mittel


10. Was ist der Unterschied zwischen frame und bounds?

Antwort:

  • frame: Die Position und Größe der View im Koordinatensystem ihrer Superview. Wird zum Positionieren der View verwendet.
  • bounds: Die Position und Größe der View in ihrem eigenen Koordinatensystem. Der Ursprung ist normalerweise (0, 0). Wird zum Zeichnen von Inhalten innerhalb der View verwendet.
  • Hauptunterschied: frame ist relativ zum übergeordneten Element, bounds ist relativ zu sich selbst.
let view = UIView(frame: CGRect(x: 50, y: 100, width: 200, height: 150))
print(view.frame)   // (50, 100, 200, 150) - Position in der Superview
print(view.bounds)  // (0, 0, 200, 150) - eigenes Koordinatensystem

Seltenheit: Häufig Schwierigkeit: Mittel


11. Wie behandeln Sie Benutzereingaben von einem UITextField?

Antwort: Es gibt mehrere Ansätze:

  • Target-Action: Fügen Sie ein Target für das .editingChanged-Ereignis hinzu
  • Delegate: Konform zum UITextFieldDelegate-Protokoll
  • Combine: Verwenden Sie Publisher (moderner Ansatz)
class ViewController: UIViewController, UITextFieldDelegate {
    let textField = UITextField()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        // Delegate-Ansatz
        textField.delegate = self
        
        // Target-Action-Ansatz
        textField.addTarget(self, action: #selector(textChanged), for: .editingChanged)
    }
    
    @objc func textChanged(_ textField: UITextField) {
        print("Text: \(textField.text ?? "")")
    }
    
    // Delegate-Methode
    func textFieldShouldReturn(_ textField: UITextField) -> Bool {
        textField.resignFirstResponder()
        return true
    }
}

Seltenheit: Sehr häufig Schwierigkeit: Leicht


SwiftUI-Grundlagen (4 Fragen)

12. Was ist SwiftUI und wie unterscheidet es sich von UIKit?

Antwort: SwiftUI ist Apples deklaratives UI-Framework. Sie beschreiben die Oberfläche als Ergebnis eines Zustands, und SwiftUI aktualisiert die View, wenn sich dieser Zustand ändert. UIKit ist imperativ: Sie erstellen und verändern View-Objekte wie UIView, UILabel und UIViewController direkt.

Im Junior-Interview sollten Sie nicht sagen, dass SwiftUI UIKit überall ersetzt. Viele produktive Apps nutzen beides. Eine starke Antwort lautet: SwiftUI ist knapp und gut für neue, zustandsgetriebene Screens; UIKit bleibt wichtig für bestehende Codebasen, spezielle Controls und APIs, die SwiftUI nicht vollständig abdeckt.

struct CounterView: View {
    @State private var count = 0

    var body: some View {
        VStack {
            Text("Count: \(count)")
            Button("Increment") {
                count += 1
            }
        }
    }
}

Seltenheit: Sehr häufig Schwierigkeit: Leicht


13. Erklären Sie @State, @Binding und @ObservedObject in SwiftUI.

Antwort: Diese Wrapper beschreiben, wo Zustand liegt und wer ihn ändern darf.

  • @State: Privater Zustand, der einer View gehört, meist für einfachen lokalen UI-Zustand.
  • @Binding: Zwei-Wege-Verbindung zu Zustand, der einer Parent-View gehört. Die Child-View kann ihn lesen und ändern, besitzt ihn aber nicht.
  • @ObservedObject: Referenz auf externe beobachtbare Modelldaten. Nutzen Sie es, wenn ein anderes Objekt die Daten besitzt und die View bei Änderungen aktualisiert werden soll. In neuerem SwiftUI-Code sehen Sie auch das Observation-Framework und @Observable, aber viele Interviews fragen weiterhin nach diesen Wrappern.
class UserData: ObservableObject {
    @Published var name = ""
}

struct ParentView: View {
    @State private var isOn = false
    @ObservedObject var userData = UserData()

    var body: some View {
        VStack {
            ChildView(isOn: $isOn)
            Text(userData.name)
        }
    }
}

struct ChildView: View {
    @Binding var isOn: Bool

    var body: some View {
        Toggle("Switch", isOn: $isOn)
    }
}

Seltenheit: Häufig Schwierigkeit: Mittel


14. Wie erstellen Sie eine Liste in SwiftUI?

Antwort: Verwenden Sie die List-View, um scrollbare Datensammlungen anzuzeigen.

struct ContentView: View {
    let fruits = ["Apfel", "Banane", "Orange", "Traube"]
    
    var body: some View {
        List(fruits, id: \.self) { fruit in
            Text(fruit)
        }
    }
}

// Mit benutzerdefiniertem Modell
struct Task: Identifiable {
    let id = UUID()
    let title: String
}

struct TaskListView: View {
    let tasks = [
        Task(title: "Lebensmittel kaufen"),
        Task(title: "Mit dem Hund Gassi gehen")
    ]
    
    var body: some View {
        List(tasks) { task in
            Text(task.title)
        }
    }
}

Seltenheit: Häufig Schwierigkeit: Leicht


15. Was sind View Modifier in SwiftUI?

Antwort: View Modifier sind Methoden, die eine neue View mit geänderten Eigenschaften erstellen. Sie sind verkettbar.

  • Häufige Modifier: .padding(), .background(), .foregroundColor(), .font(), .frame()
  • Reihenfolge ist wichtig: Modifier werden sequenziell angewendet
Text("Hallo Welt!")
    .font(.title)
    .foregroundColor(.blue)
    .padding()
    .background(Color.yellow)
    .cornerRadius(10)
    .shadow(radius: 5)

// Benutzerdefinierter Modifier
struct PrimaryButtonStyle: ViewModifier {
    func body(content: Content) -> some View {
        content
            .padding()
            .background(Color.blue)
            .foregroundColor(.white)
            .cornerRadius(8)
    }
}

extension View {
    func primaryButton() -> some View {
        modifier(PrimaryButtonStyle())
    }
}

Seltenheit: Häufig Schwierigkeit: Leicht


Daten & Netzwerke (5 Fragen)

16. Wie führen Sie in iOS einen Netzwerkrequest aus?

Antwort: Verwenden Sie URLSession. In modernem Swift kann eine Junior-Antwort async/await zeigen und erwähnen, dass ältere Codebasen oft noch Completion Handler nutzen. Eine gute Praxisantwort prüft außerdem die HTTP-Antwort, behandelt Fehler, decodiert in Codable-Modelle und aktualisiert UI auf dem Main Actor.

struct User: Codable {
    let id: Int
    let name: String
}

func fetchUser(id: Int) async throws -> User {
    let url = URL(string: "https://api.example.com/users/\(id)")!
    let (data, response) = try await URLSession.shared.data(from: url)

    guard let http = response as? HTTPURLResponse, (200...299).contains(http.statusCode) else {
        throw URLError(.badServerResponse)
    }

    return try JSONDecoder().decode(User.self, from: data)
}

Seltenheit: Sehr häufig Schwierigkeit: Mittel


17. Was ist Codable in Swift?

Antwort: Codable ist ein Typalias für die Protokolle Encodable & Decodable. Es ermöglicht die einfache Konvertierung zwischen Swift-Typen und externen Darstellungen wie JSON.

  • Automatische Synthese: Swift generiert automatisch Encoding-/Decoding-Code, wenn alle Eigenschaften Codable sind.
  • Benutzerdefinierte Schlüssel: Verwenden Sie das CodingKeys-Enum, um verschiedene Eigenschaftsnamen zuzuordnen.
struct User: Codable {
    let id: Int
    let name: String
    let email: String
}

// JSON dekodieren
let json = """
{
    "id": 1,
    "name": "John Doe",
    "email": "[email protected]"
}
""".data(using: .utf8)!

let decoder = JSONDecoder()
let user = try decoder.decode(User.self, from: json)

// In JSON kodieren
let encoder = JSONEncoder()
encoder.outputFormatting = .prettyPrinted
let jsonData = try encoder.encode(user)

Seltenheit: Sehr häufig Schwierigkeit: Leicht


18. Wie persistieren Sie Daten lokal in iOS?

Antwort: Mehrere Optionen für die lokale Datenpersistenz:

  • UserDefaults: Einfacher Key-Value-Speicher für kleine Datenmengen (Einstellungen, Präferenzen)
  • Dateisystem: Speichern Sie Dateien im Dokumenten- oder Cache-Verzeichnis
  • Core Data: Apples Framework für Objektgraphverwaltung und Persistenz
  • SQLite: Relationale Datenbank
  • Keychain: Sichere Speicherung für sensible Daten (Passwörter, Token)
// UserDefaults
UserDefaults.standard.set("John", forKey: "username")
let username = UserDefaults.standard.string(forKey: "username")

// Dateisystem
let documentsPath = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
let filePath = documentsPath.appendingPathComponent("data.json")

// Schreiben
try data.write(to: filePath)

// Lesen
let loadedData = try Data(contentsOf: filePath)

Seltenheit: Sehr häufig Schwierigkeit: Leicht


19. Was ist der Unterschied zwischen synchronen und asynchronen Operationen?

Antwort: Eine synchrone Operation blockiert den aktuellen Thread, bis sie fertig ist. Auf dem Main Thread ist das gefährlich, weil die App nicht mehr reagieren kann. Eine asynchrone Operation startet Arbeit und lässt den aktuellen Thread weiterlaufen; das Ergebnis kommt später über async/await, einen Completion Handler, einen Delegate oder einen Publisher zurück.

Beziehen Sie die Antwort im iOS-Interview auf UI-Reaktionsfähigkeit: Netzwerkaufrufe, Dateiarbeit und schwere Berechnungen dürfen den Main Thread nicht blockieren, und UI-Änderungen gehören auf den Main Actor.

func loadProfile() async {
    do {
        let user = try await fetchUser(id: 42)
        await MainActor.run {
            self.nameLabel.text = user.name
        }
    } catch {
        await MainActor.run {
            self.errorLabel.text = "Could not load profile"
        }
    }
}

Seltenheit: Häufig Schwierigkeit: Leicht


20. Was ist Grand Central Dispatch (GCD)?

Antwort: GCD ist Apples Low-Level-API zum Planen von Arbeit auf Dispatch Queues. Die Main Queue wird für UI-Arbeit genutzt, globale Queues können Hintergrundarbeit mit verschiedenen Quality-of-Service-Prioritäten ausführen.

In neuerem Swift-Code verwenden Sie oft zuerst Swift Concurrency (async/await, Task und Actors), weil asynchroner Code dadurch leichter lesbar wird. GCD bleibt wichtig, weil viele UIKit-Projekte, ältere Codebasen und Callback-APIs DispatchQueue.main.async oder Hintergrund-Queues nutzen.

DispatchQueue.global(qos: .userInitiated).async {
    let image = renderThumbnail()

    DispatchQueue.main.async {
        self.imageView.image = image
    }
}

Seltenheit: Häufig Schwierigkeit: Mittel


Newsletter subscription

Wöchentliche Karrieretipps, die wirklich funktionieren

Erhalten Sie die neuesten Einblicke direkt in Ihr Postfach

Hören Sie auf, sich zu bewerben. Beginnen Sie, eingestellt zu werden.

Verwandeln Sie Ihren Lebenslauf in einen Vorstellungsgespräch-Magneten mit KI-gestützter Optimierung, der von Arbeitssuchenden weltweit vertraut wird.

Kostenlos starten

Diesen Beitrag teilen

Verdoppeln Sie Ihre Vorstellungsgespräch-Rückrufe

Kandidaten, die ihre Lebensläufe auf die Stellenbeschreibung zuschneiden, erhalten 2,5-mal mehr Vorstellungsgespräche. Nutzen Sie unsere KI, um Ihren Lebenslauf sofort für jede Bewerbung anzupassen.