Skip to content
Alle Artikel

Cannot find 'Map' in scope in SwiftUI? So beheben Sie Map- und WebView-Imports

„Cannot find 'Map' in scope“ in SwiftUI beheben: warum Map, PhotosPicker und WebView einen zweiten Import brauchen und wie WebView auf iPhone und iPhone Duo funktioniert.

Von der AppleDuo-RedaktionVeröffentlicht 7 Min. Lesezeit

Auch verfügbar auf:EnglishEspañolFrançais日本語Türkçe

Auf dieser Seite
  1. Warum meldet SwiftUI „Cannot find 'Map' in scope“?
  2. Was ist ein Cross-Import Overlay in Swift?
  3. Welche SwiftUI-Views brauchen einen zweiten Import?
  4. Wie verwende ich die native WebView von SwiftUI in iOS 26?
  5. Wie verfolge ich Laden, Navigation und JavaScript mit WebPage?
  6. Wie unterstütze ich iOS-Versionen vor 26?
  7. Brauchen Karten und Web Views auf dem iPhone Duo etwas Besonderes?
  8. Das Wichtigste in Kürze

Sie fügen einer SwiftUI-View eine Karte hinzu, die Datei enthält bereits import SwiftUI, und Xcode bricht mit „Cannot find 'Map' in scope“ ab. Den Typ gibt es, die Schreibweise stimmt, und das Deployment Target passt. Dasselbe passiert mit PhotosPicker und mit der nativen WebView, die SwiftUI in iOS 26 erhalten hat. Die Lösung ist ein einziger Import, doch der Grund dahinter erklärt eine ganze Familie von Fehlern.

Dieser Leitfaden behandelt, warum der Fehler auftritt, was ein Cross-Import Overlay ist, welche Views einen zweiten Import brauchen und wie Sie die WebView aus iOS 26 mit WebPage verwenden. Er basiert auf Apples Dokumentation und WWDC-Sessions, den Design-Notizen in den Swift Forums und Beiträgen des iOS-Entwicklers @sarunw. WebView und WebPage sind neu in iOS 26.0, und Details können sich zwischen Releases ändern.

Warum meldet SwiftUI „Cannot find 'Map' in scope“?

Weil Map nicht Teil von SwiftUI ist. Wie @sarunw es formuliert, liegt Map in einem Cross-Import Overlay, Sie brauchen also sowohl SwiftUI als auch MapKit. Diese Datei lässt sich nicht bauen:

import SwiftUI

struct ContentView: View {
    var body: some View {
        Map() // error: cannot find 'Map' in scope
    }
}

Mit einer zusätzlichen Zeile klappt der Build:

import SwiftUI
import MapKit

struct ContentView: View {
    var body: some View {
        Map()
    }
}

Apples Dokumentation zu Map führt es unter MapKit und beschreibt es als SwiftUI-View. Der interne Name des Symbols ordnet es einem Modul namens _MapKit_SwiftUI zu, das weder MapKit noch SwiftUI ist. Dieses dritte Modul ist das Overlay.

Zwei Details machen den Fehler schwerer zu erkennen. Die Compiler-Meldung erwähnt keinen fehlenden Import, und wie @sarunw in seinem Artikel über Cross-Import Overlays anmerkt, kann die Autovervollständigung von Xcode keinen Typ aus einem nicht geladenen Modul vorschlagen. Map taucht also auch in den Vorschlägen nicht auf.

Was ist ein Cross-Import Overlay in Swift?

Ein Cross-Import Overlay ist ein Modul, das der Compiler automatisch importiert, wenn eine Quelldatei zwei bestimmte Module importiert. Die Design-Diskussion in den Swift Forums beschreibt Overlays, die aus der Kombination der Imports in einer Quelldatei ausgewählt werden. Das Overlay re-exportiert das erste Framework, das deklarierende Modul, und ergänzt APIs, die zusätzlich das zweite brauchen, das sogenannte Bystanding-Modul.

Warum steckt Map nicht direkt in SwiftUI oder MapKit? Map ist eine View und braucht deshalb SwiftUI, und es arbeitet mit MapKit-Typen und braucht deshalb MapKit. Läge es in einem der beiden Frameworks, würde jede App, die eines nutzt, das andere mitladen. Das Overlay wird nur geladen, wenn eine Datei beide angefordert hat.

Den Mechanismus können Sie im SDK sehen. Laut @sarunw liefert ein Framework mit Overlays in seinem Verzeichnis Modules einen Ordner .swiftcrossimport mit einer kleinen Datei pro Partnermodul aus:

SDK=$(xcrun --sdk iphonesimulator --show-sdk-path)
cd "$SDK/System/Library/Frameworks/MapKit.framework/Modules"
ls MapKit.swiftcrossimport
cat MapKit.swiftcrossimport/SwiftUI.swiftoverlay

