Skip to main content
Version: 1.x (beta)

Migrating to v1

Move an app from a 0.x Wemap SDK to 1.0, step by step.

Overview​

v1 replaces four things across every framework:

  • Static singletons → per-instance sessions. WemapCore.shared and WemapMap.shared are gone; a WemapCoreSDK/CoreSession or WemapMapSDK/MapSession loads the map data and is shared by the views and location sources of one screen.
  • Global mutable constants → immutable configs. CoreConstants, MapConstants, ARConstants and the VPS constants are replaced by value-type Config structs, fixed at creation time.
  • Delegates → AsyncStream. Every *Delegate protocol on a manager or a location source is removed in favour of a read-only stream property.
  • Combine → Swift Concurrency. No public API returns an AnyPublisher any more; calls are async and/or throws.

Work through the steps in order. Each step leaves the project compiling, so you can stop and test between them. Steps 1–7 apply to every app; the rest depend on what your 0.x code uses — search your project for the symbols on the left.

If your project containsAlso read
VPSARKitLocationSource, GPSLocationSource, or any *Constants from a positioning SDK8 · positioning
PackdataManaging, downloadPackdata(mapID:)9 · offline maps
GeoARView, GeoARViewDelegate, ARConstants10 · GeoAR
your own type conforming to LocationSource11 · custom location source
a symbol that still fails to compile after 1–1112, then § "I'm getting this error"
  • Effort: a few hours for a map-only app; closer to a day for an app with VPS positioning or a custom location source.
  • Toolchain: Xcode 26.0 / Swift 6.2 and iOS 15.0 are now the minimum — see Getting started § Requirements.

Tip: If you are migrating an Android app in parallel, the Android guide uses the same step numbering.

1 · Update the dependency​

Rule: move to the latest 1.x release and raise your toolchain floor.

Take the version itself — and the transitive dependency versions that come with it — from the releases page. This guide deliberately does not repeat them, so that it stays correct as 1.x moves on.

Two floors changed in v1, and they block the build before anything else does:

  • Xcode 26.0 / Swift 6.2. The SDKs ship as binary XCFrameworks, which only the toolchain that built them and newer can consume. SPM refuses the package outright; CocoaPods fails later, in the compiler.
  • iOS 15.0 deployment target, raised from 13.0.

The Map SDK's public API now exposes MapLibre 6.x types, so a pinned older MapLibre will not satisfy it.

2 · Create a session​

Rule: wherever you reached a singleton or passed a MapData, create one session per screen and pass it in.

// before
WemapMap.shared.getMapData(mapID: 19158, token: "TOKEN")
.sink(receiveCompletion: { _ in }) { mapData in
let mapView = MapView(frame: view.bounds)
mapView.mapData = mapData
}
.store(in: &cancellables)

// after
let session = try await MapSession(mapID: 19158, token: "TOKEN", config: SessionConfig(environment: .prod))
let mapView = MapView(frame: view.bounds, session: session, config: MapViewConfig())

Share the same session across a screen's WemapMapSDK/MapView, WemapGeoARSDK/GeoARView and location sources — that is what keeps navigation, POI selection and user location consistent. A second map needs its own session.

CoreSession(mapID:token:config:) and MapSession(mapID:token:config:) are both async throws; offline maps use MapSession(offlineZip:config:) (see step 9).

Removed: WemapCore.shared, WemapCore.setEnvironment, WemapCore.setItinerariesEnvironment, WemapMap.shared, WemapMap.getMapData(mapID:token:), ServiceFactory, DependencyManager.

Initializer mapping:

v0.xv1.0
MapView(frame:) + mapDataMapView(frame:session:config:)
GeoARView(frame:options:) + mapDataGeoARView(frame:session:config:)
VPSARKitLocationSource(mapData:) / (serviceURL:)try VPSARKitLocationSource(session:config:)
GPSLocationSource(mapData:)GPSLocationSource(session:)
SimulatorLocationSource(mapData:options:) / (options:)SimulatorLocationSource(session:options:)
Interface BuildermapView.configure(with:config:) / geoARView.configure(with:config:)

