swiftmapkitmktileoverlay

how to call MKTileOverlay "url" function from subclass? getting EXC_BAD_INSTRUCTION


I am getting a runtime error at the point marked below? How to call MKTileOverlay "url" function from subclass? getting EXC_BAD_INSTRUCTION?

Basically want to show custom tiles in some places, but when not available drop back to standard Apple map tiles.

class GCMapOverlay : MKTileOverlay {
    override func url(forTilePath path: MKTileOverlayPath) -> URL {
        // Get local custom map tile if available
        let optionalUrl = Bundle.main.url(
            forResource: "\(path.y)",
            withExtension: "png",
            subdirectory: "tiles/\(path.z)/\(path.x)",
            localization: nil)
        NSLog("tiles/\(path.z)/\(path.x)/\(path.y)")

        guard let url = optionalUrl else {
            // Local tile not available - want to drop back to an apple maps tile (as if MKTileOverlay wasn't subclassed)
            return super.url(forTilePath: path)    // <== RUNTIME ERROR: NetworkLoad (10): EXC_BAD_INSTRUCTION
        }

        // Local tile available so return
        return url
    }
}

in my controller

func setupTileRenderer() {
    let overlay = GCMapOverlay()
    overlay.canReplaceMapContent = true
    mapView.addOverlay(overlay, level: .aboveLabels)
    tileRenderer = MKTileOverlayRenderer(tileOverlay: overlay)
}

Solution

  • Remove overlay.canReplaceMapContent = true and change your guard statement so it loads a clear 256x256 tile.

    guard let url = optionalUrl else {
        return Bundle.main.url(forResource: "emptyTile", withExtension: "png")!
    }
    

    Since all of your custom tiles are already stored locally they will be immediately loaded over the default Apple tiles which makes canReplaceMapContent unnecessary.

    Make sure your custom tiles don't have alpha in them otherwise the Apple tile will be visible below.