Hello, we have found this crash which occurs when we use the CustomTiledLayer class. We use it to render MBTiles in the map but we haven't found the cause, we are wondering if you have some idea what could be happening, here is an image with part of the stack trace:
It looks like we are somehow ending up with a `nil` URL when we didn't expect to. Can you provide some reproducible code please?
Code looks similar to this:
import ArcGIS
class ArcGISMBTilesLayer {
var customLayer: CustomTiledLayer
static let defaultSpatialReference = SpatialReference(wkid: WKID(rawValue: 3857) ?? .webMercator)!
init(mbtilesFilePath: String) {
let tileInfo = TileInfo(
dpi: 96,
format: .png,
levelsOfDetail: ArcGISMBTilesLayer.defaultLevelsOfDetail(),
origin: ArcGISMBTilesLayer.defaultOrigin(),
spatialReference: ArcGISMBTilesLayer.defaultSpatialReference,
tileHeight: 256,
tileWidth: 256
)
self.customLayer = CustomTiledLayer(tileInfo: tileInfo, fullExtent: ArcGISMBTilesLayer.defaultEnvelope()){(tileKey: TileKey) in
let provider = SomeDataMBTilesProvider.getTiles(withPath: mbtilesFilePath)
let tileY = Int(pow(2.0, Double(tileKey.level))) - tileKey.row - 1
guard tileY >= 0 else {
return nil
}
let image: UIImage? = ImageFromTile.tile(with: provider, x: UInt(tileKey.column), y: UInt(tileY), zoom: UInt(tileKey.level))
if let image = image, let data = image.pngData() {
return data
}
else {
return nil
}
}
self.customLayer.noDataTileBehavior = .blank
}
static func defaultEnvelope() -> Envelope {
return Envelope.init(
xMin: -2.003750834278E7,
yMin: -2.003750834278E7,
xMax: 2.003750834278E7,
yMax: 2.003750834278E7,
spatialReference: defaultSpatialReference
)
}
static func defaultLevelsOfDetail() -> [LevelOfDetail] {
return [
LevelOfDetail.init(level: 0, resolution: 156543.0339279998, scale: 0.91657527591555E8),
LevelOfDetail.init(level: 1, resolution: 78271.5169639999, scale: 2.95828763795777E8),
LevelOfDetail.init(level: 2, resolution: 39135.7584820001, scale: 1.47914381897889E8),
LevelOfDetail.init(level: 3, resolution: 19567.8792409999, scale: 7.3957190948944E7),
LevelOfDetail.init(level: 4, resolution: 9783.93962049996, scale: 3.6978595474472E7),
LevelOfDetail.init(level: 5, resolution: 4891.96981024998, scale: 1.8489297737236E7),
LevelOfDetail.init(level: 6, resolution: 2445.98490512499, scale: 9244648.868618),
LevelOfDetail.init(level: 7, resolution: 1222.99245256249, scale: 4622324.434309),
LevelOfDetail.init(level: 8, resolution: 611.49622628138, scale: 2311162.217155),
LevelOfDetail.init(level: 9, resolution: 305.748113140558, scale: 1155581.108577),
LevelOfDetail.init(level: 10, resolution: 152.874056570411, scale: 577790.554289),
LevelOfDetail.init(level: 11, resolution: 76.4370282850732, scale: 288895.277144),
LevelOfDetail.init(level: 12, resolution: 38.2185141425366, scale: 144447.638572),
LevelOfDetail.init(level: 13, resolution: 19.1092570712683, scale: 72223.819286),
LevelOfDetail.init(level: 14, resolution: 9.55462853563415, scale: 36111.909643),
LevelOfDetail.init(level: 15, resolution: 4.77731426794937, scale: 18055.954822),
LevelOfDetail.init(level: 16, resolution: 2.38865713397468, scale: 9027.977411),
LevelOfDetail.init(level: 17, resolution: 1.19432856685505, scale: 4513.988705),
LevelOfDetail.init(level: 18, resolution: 0.597164283559817, scale: 2256.994353),
LevelOfDetail.init(level: 19, resolution: 0.298582141647617, scale: 1128.497176),
LevelOfDetail.init(level: 20, resolution: 0.149291070823808, scale: 564.248588),
LevelOfDetail.init(level: 21, resolution: 0.074645535411904, scale: 282.124294),
LevelOfDetail.init(level: 22, resolution: 0.037322767705952, scale: 141.062147),
LevelOfDetail.init(level: 23, resolution: 0.018661383985268, scale: 70.531074)
]
}
static func defaultOrigin() -> Point {
return Point.init(x: -2.003750834278E7, y: 2.003750834278E7, spatialReference: defaultSpatialReference)
}
}
//Some class to add layer to map operational layers
class SomeClassToAddMapLayerToMap {
func setupLayer(filePath: String) {
let mbTilesLayer = ArcGISMBTilesLayer(mbtilesFilePath: filePath)
let operationalLayer = mbTilesLayer.customLayer
addLayers(from: [operationalLayer])
}
func addLayers(from layers: [Layer]) {
viewModel?.selectedMap?.addOperationalLayers(layers)
}
}
Unfortunately there is missing code for function calls in your code. What would be really helpful is a self-contained reproducible example. Then we can debug and fix the issue.
Hello @CristhianSanchez. Please could you DM me with some more details? We'd like to reproduce this and see if we can work out a solution. We'll need some data and a self-contained reproducer project.
Thank you!