Watch out: MapData is no longer public. Read map metadata from the session — session.mapID, session.mapCenter, session.isVPSEnabled. MapView.mapData and GeoARView.mapData are gone, and MapServicing with them — the session resolves map metadata itself.

3 · Pass configs instead of setting globals​

Rule: every value you used to assign to a *Constants static is now a let property of a config struct, built in one initializer call and passed at creation time. There is no global mutable configuration left.

// before
CoreConstants.itineraryRecalculationEnabled = false
MapConstants.staleStateTimeout = 10 // TimeInterval

// after
let session = try await MapSession(
mapID: 19158, token: "TOKEN",
config: SessionConfig(itineraryRecalculationEnabled: false, environment: .dev)
)
let mapView = MapView(frame: view.bounds, session: session, config: MapViewConfig(staleStateTimeout: .seconds(10)))
v0.xv1.0Passed to
CoreConstants staticsSessionConfigCoreSession.init / MapSession.init
WemapCore.setEnvironment(_:)SessionConfig.environmentCoreSession.init / MapSession.init
WemapCore.setItinerariesEnvironment(_:)SessionConfig.directionsEnvironmentCoreSession.init / MapSession.init
MapConstants staticsMapViewConfigMapView.init / configure(with:config:)
ARConstants + ARConstants.DirectionalArrowGeoARViewConfig + GeoARViewConfig.DirectionalArrowGeoARView.init / configure
VPSARKitConstants, VPSControllerConstants, StateManagerConstantsVPSConfig — see step 8VPSARKitLocationSource.init

Renames and shape changes to expect while you move the values across:

  • MapViewConfig.staleStateTimeout is a DispatchTimeInterval, not a TimeInterval.
  • GeoARViewConfig.stepInstructionAltitude fixes the old stepInstuctionAltitude spelling, and navigationVisibilityDistance is now optional.
  • MapConstants keeps only wemapBlue; ARConstants is no longer public at all.
  • Environment lost domain and name.
  • CoreConstants.itinerariesHost / itinerariesBaseURL were stored and settable; the SessionConfig properties that replace them are computed from directionsEnvironment, so they can no longer disagree with it.

Watch out: every config property is let. Build the config you want in one init call — there is nothing to assign to afterwards, by design.

4 · Update your Coordinate and level usage​

Rule: WemapCoreSDK/Coordinate is an immutable struct built around CLLocationCoordinate2D — it no longer wraps a CLLocation — and levels are a WemapCoreSDK/Levels value rather than [Float].

// before
let coordinate = Coordinate(location: someCLLocation, levels: [0, 1])
let heading = coordinate.direction
let location = coordinate.location

// after
let coordinate = Coordinate(coordinate2D: someCLLocation.coordinate, levels: .range(0...1))
let heading = coordinate.bearing
let location = coordinate.toLocation()
v0.xv1.0
levels: [Float] (empty meant outdoor)levels: Levels (.outdoor by default)
Coordinate(location:levels:heightFromFloor:heightFromGround:)Coordinate(coordinate2D:levels:altitude:bearing:horizontalAccuracy:timestamp:heightFromFloor:heightFromGround:)
directionbearing
location: CLLocationtoLocation()
ShortStringConvertible / shortDescriptionCustomCompactStringConvertible / compactDescription

Levels has .outdoor, .single(_:) and .range(_:) (a ClosedRange<Float>), plus init(array:), union, contains, intersects, intersection and diff. Segment.levels is a Levels too.

horizontalAccuracy is a stored CLLocationAccuracy and timestamp a stored Date.

Removed: cartesian, ecef, ecefToEnuRot, enuToEcefRot, ecefToEusRot, eusToEcefRot and the copy(…) overloads.

