Skip to content

Commit b74ff0b

Browse files
committed
Upgrade arcgis sdk + create MapContentView
1 parent 99b27d8 commit b74ff0b

File tree

7 files changed

+296
-176
lines changed

7 files changed

+296
-176
lines changed

arcgis_map_sdk_ios/ios/arcgis_map_sdk_ios/Sources/arcgis_map_sdk_ios/ArcgisMapView.swift

Lines changed: 143 additions & 157 deletions
Large diffs are not rendered by default.

arcgis_map_sdk_ios/ios/arcgis_map_sdk_ios/Sources/arcgis_map_sdk_ios/GraphicsParser.swift

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -32,16 +32,14 @@ class GraphicsParser {
3232
}
3333

3434
// Apply attributes to each graphic, if present
35-
if let attributes = dictionary["attributes"] as? [String: Any] {
36-
for graphic in newGraphics {
37-
if let mutableAttributes = graphic.attributes as? NSMutableDictionary {
38-
for (key, value) in attributes {
39-
mutableAttributes[key] = value
40-
}
41-
}
42-
}
43-
}
44-
35+
if let attributes = dictionary["attributes"] as? [String: Any] {
36+
newGraphics.forEach { graphic in
37+
for (key, value) in attributes {
38+
graphic.setAttributeValue(value, forKey: key)
39+
}
40+
}
41+
}
42+
4543
return newGraphics
4644
}
4745

arcgis_map_sdk_ios/ios/arcgis_map_sdk_ios/Sources/arcgis_map_sdk_ios/ManualLocationDataSource.swift

Lines changed: 39 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@
88
import Foundation
99
import ArcGIS
1010

11-
//class ManualLocationDataSource: AGSLocationDataSource {
11+
//class ManualLocationDataSource: LocationDataSource {
1212
// public func setNewLocation(_ position: UserPosition) {
13-
// let loc = AGSLocation(
13+
// let loc = Location(
1414
// position: position.latLng.toAGSPoint(),
1515
// horizontalAccuracy: position.accuracy ?? 0,
1616
// velocity: position.velocity ?? 0,
@@ -20,3 +20,40 @@ import ArcGIS
2020
// didUpdate(loc)
2121
// }
2222
//}
23+
24+
final class CustomLocationProvider: LocationProvider {
25+
private var locationContinuation: AsyncThrowingStream<Location, Error>.Continuation?
26+
27+
// Exposed stream
28+
var locations: AsyncThrowingStream<Location, Error> {
29+
AsyncThrowingStream { continuation in
30+
self.locationContinuation = continuation
31+
}
32+
}
33+
34+
var headings: AsyncThrowingStream<Double, Error> {
35+
AsyncThrowingStream { continuation in
36+
Task {
37+
while !Task.isCancelled {
38+
continuation.yield(.random(in: 0...360))
39+
await Task.yield()
40+
}
41+
continuation.finish()
42+
}
43+
}
44+
}
45+
46+
// Push location from outside
47+
public func setNewLocation(_ position: UserPosition) {
48+
let loc = Location(
49+
position: position.latLng.toAGSPoint(),
50+
horizontalAccuracy: position.accuracy ?? 0,
51+
verticalAccuracy: position.accuracy ?? 0,
52+
speed: position.velocity ?? 0,
53+
course: position.heading ?? 0,
54+
isLastKnown: false
55+
)
56+
locationContinuation?.yield(loc)
57+
}
58+
}
59+
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
//
2+
// Created by Tarek Tolba on 29/04/2025.
3+
//
4+
5+
import SwiftUI
6+
import ArcGIS
7+
import CoreLocation
8+
9+
10+
struct MapContentView: View {
11+
@ObservedObject var mapViewModel: MapViewModel
12+
13+
init(mapViewModel: MapViewModel) {
14+
self.mapViewModel = mapViewModel
15+
}
16+
17+
var body: some View {
18+
MapViewReader { mapViewProxy in
19+
MapView(map: mapViewModel.map,
20+
viewpoint: mapViewModel.viewpoint,
21+
graphicsOverlays: [mapViewModel.defaultGraphicsOverlay])
22+
.attributionBarHidden(mapViewModel.attributionBarHidden)
23+
.locationDisplay(mapViewModel.locationDisplay)
24+
.contentInsets(mapViewModel.contentInsets)
25+
.interactionModes(mapViewModel.interactionModes)
26+
.onViewpointChanged(kind: .centerAndScale) { newViewpoint in
27+
mapViewModel.viewpoint = newViewpoint
28+
}.onScaleChanged(perform: { scale in
29+
mapViewModel.onScaleChanged?(scale)
30+
}).onVisibleAreaChanged(perform: { polygon in
31+
mapViewModel.onVisibleAreaChanged?(polygon)
32+
})
33+
.onChange(of: mapViewModel.map.basemap?.loadStatus) { newValue in
34+
if let newValue {
35+
mapViewModel.onLoadStatusChanged?(newValue)
36+
}
37+
}
38+
.task {
39+
// Store the mapViewProxy for external access
40+
mapViewModel.mapViewProxy = mapViewProxy
41+
42+
// await mapViewModel.locationDidChange()
43+
}
44+
.onDisappear {
45+
mapViewModel.stopLocationDataSource()
46+
// Clear the mapViewProxy reference when view disappears
47+
mapViewModel.mapViewProxy = nil
48+
}
49+
}
50+
}
51+
}
52+
53+
54+
class MapViewModel: ObservableObject {
55+
let map = Map()
56+
let locationDisplay = LocationDisplay()
57+
58+
@Published var viewpoint: Viewpoint
59+
@Published var mapViewProxy: MapViewProxy?
60+
@Published var attributionBarHidden: Bool = false
61+
@Published var contentInsets: EdgeInsets = EdgeInsets()
62+
@Published var interactionModes: MapViewInteractionModes = .all
63+
@Published var defaultGraphicsOverlay = GraphicsOverlay()
64+
/// The latest location update from the location data source.
65+
@Published var currentLocation: Location?
66+
67+
var onScaleChanged: ((Double) -> Void)?
68+
var onVisibleAreaChanged: ((Polygon) -> Void)?
69+
var onLoadStatusChanged: ((LoadStatus) -> Void)?
70+
71+
init(viewpoint : Viewpoint) {
72+
self.viewpoint = viewpoint
73+
}
74+
75+
// Methods that can be called from outside
76+
func setViewpoint(_ newViewpoint: Viewpoint) {
77+
viewpoint = newViewpoint
78+
}
79+
80+
func setViewpointGeometry(_ geometry: Geometry) async {
81+
guard let mapViewProxy = mapViewProxy else { return }
82+
await mapViewProxy.setViewpointGeometry(geometry)
83+
}
84+
85+
/// Stops the location data source.
86+
func stopLocationDataSource() {
87+
Task {
88+
await locationDisplay.dataSource.stop()
89+
}
90+
}
91+
92+
// /// Uses `for-await-in` to access location updates produced by the async stream.
93+
// @MainActor
94+
// func locationDidChange() async {
95+
// for await newLocation in locationDisplay.dataSource.locations {
96+
// currentLocation = newLocation
97+
// }
98+
// }
99+
}

