AppNavigator.openMap() now works on iOS
Also implemented currently unused AppNavigator.openWalkingDirections()
This commit is contained in:
@@ -1,7 +1,49 @@
|
|||||||
|
@file:OptIn(ExperimentalForeignApi::class)
|
||||||
|
|
||||||
package app.klottr.platform
|
package app.klottr.platform
|
||||||
|
|
||||||
import platform.Foundation.NSURL
|
import kotlinx.cinterop.ExperimentalForeignApi
|
||||||
|
import kotlinx.cinterop.useContents
|
||||||
|
import platform.Foundation.NSURL
|
||||||
import platform.UIKit.UIApplication
|
import platform.UIKit.UIApplication
|
||||||
|
import platform.Foundation.NSURLComponents
|
||||||
|
import platform.Foundation.NSURLQueryItem
|
||||||
|
import platform.darwin.dispatch_async
|
||||||
|
import platform.darwin.dispatch_get_main_queue
|
||||||
|
import platform.Foundation.*
|
||||||
|
|
||||||
|
private fun urlEncode(query: String): String {
|
||||||
|
// Percent-encode for use in URL query
|
||||||
|
val encoded = (query as NSString)
|
||||||
|
.stringByAddingPercentEncodingWithAllowedCharacters(
|
||||||
|
NSCharacterSet.URLQueryAllowedCharacterSet()
|
||||||
|
)
|
||||||
|
return encoded ?: query
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private fun isAtLeast(major: Int, minor: Int = 0, patch: Int = 0): Boolean {
|
||||||
|
val current = NSProcessInfo.processInfo.operatingSystemVersion
|
||||||
|
return current.useContents {
|
||||||
|
when {
|
||||||
|
this.majorVersion > major -> true
|
||||||
|
this.majorVersion < major -> false
|
||||||
|
this.minorVersion > minor -> true
|
||||||
|
this.minorVersion < minor -> false
|
||||||
|
else -> this.patchVersion >= patch
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun openUrlOnMain(url: NSURL) {
|
||||||
|
dispatch_async(dispatch_get_main_queue()) {
|
||||||
|
UIApplication.sharedApplication.openURL(
|
||||||
|
url,
|
||||||
|
options = emptyMap<Any?, Any?>(),
|
||||||
|
completionHandler = null
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
actual object AppNavigator {
|
actual object AppNavigator {
|
||||||
actual fun openUrl(url: String) {
|
actual fun openUrl(url: String) {
|
||||||
@@ -10,13 +52,35 @@ actual object AppNavigator {
|
|||||||
}
|
}
|
||||||
actual fun openMap(lat: Double, lon: Double, label: String?) {
|
actual fun openMap(lat: Double, lon: Double, label: String?) {
|
||||||
// Use Apple Maps URL scheme
|
// Use Apple Maps URL scheme
|
||||||
val encoded = label?.let { it } ?: "Place"
|
// This always opens apple maps, regardless of what navigation app you've set in system settings.
|
||||||
val url = "http://maps.apple.com/?ll=$lat,$lon&q=$encoded"
|
// There seems to be no way around that without implementing your own chooser.
|
||||||
openUrl(url)
|
val comps = NSURLComponents(string = "maps://")
|
||||||
|
comps.path = "/"
|
||||||
|
comps.queryItems = listOf(
|
||||||
|
NSURLQueryItem(name = "ll", value = "$lat,$lon"),
|
||||||
|
NSURLQueryItem(name = "q", value = label ?: "Place")
|
||||||
|
)
|
||||||
|
val nsUrl = comps.URL ?: return
|
||||||
|
openUrlOnMain(nsUrl)
|
||||||
}
|
}
|
||||||
|
|
||||||
actual fun openWalkingDirections(lat: Double?, lon: Double?, title: String?) {
|
actual fun openWalkingDirections(lat: Double?, lon: Double?, title: String?) {
|
||||||
//TODO: Implement
|
// On iOS 18.4+ there is a "default navigation app" setting in EU countries.
|
||||||
|
// This implementation makes sure to use it if available
|
||||||
|
|
||||||
|
// Build a destination string. You can replace this with a full address if you have one.
|
||||||
|
val destination = "$lat,$lon"
|
||||||
|
val encoded = urlEncode(destination)
|
||||||
|
|
||||||
|
val urlString = if (isAtLeast(18, 4, 0)) {
|
||||||
|
// iOS routes this to the user's chosen default navigation app
|
||||||
|
"geo-navigation:///directions?destination=$encoded"
|
||||||
|
} else {
|
||||||
|
// Apple Maps fallback: driving directions to destination
|
||||||
|
"maps://?daddr=$encoded&dirflg=d"
|
||||||
|
}
|
||||||
|
|
||||||
|
openUrlOnMain((NSURL(string = urlString)))
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user