compactDescription replaces shortDescription on Coordinate, Itinerary, ItinerarySearchRules, NavigationInfo, NavigationOptions, PointOfInterest, PointOfInterestType, TravelMode, ItineraryOptions and LineOptions.

Level moved from Core to the Map SDK and is a struct instead of an @objc final class; LevelData and LevelUtils went with it. Import WemapMapSDK where you used to get Level from Core.

Watch out: toLocation() allocates a fresh CLLocation on every call — hold the result rather than calling it in a loop.

5 · Replace delegates with AsyncStream​

Rule: delete the delegate conformance and consume the stream of the same name in a Task.

// before
mapView.pointOfInterestManager.delegate = self
func pointOfInterestManager(_ manager: PointOfInterestManager, didSelectPointOfInterest poi: PointOfInterest) { … }

// after — take the stream out of the manager *before* the task, so the task captures the stream, not the manager
let selectionUpdates = mapView.pointOfInterestManager.selectionUpdates
observationTasks = [
Task { [weak self] in
for await update in selectionUpdates {
guard let self else {
return
}
handle(update)
}
}
]
v0.x delegatev1.0 streams
LocationSourceDelegatecoordinates / attitudes / errors
NavigationManagerDelegatenavigationEvents (NavigationEvent) / navigationInfoUpdates / errors
PointOfInterestManagerDelegateselectionUpdates (PointOfInterestSelectionUpdate) / touchedPOIs
BuildingManagerDelegatefocusedBuildings / activeLevelChanges / errors
UserLocationManagerDelegate, ARLocationManagerDelegatecoordinates / attitudes / errors
MapViewDelegatesee step 7
VPSARKitLocationSourceDelegatesee step 8

Also removed: the publishers bridges — MapView.publishers, VPSARKitLocationSource.publishers, MapViewDelegatePublishers, VPSARKitLocationSourceDelegatePublishers. coordinatePublisher is coordinates.

UserLocationManager and ARLocationManager now conform to the read-only UserLocationProviding, renamed from LocationProviding.

Watch out: never write for await x in mapView.someManager.someStream. That captures the manager — and through it the view — for as long as the task runs, so the owner's deinit never runs, and deinit is what cancels the task: the leak keeps itself alive. Extract the stream into a local first, capture [weak self], and return — not continue — once self is gone. Hold the tasks (observationTasks above) and cancel them on teardown.

6 · Await instead of subscribing​

Rule: an AnyPublisher-returning call is now async and/or throws and returns its value directly.

// before
mapView.navigationManager.startNavigation(to: destination)
.sink(receiveCompletion: { … }, receiveValue: { navigation in … })
.store(in: &cancellables)

// after
let navigation = try await mapView.navigationManager.startNavigation(to: destination)

Calls that changed shape: ItineraryProviding.itineraries(…), ruleNames(), itinerariesInfoToMultipleDestinations(…), PointOfInterestServicing.pointsOfInterest(…), PointOfInterestManaging.sortPOIsByGraphDistance(…) / sortPOIsByDuration(…), ItineraryManager.searchRuleNames(), MapNavigationManaging.startNavigation(…), ARNavigationManaging.startNavigation(…), VPSARKitLocationSource.isVPSAvailable(at:) and distanceToVPSCoverage(from:).

Removed with Combine: Signal, EventPublisher, PassthroughRelay, CurrentValueRelay, Just.any(_:), Empty.any(…), Empty.never(), Fail.any(…).

Renames and signature changes on the same call sites:

