# Display Offline Maps

This section instructs how to register an offline-compatible map style, synchronize installed map data with the map engine, and switch to cache-only tile fetching when needed.

## Create and register an offline-compatible style

```swift
final class RegionalOfflineMapViewController: UIViewController {
    private var mapView: NGLMapView!
    private var connectivityObserver: NSObjectProtocol?
 
    override func viewDidLoad() {
        super.viewDidLoad()
 
        mapView = NGLMapView(frame: view.bounds)
        mapView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
        view.addSubview(mapView)
 
        applyStyle(named: "Bright")
        observeConnectivity()
        updateTileFetchMode()
 
        NGLRegionalOffline.refreshEngineOnMapResume(completion: nil)
    }
 
    private func applyStyle(named name: String) {
        guard let styleURL =
            NGLRegionalOfflineStyleCatalog.uri(forName: name)
        else {
            return
        }
 
        mapView.styleURL = styleURL
 
        NGLRegionalOfflineStyleCatalog.registerMapStyle(
            forMapView: mapView,
            styleURL: styleURL
        )
    }
}
```

Read the available style names with:

```swift
let styleNames = NGLRegionalOfflineStyleCatalog.styleNames
```

The current catalog includes _Bright_, _Dark_, _Satellite_, _SatelliteStreet_, _NavDay_, and _NavNight_. Register the new URL again whenever the application changes styles.

## Synchronize the map when the page appears

```swift
override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
 
    updateTileFetchMode()
    NGLRegionalOffline.onMapViewWillAppear()
}
```

Refresh explicitly after returning from the download page:

```swift
NGLRegionalOffline.refreshEngineOnMapResume { [weak self] in
    // Installed database paths are now synchronized with the map engine.
    self?.updateTileFetchMode()
}
```

## Switch to cache-only mode when offline

```swift
private func observeConnectivity() {
    connectivityObserver = NotificationCenter.default.addObserver(
        forName: NGLRegionalOfflineNetworkConnectivityDidChangeNotification,
        object: nil,
        queue: .main
    ) { [weak self] _ in
        self?.updateTileFetchMode()
    }
}
 
private func updateTileFetchMode() {
    mapView.regionalOfflineTileFetchCacheOnly =
        NGLRegionalOffline.isOfflineForRegionalFallback()
}
 
deinit {
    if let connectivityObserver {
        NotificationCenter.default.removeObserver(connectivityObserver)
    }
}
```

When _regionalOfflineTileFetchCacheOnly_ is true, the map reads from shared preview resources and installed regional databases instead of requesting regional tiles online.

## Focus the map on an installed region

```swift
let focused = NGLRegionalOffline.focusPreviewRegion(
    with: mapView,
    regionId: regionId
)
 
if !focused {
    // No usable database or bounds were found for this region.
}
```
