Geliştiriciler
SwiftUI'da "Cannot Find 'Map' in Scope" Hatası: Map ve WebView Import Çözümü
SwiftUI'da "Cannot find 'Map' in scope" çözümü: Map, PhotosPicker ve WebView neden ikinci bir import ister, WebView ve WebPage iPhone ve iPhone Duo'da nasıl çalışır.
AppleDuo EditörlüğüYayınlanma 6 dk okuma
Bu sayfada
- SwiftUI neden "Cannot find 'Map' in scope" diyor?
- Swift'te cross-import overlay nedir?
- Hangi SwiftUI view'ları ikinci bir import gerektirir?
- iOS 26'da SwiftUI'ın yerel WebView'u nasıl kullanılır?
- WebPage ile yükleme, navigasyon ve JavaScript nasıl takip edilir?
- iOS 26'dan önceki sürümler nasıl desteklenir?
- Haritalar ve web view'lar iPhone Duo'da özel bir şey gerektirir mi?
- Önemli çıkarımlar
Bir SwiftUI view'una harita eklersiniz, dosyada zaten import SwiftUI vardır ve Xcode "Cannot find 'Map' in scope" hatasıyla durur. Tür var, yazım doğru, deployment target da uygun. Aynı şey PhotosPicker ile ve SwiftUI'ın iOS 26'da kazandığı yerel WebView ile de olur. Çözüm tek bir import, ama ardındaki neden bütün bir hata ailesini açıklıyor.
Bu rehber hatanın neden ortaya çıktığını, cross-import overlay'in ne olduğunu, hangi view'ların ikinci bir import gerektirdiğini ve iOS 26 WebView'unun WebPage ile nasıl kullanılacağını anlatıyor. Apple'ın dokümantasyonuna ve WWDC oturumlarına, Swift Forums tasarım notlarına ve iOS geliştiricisi @sarunw'nin paylaşımlarına dayanıyor. WebView ve WebPage iOS 26.0 ile yeni geldi; ayrıntılar sürümler arasında değişebilir.
SwiftUI neden "Cannot find 'Map' in scope" diyor?
Çünkü Map SwiftUI'ın bir parçası değil. @sarunw'nin ifadesiyle, "Map bir cross-import overlay'de bulunur, bu yüzden hem SwiftUI'a hem MapKit'e ihtiyacınız var." Bu dosya derlenmez:
import SwiftUI
struct ContentView: View {
var body: some View {
Map() // error: cannot find 'Map' in scope
}
}
Bir satır ekleyin, derlenir:
import SwiftUI
import MapKit
struct ContentView: View {
var body: some View {
Map()
}
}
Apple'ın Map dokümantasyonu onu MapKit altında listeliyor ve bir SwiftUI view'u olarak tanımlıyor. Sembolün dahili adı onu ne MapKit ne de SwiftUI olan _MapKit_SwiftUI adlı bir modüle yerleştiriyor. Bu üçüncü modül overlay'in ta kendisi.
İki ayrıntı hatayı fark etmeyi zorlaştırıyor. Derleyici mesajı eksik bir import'tan söz etmiyor; ayrıca @sarunw'nin cross-import overlay'ler hakkındaki makalesinde belirttiği gibi Xcode'un otomatik tamamlaması, yüklenmemiş bir modüldeki bir türü öneremez. Yani Map tamamlama önerilerinde de görünmez.
Swift'te cross-import overlay nedir?
Cross-import overlay, bir kaynak dosya belirli iki modülü import ettiğinde derleyicinin otomatik olarak import ettiği bir modüldür. Swift Forums'taki tasarım tartışması, overlay'lerin "bir kaynak dosyadaki import kombinasyonuna" göre seçildiğini anlatıyor. Overlay, declaring module denen ilk framework'ü yeniden dışa aktarır ve bystanding module denen ikinci framework'e de ihtiyaç duyan API'yi ekler.
Neden Map doğrudan SwiftUI'a veya MapKit'e konmuyor? Map bir View olduğu için SwiftUI'a, MapKit türleriyle çalıştığı için de MapKit'e ihtiyaç duyar. Onu iki framework'ten birine koymak, birini kullanan her uygulamanın diğerini de yüklemesine yol açardı. Overlay ise yalnızca bir dosya ikisini de istediğinde yüklenir.
Mekanizmayı SDK'da görebilirsiniz. @sarunw'ye göre overlay'leri olan bir framework, Modules dizininde her partner modül için küçük bir dosya içeren bir .swiftcrossimport klasörüyle gelir:
SDK=$(xcrun --sdk iphonesimulator --show-sdk-path)
cd "$SDK/System/Library/Frameworks/MapKit.framework/Modules"
ls MapKit.swiftcrossimport
cat MapKit.swiftcrossimport/SwiftUI.swiftoverlay
SwiftUI.swiftoverlay dosyası, overlay modülünün adını, yani _MapKit_SwiftUI'ı veren kısa bir YAML dosyasıdır. @sarunw, iOS 26 SDK'da 36 cross-import overlay sayıyor.
Bunun günlük işte önemli bir sonucu var: import'lar dosya bazındadır. MapKit'i uygulamanızın giriş noktasında import etmek, yalnızca SwiftUI'ı import eden başka bir dosyada Map'i kullanılabilir yapmaz. View'u kullanan her dosyanın iki import'a da ihtiyacı vardır.
Hangi SwiftUI view'ları ikinci bir import gerektirir?
@sarunw'nin pratik kuralı: türün bağlı olduğu iki framework'ü bulun ve ikisini de import edin. Yaygın olanlar, Apple dokümantasyonundaki kullanılabilirlik bilgileriyle birlikte şunlar:
| SwiftUI API'si | Ayrıca import edin | Kullanılabildiği sürüm |
|---|---|---|
Map, Marker, Annotation | MapKit | iOS 14 (Map); harita içeriği için iOS 17 |
PhotosPicker | PhotosUI | iOS 16 |
WebView | WebKit | iOS 26 |
VideoPlayer | AVKit | iOS 14 |
SubscriptionStoreView | StoreKit | iOS 17 |
SpriteView | SpriteKit | iOS 14 |
SignInWithAppleButton | AuthenticationServices | iOS 14 |
Apple'ın dokümantasyonu bu sembollerin her birini hem kendi framework'üne hem SwiftUI'a ait olarak kaydediyor. @sarunw'nin makalesi daha fazla çift ekliyor: StoreKit ile ProductView, QuickLook ile .quickLookPreview(_:), SceneKit ve RealityKit ile SceneView ve RealityView, Translation ile .translationPresentation ve SwiftData ile .modelContainer.
Yani SwiftUI'a benzeyen bir tür için "Cannot find 'X' in scope" gördüğünüzde, bir yazım hatasından veya kullanılabilirlik sorunundan şüphelenmeden önce eksik bir ikinci import olup olmadığını kontrol edin. Map içinde Marker ve Annotation kullanılan MapKit content-builder API'si, Apple'ın Meet MapKit for SwiftUI oturumuyla birlikte iOS 17'de geldi.
iOS 26'da SwiftUI'ın yerel WebView'u nasıl kullanılır?
iOS 26'dan önce SwiftUI'da bir web sayfası göstermek, WKWebView'u bir UIViewRepresentable içine sarmak demekti. @sarunw'nin ifadesiyle, "SwiftUI'ın iOS 26'da nihayet yerel bir WebView'u var." Apple'ın What's new in SwiftUI oturumu onu, Safari gibi WebKit ile çalışan, "uygulamanızda web içeriği göstermek için yeni bir SwiftUI view'u" olarak tanımlıyor.
WebView de bir cross-import overlay türü. Apple'ın WebView dokümantasyonu onu WebKit ve SwiftUI altında listeliyor ve örnekleri iki import ile başlıyor. Bir kullanım koşulları sayfası veya bir yardım makalesi için URL initializer'ı yeterli:
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:) opsiyonel bir URL alır ve sayfadaki bağlantılar bir tarayıcıdaki gibi çalışır. Apple, bir WebView'un bir ScrollView gibi kaydığını ve scrollBounceBehavior(_:axes:) kabul ettiğini belirtiyor. WebKit, webViewBackForwardNavigationGestures(_:), webViewLinkPreviews(_:), webViewTextSelection(_:) ve webViewContentBackground(_:) gibi modifier'lar ekliyor. Apple'ın Meet WebKit for SwiftUI oturumuna göre mevcut findNavigator(isPresented:) modifier'ı sayfada bulma özelliğini ekliyor.
WebPage ile yükleme, navigasyon ve JavaScript nasıl takip edilir?
URL initializer'ı size sayfa hakkında hiçbir şey söyleyemez. Başlığa, ilerlemeye veya JavaScript'e ihtiyaç duyduğunuzda @sarunw'nin önerisi "WebView'u WebPage ile eşleştirmek." Apple'ın WebPage dokümantasyonu onu etkileşimli web içeriğini kontrol eden ve yöneten Observable bir sınıf olarak tanımlıyor. Onu @State içinde tutun ve WebView(_:)'a verin:
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")!))
}
}
}
WebPage observable olduğu için başlık ve ilerleme çubuğu, bir delegate veya coordinator olmadan kendiliğinden güncellenir. Apple'ın dokümantasyonu bir WebPage'in aynı anda yalnızca bir WebView'a bağlanabileceğini ekliyor. İlk başvuracağınız üyeler şunlar:
| WebPage üyesi | Size ne verir |
|---|---|
title, url | Sayfa başlığı ve geçerli URL |
isLoading, estimatedProgress | Yükleme durumu ve 0 ile 1 arasındaki ilerleme |
themeColor | Sayfanın theme-color meta etiketindeki renk |
backForwardList | Bir öğesini yükleyebileceğiniz geçmiş |
load(_:), load(html:baseURL:) | Olaylardan oluşan async bir sequence döndüren navigasyon |
callJavaScript(_:arguments:in:contentWorld:) | JavaScript çalıştırıp sonuç alma |
Her load çağrısı navigasyon olaylarından oluşan async bir sequence döndürür. Apple'ın oturumuna göre bir navigasyon startedProvisionalNavigation ile başlar, ardından tamamlanır veya başarısız olur. Bir sayfanın bitmesini beklemeniz gerektiğinde sequence'i for try await ile dolaşın ya da bir view'dan currentNavigationEvent değerini okuyun.
JavaScript için callJavaScript, async throws olup opsiyonel bir Any döndürür. arguments sözlüğündeki anahtarlar betikte yerel değişkenlere dönüşür:
let heading = try await page.callJavaScript(
"return document.querySelector(selector)?.textContent",
arguments: ["selector": "h1"]
) as? String
Navigasyonlara izin vermek veya onları engellemek için bir türü WebPage.NavigationDeciding'e uygun hale getirip WebPage(configuration:navigationDecider:)'a verin. Apple'ın oturumu, URLSchemeHandler protokolü üzerinden özel URL şemalarını da ele alıyor.
iOS 26'dan önceki sürümler nasıl desteklenir?
WebView ve WebPage iOS 26 veya üstünü gerektirir. Deployment target'ınız daha düşükse, @sarunw'nin önerdiği gibi bir WKWebView sarmalayıcısını koruyun ve çalışma zamanında seçim yapın:
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))
}
}
Dosyanın yine hem import SwiftUI hem import WebKit içermesi gerekir. Eski yol, SwiftUI view'u her güncellediğinde yeniden yükleme yapar; bu yüzden gerçek bir uygulamada load çağırmadan önce geçerli URL'yi karşılaştırın. Bir geliştirici, Sarah Reichelt, oturumdaki navigasyon takibi örneğinin sonraki iOS 26 betalarında derlenmeyi bıraktığını fark etti; bu yüzden örnekleri kendi Xcode sürümünüzle doğrulayın.
Haritalar ve web view'lar iPhone Duo'da özel bir şey gerektirir mi?
Import'lar her iPhone'da aynı şekilde çalışır, ama iPhone Duo bu view'ların yaşadığı alanı değiştirir.
- Açıkken daha fazla alan. iPhone Duo size class'ları rehberimizde açıklandığı gibi iç ekran iki yönde de regular genişlik ve regular yükseklik bildirir. Bir harita veya web view, bir yığına itilmek yerine bir
NavigationSplitView'da bir listenin yanında durabilir. - Toolbar düğmeleri taşınır. Yukarıdaki Reload düğmesi gibi
.toolbarile birWebView'a veyaMap'e eklediğiniz düğmeler, iOS 27.1 SDK ile derlediğinizde dikey bar'a geçer. iPhone Duo dikey toolbar rehberimizin önerdiği gibi onlara bir sembol ve bir başlık verin. iOS 26 toolbar rehberimiz bu düğmelerin gruplanmasını ele alıyor. - Kenardan kenara içerik. Apple'ın örneği bir
WebView'a.ignoresSafeArea()uyguluyor. iPhone Duo'da dikey bar yalnızca bir tarafa inset ekler. Safe area rehberimizdeki Apple önerisi, arka planların bar'ların altına uzanabileceği, ancak etkileşimli öğelerin içeride kalması gerektiği yönünde. Bir web sayfası bağlantılarla doludur; bu yüzden o kenarı yok saymadan önce içeriğinin bar'dan uzak kaldığını kontrol edin. - Kat yeri. Özel bir düğme gibi bir haritanın üzerine çizdiğiniz her overlay kontrolü katlanma yerinden uzak durmalı. Katlanma yerindeki reserved region'lar rehberimiz onu nasıl bulacağınızı gösteriyor.
Önemli çıkarımlar
- "Cannot find 'Map' in scope" eksik bir ikinci import anlamına gelir:
import SwiftUI'ın yanınaimport MapKitekleyin. Map,PhotosPickerveWebView, yalnızca bir dosya iki framework'ü de import ettiğinde yüklenen_MapKit_SwiftUIgibi gizli modüller olan cross-import overlay'lerde bulunur.- Import'lar dosya bazındadır; bu yüzden view'u kullanan her dosyanın ikisine de ihtiyacı vardır.
- iOS 26, WebKit'te yerel bir
WebViewekliyor. Basit sayfalar içinWebView(url:), başlık, ilerleme, navigasyon vecallJavaScriptiçin birWebPageileWebView(page)kullanın. - Eski hedefler için
if #available(iOS 26.0, *)arkasında birWKWebViewsarmalayıcısı tutun. - iPhone Duo'da haritaların ve web view'ların üzerindeki toolbar öğeleri dikey bar'a taşınır; bu yüzden onlara ikon verin ve etkileşimli içeriği safe area içinde tutun.
Sırada, haritanızın veya web view'unuzun üzerindeki düğmeleri iOS 26'da SwiftUI toolbar rehberimizle düzenleyin, ardından iPhone Duo hazırlık kontrol listesini uygulayın. Uygulamaların menteşeyle neler yapabildiğini görmek için Built for the fold sayfasına göz atın.
Sık sorulan sorular
SwiftUI neden cannot find Map in scope diyor?
Map, SwiftUI'ın kendisinde değil MapKit ve SwiftUI'ın bir cross-import overlay'inde tanımlanır. Derleyici bu overlay'i yalnızca aynı dosya iki modülü de import ettiğinde yükler; bu yüzden import SwiftUI'ın yanına import MapKit ekleyin.
Swift'te cross-import overlay nedir?
Aynı anda iki framework'e ihtiyaç duyan API'leri ekleyen, _MapKit_SwiftUI gibi gizli bir modüldür. Derleyici, bir kaynak dosya iki framework'ü de import ettiğinde onu otomatik olarak import eder; böylece framework'lerin hiçbiri diğerine bağımlı olmak zorunda kalmaz.
MapKit'i başka bir dosyada import etmek yeterli mi?
Hayır. Import'lar her kaynak dosya için ayrı geçerlidir ve overlay, her dosyadaki import kombinasyonuna göre seçilir. Map kullanan her dosyada hem import SwiftUI hem import MapKit gerekir.
SwiftUI'ın yerel WebView'u hangi iOS sürümüyle geldi?
WebView ve model türü WebPage, iOS 26.0 ile yeni geldi ve WebKit'in bir parçası. Kullanmak için SwiftUI ve WebKit'i import edin. Daha eski sürümlerde WKWebView etrafındaki UIViewRepresentable sarmalayıcıyı koruyun.
Bir SwiftUI WebView'da JavaScript nasıl çalıştırılır?
Bir WebPage oluşturun, onu WebView'a verin ve betiğinizle try await page.callJavaScript çağırın. Sonuç opsiyonel bir Any değeridir; bu yüzden onu beklediğiniz Swift türüne cast edin.
Kaynaklar
- WebView · Apple Developer Documentation
- WebPage · Apple Developer Documentation
- Map · Apple Developer Documentation
- PhotosPicker · Apple Developer Documentation
- Meet WebKit for SwiftUI (WWDC25) · Apple Developer
- What's new in SwiftUI (WWDC25) · Apple Developer
- Meet MapKit for SwiftUI (WWDC23) · Apple Developer
- Cross-import overlays · Swift Forums
- Why some Swift types only appear when you import two modules · Sarunw
- SwiftUI has a native WebView in iOS 26 · Sarunw
- SwiftUI WebView · TrozWare (Sarah Reichelt)
- Cannot find Map in scope even though you imported SwiftUI? · @sarunw on X
- Map, PhotosPicker and WebView live in cross-import overlays · @sarunw on X
- SwiftUI finally has a native WebView in iOS 26 · @sarunw on X
- Pair WebView with WebPage · @sarunw on X
Katlanmayı uygulamanızın bir parçası yapın.
iPhone Duo ile gerçekten bir şey yapan uygulama ve oyunları tanıtıyoruz. App Store bağlantısıyla sizinkini gönderin ya da diğer geliştiricilerin neler yaptığına bakın.