11import ArcGIS
22import Foundation
33import Flutter
4+ import SwiftUI
5+
46
57class ArcgisMapView : NSObject , FlutterPlatformView {
68
7- private let defaultGraphicsOverlay = AGSGraphicsOverlay ( )
9+ private let defaultGraphicsOverlay = GraphicsOverlay ( )
810
911 private let methodChannel : FlutterMethodChannel
1012 private let zoomEventChannel : FlutterEventChannel
@@ -20,22 +22,23 @@ class ArcgisMapView: NSObject, FlutterPlatformView {
2022
2123 private let initialZoom : Int
2224
23- private var mapView : AGSMapView
24- private let map = AGSMap ( )
25- private let graphicsOverlay = AGSGraphicsOverlay ( )
26- private let userIndicatorGraphic = AGSGraphic ( )
27- private let pinGraphic = AGSGraphic ( )
28- private let routeLineGraphic = AGSGraphic ( )
25+ private var mapView : MapView
26+ private let map = Map ( )
27+ private let graphicsOverlay = GraphicsOverlay ( )
28+ private let userIndicatorGraphic = Graphic ( )
29+ private let pinGraphic = Graphic ( )
30+ private let routeLineGraphic = Graphic ( )
2931
30- private var routeLineGraphics = [ AGSGraphic ] ( )
32+ private var routeLineGraphics = [ Graphic ] ( )
3133
32- private var routePoints = Array < AGSPoint > ( )
34+ private var routePoints = Array < Point > ( )
3335
3436
3537 private static let defaultDuration = 0.8
36-
38+
39+ private var hostingController : UIHostingController < MapView >
3740 func view( ) -> UIView {
38- return mapView
41+ return hostingController . view
3942 }
4043
4144 init (
@@ -61,73 +64,65 @@ class ArcgisMapView: NSObject, FlutterPlatformView {
6164 centerPositionEventChannel. setStreamHandler ( centerPositionStreamHandler)
6265
6366 if let apiKey = mapOptions. apiKey {
64- AGSArcGISRuntimeEnvironment . apiKey = apiKey
67+ ArcGISEnvironment . apiKey = APIKey ( apiKey)
6568 }
6669 if let licenseKey = mapOptions. licenseKey {
6770 do {
68- try AGSArcGISRuntimeEnvironment . setLicenseKey ( licenseKey)
71+ try ArcGISEnvironment . setLicense ( with : LicenseKey ( licenseKey) ! )
6972 } catch {
7073 print ( " setLicenseKey failed. \( error) " )
7174 }
7275 }
7376
7477 initialZoom = Int ( mapOptions. zoom)
78+
79+ let viewpoint = Viewpoint (
80+ latitude: mapOptions. initialCenter. latitude,
81+ longitude: mapOptions. initialCenter. longitude,
82+ scale: convertZoomLevelToMapScale ( Int ( mapOptions. zoom) )
83+ )
7584
76- mapView = AGSMapView . init ( frame : frame )
85+ mapView = MapView . init ( map : map , viewpoint : viewpoint , graphicsOverlays : [ defaultGraphicsOverlay ] , )
7786
87+ // Embed the SwiftUI MapView into a UIHostingController
88+ hostingController = UIHostingController ( rootView: mapView)
89+ hostingController. view. frame = frame
90+ hostingController. view. backgroundColor = . clear
91+
7892 super. init ( )
7993
8094 if let isAttributionTextVisible = mapOptions. isAttributionTextVisible {
81- mapView. isAttributionTextVisible = isAttributionTextVisible
95+ mapView. attributionBarHidden ( ! isAttributionTextVisible)
8296 }
8397
8498 if mapOptions. basemap != nil {
85- map. basemap = AGSBasemap ( style: parseBaseMapStyle ( mapOptions. basemap!) )
99+ map. basemap = Basemap ( style: parseBaseMapStyle ( mapOptions. basemap!) )
86100 } else {
87101 let layers = mapOptions. vectorTilesUrls!. map { url in
88- AGSArcGISVectorTiledLayer ( url: URL ( string: url) !)
102+ ArcGISVectorTiledLayer ( url: URL ( string: url) !)
89103 }
90- map. basemap = AGSBasemap ( baseLayers: layers, referenceLayers : nil )
104+ map. basemap = Basemap ( baseLayers: layers)
91105 }
92106
93107 map. minScale = convertZoomLevelToMapScale ( mapOptions. minZoom)
94108 map. maxScale = convertZoomLevelToMapScale ( mapOptions. maxZoom)
95109
96- mapView. map = map
97- mapView. graphicsOverlays. add ( defaultGraphicsOverlay)
98-
99- mapScaleObservation = mapView. observe ( \. mapScale) { [ weak self] ( map, notifier) in
100- DispatchQueue . main. async {
101- guard let self = self else {
102- return
103- }
104- let newZoom = self . convertScaleToZoomLevel ( self . mapView. mapScale)
105- self . zoomStreamHandler. addZoom ( zoom: newZoom)
106- }
110+ mapView. onScaleChanged { [ weak self] scale in
111+ guard let self = self else { return }
112+ let newZoom = self . convertScaleToZoomLevel ( scale)
113+ self . zoomStreamHandler. addZoom ( zoom: newZoom)
107114 }
108- mapVisibleAreaObservation = mapView. observe ( \. visibleArea) { [ weak self] ( map, notifier) in
109- DispatchQueue . main. async {
110- guard let self = self else {
111- return
112- }
113- guard let center = self . mapView. visibleArea? . extent. center else {
114- return
115- }
116- guard let wgs84Center = AGSGeometryEngine . projectGeometry ( center, to: . wgs84( ) ) as? AGSPoint else { return }
115+ mapView. onVisibleAreaChanged { [ weak self] polygon in
116+ guard let self = self else { return }
117+ let center = polygon. extent. center
118+ if let wgs84Center = GeometryEngine . project ( center, into: . wgs84) as? Point {
117119 self . centerPositionStreamHandler. add ( center: LatLng ( latitude: wgs84Center. y, longitude: wgs84Center. x) )
118120 }
119121 }
120122
121-
122- let viewpoint = AGSViewpoint (
123- latitude: mapOptions. initialCenter. latitude,
124- longitude: mapOptions. initialCenter. longitude,
125- scale: convertZoomLevelToMapScale ( Int ( mapOptions. zoom) )
126- )
127- mapView. setViewpoint ( viewpoint)
128-
129123 setMapInteractive ( mapOptions. isInteractive)
130124 setupMethodChannel ( )
125+
131126
132127 mapLoadStatusObservation = map. observe ( \. loadStatus, options: . initial) { [ weak self] ( map, notifier) in
133128 DispatchQueue . main. async {
@@ -186,10 +181,11 @@ class ArcgisMapView: NSObject, FlutterPlatformView {
186181 result ( FlutterError ( code: " missing_data " , message: " lodFactor not provided " , details: nil ) )
187182 return
188183 }
189-
190- let currentZoomLevel = convertScaleToZoomLevel ( mapView . mapScale )
184+
185+ let currentZoomLevel = convertScaleToZoomLevel ( currentScale )
191186 let totalZoomLevel = currentZoomLevel + lodFactor
192187 if ( totalZoomLevel > convertScaleToZoomLevel ( map. maxScale) ) {
188+ result ( true )
193189 return
194190 }
195191 let newScale = convertZoomLevelToMapScale ( totalZoomLevel)
@@ -217,6 +213,7 @@ class ArcgisMapView: NSObject, FlutterPlatformView {
217213 let currentZoomLevel = convertScaleToZoomLevel ( mapView. mapScale)
218214 let totalZoomLevel = currentZoomLevel - lodFactor
219215 if ( totalZoomLevel < convertScaleToZoomLevel ( map. minScale) ) {
216+ result ( true )
220217 return
221218 }
222219 let newScale = convertZoomLevelToMapScale ( totalZoomLevel)
@@ -245,12 +242,12 @@ class ArcgisMapView: NSObject, FlutterPlatformView {
245242 do {
246243 let padding : ViewPadding = try JsonUtil . objectOfJson ( args)
247244
248- mapView. contentInset = UIEdgeInsets (
245+ mapView. contentInsets ( EdgeInsets (
249246 top: padding. top,
250- left : padding. left,
247+ leading : padding. left,
251248 bottom: padding. bottom,
252- right : padding. right
253- )
249+ trailing : padding. right
250+ ) )
254251
255252 result ( true )
256253 } catch {
@@ -278,7 +275,7 @@ class ArcgisMapView: NSObject, FlutterPlatformView {
278275 }
279276
280277 mapView. setViewpoint (
281- AGSViewpoint ( center: point. toAGSPoint ( ) , scale: scale) ,
278+ Viewpoint ( center: point. toAGSPoint ( ) , scale: scale) ,
282279 duration: ( animationOptions? . duration ?? 0 ) / 1000 ,
283280 curve: animationOptions? . arcgisAnimationCurve ( ) ?? . linear
284281 ) { success in
@@ -297,7 +294,7 @@ class ArcgisMapView: NSObject, FlutterPlatformView {
297294
298295 do {
299296 let payload : MoveToPointsPayload = try JsonUtil . objectOfJson ( args)
300- let polyline = AGSPolyline ( points: payload. points. map { latLng in AGSPoint ( x: latLng. longitude, y: latLng. latitude, spatialReference: . wgs84( ) ) } )
297+ let polyline = Polyline ( points: payload. points. map { latLng in Point ( x: latLng. longitude, y: latLng. latitude, spatialReference: . wgs84) } )
301298
302299 if ( payload. padding != nil ) {
303300 mapView. setViewpointGeometry ( polyline. extent, padding: payload. padding!) { success in
@@ -315,7 +312,7 @@ class ArcgisMapView: NSObject, FlutterPlatformView {
315312
316313 private func onAddGraphic( _ call: FlutterMethodCall , _ result: @escaping FlutterResult ) {
317314 let parser = GraphicsParser ( registrar: flutterPluginRegistrar)
318- var newGraphics = [ AGSGraphic ] ( )
315+ var newGraphics = [ Graphic ] ( )
319316 do {
320317 newGraphics. append ( contentsOf: try parser. parse ( dictionary: call. arguments as! Dictionary < String , Any > ) )
321318 } catch {
@@ -325,7 +322,7 @@ class ArcgisMapView: NSObject, FlutterPlatformView {
325322
326323
327324 let existingIds = defaultGraphicsOverlay. graphics. compactMap { object in
328- let graphic = object as! AGSGraphic
325+ let graphic = object as! Graphic
329326 return graphic. attributes [ " id " ] as? String
330327 }
331328
@@ -359,13 +356,13 @@ class ArcgisMapView: NSObject, FlutterPlatformView {
359356 }
360357
361358 let newGraphics = defaultGraphicsOverlay. graphics. filter ( { element in
362- let graphic = element as! AGSGraphic
359+ let graphic = element as! Graphic
363360 let id = graphic. attributes [ " id " ] as? String
364361 return id != graphicId
365362 } )
366363
367- defaultGraphicsOverlay. graphics . removeAllObjects ( )
368- defaultGraphicsOverlay. graphics . addObjects ( from : newGraphics)
364+ defaultGraphicsOverlay. removeAllGraphics ( )
365+ defaultGraphicsOverlay. addGraphics ( newGraphics)
369366
370367 result ( true )
371368 }
@@ -376,7 +373,7 @@ class ArcgisMapView: NSObject, FlutterPlatformView {
376373 return
377374 }
378375
379- map. basemap = AGSBasemap ( style: parseBaseMapStyle ( baseMapString) )
376+ map. basemap = Basemap ( style: parseBaseMapStyle ( baseMapString) )
380377
381378 result ( true )
382379 }
@@ -386,7 +383,7 @@ class ArcgisMapView: NSObject, FlutterPlatformView {
386383 result ( true )
387384 }
388385
389- private func notifyStatus( _ status: AGSLoadStatus ) {
386+ private func notifyStatus( _ status: LoadStatus ) {
390387 methodChannel. invokeMethod ( " onStatusChanged " , arguments: status. jsonValue ( ) )
391388 }
392389
@@ -414,8 +411,8 @@ class ArcgisMapView: NSObject, FlutterPlatformView {
414411 // don't set "isMagnifierEnabled" since we don't want to use this feature
415412 }
416413
417- private func parseBaseMapStyle( _ string: String ) -> AGSBasemapStyle {
418- let baseMapStyle = AGSBasemapStyle . allCases. first { enumValue in
414+ private func parseBaseMapStyle( _ string: String ) -> Basemap . Style {
415+ let baseMapStyle = Basemap . allCases. first { enumValue in
419416 enumValue. getJsonValue ( ) == string
420417 }
421418 if baseMapStyle == nil {
@@ -588,7 +585,7 @@ class ArcgisMapView: NSObject, FlutterPlatformView {
588585 }
589586 }
590587
591- private func operationWithSymbol( _ call: FlutterMethodCall , _ result: @escaping FlutterResult , handler: ( AGSSymbol ) -> Void ) {
588+ private func operationWithSymbol( _ call: FlutterMethodCall , _ result: @escaping FlutterResult , handler: ( Symbol ) -> Void ) {
592589 do {
593590 guard let args = call. arguments as? [ String : Any ] else {
594591 result ( FlutterError ( code: " missing_data " , message: " Invalid arguments " , details: nil ) )
@@ -604,8 +601,8 @@ class ArcgisMapView: NSObject, FlutterPlatformView {
604601 }
605602}
606603
607- extension AGSBasemapStyle : CaseIterable {
608- public static var allCases : [ AGSBasemapStyle ] {
604+ extension Basemap . Style : CaseIterable {
605+ public static var allCases : [ Basemap . Style ] {
609606 [
610607 . arcGISImagery,
611608 . arcGISImageryStandard,
@@ -657,7 +654,7 @@ extension AGSBasemapStyle: CaseIterable {
657654 }
658655}
659656
660- extension AGSBasemapStyle {
657+ extension Basemap . Style {
661658 func getJsonValue( ) -> String ? {
662659 switch self {
663660 case . arcGISImagery:
@@ -763,27 +760,25 @@ struct MoveToPointsPayload : Codable {
763760 let padding : Double ?
764761}
765762
766- extension AGSLoadStatus {
763+ extension LoadStatus {
767764 func jsonValue( ) -> String {
768765 switch self {
769766 case . loaded:
770767 return " loaded "
771768 case . loading:
772769 return " loading "
773- case . failedToLoad :
774- return " failedToLoad "
770+ case . failed :
771+ return " failed "
775772 case . notLoaded:
776773 return " notLoaded "
777- case . unknown:
778- return " unknown "
779774 @unknown default :
780775 return " unknown "
781776 }
782777 }
783778}
784779
785780extension String {
786- func autoPanModeFromString( ) -> AGSLocationDisplayAutoPanMode ? {
781+ func autoPanModeFromString( ) -> LocationDisplay . AutoPanMode ? {
787782 switch self {
788783 case " compassNavigation " :
789784 return . compassNavigation
@@ -799,7 +794,7 @@ extension String {
799794 }
800795}
801796
802- extension AGSLocationDisplayAutoPanMode {
797+ extension LocationDisplay . AutoPanMode {
803798 func toName( ) -> String ? {
804799 switch self {
805800 case . off:
0 commit comments