v0.xv1.0
ItineraryService, ItineraryServiceErrorDirectionsService, DirectionsServiceError (gained graphUnavailable and requestFailed(code:reason:); noItinerariesFound gained reason)
ItineraryServicingrenamed DirectionsServicing and no longer public
ItineraryProviding.graph(id:), ruleNames(graphId:)graph(), ruleNames()
itineraries(…mapId:)itineraries(…) — no mapId
itinerariesInfoToMultipleDestinations(origin:pois:mapID:)(origin:destinations:travelMode:searchRules:), taking [Coordinate] and returning [CoordinateWithItineraryInfo] — the POI-based call is now itinerariesInfoToMultiplePOIs(origin:pois:…)
PointOfInterestServicing.pointsOfInterestList(mapID:limit:)pointsOfInterest(limit:)
PointOfInterestWithInfo (typealias)PointOfInterestWithItineraryInfo
PointOfInterestManaging.getPOIs()getAllPOIs()
PointOfInterestManager.SelectionModePointOfInterestSelectionMode
ItineraryManager.itineraries, getItineraries(…)drawnItineraries, computeItineraries(…)
ItineraryManager.searchRuleNames(graphId:)searchRuleNames()
NavigationManaging.infoUpdatesTimeIntervalnavigationInfoUpdatesInterval
MapView.map (WemapMap)removed with the type
Building.isEqual(_:) / hashHashable / hashValue; levels is read-only
Logger.d/i/v/e/fsame, plus a privacy parameter; Logger.category is read-only

ItineraryManager.addItinerary(_:options:) returns Bool instead of (inserted:memberAfterInsert:), and removeItinerary(_:) returns Bool instead of Itinerary?. startNavigation overloads take an additional userTrackingMode, and their itineraryOptions parameter is optional — nil preserves the current options. MapPointOfInterestManaging.selectPOI(…) and centerToPOI(…) take an optional zoom.

Watch out: the SDK builds in Swift 6 language mode. The view and manager surfaces are @MainActor without @preconcurrency, so a call from a non-isolated context no longer compiles implicitly — hop to the main actor explicitly. LocationSource, UserLocationProviding, ItineraryProviding and PointOfInterestServicing gained a Sendable requirement (see step 11).

7 · Views: LoadPhase and non-optional managers​

Rule: wait for the view with awaitLoaded() (or observe loadPhases), then use its managers without optional handling.

// before
mapView.mapDelegate = self
func mapViewLoaded(_ mapView: MapView, style: MLNStyle, data: MapData) {
mapView.navigationManager?.startNavigation(…)
}

// after
try await mapView.awaitLoaded()
mapView.navigationManager.startNavigation(…) // no optional, no `if let`

MapViewDelegate is removed. MapView reports loading through loadPhase / loadPhases (LoadPhase) and awaitLoaded(), and taps that selected no POI through touchedPoints. MapView.isLoaded and MapView.mapDelegate are gone with it. mapViewLoaded(_:style:data:) has no replacement payload: MapData is no longer public, and MapView.style is non-nil from .ready onward.

Every late-initialized member of both views is a plain non-optional property, and misuse is reported with a diagnostic naming the property instead of "Unexpectedly found nil while unwrapping an Optional value":

  • WemapMapSDK/MapView: session, config, pointOfInterestManager, navigationManager, buildingManager, itineraryManager, userLocationManager
  • WemapGeoARSDK/GeoARView: session, config, pointOfInterestManager, navigationManager, locationManager

map.navigationManager.startNavigation(…) is unaffected, but if let manager = map.navigationManager and map.navigationManager?.… no longer compile — drop the optional handling and gate the access on awaitLoaded() or loadPhases instead.

Failures are now reported. A map that fails to load settles .failed; in v0.x it logged mapViewDidFailLoadingMap, told nobody, and left awaitLoaded() suspended forever. A points-of-interest download failure settles .failed as well, and in that case every manager stays usable, exactly as before.

MapView.initialCamera sets the camera the map opens at, in place of the one derived from the map data. It is handed over rather than applied — the camera needs a laid-out view — so set it before the view is laid out; a later assignment is ignored and logged. MapView.isInitialCameraApplied / awaitInitialCamera() report when it has been applied; it is not part of LoadPhase.

Watch out: isLoaded was true after a failure too, so its closest equivalent is !loadPhase.isLoading — not loadPhase.isReady.

