3.5 KiB
3.5 KiB
VSCode Migration — Technical Findings
Back to projects/vscode-migration/vscode-migration. Verified on Xcode 26.6 / Swift 6.3.3, Sep 2026.
App target readiness
- DMG and App Store targets compile identical sources (1398 files);
FEATURE_FLAGSis empty for the app — onlyDEBUGremains (SPM handles it). - No ObjC/C in
macOS/DuckDuckGo/, empty bridging header. - Unit Tests compile only 2 app files directly; the rest is
@testable import→ can switch to the library. - 46 app files are shared with helper targets (VPN 36, DBP agent 18, NetP extensions 14 each):
UserText.swift,UserDefaultsWrapper,ConfigurationManager,Subscription*,TipKit*,VPN*,DuckDuckGoUserAgent, … - Remaining Xcode-only resources: storyboards
PasswordManager,BookmarksBar,NavigationBar,Feedback+BookmarksBarCollectionViewItem.xib; 8.xcdatamodeldin the app, 3 in BSK.
Asset catalogs
- Xcode generates asset symbols with
actool --bundle-identifier … --generate-swift-asset-symbols X.swift. In that mode actool writes noAssets.car, so compiling is a second invocation (same as Xcode'sGenerateAssetSymbols+CompileAssetCatalog). - For package targets Xcode and
swiftbuildgenerateImageResource/ColorResourcesymbols but notNSImage.foo/NSColor.fooextensions. The app target uses extensions (e.g.NSImage.menuVertical16) → those call sites must change when moving into a package. - Native
swift build(also what SourceKit-LSP uses) neither compiles catalogs nor generates symbols. - Native SwiftPM resource bundles are flat and lack Info.plist; CoreUI ignores
Assets.carwithoutCFBundleIdentifier. - In Xcode's plugin sandbox actool fails for iOS ("No available simulator runtimes"); macOS works. So a plugin can't replace Xcode's processing on iOS.
- Plugin environment is identical for native and
swiftbuild→ can't tell them apart; Xcode is detectable by the/BuildToolPluginIntermediates/work dir. - Asset usage in the app catalog: ~415 via symbols, ~57 via string names, 20 only from storyboards, ~300 apparently unreferenced (heuristic).
Extensions in VSCode tasks
tasks.jsondependsOnhas no up-to-date check → needs a gate script (input hash viagit ls-files -s+ diff, stamp file).xcodebuildalways visits explicit target dependencies (planning, Provisional Inputs) even when nothing changed; no flag to skip. Gating extensions only pays off once the app is built withswift buildand assembled by a script.- Assemble: copy pre-signed extensions, sign the outer app last without
--deep; same Team ID; embed provisioning profiles for NetworkExtension entitlements; system extension activates only from/Applications. - Embedded: Login Items
DuckDuckGo VPN.app,DuckDuckGo Personal Information Removal.app; PlugInsNetworkProtectionAppExtension.appex,VPNProxyExtension.appex.
Toolchain
~/.swiftly/bin/swift(6.2) is first in PATH; it can't compile packages importing WebKit against the macOS 26 SDK. Usexcrun swift, and setswift.pathin VSCode to Xcode's toolchain.- Native builds rewrite stale
Package.resolvedfiles (e.g.SharedPackages/Onboarding) — don't commit those.
Pre-existing issues found
UIComponentsTests: macOS 15 API without@available(package min 12.3).PerformanceTestTests: reference removed types (CoreWebVitalsAssessment,averageResourceSize).DataBrokerProtectionCore: emptyDBP.xcassetsinside.copy("BundleResources")— dead, never compiled.