Die Datei SwiftUI.swiftoverlay ist eine kurze YAML-Datei, die das Overlay-Modul _MapKit_SwiftUI benennt. @sarunw zählt 36 Cross-Import Overlays im iOS 26 SDK.

Eine Folge ist im Alltag wichtig: Imports gelten pro Datei. Wenn Sie MapKit im Einstiegspunkt Ihrer App importieren, ist Map deshalb nicht in einer anderen Datei verfügbar, die nur SwiftUI importiert. Jede Datei, die die View verwendet, braucht beide Imports.

Welche SwiftUI-Views brauchen einen zweiten Import?

Die Faustregel von @sarunw: Finden Sie die zwei Frameworks, von denen der Typ abhängt, und importieren Sie beide. Das sind die häufigsten, mit Verfügbarkeit laut Apples Dokumentation:

SwiftUI-APIZusätzlich importierenVerfügbar ab
Map, Marker, AnnotationMapKitiOS 14 (Map); iOS 17 für Karteninhalte
PhotosPickerPhotosUIiOS 16
WebViewWebKitiOS 26
VideoPlayerAVKitiOS 14
SubscriptionStoreViewStoreKitiOS 17
SpriteViewSpriteKitiOS 14
SignInWithAppleButtonAuthenticationServicesiOS 14

Apples Dokumentation ordnet jedes dieser Symbole sowohl seinem Framework als auch SwiftUI zu. Der Artikel von @sarunw nennt weitere Paare, darunter ProductView mit StoreKit, .quickLookPreview(_:) mit QuickLook, SceneView und RealityView mit SceneKit und RealityKit, .translationPresentation mit Translation und .modelContainer mit SwiftData.

Wenn Sie also „Cannot find 'X' in scope“ für einen Typ sehen, der nach SwiftUI aussieht, prüfen Sie auf einen fehlenden zweiten Import, bevor Sie einen Tippfehler oder ein Verfügbarkeitsproblem vermuten. Die Content-Builder-API von MapKit mit Marker und Annotation innerhalb von Map kam mit iOS 17 und Apples Session Meet MapKit for SwiftUI.

Wie verwende ich die native WebView von SwiftUI in iOS 26?

Vor iOS 26 musste man WKWebView in ein UIViewRepresentable verpacken, um in SwiftUI eine Webseite anzuzeigen. Wie @sarunw es formuliert, hat SwiftUI in iOS 26 endlich eine native WebView. Apples Session What's new in SwiftUI nennt sie eine neue SwiftUI-View zur Anzeige von Webinhalten in Ihrer App, angetrieben von WebKit wie Safari.

Auch WebView ist ein Typ aus einem Cross-Import Overlay. Apples WebView-Dokumentation führt sie unter WebKit und SwiftUI, und ihre Beispiele beginnen mit beiden Imports. Für eine Seite mit Nutzungsbedingungen oder einen Hilfeartikel genügt der URL-Initializer:

import SwiftUI
import WebKit

struct HelpView: View {
    var body: some View {
        NavigationStack {
            WebView(url: URL(string: "https://www.swift.org"))
                .navigationTitle("Help")
                .webViewBackForwardNavigationGestures(.disabled)
        }
    }
}

init(url:) nimmt eine optionale URL entgegen, und Links innerhalb der Seite funktionieren wie in einem Browser. Apple weist darauf hin, dass eine WebView wie eine ScrollView scrollt und scrollBounceBehavior(_:axes:) akzeptiert. WebKit ergänzt Modifier wie webViewBackForwardNavigationGestures(_:), webViewLinkPreviews(_:), webViewTextSelection(_:) und webViewContentBackground(_:). Der bestehende Modifier findNavigator(isPresented:) ergänzt laut Apples Session Meet WebKit for SwiftUI die Suche auf der Seite.

Wie verfolge ich Laden, Navigation und JavaScript mit WebPage?

Der URL-Initializer verrät Ihnen nichts über die Seite. Wenn Sie Titel, Fortschritt oder JavaScript brauchen, rät @sarunw, WebView mit WebPage zu kombinieren. Apples WebPage-Dokumentation beschreibt sie als Observable-Klasse, die interaktive Webinhalte steuert und verwaltet. Halten Sie sie in @State und übergeben Sie sie an WebView(_:):

import SwiftUI
import WebKit

struct BrowserView: View {
    @State private var page = WebPage()

    var body: some View {
        NavigationStack {
            WebView(page)
                .navigationTitle(page.title)
                .safeAreaInset(edge: .top) {
                    if page.isLoading {
                        ProgressView(value: page.estimatedProgress)
                    }
                }
                .toolbar {
                    Button("Reload", systemImage: "arrow.clockwise") {
                        page.reload(fromOrigin: false)
                    }
                }
        }
        .onAppear {
            page.load(URLRequest(url: URL(string: "https://www.webkit.org")!))
        }
    }
}