Watch out: one view of each kind per session. A session holds one map renderer and one AR renderer slot, so a second MapView on the same session evicts the first, which keeps drawing while no manager drives it.

8 · If you use positioning (VPS or GPS)​

Rule: construct the source with the session and a VPSConfig, and consume its streams instead of a delegate.

// before
VPSControllerConstants.backgroundScanDistanceThreshold = 20
let source = VPSARKitLocationSource(mapData: mapData)
source.vpsDelegate = self

// after
let source = try VPSARKitLocationSource(
session: session,
config: VPSConfig(controller: VPSControllerConfig(backgroundScanDistanceThreshold: 20))
)
let states = source.states // out of the source before the task, as in step 5
observationTask = Task { [weak self] in
for await state in states {
guard let self else {
return
}
handle(state)
}
}

VPSARKitLocationSource.init(session:config:) throws. VPSConfig composes VPSLocationSourceConfig, VPSControllerConfig, VPSStateManagerConfig, VPSStaticPositionDetectorConfig and VPSConveyingDetectorConfig — under the labels locationSource:, controller:, stateManager:, staticPositionDetector: and conveyingDetector: — replacing VPSARKitConstants, VPSControllerConstants and StateManagerConstants.

VPSARKitLocationSourceDelegate is removed in favour of states, scanStatuses, backgroundScanStatuses, cameraTrackingStates, userLocalizationUpdates and errors. delegate, vpsDelegate, attitudeDelegate, captureDelegate, observer and delegateQueue are gone with it.

Other changes:

v0.xv1.0
VPSARKitLocationSourceError.failedToConvertUIImageToPNGDatafailedToConvertUIImageToData (and a new noVPSEndpoint case)
VPSARKitLocationSourceObserver, willSendImageremoved
DegradedPositioningReason.vpsTrackingInterruptedremoved
TrackingState / WorldMappingStatus / DegradedPositioningReason.Reason / UIDeviceOrientation helpers description / isStable / isTrackingremoved
GPSLocationSource(mapData:)GPSLocationSource(session:); isAvailable is read-only

VPSARKitLocationSource no longer conforms to AttitudeSource, CameraCaptureProviding, ConveyingDetecting or NavigationManagerInterceptor, and attitudeAccuracy / buffersPublisher were removed. GeoJsonItinerary moved here from Core.

9 · If you use offline maps​

Rule: get a packdata service from the session, then open the downloaded package as a session.

// before
let manager: PackdataManaging = …
manager.downloadPackdata(mapID: 19158)
.flatMap { manager.loadMapData(fromZip: $0.fileURL) }
.sink { mapData in … }
.store(in: &cancellables)

// after
let service = MapSession.createPackdataService(mapID: 19158, environment: .prod)
let packdata = try await service.downloadPackdata()
let session = try await MapSession(offlineZip: packdata.fileURL)
v0.xv1.0
PackdataManagingPackdataServicing, from MapSession.createPackdataService(mapID:environment:)
downloadPackdata(mapID:), isNewPackdataAvailable(mapID:eTag:)downloadPackdata(), isNewPackdataAvailable(eTag:) — mapID is bound at construction
loadMapData(fromZip:)MapSession(offlineZip:config:)

Packdata still carries fileURL, eTag, version and fileName.

10 · If you use GeoAR​

Rule: same as the map — session in, loadPhase out, GeoARViewConfig for the tunables.

GeoARViewDelegate is removed, together with GeoARView.isLoaded and GeoARView.viewDelegate. GeoARView reports loading through loadPhase / loadPhases (LoadPhase) and awaitLoaded(), the same surface as MapView — so geoARViewLoaded(_:mapData:) has no replacement callback at all.

ARConstants and ARConstants.DirectionalArrow became GeoARViewConfig and GeoARViewConfig.DirectionalArrow — see step 3. ARPointOfInterestManaging.isFixedSize moved off PointOfInterestManager onto the protocol. UIInterfaceOrientation.description was removed.

