Yandex Maps SDK Integration in Mobile App
Yandex Maps — default choice for Russian apps with maps: better coverage in CIS, Russian toponyms without transliteration artifacts, working transit router for Russian cities. MapKit SDK for Android and iOS changed substantially starting version 4.x — lightweight version renamed, annotation API redesigned.
SDK Versions: Full vs Lite
Yandex provides two versions:
| Version | Size | Offline Maps | Routes | Search |
|---|---|---|---|---|
| MapKit Full | ~40 MB | Yes | Yes | Yes |
| MapKit Lite | ~15 MB | No | No | Geocoder only |
For most apps Lite is sufficient — if offline and transit routes not needed.
Initialization
API key obtained at developer.tech.yandex.ru. Unlike Google Maps, key is not tied to Bundle ID / applicationId on creation — restrictions configured separately in dashboard.
Android:
// build.gradle
implementation("com.yandex.android:maps.mobile:4.6.1-full")
// Application.onCreate()
MapKitFactory.setApiKey("YOUR_API_KEY")
MapKitFactory.initialize(this)
iOS (Swift Package Manager):
// Package.swift dependency:
// .package(url: "https://github.com/yandex/mapkit-ios-demo", from: "4.6.1")
// AppDelegate / App init:
import YandexMapsMobile
MapKit.setApiKey("YOUR_API_KEY")
Initialization must happen before creating first MapView. Forgotten MapKitFactory.initialize on Android gives IllegalStateException with unclear message about API key not set, even though setApiKey called.
Android Map Work
class MapActivity : AppCompatActivity(), MapObjectTapListener {
private lateinit var mapView: MapView
private lateinit var mapObjects: MapObjectCollection
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_map)
mapView = findViewById(R.id.mapView)
MapKitFactory.getInstance().onStart()
mapView.onStart()
val map = mapView.mapWindow.map
map.move(
CameraPosition(Point(55.7558, 37.6173), 12f, 0f, 0f)
)
mapObjects = map.mapObjects.addCollection()
addMarker(Point(55.7558, 37.6173), "Center")
}
private fun addMarker(point: Point, text: String) {
val placemark = mapObjects.addPlacemark().apply {
geometry = point
setIcon(ImageProvider.fromBitmap(createBitmapIcon()))
addTapListener(this@MapActivity)
}
val textStyle = TextStyle().apply {
this.size = 12f
placement = TextStyle.Placement.BOTTOM
}
placemark.setText(text, textStyle)
}
override fun onMapObjectTap(mapObject: MapObject, point: Point): Boolean {
Toast.makeText(this, (mapObject as? PlacemarkMapObject)?.getText() ?: "", Toast.LENGTH_SHORT).show()
return true
}
override fun onStop() {
mapView.onStop()
MapKitFactory.getInstance().onStop()
super.onStop()
}
}
Lifecycle methods mapView.onStart() / mapView.onStop() — mandatory. Skipping onStop leads to memory leak and continued rendering in background.
Search and Geocoding via Search API
val searchManager = SearchFactory.getInstance()
.createSearchManager(SearchManagerType.COMBINED)
val searchSession = searchManager.submit(
"cafes nearby",
VisibleRegionUtils.toPolygon(mapView.mapWindow.map.visibleRegion),
SearchOptions().apply {
searchTypes = SearchType.BIZ.value
resultPageSize = 20
},
object : Session.SearchListener {
override fun onSearchResponse(response: Response) {
for (item in response.collection.children) {
val point = item.obj?.geometry?.firstOrNull()?.point ?: continue
addMarker(point, item.obj?.name ?: "")
}
}
override fun onSearchError(error: Error) {}
}
)
Routes: DrivingRouter
val drivingRouter = DirectionsFactory.getInstance().createDrivingRouter(DrivingRouterType.COMBINED)
val points = listOf(
RequestPoint(Point(55.7558, 37.6173), RequestPointType.WAYPOINT, null, null),
RequestPoint(Point(59.9343, 30.3351), RequestPointType.WAYPOINT, null, null)
)
drivingRouter.requestRoutes(
points,
DrivingOptions().apply { routesCount = 1 },
VehicleOptions(),
object : DrivingSession.DrivingRouteListener {
override fun onDrivingRoutes(routes: MutableList<DrivingRoute>) {
if (routes.isNotEmpty()) {
mapView.mapWindow.map.mapObjects.addPolyline(routes[0].geometry)
}
}
override fun onDrivingRoutesError(error: Error) {}
}
)
Timeline
1–3 days. Basic map with markers — 1 day. Search + routes + custom icons — 2–3 days. Cost calculated individually.