example/ios/Podfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# Uncomment this line to define a global platform for your project
2-
platform :ios, '13.0'
2+
platform :ios, '16.0'
33

44
# CocoaPods analytics sends network stats synchronously affecting flutter build latency.
55
ENV['COCOAPODS_DISABLE_STATS'] = 'true'

example/ios/Podfile.lock

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,6 @@ SPEC CHECKSUMS:
1717
Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7
1818
geolocator_apple: d981750b9f47dbdb02427e1476d9a04397beb8d9
1919

20-
PODFILE CHECKSUM: cc1f88378b4bfcf93a6ce00d2c587857c6008d3b
20+
PODFILE CHECKSUM: ae273562e2241d2b1bd4b6d2d349a48b8fe1a2a7
2121

2222
COCOAPODS: 1.16.2

example/ios/Runner.xcodeproj/project.pbxproj

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,7 @@
179179
);
180180
mainGroup = 97C146E51CF9000F007C117D;
181181
packageReferences = (
182-
781AD8BC2B33823900A9FFBB /* XCLocalSwiftPackageReference "Flutter/ephemeral/Packages/FlutterGeneratedPluginSwiftPackage" */,
182+
781AD8BC2B33823900A9FFBB /* XCLocalSwiftPackageReference "FlutterGeneratedPluginSwiftPackage" */,
183183
);
184184
productRefGroup = 97C146EF1CF9000F007C117D /* Products */;
185185
projectDirPath = "";
@@ -369,7 +369,7 @@
369369
DEVELOPMENT_TEAM = 64Z45JP26B;
370370
ENABLE_BITCODE = NO;
371371
INFOPLIST_FILE = Runner/Info.plist;
372-
IPHONEOS_DEPLOYMENT_TARGET = 14.0;
372+
IPHONEOS_DEPLOYMENT_TARGET = 16.0;
373373
LD_RUNPATH_SEARCH_PATHS = (
374374
"$(inherited)",
375375
"@executable_path/Frameworks",
@@ -499,7 +499,7 @@
499499
DEVELOPMENT_TEAM = 64Z45JP26B;
500500
ENABLE_BITCODE = NO;
501501
INFOPLIST_FILE = Runner/Info.plist;
502-
IPHONEOS_DEPLOYMENT_TARGET = 14.0;
502+
IPHONEOS_DEPLOYMENT_TARGET = 16.0;
503503
LD_RUNPATH_SEARCH_PATHS = (
504504
"$(inherited)",
505505
"@executable_path/Frameworks",
@@ -523,7 +523,7 @@
523523
DEVELOPMENT_TEAM = 64Z45JP26B;
524524
ENABLE_BITCODE = NO;
525525
INFOPLIST_FILE = Runner/Info.plist;
526-
IPHONEOS_DEPLOYMENT_TARGET = 14.0;
526+
IPHONEOS_DEPLOYMENT_TARGET = 16.0;
527527
LD_RUNPATH_SEARCH_PATHS = (
528528
"$(inherited)",
529529
"@executable_path/Frameworks",
@@ -562,7 +562,7 @@
562562
/* End XCConfigurationList section */
563563

564564
/* Begin XCLocalSwiftPackageReference section */
565-
781AD8BC2B33823900A9FFBB /* XCLocalSwiftPackageReference "Flutter/ephemeral/Packages/FlutterGeneratedPluginSwiftPackage" */ = {
565+
781AD8BC2B33823900A9FFBB /* XCLocalSwiftPackageReference "FlutterGeneratedPluginSwiftPackage" */ = {
566566
isa = XCLocalSwiftPackageReference;
567567
relativePath = Flutter/ephemeral/Packages/FlutterGeneratedPluginSwiftPackage;
568568
};

0 commit comments

Comments
 (0)