Skip to content

Latest commit

 

History

History
136 lines (102 loc) · 5.91 KB

File metadata and controls

136 lines (102 loc) · 5.91 KB

moko-kswift overview

moko-kswift - Gradle-плагин, разработанный командой IceRock, для генерации Swift-friendly кода для Kotlin/Native.

Проверка работы плагина

Фича Kotlin-а Ожидание Статус Комментарий
sealed-класс Сгенерируется bridge-код для перевода класса в enum Всё ок 👍
sealed-класс с глубокой иерархией Сгенерируется bridge-код для перевода в один enum ⚠️ Генерируется по enum-у для каждого sealed-класса вместо одного
sealed-интерфейс Сгенерируется bridge-код для перевода в enum Всё ок (y)
extension function over platform class Сгенерируется extension на стороне Swift-а ⚠️ Платформенные классы - это классы из пакета platform.*

Sealed class with deep hierarchy

Допустим, была вот такая иерархия классов:

sealed class SealedWithDeepHierarchy {  
  
    abstract val param: String  
  
    sealed class LocalTrigger : SealedWithDeepHierarchy() {  
        object First : LocalTrigger() {  
            override val param: String = "first"  
 		}  
    }  
  
    sealed class RemoteTrigger : SealedWithDeepHierarchy() {  
        class Second(override val param: String) : RemoteTrigger()  
        data class Third(override val param: String) : RemoteTrigger()  
    }  
  
}

На стороне Kotlin-а такие классы очень удобно разворачивать внутри when-выражения:

private fun example(s: SealedWithDeepHierarchy) {  
    when (s) {  
        SealedWithDeepHierarchy.LocalTrigger.First -> TODO()  
        is SealedWithDeepHierarchy.RemoteTrigger.Second -> TODO()  
        is SealedWithDeepHierarchy.RemoteTrigger.Third -> TODO()  
    }  
}

С moko-swift сгенерировался вот такой swift-код:

public enum SealedWithDeepHierarchyLocalTriggerKs {  
  
  case first  
  
  public init(_ obj: SealedWithDeepHierarchy.LocalTrigger) {  
    if obj is HHMobileSdk.SealedWithDeepHierarchy.LocalTriggerFirst {  
      self = .first  
    } else {  
      fatalError("SealedWithDeepHierarchyLocalTriggerKs not syncronized with SealedWithDeepHierarchy.LocalTrigger class")  
    }  
  }  
  
}  
  
public enum SealedWithDeepHierarchyRemoteTriggerKs {  
  
  case second(SealedWithDeepHierarchy.RemoteTriggerSecond)  
  case third(SealedWithDeepHierarchy.RemoteTriggerThird)  
  
  public init(_ obj: SealedWithDeepHierarchy.RemoteTrigger) {  
    if let obj = obj as? HHMobileSdk.SealedWithDeepHierarchy.RemoteTriggerSecond {  
      self = .second(obj)  
    } else if let obj = obj as? HHMobileSdk.SealedWithDeepHierarchy.RemoteTriggerThird {  
      self = .third(obj)  
    } else {  
      fatalError("SealedWithDeepHierarchyRemoteTriggerKs not syncronized with SealedWithDeepHierarchy.RemoteTrigger class")  
    }  
  }  
  
}  
  
public enum SealedWithDeepHierarchyKs {  
  
  case localTrigger(SealedWithDeepHierarchy.LocalTrigger)  
  case remoteTrigger(SealedWithDeepHierarchy.RemoteTrigger)  
  
  public init(_ obj: SealedWithDeepHierarchy) {  
    if let obj = obj as? HHMobileSdk.SealedWithDeepHierarchy.LocalTrigger {  
      self = .localTrigger(obj)  
    } else if let obj = obj as? HHMobileSdk.SealedWithDeepHierarchy.RemoteTrigger {  
      self = .remoteTrigger(obj)  
    } else {  
      fatalError("SealedWithDeepHierarchyKs not syncronized with SealedWithDeepHierarchy class")  
    }  
  }  
  
}

И соответственно, использовать это можно вот так:

func mokoKswiftUsage(c: SealedWithDeepHierarchy) {
        switch SealedWithDeepHierarchyKs(c) {
        
        case let .localTrigger(tr):
            switch SealedWithDeepHierarchyLocalTriggerKs(tr) {
            case .first:
                <#code#>
            }
            
            
        case let .remoteTrigger(tr):
            switch SealedWithDeepHierarchyRemoteTriggerKs(tr) {
            case .second(_):
                <#code#>
            case .third(_):
                <#code#>
            }
        }
    }

Для большего удобства хорошо бы иметь единый enum.

Extension function over platform class

Ожидал, что это сработает для любого платформенного класса. Мы считаем платформенными классами любые классы типов (String / Int / Boolean / etc) + какие-то специфичные платформенные (тот же platform.UIKit.UILabel для iOS).

Но оказалось, что учитываются только платформенные, у которых в package name-е 3 части, первая из которых равна platform.

Поэтому для fun String.myExtensionFunction() маппинг не сработал.