Hello, I’m trying to implement a iOS delegate on my actual
implementation of kotlin.
I cannot do the delegate implementation because of gaps on kotlin knowledge. Im trying to doing this:
actual fun Location.getLocation(
getLocation: (location: GeoPoint) -> Unit
) {
locationManager.requestWhenInUseAuthorization()
locationManager.setDelegate(CLLocationManagerDelegate(CLLocationManagerImpl()))
locationManager.location?.coordinate.let { clLocation ->
val location = clLocation as CLLocationCoordinate2D
getLocation(GeoPoint(location.latitude, location.longitude))
}
}
class CLLocationManagerImpl: CLLocationManagerDelegateProtocol, NSObject() {
override fun locationManager(manager: CLLocationManager, didStartMonitoringFromRegion: CLRegion) {
val location = didStartMonitoringFromRegion.center as CLLocationCoordinate2D
print("Impl Found user's latutide: ${location.latitude}")
}
}
class CLLocationManagerDelegate(delegate: CLLocationManagerDelegateProtocol) : CLLocationManagerDelegateProtocol by delegate {
override public open fun locationManager(manager: CLLocationManager, didStartMonitoringFromRegion: CLRegion) {
val location = didStartMonitoringFromRegion.center as CLLocationCoordinate2D
print("Delegate Found user's latutide: ${location.latitude}")
}
}
On this approach the problem is that the compiler says 'locationManager' overrides nothing
and Conflicting overloads: public open fun locationManager(manager: CLLocation...
between implementation and delegate.
On the other hand if I try to doing the implementation without the NSObject
inheritance this force me to implement object methods and cannot calls the same super methods on overrides
class CLLocationManagerImpl: CLLocationManagerDelegateProtocol {
// Here force to me to implement many fun of NSObject without access to super functions
override fun locationManager(manager: CLLocationManager, didStartMonitoringFromRegion: CLRegion) {
val location = didStartMonitoringFromRegion.center as CLLocationCoordinate2D
print("Impl Found user's latutide: ${location.latitude}")
}
}
Hello, @guillodacosta!
On the first sight, I assume you just misspelled the input parameter name for the locationManager(...)
function. As I can see, there is a didStartMonitoringForRegion
parameter, not the ...FromRegion
. When I fixed it, your sample has built correctly. Please give this a try, and tell if it won’t help.
Thanks @Artyom.Degtyarev, I fix it but I cannot compile yet, when is not a problem is other on my project. I update the code at moment.
actual fun Location.getLocation(onGetLocation: (location: GeoPoint) -> Unit) {
locationManager.setDelegate(CLLocationManagerDelegate(CLLocationManagerDelegateImpl()))
locationManager.requestWhenInUseAuthorization()
}
class CLLocationManagerDelegateImpl: CLLocationManagerDelegateProtocol, NSObject() {
override fun locationManager(manager: CLLocationManager, didUpdateLocations: List<*>) {
didUpdateLocations.last { lastLocation ->
val location = lastLocation as CLLocation
location.coordinate.let { print("Impl Found user's latutide: ${it}") }
return
}
}
}
private class CLLocationManagerDelegate(delegate: CLLocationManagerDelegateProtocol) : CLLocationManagerDelegateProtocol by delegate, NSObject() {
@Suppress("CONFLICTING_OVERLOADS")
override fun locationManager(manager: CLLocationManager, didStartMonitoringForRegion: CLRegion) {
//super.locationManager(manager, didStartMonitoringForRegion = didStartMonitoringForRegion)
}
@Suppress("CONFLICTING_OVERLOADS")
override fun locationManager(manager: CLLocationManager, didEnterRegion: CLRegion) {
//super.locationManager(manager, didEnterRegion = didEnterRegion)
}
@Suppress("CONFLICTING_OVERLOADS")
override fun locationManager(manager: CLLocationManager, didExitRegion: CLRegion) {}
override fun locationManager(manager: CLLocationManager, didUpdateLocations: List<*>) {
didUpdateLocations.last { lastLocation ->
val location = lastLocation as CLLocation
location.coordinate.let { print("Delegate Found user's latutide: ${it}") }
return
}
}
}
Whit this I have many questions and problems.
If I don’t use or create the CLLocationManagerDelegate
instead this I use only the CLLocationManagerDelegateImpl
like delegate, never enter to locationManager
in delegate although is the only way it compiles.
If I don’t use the NSObject()
the class request the overrides of same
If I did not applied the 3 locationManager
functions the class request the overrides of same
If I did applied the override of three locationManager, the static code verification say is not possible because is same signature
If I add the @Suppress("CONFLICTING_OVERLOADS")
to the locationManagers
the compiler present a weir error with all classes of project.
e
Compilation failed: Collection is empty.
* Source files: Failure.kt.... all classes
* Compiler version info: Konan: 1.2.1 / Kotlin: 1.3.31
* Output kind: FRAMEWORK
e: java.util.NoSuchElementException: Collection is empty....
First of all, I’d recommend using the most recent release of the compiler(it’s 1.3.50 currently). Also please provide full stack-trace and some kind of a reproduce steps if possible. I’m not sure whether it is a compiler issue or a mistake in the realization.
Thanks again @Artyom.Degtyarev
I did updated the compiler to 1.3.50
and I finally can compile the project but now I see a runtime error when I try to assign the delegate locationManager.setDelegate(derived)
.
The actual error showing in my xcode on runtime is:
/Users/teamcity/buildAgent/work/4d622a065c544371/runtime/src/main/cpp/ObjCInterop.cpp:125: runtime assert: Unable to add method to Objective-C class
Where teamcity is not even a user from my machine.
I show to you the code like actually I’m working:
actual fun Location.getLocation(onGetLocation: (location: GeoPoint) -> Unit) {
val delegate = CLLocationManagerDelegateImpl()
val derived = CLLocationManagerDelegate(delegate)
locationManager.setDelegate(derived)
locationManager.requestWhenInUseAuthorization()
}
class CLLocationManagerDelegateImpl: CLLocationManagerDelegateProtocol, NSObject() {
override fun locationManager(manager: CLLocationManager, didUpdateLocations: List<*>) {
didUpdateLocations.last { lastLocation ->
val location = lastLocation as CLLocation
location.coordinate.let { print("DelegateImpl found user's latitude: ${it}") }
return
}
}
}
@Suppress("CONFLICTING_OVERLOADS")
class CLLocationManagerDelegate(delegate: CLLocationManagerDelegateProtocol) : CLLocationManagerDelegateProtocol by delegate, NSObject() {
override fun locationManager(manager: CLLocationManager, didStartMonitoringForRegion: CLRegion) {}
override fun locationManager(manager: CLLocationManager, didEnterRegion: CLRegion) {}
override fun locationManager(manager: CLLocationManager, didExitRegion: CLRegion) {}
}
By last, I allredy cleaned deriveddata
and gradle caches
Sorry, but I cannot tell something more informative without a reproducer.