@@ -110,8 +110,14 @@ class ArcgisMapView: NSObject, FlutterPlatformView {
110110    } 
111111
112112    private  func  setupMethodChannel( )  { 
113-         methodChannel. setMethodCallHandler ( {  [ self ]  ( call:  FlutterMethodCall ,  result:  @escaping  FlutterResult )  ->  Void  in 
114-             switch  ( call. method)  { 
113+         methodChannel. setMethodCallHandler ( { 
114+             [ weak self]  ( call:  FlutterMethodCall ,  result:  @escaping  FlutterResult )  ->  Void  in 
115+             guard  let  self =  self  else  { 
116+                 result ( FlutterError ( code:  " disposed " ,  message:  " View was disposed " ,  details:  nil ) ) 
117+                 return 
118+             } 
119+             
120+             switch  call. method { 
115121            case  " on_init_complete " :  waitForViewToInit ( call,  result) 
116122            case  " zoom_in " :  onZoomIn ( call,  result) 
117123            case  " zoom_out " :  onZoomOut ( call,  result) 
@@ -146,17 +152,18 @@ class ArcgisMapView: NSObject, FlutterPlatformView {
146152
147153    private  func  waitForViewToInit( _ call:  FlutterMethodCall ,  _ result:  @escaping  FlutterResult )  { 
148154        if  mapContentView. viewModel. mapViewProxy !=  nil  { 
149-                  result ( true ) 
155+             result ( true ) 
150156        }  else  { 
151-             mapContentView. viewModel. onViewInit =  {  [ weak self ]  in 
157+             mapContentView. viewModel. onViewInit =  {  [ weak vm  =  mapContentView . viewModel ]  in 
152158                result ( true ) 
159+                 vm? . onViewInit =  nil 
153160            } 
154161        } 
155162    } 
156163
157164    private  func  onZoomIn( _ call:  FlutterMethodCall ,  _ result:  @escaping  FlutterResult )  { 
158-           let  currentScale  =  mapContentView. viewModel. viewpoint. targetScale
159- 
165+         let  currentScale  =  mapContentView. viewModel. viewpoint. targetScale
166+          
160167        guard  let  args =  call. arguments as?  [ String :  Any ]  else  { 
161168            result ( FlutterError ( code:  " missing_data " ,  message:  " Invalid arguments " ,  details:  nil ) ) 
162169            return 
@@ -176,9 +183,10 @@ class ArcgisMapView: NSObject, FlutterPlatformView {
176183            } 
177184        } 
178185        let  newScale  =  ArcgisMapView . convertZoomLevelToMapScale ( totalZoomLevel) 
179-         Task  { 
186+         Task  {  [ weak self]  in 
187+             guard  let  self =  self  else  {  return  } 
180188            do  { 
181-                 await  mapContentView. viewModel. mapViewProxy? . setViewpointScale ( newScale) 
189+                 await  self . mapContentView. viewModel. mapViewProxy? . setViewpointScale ( newScale) 
182190                result ( true ) 
183191            } 
184192        } 
@@ -206,20 +214,23 @@ class ArcgisMapView: NSObject, FlutterPlatformView {
206214            } 
207215        } 
208216        let  newScale  =  ArcgisMapView . convertZoomLevelToMapScale ( totalZoomLevel) 
209-         Task  { 
217+         Task  {  [ weak self]  in 
218+             guard  let  self =  self  else  {  return  } 
210219            do  { 
211-                 let  success  =  await  mapContentView. viewModel. mapViewProxy? . setViewpointScale ( newScale) 
220+                 let  success  =  await  self . mapContentView. viewModel. mapViewProxy? . setViewpointScale ( 
221+                     newScale) 
212222                result ( success) 
213223            } 
214224        } 
215225    } 
216- 
217-     private  func  onRotate( _ call:  FlutterMethodCall ,  _ result: @escaping  FlutterResult )  { 
226+      
227+     private  func  onRotate( _ call:  FlutterMethodCall ,  _ result:   @escaping  FlutterResult )  { 
218228        guard  let  angleDouble =  call. arguments as?  Double  else  { 
219229            result ( FlutterError ( code:  " missing_data " ,  message:  " Invalid arguments " ,  details:  nil ) ) 
220230            return 
221231        } 
222-         Task  { 
232+         Task  {  [ weak self]  in 
233+             guard  let  self =  self  else  {  return  } 
223234            do  { 
224235                let  success  =  await  mapContentView. viewModel. mapViewProxy? . setViewpointRotation ( angleDouble) 
225236                result ( success) 
@@ -254,7 +265,8 @@ class ArcgisMapView: NSObject, FlutterPlatformView {
254265            result ( FlutterError ( code:  " missing_data " ,  message:  " Invalid arguments " ,  details:  nil ) ) 
255266            return 
256267        } 
257-         Task  { 
268+         Task  {  [ weak self]  in 
269+             guard  let  self =  self  else  {  return  } 
258270            do  { 
259271                let  point :  LatLng  =  try   JsonUtil . objectOfJson ( args [ " point " ]  as!  Dictionary < String ,  Any > ) 
260272                let  zoomLevel  =  args [ " zoomLevel " ]  as?  Int 
@@ -266,9 +278,9 @@ class ArcgisMapView: NSObject, FlutterPlatformView {
266278                if  let  zoomLevel =  zoomLevel { 
267279                    scale =  ArcgisMapView . convertZoomLevelToMapScale ( zoomLevel) 
268280                }  else  { 
269-                     scale =  mapContentView. viewModel. viewpoint. targetScale
281+                     scale =  self . mapContentView. viewModel. viewpoint. targetScale
270282                } 
271-                 let  success  =  await  mapContentView. viewModel. mapViewProxy? . setViewpoint ( 
283+                 let  success  =  await  self . mapContentView. viewModel. mapViewProxy? . setViewpoint ( 
272284                    Viewpoint ( center:  point. toAGSPoint ( ) ,  scale:  scale) , 
273285                    duration:  ( animationOptions? . duration ??  0 )  /  1000 
274286                ) 
@@ -287,9 +299,12 @@ class ArcgisMapView: NSObject, FlutterPlatformView {
287299        Task  { 
288300            do  { 
289301                let  payload :  MoveToPointsPayload  =  try   JsonUtil . objectOfJson ( args) 
290-                 let  polyline  =  Polyline ( points:  payload. points. map  {  latLng in  Point ( x:  latLng. longitude,  y: latLng. latitude,  spatialReference:  . wgs84)  } ) 
291- 
292-                 if ( payload. padding !=  nil )  { 
302+                 let  polyline  =  Polyline ( 
303+                     points:  payload. points. map  {  latLng in 
304+                         Point ( x:  latLng. longitude,  y:  latLng. latitude,  spatialReference:  . wgs84) 
305+                     } ) 
306+                 
307+                 if  payload. padding !=  nil  { 
293308                    let  success  =  try   await  mapContentView. viewModel. mapViewProxy!. setViewpointGeometry ( polyline. extent,  padding:  payload. padding!) 
294309                    result ( success) 
295310                }  else  { 
@@ -312,8 +327,9 @@ class ArcgisMapView: NSObject, FlutterPlatformView {
312327            return 
313328        } 
314329
315-         
316-         let  existingIds  =  mapContentView. viewModel. defaultGraphicsOverlay. graphics. compactMap  {  object in 
330+ 
331+         let  existingIds  =  mapContentView. viewModel. defaultGraphicsOverlay. graphics. compactMap  { 
332+             object in 
317333            let  graphic  =  object as!  Graphic 
318334            return  graphic. attributes [ " id " ]  as?  String 
319335        } 
@@ -327,7 +343,7 @@ class ArcgisMapView: NSObject, FlutterPlatformView {
327343            return  existingIds. contains ( id) 
328344        } ) 
329345
330-         if ( hasExistingGraphics)  { 
346+         if   hasExistingGraphics { 
331347            result ( false ) 
332348            return 
333349        } 
@@ -370,7 +386,8 @@ class ArcgisMapView: NSObject, FlutterPlatformView {
370386    } 
371387
372388    private  func  onRetryLoad( _ call:  FlutterMethodCall ,  _ result:  @escaping  FlutterResult )  { 
373-         Task  { 
389+         Task  {  [ weak self]  in 
390+             guard  let  self =  self  else  {  return  } 
374391            do  { 
375392                try   await  mapContentView. viewModel. map. retryLoad ( ) 
376393                result ( true ) 
@@ -430,9 +447,10 @@ class ArcgisMapView: NSObject, FlutterPlatformView {
430447
431448
432449    private  func  onStartLocationDisplayDataSource( _ call:  FlutterMethodCall ,  _ result:  @escaping  FlutterResult )  { 
433-         Task  { 
450+         Task  {  [ weak self]  in 
451+             guard  let  self =  self  else  {  return  } 
434452            do  { 
435-                 try   await  mapContentView. viewModel. locationDisplay. dataSource. start ( ) ; 
453+                 try   await  self . mapContentView. viewModel. locationDisplay. dataSource. start ( ) 
436454                result ( true ) 
437455            } 
438456            catch { 
@@ -447,9 +465,10 @@ class ArcgisMapView: NSObject, FlutterPlatformView {
447465    } 
448466
449467    private  func  onStopLocationDisplayDataSource( _ call:  FlutterMethodCall ,  _ result:  @escaping  FlutterResult )  { 
450-         Task  { 
468+         Task  {  [ weak self]  in 
469+             guard  let  self =  self  else  {  return  } 
451470            do  { 
452-                 await  mapContentView. viewModel. locationDisplay. dataSource. stop ( ) 
471+                 await  self . mapContentView. viewModel. locationDisplay. dataSource. stop ( ) 
453472                result ( true ) 
454473            } 
455474        } 
@@ -568,18 +587,19 @@ class ArcgisMapView: NSObject, FlutterPlatformView {
568587    } 
569588
570589    private  func  onExportImage( _ result:  @escaping  FlutterResult )  { 
571-         Task  { 
572-               do  { 
573-                   let  image  =  try   await  mapContentView. viewModel. mapViewProxy!. exportImage ( ) 
574-                   if  let  imageData =  image. pngData ( )  { 
575-                       result ( FlutterStandardTypedData ( bytes:  imageData) ) 
576-                   }  else  { 
577-                       result ( FlutterError ( code:  " conversion_error " ,  message:  " Failed to convert image to PNG data " ,  details:  nil ) ) 
578-                   } 
579-               }  catch  { 
580-                   result ( FlutterError ( code:  " export_error " ,  message:  error. localizedDescription,  details:  nil ) ) 
581-               } 
582-           } 
590+         Task  {  [ weak self]  in 
591+             guard  let  self =  self  else  {  return  } 
592+             do  { 
593+                 let  image  =  try   await  self . mapContentView. viewModel. mapViewProxy!. exportImage ( ) 
594+                 if  let  imageData =  image. pngData ( )  { 
595+                     result ( FlutterStandardTypedData ( bytes:  imageData) ) 
596+                 }  else  { 
597+                     result ( FlutterError ( code:  " conversion_error " ,  message:  " Failed to convert image to PNG data " ,  details:  nil ) ) 
598+                 } 
599+             }  catch  { 
600+                 result ( FlutterError ( code:  " export_error " ,  message:  error. localizedDescription,  details:  nil ) ) 
601+             } 
602+         } 
583603    } 
584604
585605    private  func  operationWithSymbol( _ call:  FlutterMethodCall ,  _ result:  @escaping  FlutterResult ,  handler:  ( Symbol )  ->  Void )  { 
@@ -591,11 +611,23 @@ class ArcgisMapView: NSObject, FlutterPlatformView {
591611            let  symbol  =  try   GraphicsParser ( registrar:  flutterPluginRegistrar) . parseSymbol ( args) 
592612            handler ( symbol) 
593613            result ( true ) 
594-         } 
595-         catch  { 
614+         }  catch  { 
596615            result ( FlutterError ( code:  " unknown_error " ,  message:  " Error while adding graphic.  \( error) " ,  details:  nil ) ) 
597616        } 
598617    } 
618+     
619+     deinit  { 
620+         mapContentView. viewModel. onScaleChanged =  nil 
621+         mapContentView. viewModel. onVisibleAreaChanged =  nil 
622+         mapContentView. viewModel. onLoadStatusChanged =  nil 
623+         mapContentView. viewModel. onViewInit =  nil 
624+         mapContentView. viewModel. mapViewProxy =  nil 
625+         mapContentView. viewModel. stopLocationDataSource ( ) 
626+         
627+         zoomEventChannel. setStreamHandler ( nil ) 
628+         centerPositionEventChannel. setStreamHandler ( nil ) 
629+         methodChannel. setMethodCallHandler ( nil ) 
630+     } 
599631} 
600632
601633extension  Basemap . Style :  CaseIterable  { 
@@ -788,18 +820,18 @@ extension Basemap.Style {
788820            return  " osmNavigation " 
789821        case  . osmNavigationDark: 
790822            return  " osmNavigationDark " 
791- 
823+              
792824        } 
793825    } 
794826} 
795827
796- struct  MoveToPointsPayload   :  Codable  { 
797-     let  points   :  [ LatLng ] 
798-     let  padding   :  Double ? 
828+ struct  MoveToPointsPayload :  Codable  { 
829+     let  points :  [ LatLng ] 
830+     let  padding :  Double ? 
799831} 
800832
801833extension  LoadStatus  { 
802-     func  jsonValue( )    ->  String  { 
834+     func  jsonValue( )  ->  String  { 
803835        switch  self  { 
804836        case  . loaded: 
805837            return  " loaded " 
@@ -818,16 +850,16 @@ extension LoadStatus {
818850extension  String  { 
819851    func  autoPanModeFromString( )  ->  LocationDisplay . AutoPanMode ?   { 
820852        switch  self  { 
821-              case  " compassNavigation " : 
822-                  return  . compassNavigation
823-              case  " navigation " : 
824-                  return  . navigation
825-              case  " recenter " : 
826-                  return  . recenter
827-              case  " off " : 
828-                  return  . off
829-              default : 
830-                  return  nil 
853+         case  " compassNavigation " : 
854+             return  . compassNavigation
855+         case  " navigation " : 
856+             return  . navigation
857+         case  " recenter " : 
858+             return  . recenter
859+         case  " off " : 
860+             return  . off
861+         default : 
862+             return  nil 
831863        } 
832864    } 
833865} 
0 commit comments