Reputation: 225
I followed the tutorial: https://kotlinlang.org/docs/tutorials/native/mpp-ios-android.html and successfully export a jar file for Android and a framework for iOS. After I want to implement something more complex. I uses Android Studio Kotlin with the codes below:
Model.kt:
package org.kotlin.mpp.mobile.BusinessLogic
abstract class Model{
var _id:Long = 0
abstract fun PolymorphismTest()
}
Sales.kt:
package org.kotlin.mpp.mobile.BusinessLogic
class Sales : Model() {
init {
this._id = _counter
_counter++
}
companion object {
private var _counter: Long = 0
}
fun get_counter(): Long {
return _counter
}
private val _salesItems:MutableList<SalesItem> = ArrayList()
fun SalesItems(): MutableList<SalesItem> {
return _salesItems
}
fun TotalAmount():Double
{
var totalAmount:Double = 0.0
for(aSalesItem in _salesItems)
{
totalAmount += aSalesItem.SubTotal()
}
return totalAmount
}
fun AddSalesItem(salesItem: SalesItem)
{
this._salesItems.add(salesItem)
}
fun AddSalesItem(itemName:String, itemCode:String, quantity:Double, amount:Double )
{
val aSalesItem = SalesItem()
aSalesItem._itemCode = itemCode
aSalesItem._itemName = itemName
aSalesItem._quantity = quantity
aSalesItem._amount = amount
this.AddSalesItem(aSalesItem)
}
fun ToString(): String {
return "Sales: $this._id"
}
override fun PolymorphismTest() {
println("This is method from Sales")
}
}
SalesItem.kt:
package org.kotlin.mpp.mobile.BusinessLogic
class SalesItem : Model() {
init {
this._id = _counter
_counter++
}
companion object {
private var _counter: Long = 0
}
fun get_counter(): Long {
return _counter
}
var _sales: Sales? = null
var _amount:Double = 0.toDouble()
var _quantity:Double = 0.toDouble()
fun SubTotal(): Double {
return _amount * _quantity
}
var _itemName:String? = null
var _itemCode:String? = null
fun Sales():Sales?{
return _sales
}
fun SalesItem(sales:Sales)
{
_sales = sales
this._id = _counter
_counter++
}
fun ToString(): String {
return "Sales: $this._id"
}
override fun PolymorphismTest() {
println("This is method from SalesItem")
}
}
I export these codes into a framework then imported into Xcode and using Swift to call
ViewController.swift
import UIKit
import SharedCode
class ViewController: UIViewController{
override func viewDidLoad(){
super.viewDidLoad()
print("Creating Sales Object")
let sales = Sales() //error here
}
}
After that I met the errors of
Instances of kotlin.Error, kotlin.RuntimeException and subclasses aren't propagated from Kotlin to Objective-C/Swift. Other exceptions can be propagated as NSError if method has or inherits @Throws annotation. Uncaught Kotlin exception: kotlin.native.concurrent.InvalidMutabilityException: mutation attempt of frozen org.kotlin.mpp.mobile.BusinessLogic.Sales.Companion@228b588 at 0 SharedCode
Upvotes: 2
Views: 3219
Reputation: 4992
Kotlin/Native has different threading model. The idea is that an instance of an object has to be frozen to be accessed from all threads. There is .freeze()
extension method for that.
By default, object Smth
are also frozen. In the code sniper you have mutable fields in companion object.
A possible workaround could be to replace companion object with an ordinary class, that you create explicitly
https://kotlinlang.org/docs/reference/native/concurrency.html#concurrency-in-kotlinnative
https://kotlinlang.org/docs/reference/native/immutability.html#immutability-in-kotlinnative
Upvotes: 2