SceneKit is no longer part of the AR view's API. GeoARView is a UIView instead of an SCNView, and GeoARView.camera, .geoScene and .rootNode are gone with GeoCamera, GeoEntity and GeoNode — the scene graph is now an implementation detail, so a future renderer change costs you nothing. The options parameter went with them: GeoARView(frame:session:config:), GeoAR(session:config:makeARView:) and the makeARView closure take no [String: Any]. Nothing replaces the removed members; if you were reading the scene graph, tell us what for.

Watch out: on the Interface Builder path the config goes into the configure(with:config:) call itself. There is no settable config property to assign after the fact, and configure only runs once — a second call is ignored.

11 · If you implement a custom LocationSource​

Rule: publish coordinates through streams instead of a delegate. The assignment point does not change.

// before
final class MyLocationSource: LocationSource {
weak var delegate: LocationSourceDelegate?
var supportsHeading: Bool { true }
func report(_ c: Coordinate) { delegate?.locationSource(self, didUpdateCoordinate: c) }
}

// after
@MainActor
final class MyLocationSource: LocationSource {
static var isAvailable: Bool { true }
var coordinates: AsyncStream<Coordinate> { … }
var attitudes: AsyncStream<Attitude> { … }
var errors: AsyncStream<Error> { … }
var supportsAttitude: Bool { true }
var isStarted: Bool { … }
func start() { … }
func stop() { … }
}
v0.xv1.0
LocationSource.delegate (LocationSourceDelegate)coordinates / attitudes / errors
LocationSource.supportsHeadingsupportsAttitude
SimulationOptions.simulateHeadingsimulateAttitude

Assign the source exactly as before — mapView.userLocationManager.locationSource for the map, and geoARView.locationManager.locationSource for AR.

WemapCoreSDK/LocationSource is @MainActor and refines AnyObject, Sendable, so the conformance carries Sendable for you — but the type has to actually satisfy it. UserLocationProviding, ItineraryProviding and PointOfInterestServicing gained the same requirement.

Watch out: a source your app starts stays your app's to stop. The SDK reference-counts its own start and stop requests, so a view disabling its location component no longer stops a source it did not start.

12 · Symbols that are no longer public API​

Rule: these were public in 0.x and are not part of the supported surface any more. There is no customer-facing replacement for any of them — if your app uses one, plan the migration off it.

Some exist only for cross-module needs inside the SDK now. They are excluded from this documentation, and reaching one fails to compile with "is inaccessible due to '@_spi' protection level":

MapData, CoreConstants, DataStore, Graph with Vertex / Edge, LocationProcessor, NavigationManager, PointOfInterestManager, ItineraryProvider, ServiceBase / RemoteServiceBase / LocalServiceBase, FileServicing, AttitudeSource with SystemAttitudeSource, ConveyingDetecting with ConveyingBuffer, NavigationRendering, PointOfInterestRendering, NavigationManagerInterceptor, CameraCaptureDelegate / CameraCaptureProviding with ViewParameters, InstructionKey, Inclination, Status, HTTPMethod / HTTPHeaders / HTTPHeader / URLRequestConvertible, Attribute, Validator, Math, GeoUtils, GeoConstants, JSONBodyEncoder / QueryEncoder, Zip with ZipError, VisualDebugger, MapPointOfInterestManaging.defaultZoom, Coordinate.equals(…), ARConstants, LocalPose with MatF4x4, and the GeoARView camera-provider members.

Removed outright, with no replacement: toDispatchTimeInterval(), toUnix(), allPerform(_:), filterPolygons(), filterMultiPolygons(), localize(args:locale:comment:), Polygon.distance(to:), MultiPolygon.distance(to:), Polygon.init(center:radius:), JSONDecoder.create(keyEncodingStrategy:) / JSONEncoder.create(keyEncodingStrategy:), DecodingError.Context.init(debugDescription:underlyingError:), Logger.elapsedTimePrefix(), GitInfo, PointOfInterest.customerID, Itinerary.legsSegments, Itinerary.toGeoJsonItinerary(), the legsSteps setter, NavigationInstructions.direction, and DispatchQueue.computation / navigation / network.

