Hi.
The problem you're seeing is that you're trying to use an AGSLayer that is already being used. In Runtime, for performance reasons, many objects cannot be used (or "owned") by more than one other object. In this case, your AGSMap owns a AGSBasemap which owns the layer you are reusing (Coast_url). Your code is trying to create a new AGSBasemap with a layer that is already "owned" by map's current basemap.
If you look in the Xcode console, you will see the following when you try to create the new AGSMap.
ArcGIS Runtime Error Occurred. Set a breakpoint on C++ exceptions to see the original callstack and context for this error: Error Domain=com.esri.arcgis.runtime.error Code=24 "Object is already owned." UserInfo={NSLocalizedFailureReason=Already owned., NSLocalizedDescription=Object is already owned., Additional Message=Already owned.}
Instead, you will need to create an entirely new AGSArcGISMapImageLayer (or AGSArcGISTiledLayer) and use that in a new AGSBasemap. You could modify your code like this to achieve this, using an enum instead of strings…
enum CustomBasemap {
enum Language {
case EN
case AR
}
case coast
case satellite
case hybrid(language: Language)
case streetmap(language: Language)
func getLayer() -> AGSLayer {
switch self {
case .coast:
return AGSArcGISMapImageLayer(url: URL(string:"https://services.gisqatar.org.qa/server/rest/services/Vector/Coast/MapServer")!)
case .satellite:
return AGSArcGISTiledLayer(url: URL(string:"https://services.gisqatar.org.qa/server/rest/services/Imagery/QatarSatelitte/MapServer")!)
case .hybrid(let language):
switch language {
case .EN:
return AGSArcGISTiledLayer(url:URL(string: "https://services.gisqatar.org.qa/server/rest/services/Vector/Qatar_StreetMap_Hybrid_E/MapServer")!)
case .AR:
return AGSArcGISTiledLayer(url:URL(string: "https://services.gisqatar.org.qa/server/rest/services/Vector/Qatar_StreetMap_Hybrid_Ar_Test/MapServer")!)
}
case .streetmap(let language):
switch language {
case .EN:
return AGSArcGISTiledLayer(url:URL(string: "https://services.gisqatar.org.qa/server/rest/services/Vector/Qatar_StreetMap_E/MapServer")!)
case .AR:
return AGSArcGISTiledLayer(url:URL(string: "https://services.gisqatar.org.qa/server/rest/services/Vector/Qatar_StreetMap_A/MapServer")!)
}
}
}
func getBasemap() -> AGSBasemap {
return AGSBasemap(baseLayer: getLayer())
}
}
and then set the basemap on the existing map (which will save you creating a new map and setting initialViewpoints):
var basemapType: CustomBasemap = .coast
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
self.map = AGSMap(basemap: basemapType.getBasemap())
self.mapView.map = self.map
self.SetMapExtent()
}
...
func Coast_Map_Tapped() {
basemapType = .coast
self.map.basemap = basemapType.getBasemap()
}
Hope that helps.