Weil WebPage beobachtbar ist, aktualisieren sich Titel und Fortschrittsbalken von selbst, ohne Delegate oder Coordinator. Apples Dokumentation ergänzt, dass eine WebPage jeweils nur an eine WebView gebunden sein kann. Diese Member brauchen Sie zuerst:

WebPage-MemberWas Sie damit erhalten
title, urlSeitentitel und aktuelle URL
isLoading, estimatedProgressLadezustand und Fortschritt von 0 bis 1
themeColorDie Farbe aus dem theme-color-Meta-Tag der Seite
backForwardListDen Verlauf, aus dem Sie einen Eintrag laden können
load(_:), load(html:baseURL:)Navigation, die eine asynchrone Sequenz von Ereignissen liefert
callJavaScript(_:arguments:in:contentWorld:)JavaScript ausführen und ein Ergebnis erhalten

Jeder Aufruf von load liefert eine asynchrone Sequenz von Navigationsereignissen. Laut Apples Session beginnt eine Navigation mit startedProvisionalNavigation und wird dann abgeschlossen oder schlägt fehl. Durchlaufen Sie die Sequenz mit for try await, wenn Sie warten müssen, bis eine Seite fertig ist, oder lesen Sie currentNavigationEvent in einer View aus.

Für JavaScript ist callJavaScript async throws und liefert ein optionales Any. Schlüssel im Dictionary arguments werden im Skript zu lokalen Variablen:

let heading = try await page.callJavaScript(
    "return document.querySelector(selector)?.textContent",
    arguments: ["selector": "h1"]
) as? String

Um Navigationen zuzulassen oder zu blockieren, lassen Sie einen Typ WebPage.NavigationDeciding erfüllen und übergeben ihn an WebPage(configuration:navigationDecider:). Apples Session behandelt außerdem eigene URL-Schemata über das Protokoll URLSchemeHandler.

Wie unterstütze ich iOS-Versionen vor 26?

WebView und WebPage setzen iOS 26 oder neuer voraus. Liegt Ihr Deployment Target niedriger, behalten Sie einen WKWebView-Wrapper und entscheiden zur Laufzeit, wie @sarunw vorschlägt:

struct ArticleView: View {
    let url: URL

    var body: some View {
        if #available(iOS 26.0, *) {
            WebView(url: url)
        } else {
            LegacyWebView(url: url)
        }
    }
}

struct LegacyWebView: UIViewRepresentable {
    let url: URL

    func makeUIView(context: Context) -> WKWebView {
        WKWebView()
    }

    func updateUIView(_ webView: WKWebView, context: Context) {
        webView.load(URLRequest(url: url))
    }
}

Die Datei braucht weiterhin sowohl import SwiftUI als auch import WebKit. Der Legacy-Pfad lädt bei jeder Aktualisierung der View durch SwiftUI neu, vergleichen Sie in einer echten App also die aktuelle URL, bevor Sie load aufrufen. Die Entwicklerin Sarah Reichelt stellte fest, dass sich das Beispiel zur Navigationsverfolgung aus der Session in späteren Betas von iOS 26 nicht mehr kompilieren ließ, prüfen Sie Beispiele also mit Ihrer Xcode-Version.

Brauchen Karten und Web Views auf dem iPhone Duo etwas Besonderes?

Die Imports funktionieren auf jedem iPhone gleich, doch das iPhone Duo verändert den Raum, in dem diese Views leben.

  • Mehr Platz im geöffneten Zustand. Das innere Display meldet in beiden Ausrichtungen reguläre Breite und reguläre Höhe, wie unser Leitfaden zu den Size Classes des iPhone Duo erklärt. Eine Karte oder Web View kann in einer NavigationSplitView neben einer Liste stehen, statt auf einen Stack geschoben zu werden.
  • Toolbar-Buttons wandern. Buttons, die Sie mit .toolbar an eine WebView oder Map hängen, wie den Reload-Button oben, wandern in die vertikale Bar, wenn Sie mit dem iOS 27.1 SDK bauen. Geben Sie ihnen ein Symbol und einen Titel, wie unser Leitfaden zur vertikalen Toolbar auf dem iPhone Duo empfiehlt. Unser Leitfaden zur Toolbar in iOS 26 behandelt das Gruppieren dieser Buttons.
  • Inhalte bis zum Rand. Apples Beispiel wendet .ignoresSafeArea() auf eine WebView an. Auf dem iPhone Duo fügt die vertikale Bar nur auf einer Seite einen Inset hinzu. Apples Empfehlung in unserem Leitfaden zur Safe Area lautet, dass Hintergründe unter Bars reichen dürfen, interaktive Elemente aber innerhalb bleiben sollten. Eine Webseite ist voller Links, prüfen Sie also, ob ihr Inhalt frei von der Bar bleibt, bevor Sie diese Kante ignorieren.
  • Die Falz. Eigene Steuerelemente, die Sie über eine Karte legen, etwa einen eigenen Button, gehören weg von der Faltkante. Unser Leitfaden zu den Reserved Regions an der Faltkante zeigt, wie Sie sie finden.