Changes that compile but behave differently​

Nothing in this list produces a compiler error. Check each one against your app.

ChangeWhat to do
isLoaded had been true after a failure tooits equivalent is !loadPhase.isLoading, not loadPhase.isReady
A map that fails to load settles .failedawaitLoaded() throws instead of suspending forever — handle it
A coordinate's time is encoded in Unix secondsif you persisted or forwarded encoded coordinates, re-check the unit
Coordinate.bearing of -1 is encoded now (it means 359°)it is no longer dropped as an invalid sentinel; accuracy is sent only when positive
MapCameraState equality is epsilon-baseda camera you built compares equal to the one the map reports
The user location indicator greys the moment tracking is lostit no longer stays blue for staleStateTimeout
The attribution sheet is presented from the hosting view controllerfound up the responder chain, not the app's topmost controller
startNavigation sets userTrackingMode itselfit follows with heading when navigation starts
A second MapView or GeoARView on one session evicts the firstone view of each kind per session; a second map needs its own

"I'm getting this error"​

ErrorGo to
cannot find 'WemapCore' in scopeStep 2
cannot find 'WemapMap' in scopeStep 2
'mapData' is inaccessible due to '@_spi' protection levelStep 2
argument 'session' missingStep 2
cannot assign to property: 'environment' is a 'let' constantStep 3
cannot find 'CoreConstants' / 'MapConstants' / 'ARConstants' in scopeStep 3
value of type 'Coordinate' has no member 'direction'Step 4
cannot convert value of type '[Float]' to expected argument type 'Levels'Step 4
value of type 'Coordinate' has no member 'location'Step 4
cannot find 'shortDescription' in scopeStep 4
value of type 'AnyPublisher<…>' has no member 'sink' after a renameStep 6
call is 'async' but is not marked with 'await'Step 6
main actor-isolated property … can not be referenced from a nonisolated contextStep 6
cannot find type 'MapViewDelegate' in scopeStep 7
initializer for conditional binding must have Optional type, not 'NavigationManager'Step 7
call can throw but is not marked with 'try' on VPSARKitLocationSource.initStep 8
cannot find type 'VPSARKitLocationSourceDelegate' in scopeStep 8
cannot find type 'PackdataManaging' in scopeStep 9
type 'MyLocationSource' does not conform to protocol 'Sendable'Step 11
is inaccessible due to '@_spi' protection levelStep 12
cannot find 'customerID' / 'legsSegments' / 'GitInfo' in scopeStep 12

Reference: renamed, moved and removed API​

v0.x symbolv1.0 replacementStep
ARConstantsGeoARViewConfig3
Coordinate.directionCoordinate.bearing4
Coordinate.locationCoordinate.toLocation()4
CoreConstantsSessionConfig3
GeoARViewDelegateloadPhase / loadPhases / awaitLoaded()10
ItineraryManager.getItineraries(…)computeItineraries(…)6
ItineraryServiceDirectionsService6
Level (Core)Level (Map SDK), now a struct4
LocationSource.supportsHeadingsupportsAttitude11
MapConstants.staleStateTimeoutMapViewConfig.staleStateTimeout (DispatchTimeInterval)3
MapViewDelegateloadPhase / loadPhases / touchedPoints7
PackdataManagingPackdataServicing9
PointOfInterestManaging.getPOIs()getAllPOIs()6
ShortStringConvertibleCustomCompactStringConvertible4
VPSARKitConstantsVPSConfig8
WemapCore.sharedCoreSession2
WemapMap.getMapData(mapID:token:)MapSession(mapID:token:config:)2
……

Getting help​

Sample apps: wemap-sdk-sample-apps-ios. Anything unclear or missing here — contact the Wemap team.