Das Wichtigste in Kürze

  • „Cannot find 'Map' in scope“ bedeutet einen fehlenden zweiten Import: Ergänzen Sie import MapKit neben import SwiftUI.
  • Map, PhotosPicker und WebView liegen in Cross-Import Overlays, verborgenen Modulen wie _MapKit_SwiftUI, die nur geladen werden, wenn eine Datei beide Frameworks importiert.
  • Imports gelten pro Datei, daher braucht jede Datei, die die View verwendet, beide.
  • iOS 26 ergänzt eine native WebView in WebKit. Verwenden Sie WebView(url:) für einfache Seiten und WebView(page) mit einer WebPage für Titel, Fortschritt, Navigation und callJavaScript.
  • Behalten Sie für ältere Targets einen WKWebView-Wrapper hinter if #available(iOS 26.0, *).
  • Auf dem iPhone Duo wandern Toolbar-Elemente über Karten und Web Views in die vertikale Bar, geben Sie ihnen also Icons und halten Sie interaktive Inhalte innerhalb der Safe Area.

Ordnen Sie als Nächstes die Buttons über Ihrer Karte oder Web View mit unserem Leitfaden zur SwiftUI Toolbar in iOS 26, und arbeiten Sie dann die Checkliste zur iPhone Duo Vorbereitung durch. Was Apps mit der Faltung anfangen können, sehen Sie unter Built for the fold.

Häufige Fragen

Warum meldet SwiftUI „Cannot find 'Map' in scope“?

Map ist in einem Cross-Import Overlay von MapKit und SwiftUI deklariert, nicht in SwiftUI selbst. Der Compiler lädt dieses Overlay nur, wenn dieselbe Datei beide Module importiert, ergänzen Sie also import MapKit neben import SwiftUI.

Was ist ein Cross-Import Overlay in Swift?

Es ist ein verborgenes Modul wie _MapKit_SwiftUI, das APIs ergänzt, die zwei Frameworks gleichzeitig brauchen. Der Compiler importiert es automatisch, wenn eine Quelldatei beide Frameworks importiert, sodass keines der beiden Frameworks vom anderen abhängen muss.

Reicht es, MapKit in einer anderen Datei zu importieren?

Nein. Imports gelten pro Quelldatei, und das Overlay wird aus der Kombination der Imports in jeder Datei bestimmt. Jede Datei, die Map verwendet, braucht sowohl import SwiftUI als auch import MapKit.

Mit welcher iOS-Version kam die native WebView in SwiftUI?

WebView und der zugehörige Modelltyp WebPage sind neu in iOS 26.0 und gehören zu WebKit. Importieren Sie SwiftUI und WebKit, um sie zu verwenden. Auf älteren Versionen behalten Sie einen UIViewRepresentable-Wrapper um WKWebView.

Wie führe ich JavaScript in einer SwiftUI WebView aus?

Erstellen Sie eine WebPage, übergeben Sie sie an WebView, und rufen Sie try await page.callJavaScript mit Ihrem Skript auf. Das Ergebnis ist ein optionaler Any-Wert, casten Sie ihn also in den erwarteten Swift-Typ.

Quellen

  1. WebView · Apple Developer Documentation
  2. WebPage · Apple Developer Documentation
  3. Map · Apple Developer Documentation
  4. PhotosPicker · Apple Developer Documentation
  5. Meet WebKit for SwiftUI (WWDC25) · Apple Developer
  6. What's new in SwiftUI (WWDC25) · Apple Developer
  7. Meet MapKit for SwiftUI (WWDC23) · Apple Developer
  8. Cross-import overlays · Swift Forums
  9. Why some Swift types only appear when you import two modules · Sarunw
  10. SwiftUI has a native WebView in iOS 26 · Sarunw
  11. SwiftUI WebView · TrozWare (Sarah Reichelt)
  12. Cannot find Map in scope even though you imported SwiftUI? · @sarunw on X
  13. Map, PhotosPicker and WebView live in cross-import overlays · @sarunw on X
  14. SwiftUI finally has a native WebView in iOS 26 · @sarunw on X
  15. Pair WebView with WebPage · @sarunw on X

Machen Sie das Scharnier zum Teil Ihrer App.

Wir stellen Apps und Spiele vor, die mit dem iPhone Duo wirklich etwas anfangen. Schicken Sie uns Ihre mit einem Link zum App Store – oder sehen Sie sich an, was andere gebaut haben.

[email protected]