Upgrade to Pro — share decks privately, control downloads, hide ads and more …

逆引きKotlin Multiplatform 〜Swiftに対応するKotlinの機能と、K...

Taiki Suzuki
October 19, 2023

逆引きKotlin Multiplatform 〜Swiftに対応するKotlinの機能と、KMPによる変換後の実態〜

CA.swift #17
https://cyberagent.connpass.com/event/294197/
https://fortee.jp/iosdc-japan-2023/proposal/e9ffca7b-d40e-4e26-a393-0baf59c001d4

弊チームではKotlin Multiplatformを採用していますが、一部のメンバーが新機能開発等を通して試験運用していたため、本格的にチーム全体で運用し始めたのは2023年からとなります。 そこで、実際のアプリの機能を一部抜粋したチュートリアルプロジェクトを作成し、その演習に取り組んでもらうことでチームメンバーへのKMPのインストールを実施しました。

チュートリアルプロジェクトの一部を使って、Swiftの機能に対応するKotlinの機能を解説しつつ、KMPによって変換されることでSwiftからはどのように参照できるのかを話します。

Taiki Suzuki

October 19, 2023
Tweet

More Decks by Taiki Suzuki

Other Decks in Programming

Transcript

  1. Basic Syntax val value: Int = 0 println("value = $value")

    var value2 = 1 println("value2 = $value2") value2 = 2 println("value2 = $value2") let value: Int = 0 print("value = \(value)") var value2 = 1 print("value2 = \(value2)") value2 = 2 print("value2 = \(value2)")
  2. Basic Syntax val value: Int = 0 println("value = $value")

    var value2 = 1 println("value2 = $value2") value2 = 2 println("value2 = $value2") let value: Int = 0 print("value = \(value)") var value2 = 1 print("value2 = \(value2)") value2 = 2 print("value2 = \(value2)") valͰఆ਺ͷએݴΛ͢Δ
 ܕͷએݴ͸Swiftͱಉ༷ͳ༷ࣜͰলུ΋Ͱ͖Δ
  3. Basic Syntax val value: Int = 0 println("value = $value")

    var value2 = 1 println("value2 = $value2") value2 = 2 println("value2 = $value2") let value: Int = 0 print("value = \(value)") var value2 = 1 print("value2 = \(value2)") value2 = 2 print("value2 = \(value2)") จࣈྻʹม׵͍ͨ͠৔߹͸$Xxx ϝϯόʔΛม׵͍ͨ͠৔߹͸${Xxx.Yyy}
  4. Basic Syntax val value: Int = 0 println("value = $value")

    var value2 = 1 println("value2 = $value2") value2 = 2 println("value2 = $value2") let value: Int = 0 print("value = \(value)") var value2 = 1 print("value2 = \(value2)") value2 = 2 print("value2 = \(value2)") varͰม਺ͷએݴΛ͢Δ
  5. Function fun sum(lhs: Int, rhs: Int = 0,): Int {

    return lhs + rhs } fun sum(lhs: Int, rhs: Int = 0,): Int = lhs + rhs val result = sum(rhs = 1, 2,) func sum(lhs: Int, rhs: Int = 0) -> Int { return lhs + rhs } let result = sum(lhs: 1, rhs: 2)
  6. Function fun sum(lhs: Int, rhs: Int = 0,): Int {

    return lhs + rhs } fun sum(lhs: Int, rhs: Int = 0,): Int = lhs + rhs val result = sum(rhs = 1, 2,) func sum(lhs: Int, rhs: Int = 0) -> Int { return lhs + rhs } let result = sum(lhs: 1, rhs: 2) funͰؔ਺Λએݴ͢Δ Swiftͱಉ༷ʹσϑΥϧτҾ਺ΛఆٛͰ͖Δ ࠷ޙʹఆٛͨ͠Ҿ਺ͷʮ,ʯΛলུ΋Ͱ͖Δ
  7. Function fun sum(lhs: Int, rhs: Int = 0,): Int {

    return lhs + rhs } fun sum(lhs: Int, rhs: Int = 0,): Int = lhs + rhs val result = sum(rhs = 1, 2,) func sum(lhs: Int, rhs: Int = 0) -> Int { return lhs + rhs } let result = sum(lhs: 1, rhs: 2) { … }ͰׅΒͣʹɺʮ=ʯͰ݁ՌΛฦ͢ॻ͖ํ΋Ͱ͖Δ
  8. Function fun sum(lhs: Int, rhs: Int = 0,): Int {

    return lhs + rhs } fun sum(lhs: Int, rhs: Int = 0,): Int = lhs + rhs val result = sum(rhs = 1, 2,) func sum(lhs: Int, rhs: Int = 0) -> Int { return lhs + rhs } let result = sum(lhs: 1, rhs: 2) Ҿ਺໊͸লུ΋Ͱ͖Δ ࠷ޙͷҾ਺ͷʮ,ʯΛলུ΋Ͱ͖Δ
  9. Function fun sum(lhs: Int, rhs: Int = 0,): Int {

    return lhs + rhs } fun sum(lhs: Int, rhs: Int = 0,): Int = lhs + rhs val result = sum(rhs = 1, 2,) FilenameKt.sum(lhs: Int32, rhs: Int32) -> Int32 📦 shared.framework
  10. Function fun sum(lhs: Int, rhs: Int = 0,): Int {

    return lhs + rhs } fun sum(lhs: Int, rhs: Int = 0,): Int = lhs + rhs val result = sum(rhs = 1, 2,) FilenameKt.sum(lhs: Int32, rhs: Int32) -> Int32 📦 shared.framework KMPʹΑͬͯੜ੒͞ΕͨFrameworkΛ Swift͔Βࢀরͨ͠ͱ͖ͷݟ͑ํ
  11. Function fun sum(lhs: Int, rhs: Int = 0,): Int {

    return lhs + rhs } fun sum(lhs: Int, rhs: Int = 0,): Int = lhs + rhs val result = sum(rhs = 1, 2,) FilenameKt.sum(lhs: Int32, rhs: Int32) -> Int32 📦 shared.framework __attribute__((swift_name("FilenameKt"))) @interface SharedFilenameKt : SharedBase + (int32_t)sumLhs:(int32_t)lhs rhs:(int32_t)rhs __attribute__((swift_name("sum(lhs:rhs:)"))); @end __attribute__((swift_name("KotlinBase"))) @interface SharedBase : NSObject - (instancetype)init __attribute__((unavailable)); + (instancetype)new __attribute__((unavailable)); + (void)initialize __attribute__((objc_requires_super)); @end
  12. Function fun sum(lhs: Int, rhs: Int = 0,): Int {

    return lhs + rhs } fun sum(lhs: Int, rhs: Int = 0,): Int = lhs + rhs val result = sum(rhs = 1, 2,) FilenameKt.sum(lhs: Int32, rhs: Int32) -> Int32 📦 shared.framework __attribute__((swift_name("FilenameKt"))) @interface SharedFilenameKt : SharedBase + (int32_t)sumLhs:(int32_t)lhs rhs:(int32_t)rhs __attribute__((swift_name("sum(lhs:rhs:)"))); @end __attribute__((swift_name("KotlinBase"))) @interface SharedBase : NSObject - (instancetype)init __attribute__((unavailable)); + (instancetype)new __attribute__((unavailable)); + (void)initialize __attribute__((objc_requires_super)); @end KotlinͰάϩʔόϧؔ਺ͱͯ͠fun sumΛఆ͍ٛͯͨ͠ͷͰ {ఆ͍ٛͯ͠ΔϑΝΠϧ໊}Ktͷ໋໊نଇͰΫϥε͕ੜ੒͞Ε ͦͷΫϥεؔ਺ͱͯ͠ग़ྗ͞ΕΔ
  13. Function fun sum(lhs: Int, rhs: Int = 0,): Int {

    return lhs + rhs } fun sum(lhs: Int, rhs: Int = 0,): Int = lhs + rhs val result = sum(rhs = 1, 2,) FilenameKt.sum(lhs: Int32, rhs: Int32) -> Int32 📦 shared.framework __attribute__((swift_name("FilenameKt"))) @interface SharedFilenameKt : SharedBase + (int32_t)sumLhs:(int32_t)lhs rhs:(int32_t)rhs __attribute__((swift_name("sum(lhs:rhs:)"))); @end __attribute__((swift_name("KotlinBase"))) @interface SharedBase : NSObject - (instancetype)init __attribute__((unavailable)); + (instancetype)new __attribute__((unavailable)); + (void)initialize __attribute__((objc_requires_super)); @end ੜ੒͞ΕΔΫϥε͸جຊతʹʮKotlinBaseʯΛܧঝ͍ͯ͠Δ ͦͷ࣮ଶ͸NSObjectͷαϒΫϥεͰɺSwift͔Β͸୯ମͰ ΠϯελϯεԽ͢Δ͜ͱ͕Ͱ͖ͳ͍Ϋϥε
  14. Function fun sum(lhs: Int, rhs: Int = 0,): Int {

    return lhs + rhs } fun sum(lhs: Int, rhs: Int = 0,): Int = lhs + rhs val result = sum(rhs = 1, 2,) FilenameKt.sum(lhs: Int32, rhs: Int32) -> Int32 📦 shared.framework ͪͳΈʹ਺஋ܕͷϚοϐϯά͸࣍ͷΑ͏ʹͳΓ·͢
  15. Function fun getByte(): Byte = 10 fun getUByte(): UByte =

    10U fun getShort(): Short = 10 fun getUShot(): UShort = 10U fun getInt(): Int = 10 fun getUInt(): UInt = 10U fun getLong(): Long = 10L fun getULong(): ULong = 10UL fun getFloat(): Float = 10F fun getDouble(): Double = 10.0 let byte: Int8 = FilenameKt.getByte() let ubyte: UInt8 = FilenameKt.getUByte() let short: Int16 = FilenameKt.getShort() let ushort: UInt16 = FilenameKt.getUShot() let int: Int32 = FilenameKt.getInt() let uint: UInt32 = FilenameKt.getUInt() let long: Int64 = FilenameKt.getLong() let ulong: UInt64 = FilenameKt.getULong() let float: Float = FilenameKt.getFloat() let double: Double = FilenameKt.getDouble() 📦 shared.framework
  16. Closure val minus: (Int, Int) -> Int = { lhs:

    Int, rhs, -> lhs - rhs } val plus2: (Int) -> Int = { it + 2 } let minus: (Int, Int) -> Int = { lhs, rhs in lhs - rhs } let plus2: (Int) -> Int = { $0 + 2 }
  17. Closure val minus: (Int, Int) -> Int = { lhs:

    Int, rhs, -> lhs - rhs } val plus2: (Int) -> Int = { it + 2 } let minus: (Int, Int) -> Int = { lhs, rhs in lhs - rhs } let plus2: (Int) -> Int = { $0 + 2 } SwiftͷClosure͸KotlinͷLambdaͱରԠ͢Δ એݴͷ࢓ํ͸جຊతʹಉ͡
  18. Closure val minus: (Int, Int) -> Int = { lhs:

    Int, rhs, -> lhs - rhs } val plus2: (Int) -> Int = { it + 2 } let minus: (Int, Int) -> Int = { lhs, rhs in lhs - rhs } let plus2: (Int) -> Int = { $0 + 2 } Ҿ਺Λলུ͢Δ৔߹͸ʮitʯͰΞΫηε͢Δ
  19. If expression if (result % 2 == 0) { println("result

    is even number") } else { println("result is odd number") } val ifResult = if (result % 2 == 0) { "even number" } else { "odd number" } println("ifResult = $ifResult") if result % 2 == 0 { print("result is even number") } else { print("result is odd number") } let ifResult = if result % 2 == 0 { "even number" } else { "odd number" } print("ifResult = \(ifResult)")
  20. If expression if (result % 2 == 0) { println("result

    is even number") } else { println("result is odd number") } val ifResult = if (result % 2 == 0) { "even number" } else { "odd number" } println("ifResult = $ifResult") if result % 2 == 0 { print("result is even number") } else { print("result is odd number") } let ifResult = if result % 2 == 0 { "even number" } else { "odd number" } print("ifResult = \(ifResult)") ( )Λলུ͢Δ͜ͱ͸Ͱ͖ͳ͍
  21. If expression if (result % 2 == 0) { println("result

    is even number") } else { println("result is odd number") } val ifResult = if (result % 2 == 0) { "even number" } else { "odd number" } println("ifResult = $ifResult") if result % 2 == 0 { print("result is even number") } else { print("result is odd number") } let ifResult = if result % 2 == 0 { "even number" } else { "odd number" } print("ifResult = \(ifResult)") Swift 5.9Ͱಋೖ͞Εͨif and switch expressionsͱಉ༷ʹ ifจ಺Ͱ஋Λฦͯ͠ఆ਺ɾม਺ʹ୅ೖ͢Δ͜ͱ͕Ͱ͖Δ
  22. Switch expression when (result % 2) { 0 -> {

    println("result is even number") } 1 -> { println("result is odd number") } else -> println("unknown") } val whenResult = when (result % 2) { 0 -> "result is even number" 1 -> "result is odd number" else -> "unknown" } println("whenResult = $whenResult") switch result % 2 { case 0: print("result is even number") case 1: print("result is odd number") default: print("unknown") } let whenResult = switch result % 2 { case 0: "result is even number" case 1: "result is odd number" default: "unknown" } print("whenResult = \(whenResult)")
  23. Switch expression when (result % 2) { 0 -> {

    println("result is even number") } 1 -> { println("result is odd number") } else -> println("unknown") } val whenResult = when (result % 2) { 0 -> "result is even number" 1 -> "result is odd number" else -> "unknown" } println("whenResult = $whenResult") switch result % 2 { case 0: print("result is even number") case 1: print("result is odd number") default: print("unknown") } let whenResult = switch result % 2 { case 0: "result is even number" case 1: "result is odd number" default: "unknown" } print("whenResult = \(whenResult)") switch෼ʹରԠ͢Δͷ͕whenจ
  24. Switch expression when (result % 2) { 0 -> {

    println("result is even number") } 1 -> { println("result is odd number") } else -> println("unknown") } val whenResult = when (result % 2) { 0 -> "result is even number" 1 -> "result is odd number" else -> "unknown" } println("whenResult = $whenResult") switch result % 2 { case 0: print("result is even number") case 1: print("result is odd number") default: print("unknown") } let whenResult = switch result % 2 { case 0: "result is even number" case 1: "result is odd number" default: "unknown" } print("whenResult = \(whenResult)") ֘౰ͷέʔεΛࢦఆ͠ʮ-> { … }ʯͰର৅ͷॲཧΛهࡌ͢Δ 1ߦͷ৔߹͸{ }Λলུ΋Ͱ͖Δ
  25. Switch expression when (result % 2) { 0 -> {

    println("result is even number") } 1 -> { println("result is odd number") } else -> println("unknown") } val whenResult = when (result % 2) { 0 -> "result is even number" 1 -> "result is odd number" else -> "unknown" } println("whenResult = $whenResult") switch result % 2 { case 0: print("result is even number") case 1: print("result is odd number") default: print("unknown") } let whenResult = switch result % 2 { case 0: "result is even number" case 1: "result is odd number" default: "unknown" } print("whenResult = \(whenResult)") ifจಉ༷ʹఆ਺ɾม਺ʹ஋Λ୅ೖͰ͖Δ
  26. do-catch expression fun throwableMinus(lhs: Int, rhs: Int): Int { val

    result = lhs - rhs if (result < 0) { throw IllegalStateException() } return result } try { val result = throwableMinus(0, 1) println("result = $result") } catch (exception: Exception) { println("exception = $exception") } func throwableMinus(lhs: Int, rhs: Int) throws -> Int { let result = lhs - rhs if (result < 0) { throw NSError() } return result } do { let result = try throwableMinus(lhs: 0, rhs: 1) print("result = \(result)") } catch { print("error = \(error)") }
  27. do-catch expression fun throwableMinus(lhs: Int, rhs: Int): Int { val

    result = lhs - rhs if (result < 0) { throw IllegalStateException() } return result } try { val result = throwableMinus(0, 1) println("result = $result") } catch (exception: Exception) { println("exception = $exception") } func throwableMinus(lhs: Int, rhs: Int) throws -> Int { let result = lhs - rhs if (result < 0) { throw NSError() } return result } do { let result = try throwableMinus(lhs: 0, rhs: 1) print("result = \(result)") } catch { print("error = \(error)") } ҟৗܥͷ৔߹ʹExceptionΛ౤͛Δ
  28. do-catch expression fun throwableMinus(lhs: Int, rhs: Int): Int { val

    result = lhs - rhs if (result < 0) { throw IllegalStateException() } return result } try { val result = throwableMinus(0, 1) println("result = $result") } catch (exception: Exception) { println("exception = $exception") } func throwableMinus(lhs: Int, rhs: Int) throws -> Int { let result = lhs - rhs if (result < 0) { throw NSError() } return result } do { let result = try throwableMinus(lhs: 0, rhs: 1) print("result = \(result)") } catch { print("error = \(error)") } try-catchͰExceptionͷϋϯυϦϯάΛ͢Δ SwiftͷΑ͏ʹdo-catchͰғΘͳ͍ͱΤϥʔʹͳΔػߏ͸ͳ͍
  29. do-catch expression let result = PlatformKt.throwableMinus(lhs: 0, rhs: 1) print("result

    = \(result)") 📦 shared.framework fun throwableMinus(lhs: Int, rhs: Int): Int { val result = lhs - rhs if (result < 0) { throw IllegalStateException() } return result }
  30. do-catch expression let result = PlatformKt.throwableMinus(lhs: 0, rhs: 1) print("result

    = \(result)") 📦 shared.framework fun throwableMinus(lhs: Int, rhs: Int): Int { val result = lhs - rhs if (result < 0) { throw IllegalStateException() } return result } Function doesn't have or inherit @Throws annotation and thus exception isn't propagated from Kotlin to Objective-C/Swift as NSError. It is considered unexpected and unhandled instead. Program will be terminated. Uncaught Kotlin exception: kotlin.IllegalStateException ࣮ߦ࣌ʹKotlinͰ౤͛ΒΕͨException͕ϋϯυϦϯάͰ͖ͣ fatalErrorͰΞϓϦ͕Ϋϥογϡ͢Δ
  31. do-catch expression do { let result = try FilenameKt.throwableMinus( lhs:

    0, rhs: 1 ) print("result = \(result)") } catch { let exception = (error as NSError).kotlinException print(exception as? KotlinIllegalStateException) } 📦 shared.framework @Throws(IllegalStateException::class) fun throwableMinus(lhs: Int, rhs: Int): Int { val result = lhs - rhs if (result < 0) { throw IllegalStateException() } return result }
  32. do-catch expression do { let result = try FilenameKt.throwableMinus( lhs:

    0, rhs: 1 ) print("result = \(result)") } catch { let exception = (error as NSError).kotlinException print(exception as? KotlinIllegalStateException) } 📦 shared.framework @Throws(IllegalStateException::class) fun throwableMinus(lhs: Int, rhs: Int): Int { val result = lhs - rhs if (result < 0) { throw IllegalStateException() } return result } @ThrowsͰ౤͛ΒΕΔExceptionΛ໌ࣔ͢Δͱ SwiftͰtry-catchͰ͖ΔΑ͏ʹͳΔ
  33. do-catch expression do { let result = try FilenameKt.throwableMinus( lhs:

    0, rhs: 1 ) print("result = \(result)") } catch { let exception = (error as NSError).kotlinException print(exception as? KotlinIllegalStateException) } 📦 shared.framework @Throws(IllegalStateException::class) fun throwableMinus(lhs: Int, rhs: Int): Int { val result = lhs - rhs if (result < 0) { throw IllegalStateException() } return result } __attribute__((swift_name("FilenameKt"))) @interface SharedFilenameKt : SharedBase /** * @note This method converts instances of IllegalStateException to errors. * Other uncaught Kotlin exceptions are fatal. */ + (int32_t)throwableMinusLhs:(int32_t)lhs rhs:(int32_t)rhs error:(NSError * _Nullable * _Nullable)error __attribute__((swift_name(“throwableMinus(lhs:rhs:)"))) __attribute__((swift_error(nonnull_error))); @end
  34. do-catch expression do { let result = try FilenameKt.throwableMinus( lhs:

    0, rhs: 1 ) print("result = \(result)") } catch { let exception = (error as NSError).kotlinException print(exception as? KotlinIllegalStateException) } 📦 shared.framework @Throws(IllegalStateException::class) fun throwableMinus(lhs: Int, rhs: Int): Int { val result = lhs - rhs if (result < 0) { throw IllegalStateException() } return result } __attribute__((swift_name("FilenameKt"))) @interface SharedFilenameKt : SharedBase /** * @note This method converts instances of IllegalStateException to errors. * Other uncaught Kotlin exceptions are fatal. */ + (int32_t)throwableMinusLhs:(int32_t)lhs rhs:(int32_t)rhs error:(NSError * _Nullable * _Nullable)error __attribute__((swift_name(“throwableMinus(lhs:rhs:)"))) __attribute__((swift_error(nonnull_error))); @end @ThrowsͰ໌͍ࣔͯ͠ΔExceptionҎ֎͕౤͛ΒΕΔͱ ࣮ߦ࣌ʹfatalErrorͰΞϓϦ͕Ϋϥογϡ͢ΔͷͰ஫ҙ
  35. Tuple fun getPair(): Pair<String, Int> { return "hoge" to 10

    } val pair = getPair() println("first = ${pair.first}") println("second = ${pair.second}") val (string, int) = getPair() println("string = $string") println("int = $int”) val triple = Triple("hoge", 10, false) println("first = ${triple.first}") println("second = ${triple.second}") println("second = ${triple.third}") func getTuple() -> (String, Int) { return ("hoge", 10) } let tuple = getTuple() print("0 = \(tuple.0)") print("1 = \(tuple.1)") let (string, int) = getTuple() print("string = \(string)") print("int = \(int)”) let tuple2 = ("hoge", 10, false) print("0 = \(tuple2.0)") print("1 = \(tuple2.1)") print("2 = \(tuple2.2)")
  36. Tuple fun getPair(): Pair<String, Int> { return "hoge" to 10

    } val pair = getPair() println("first = ${pair.first}") println("second = ${pair.second}") val (string, int) = getPair() println("string = $string") println("int = $int”) val triple = Triple("hoge", 10, false) println("first = ${triple.first}") println("second = ${triple.second}") println("second = ${triple.third}") func getTuple() -> (String, Int) { return ("hoge", 10) } let tuple = getTuple() print("0 = \(tuple.0)") print("1 = \(tuple.1)") let (string, int) = getTuple() print("string = \(string)") print("int = \(int)”) let tuple2 = ("hoge", 10, false) print("0 = \(tuple2.0)") print("1 = \(tuple2.1)") print("2 = \(tuple2.2)") Pairͱ͍͏δΣωϦοΫͳܕ
  37. Tuple fun getPair(): Pair<String, Int> { return "hoge" to 10

    } val pair = getPair() println("first = ${pair.first}") println("second = ${pair.second}") val (string, int) = getPair() println("string = $string") println("int = $int”) val triple = Triple("hoge", 10, false) println("first = ${triple.first}") println("second = ${triple.second}") println("second = ${triple.third}") func getTuple() -> (String, Int) { return ("hoge", 10) } let tuple = getTuple() print("0 = \(tuple.0)") print("1 = \(tuple.1)") let (string, int) = getTuple() print("string = \(string)") print("int = \(int)”) let tuple2 = ("hoge", 10, false) print("0 = \(tuple2.0)") print("1 = \(tuple2.1)") print("2 = \(tuple2.2)") 1ͭ໨ͷ஋͸ fi rstɺ2ͭ໨ͷ஋͸secondͰΞΫηεͰ͖Δ
  38. Tuple fun getPair(): Pair<String, Int> { return "hoge" to 10

    } val pair = getPair() println("first = ${pair.first}") println("second = ${pair.second}") val (string, int) = getPair() println("string = $string") println("int = $int”) val triple = Triple("hoge", 10, false) println("first = ${triple.first}") println("second = ${triple.second}") println("second = ${triple.third}") func getTuple() -> (String, Int) { return ("hoge", 10) } let tuple = getTuple() print("0 = \(tuple.0)") print("1 = \(tuple.1)") let (string, int) = getTuple() print("string = \(string)") print("int = \(int)”) let tuple2 = ("hoge", 10, false) print("0 = \(tuple2.0)") print("1 = \(tuple2.1)") print("2 = \(tuple2.2)") ෼͚ͯऔΓग़͢͜ͱ΋Ͱ͖Δ
  39. Tuple fun getPair(): Pair<String, Int> { return "hoge" to 10

    } val pair = getPair() println("first = ${pair.first}") println("second = ${pair.second}") val (string, int) = getPair() println("string = $string") println("int = $int”) val triple = Triple("hoge", 10, false) println("first = ${triple.first}") println("second = ${triple.second}") println("second = ${triple.third}") func getTuple() -> (String, Int) { return ("hoge", 10) } let tuple = getTuple() print("0 = \(tuple.0)") print("1 = \(tuple.1)") let (string, int) = getTuple() print("string = \(string)") print("int = \(int)”) let tuple2 = ("hoge", 10, false) print("0 = \(tuple2.0)") print("1 = \(tuple2.1)") print("2 = \(tuple2.2)") 3ͭͷ஋Λѻ͍͍ͨ৔߹͸Tripleͱ͍͏ผͳܕΛ࢖͏
  40. Tuple let pair: KotlinPair<NSString, KotlinInt> = FilenameKt.getPair() let first =

    pair.first as String? let second = pair.second?.intValue 📦 shared.framework fun getPair(): Pair<String, Int> { return "hoge" to 10 } val pair = getPair() println("first = ${pair.first}") println("second = ${pair.second}") val (string, int) = getPair() println("string = $string") println("int = $int”) val triple = Triple("hoge", 10, false) println("first = ${triple.first}") println("second = ${triple.second}") println("second = ${triple.third}")
  41. Tuple let pair: KotlinPair<NSString, KotlinInt> = FilenameKt.getPair() let first =

    pair.first as String? let second = pair.second?.intValue 📦 shared.framework fun getPair(): Pair<String, Int> { return "hoge" to 10 } val pair = getPair() println("first = ${pair.first}") println("second = ${pair.second}") val (string, int) = getPair() println("string = $string") println("int = $int”) val triple = Triple("hoge", 10, false) println("first = ${triple.first}") println("second = ${triple.second}") println("second = ${triple.third}") Swift͔ΒΞΫηεͨ͠৔߹͸KotlinPairܕͱͳΔ ޙ΄ͲGenericͷηΫγϣϯͰ΋આ໌͠·͕͢ ܕύϥϝʔλʹAnyObject͕ඞཁʹͳΔͨΊ <String, Int>Ͱ͸ͳ͘<NSString, KotlinInt>ʹͳΔ
  42. Tuple let pair: KotlinPair<NSString, KotlinInt> = FilenameKt.getPair() let first =

    pair.first as String? let second = pair.second?.intValue 📦 shared.framework fun getPair(): Pair<String, Int> { return "hoge" to 10 } val pair = getPair() println("first = ${pair.first}") println("second = ${pair.second}") val (string, int) = getPair() println("string = $string") println("int = $int”) val triple = Triple("hoge", 10, false) println("first = ${triple.first}") println("second = ${triple.second}") println("second = ${triple.third}") __attribute__((swift_name("FilenameKt"))) @interface SharedFilenameKt : SharedBase + (SharedKotlinPair<NSString *, SharedInt *> *)getPair __attribute__((swift_name("getPair()"))); @end __attribute__((swift_name("KotlinPair"))) @interface SharedKotlinPair<__covariant A, __covariant B> : SharedBase @property (readonly) A _Nullable first __attribute__((swift_name("first"))); @property (readonly) B _Nullable second __attribute__((swift_name("second"))); @end
  43. Tuple let pair: KotlinPair<NSString, KotlinInt> = FilenameKt.getPair() let first =

    pair.first as String? let second = pair.second?.intValue 📦 shared.framework fun getPair(): Pair<String, Int> { return "hoge" to 10 } val pair = getPair() println("first = ${pair.first}") println("second = ${pair.second}") val (string, int) = getPair() println("string = $string") println("int = $int”) val triple = Triple("hoge", 10, false) println("first = ${triple.first}") println("second = ${triple.second}") println("second = ${triple.third}") fi rstͱsecondʹΞΫηεͰ͖Δ͕ KotlinPairͷܕύϥϝʔλͷఆٛͷղऍ্OptionalʹͳΔ
  44. Array val strings: List<String> = listOf( "back", "to", "the", "future"

    ) println("strings = $strings") val strings2: List<String> = emptyList() println("strings2 = $strings2") val strings3 = strings + listOf("part", "ii") println("strings3 = $strings3") let strings = [ "back", "to", "the", "future" ] print("strings = \(strings)") let strings2: [String] = [] print("strings2 = \(strings2)") let strings3 = strings + ["part", "ii"] print("strings3 = \(strings3)")
  45. Array val strings: List<String> = listOf( "back", "to", "the", "future"

    ) println("strings = $strings") val strings2: List<String> = emptyList() println("strings2 = $strings2") val strings3 = strings + listOf("part", "ii") println("strings3 = $strings3") let strings = [ "back", "to", "the", "future" ] print("strings = \(strings)") let strings2: [String] = [] print("strings2 = \(strings2)") let strings3 = strings + ["part", "ii"] print("strings3 = \(strings3)") ArrayʹରԠ͢Δͷ͸ListͰ͢
 List͸interfaceͳͷͰconstructorΛ࣋ͨͳ͍ͨΊ listOfͰΠϯελϯεԽ͠·͢
  46. Array val strings: List<String> = listOf( "back", "to", "the", "future"

    ) println("strings = $strings") val strings2: List<String> = emptyList() println("strings2 = $strings2") val strings3 = strings + listOf("part", "ii") println("strings3 = $strings3") let strings = [ "back", "to", "the", "future" ] print("strings = \(strings)") let strings2: [String] = [] print("strings2 = \(strings2)") let strings3 = strings + ["part", "ii"] print("strings3 = \(strings3)") ۭ഑ྻ͸emptyListͰΠϯελϯεԽ΋Ͱ͖·͢
  47. Array val strings: List<String> = listOf( "back", "to", "the", "future"

    ) println("strings = $strings") val strings2: List<String> = emptyList() println("strings2 = $strings2") val strings3 = strings + listOf("part", "ii") println("strings3 = $strings3") let strings = [ "back", "to", "the", "future" ] print("strings = \(strings)") let strings2: [String] = [] print("strings2 = \(strings2)") let strings3 = strings + ["part", "ii"] print("strings3 = \(strings3)") ഑ྻಉ࢜ͷ݁߹΋Ͱ͖·͢
  48. Array val mutableStrings: MutableList<String> = mutableListOf( "harry", "potter", "and", "the",

    “goblet" ) mutableStrings.removeLast() mutableStrings.add("philosopher's") mutableStrings.add("stone") println("mutableStrings = $mutableStrings") var mutableStrings = [ "harry", “potter", "and", "the", “goblet" ] mutableStrings.removeLast() mutableStrings.append("philosopher's") mutableStrings.append("stone") print("mutableStrings = \(mutableStrings)")
  49. Array val mutableStrings: MutableList<String> = mutableListOf( "harry", "potter", "and", "the",

    “goblet" ) mutableStrings.removeLast() mutableStrings.add("philosopher's") mutableStrings.add("stone") println("mutableStrings = $mutableStrings") var mutableStrings = [ "harry", “potter", "and", "the", “goblet" ] mutableStrings.removeLast() mutableStrings.append("philosopher's") mutableStrings.append("stone") print("mutableStrings = \(mutableStrings)") mutableͳArrayʹରԠ͢Δͷ͸MutableListͰ͢
 MutableList͸ListΛ࠾༻ͨ͠interfaceͳͷͰ
 constructorΛ࣋ͨͳ͍ͨΊmutableListOf ͰΠϯελϯεԽ͠·͢
  50. Array val mutableStrings: MutableList<String> = mutableListOf( "harry", "potter", "and", "the",

    “goblet" ) mutableStrings.removeLast() mutableStrings.add("philosopher's") mutableStrings.add("stone") println("mutableStrings = $mutableStrings") var mutableStrings = [ "harry", “potter", "and", "the", “goblet" ] mutableStrings.removeLast() mutableStrings.append("philosopher's") mutableStrings.append("stone") print("mutableStrings = \(mutableStrings)") SwiftͷArrayͱಉ༷ͳ഑ྻૢ࡞͕Ͱ͖·͢
  51. Array let strings: [String] = FilenameKt.strings let mutableStrings: NSMutableArray =

    FilenameKt.mutableStrings 📦 shared.framework val strings = listOf( “A", “B", “C" ) val mutableStrings = mutableListOf( "A", "B", "C", “D", “E" )
  52. Array let strings: [String] = FilenameKt.strings let mutableStrings: NSMutableArray =

    FilenameKt.mutableStrings 📦 shared.framework val strings = listOf( “A", “B", “C" ) val mutableStrings = mutableListOf( "A", "B", "C", “D", “E" ) NSArrayͱͯ͠ग़ྗ͞Ε·͕͢ɺObjectiveCBridgeable
 ʹΑΔ҉໧తͳม׵ʹΑͬͯSwiftͷArrayͱͯ͠ར༻Ͱ͖·͢ __attribute__((swift_name("FilenameKt"))) @interface SharedFilenameKt : SharedBase @property (class, readonly) NSArray<NSString *> *strings __attribute__((swift_name("strings"))); @end
  53. Array let strings: [String] = FilenameKt.strings let mutableStrings: NSMutableArray =

    FilenameKt.mutableStrings 📦 shared.framework val strings = listOf( “A", “B", “C" ) val mutableStrings = mutableListOf( "A", "B", "C", “D", “E" ) __attribute__((swift_name("FilenameKt"))) @interface SharedFilenameKt : SharedBase @property (class, readonly) NSMutableArray<NSString *> *mutableStrings __attribute__((swift_name("mutableStrings"))); @end NSMutableArrayͱͯ͠ग़ྗ͞Ε·͢
 KotlinͷList͕΋ͱ΋ͱࢀরܕͳͷͰɺଞͷม਺ʹ୅ೖͯ͠ ഑ྻૢ࡞Λߦͬͨͱͯ͠΋ɺมߋ͕ద༻͞Ε·͢
  54. Dictionary val map: Map<String, String> = mapOf( "firstName" to "marty",

    "lastName" to "mcfly", ) println("map = $map") println(map["firstName"]) println(map["unknown"]) println(map.getOrElse("unknown") { "defaultValue" }) println("map.keys = ${map.keys}") println("map.values = ${map.values}") val map2 = map + mapOf("hobby" to "music") println("map2 = $map2”) let map: [String: String] = [ "firstName": "marty", "lastName": "mcfly", ] print("map = \(map)") print(map["firstName"]) print(map["unknown"]) print(map["unknown", default: "defaultValue"]) print("map.keys = \(map.keys)") print("map.values = \(map.values)") let map2 = map.merging(["hobby": "music"]) { $1 } print("map2 = \(map2)”)
  55. Dictionary val map: Map<String, String> = mapOf( "firstName" to "marty",

    "lastName" to "mcfly", ) println("map = $map") println(map["firstName"]) println(map["unknown"]) println(map.getOrElse("unknown") { "defaultValue" }) println("map.keys = ${map.keys}") println("map.values = ${map.values}") val map2 = map + mapOf("hobby" to "music") println("map2 = $map2”) let map: [String: String] = [ "firstName": "marty", "lastName": "mcfly", ] print("map = \(map)") print(map["firstName"]) print(map["unknown"]) print(map["unknown", default: "defaultValue"]) print("map.keys = \(map.keys)") print("map.values = \(map.values)") let map2 = map.merging(["hobby": "music"]) { $1 } print("map2 = \(map2)”) DictionaryʹରԠ͢Δͷ͸MapͰ͢
 Map͸interfaceͳͷͰconstructorΛ࣋ͨͳ͍ͨΊ mapOfͰΠϯελϯεԽ͠·͢
  56. Dictionary val map: Map<String, String> = mapOf( "firstName" to "marty",

    "lastName" to "mcfly", ) println("map = $map") println(map["firstName"]) println(map["unknown"]) println(map.getOrElse("unknown") { "defaultValue" }) println("map.keys = ${map.keys}") println("map.values = ${map.values}") val map2 = map + mapOf("hobby" to "music") println("map2 = $map2”) let map: [String: String] = [ "firstName": "marty", "lastName": "mcfly", ] print("map = \(map)") print(map["firstName"]) print(map["unknown"]) print(map["unknown", default: "defaultValue"]) print("map.keys = \(map.keys)") print("map.values = \(map.values)") let map2 = map.merging(["hobby": "music"]) { $1 } print("map2 = \(map2)”) ΩʔࢦఆͰ஋ΛऔಘͰ͖Δ
  57. Dictionary val map: Map<String, String> = mapOf( "firstName" to "marty",

    "lastName" to "mcfly", ) println("map = $map") println(map["firstName"]) println(map["unknown"]) println(map.getOrElse("unknown") { "defaultValue" }) println("map.keys = ${map.keys}") println("map.values = ${map.values}") val map2 = map + mapOf("hobby" to "music") println("map2 = $map2”) let map: [String: String] = [ "firstName": "marty", "lastName": "mcfly", ] print("map = \(map)") print(map["firstName"]) print(map["unknown"]) print(map["unknown", default: "defaultValue"]) print("map.keys = \(map.keys)") print("map.values = \(map.values)") let map2 = map.merging(["hobby": "music"]) { $1 } print("map2 = \(map2)”) ΩʔʹରԠ͢Δ஋͕nullͩͬͨ৔߹ʹ σϑΥϧτ஋Λฦ͢͜ͱ΋Ͱ͖Δ
  58. Dictionary val map: Map<String, String> = mapOf( "firstName" to "marty",

    "lastName" to "mcfly", ) println("map = $map") println(map["firstName"]) println(map["unknown"]) println(map.getOrElse("unknown") { "defaultValue" }) println("map.keys = ${map.keys}") println("map.values = ${map.values}") val map2 = map + mapOf("hobby" to "music") println("map2 = $map2”) let map: [String: String] = [ "firstName": "marty", "lastName": "mcfly", ] print("map = \(map)") print(map["firstName"]) print(map["unknown"]) print(map["unknown", default: "defaultValue"]) print("map.keys = \(map.keys)") print("map.values = \(map.values)") let map2 = map.merging(["hobby": "music"]) { $1 } print("map2 = \(map2)”) Mapಉ࢜ͷ݁߹΋Ͱ͖Δ
  59. Dictionary val mutableMap: MutableMap<String, String> = mutableMapOf( "firstName" to "emmett",

    "nickName" to "doc", ) mutableMap.remove("nickName") mutableMap["lastName"] = "brown" println("mutableMap = $mutableMap") var mutableMap = [ "firstName": "emmett", "nickName": "doc", ] mutableMap.removeValue(forKey: "nickName") mutableMap["lastName"] = "brown" print("mutableMap = \(mutableMap)")
  60. Dictionary val mutableMap: MutableMap<String, String> = mutableMapOf( "firstName" to "emmett",

    "nickName" to "doc", ) mutableMap.remove("nickName") mutableMap["lastName"] = "brown" println("mutableMap = $mutableMap") var mutableMap = [ "firstName": "emmett", "nickName": "doc", ] mutableMap.removeValue(forKey: "nickName") mutableMap["lastName"] = "brown" print("mutableMap = \(mutableMap)") mutableͳDictionaryʹରԠ͢Δͷ͸MutableMapͰ͢
 MutableMap͸MapΛ࠾༻ͨ͠interfaceͳͷͰ
 constructorΛ࣋ͨͳ͍ͨΊmutableMapOf ͰΠϯελϯεԽ͠·͢
  61. Dictionary val mutableMap: MutableMap<String, String> = mutableMapOf( "firstName" to "emmett",

    "nickName" to "doc", ) mutableMap.remove("nickName") mutableMap["lastName"] = "brown" println("mutableMap = $mutableMap") var mutableMap = [ "firstName": "emmett", "nickName": "doc", ] mutableMap.removeValue(forKey: "nickName") mutableMap["lastName"] = "brown" print("mutableMap = \(mutableMap)") SwiftͷDictionayͱಉ༷ͳࣙॻ഑ྻૢ࡞͕Ͱ͖·͢
  62. Dictionary let map: [String : String] = FilenameKt.map let mutableMap:

    KotlinMutableDictionary<NSString, NSString> = FilenameKt.mutableMap let mutableDictionary: NSMutableDictionary = mutableMap 📦 shared.framework val map: Map<String, String> = mapOf( "firstName" to "marty", "lastName" to "mcfly", ) val mutableMap: MutableMap<String, String> = mutableMapOf( "firstName" to "emmett", "lastName" to "brown", )
  63. Dictionary let map: [String : String] = FilenameKt.map let mutableMap:

    KotlinMutableDictionary<NSString, NSString> = FilenameKt.mutableMap let mutableDictionary: NSMutableDictionary = mutableMap 📦 shared.framework val map: Map<String, String> = mapOf( "firstName" to "marty", "lastName" to "mcfly", ) val mutableMap: MutableMap<String, String> = mutableMapOf( "firstName" to "emmett", "lastName" to "brown", ) __attribute__((swift_name("FilenameKt"))) @interface SharedFilenameKt : SharedBase @property (class, readonly) NSDictionary<NSString *, NSString *> *map __attribute__((swift_name("map"))); @end NSDictionaryͱͯ͠ग़ྗ͞Ε·͕͢ɺObjectiveCBridgeable
 ʹΑΔ҉໧తͳม׵ʹΑͬͯSwiftͷDictionayͱͯ͠ར༻Ͱ͖·͢
  64. Dictionary let map: [String : String] = FilenameKt.map let mutableMap:

    KotlinMutableDictionary<NSString, NSString> = FilenameKt.mutableMap let mutableDictionary: NSMutableDictionary = mutableMap 📦 shared.framework val map: Map<String, String> = mapOf( "firstName" to "marty", "lastName" to "mcfly", ) val mutableMap: MutableMap<String, String> = mutableMapOf( "firstName" to "emmett", "lastName" to "brown", ) __attribute__((swift_name("FilenameKt"))) @interface SharedFilenameKt : SharedBase @property (class, readonly) SharedMutableDictionary<NSString *, NSString *> *mutableMap __attribute__((swift_name("mutableMap"))); @end __attribute__((swift_name("KotlinMutableDictionary"))) @interface SharedMutableDictionary<KeyType, ObjectType> : NSMutableDictionary<KeyType, ObjectType> @end NSMutableDictionaryͷαϒΫϥεͷKotlinMutableDictionay ͱͯ͠ग़ྗ͞Ε·͢ɻ
 KotlinͷMap͕΋ͱ΋ͱࢀরܕͳͷͰɺଞͷม਺ʹ୅ೖͯ͠ ࣙॻ഑ྻૢ࡞Λߦͬͨͱͯ͠΋ɺมߋ͕ద༻͞Ε·͢
  65. Optional var count: Int? = null println("count = $count") count

    = 1234 println("count = $count") println("count?.toString() = ${count?.toString()}") var count: Int? = nil print("count = $count") count = 1234 print("count = $count") print("count?.description = \(count?.description)")
  66. Optional var count: Int? = null println("count = $count") count

    = 1234 println("count = $count") println("count?.toString() = ${count?.toString()}") var count: Int? = nil print("count = $count") count = 1234 print("count = $count") print("count?.description = \(count?.description)") Swiftͱಉ༷ʹʮ?ʯΛܕͷsu ff i xʹࢦఆ͢Δ͜ͱͰ Nullableͱͯ͠ѻ͏͜ͱ͕Ͱ͖·͢
  67. Optional var count: Int? = null println("count = $count") count

    = 1234 println("count = $count") println("count?.toString() = ${count?.toString()}") var count: Int? = nil print("count = $count") count = 1234 print("count = $count") print("count?.description = \(count?.description)") Swiftͱಉ༷ʹʮ?ʯΛม਺ͷsu ff i xʹࢦఆ͢Δ͜ͱͰ ؔ਺΍ϝϯόʔʹΞΫηεͰ͖·͢
  68. Optional var count: Int? = 1234 println("count!!.toString() = ${count!!.toString()}”) count

    = null try { count!!.toDouble() } catch (exception: Exception) { println("exception = $exception") } var count: Int? = 1234 print("count!.description = \(count!.description)")
  69. Optional var count: Int? = 1234 println("count!!.toString() = ${count!!.toString()}”) count

    = null try { count!!.toDouble() } catch (exception: Exception) { println("exception = $exception") } var count: Int? = 1234 print("count!.description = \(count!.description)") ʮ!!ʯΛม਺ͷsu ff i xʹࢦఆ͢Δ͜ͱͰ ڧ੍తʹؔ਺΍ϝϯόʔʹΞΫηεͰ͖·͢
  70. Optional var count: Int? = 1234 println("count!!.toString() = ${count!!.toString()}”) count

    = null try { count!!.toDouble() } catch (exception: Exception) { println("exception = $exception") } var count: Int? = 1234 print("count!.description = \(count!.description)") ڧ੍unwrapͨ͠ࡍʹnullͰ͋ͬͯ΋ɺtry-catchͰ
 NullPointerExceptionΛϋϯυϦϯάͰ͖·͢
  71. Optional if (count != null) { val unwrapped: Int =

    count } if (count == null) { return } val unwrapped: Int = count val another: Int = count ?: 0 if let count { let unwrapped: Int = count } guard let count else { return } let unwrapped: Int = count let another: Int = count ?? 0
  72. Optional if (count != null) { val unwrapped: Int =

    count } if (count == null) { return } val unwrapped: Int = count val another: Int = count ?: 0 if let count { let unwrapped: Int = count } guard let count else { return } let unwrapped: Int = count let another: Int = count ?? 0 Smart CastʹΑͬͯɺ೚ҙͷίʔϓ಺ͰnullͰ͸ͳ͍ ͜ͱΛอূͯ͘͠ΕΔ
  73. Optional if (count != null) { val unwrapped: Int =

    count } if (count == null) { return } val unwrapped: Int = count val another: Int = count ?: 0 if let count { let unwrapped: Int = count } guard let count else { return } let unwrapped: Int = count let another: Int = count ?? 0 Smart CastʹΑͬͯɺૣظreturnޙ΋೚ҙͷείʔϓ಺Ͱ nullͰ͸ͳ͍͜ͱΛอূͯ͘͠ΕΔ
  74. Optional if (count != null) { val unwrapped: Int =

    count } if (count == null) { return } val unwrapped: Int = count val another: Int = count ?: 0 if let count { let unwrapped: Int = count } guard let count else { return } let unwrapped: Int = count let another: Int = count ?? 0 Elvis OperatorΛ࢖͏͜ͱͰɺSwiftͷNil Coalescing Operator ͱಉ༷ͷૢ࡞͕Ͱ͖Δ
  75. Optional let string: String? = FilenameKt.optionalString let list: [Any] =

    FilenameKt.list let map: [AnyHashable: Any] = FilenameKt.map 📦 shared.framework var optionalString: String? = “ABCD" var list: List<Int?> = emptyList() var map: Map<String?, String?> = emptyMap()
  76. Optional let string: String? = FilenameKt.optionalString let list: [Any] =

    FilenameKt.list let map: [AnyHashable: Any] = FilenameKt.map 📦 shared.framework var optionalString: String? = “ABCD" var list: List<Int?> = emptyList() var map: Map<String?, String?> = emptyMap() __attribute__((swift_name("FilenameKt"))) @interface SharedFilenameKt : SharedBase @property (class) NSString * _Nullable optionalString __attribute__((swift_name("optionalString"))); @end NullableͳNSStringͱͯ͠ग़ྗ͞ΕɺObjectiveCBridgeable
 ʹΑΔ҉໧తͳม׵ʹΑͬͯSwiftͷOptionalʹม׵͞ΕΔ
  77. Optional let string: String? = FilenameKt.optionalString let list: [Any] =

    FilenameKt.list let map: [AnyHashable: Any] = FilenameKt.map 📦 shared.framework var optionalString: String? = “ABCD" var list: List<Int?> = emptyList() var map: Map<String?, String?> = emptyMap() __attribute__((swift_name("FilenameKt"))) @interface SharedFilenameKt : SharedBase @property (class) NSArray<id> *list __attribute__((swift_name("list"))); @end ޙ΄ͲGenericͷηΫγϣϯͰ΋આ໌͠·͕͢ɺList͸interface Ͱ͕͢Objective-Cͷprotocol͕GenericʹରԠ͍ͯ͠ͳ͍ͨΊ idܕʹม׵͞ΕΔ͜ͱͰɺ[Any]ͱͳͬͯ͠·͍·͢
  78. Optional let string: String? = FilenameKt.optionalString let list: [Any] =

    FilenameKt.list let map: [AnyHashable: Any] = FilenameKt.map 📦 shared.framework var optionalString: String? = “ABCD" var list: List<Int?> = emptyList() var map: Map<String?, String?> = emptyMap() __attribute__((swift_name("FilenameKt"))) @interface SharedFilenameKt : SharedBase @property (class) NSDictionary<id, id> *map __attribute__((swift_name("map"))); @end ޙ΄ͲGenericͷηΫγϣϯͰ΋આ໌͠·͕͢ɺMap͸interface Ͱ͕͢Objective-Cͷprotocol͕GenericʹରԠ͍ͯ͠ͳ͍ͨΊ Idܕʹม׵͞ΕΔ͜ͱͰɺ[AnyHashable: Any]ͱͳͬͯ͠·͍·͢
  79. Class class UserRepository( private val mutableUsernames: MutableList<String>, ) { var

    lastUsername: String? = null private set val usernames: List<String> get() = mutableUsernames constructor(usernames: List<String>) : this( mutableUsernames = usernames.toMutableList() ) { lastUsername = mutableUsernames.lastOrNull() println("Constructor block: $mutableUsernames") println("Constructor block: $lastUsername") } init { println("Init block: $mutableUsernames") println("Init block: $lastUsername") } fun addUsername(username: String) { mutableUsernames.add(username) lastUsername = mutableUsernames.lastOrNull() } } final class UserRepository { private var mutableUsernames: [String] private(set) var lastUsername: String? var usernames: [String] { mutableUsernames } init(usernames: [String]) { self.mutableUsernames = usernames self.lastUsername = usernames.last } func addUsername(username: String) { mutableUsernames += [username] lastUsername = mutableUsernames.last } }
  80. Class class UserRepository( private val mutableUsernames: MutableList<String>, ) { var

    lastUsername: String? = null private set val usernames: List<String> get() = mutableUsernames constructor(usernames: List<String>) : this( mutableUsernames = usernames.toMutableList() ) { lastUsername = mutableUsernames.lastOrNull() println("Constructor block: $mutableUsernames") println("Constructor block: $lastUsername") } init { println("Init block: $mutableUsernames") println("Init block: $lastUsername") } fun addUsername(username: String) { mutableUsernames.add(username) lastUsername = mutableUsernames.lastOrNull() } } final class UserRepository { private var mutableUsernames: [String] private(set) var lastUsername: String? var usernames: [String] { mutableUsernames } init(usernames: [String]) { self.mutableUsernames = usernames self.lastUsername = usernames.last } func addUsername(username: String) { mutableUsernames += [username] lastUsername = mutableUsernames.last } } primary constructorʹϝϯόʔΛ ࣋ͨͤΔ͜ͱ͕Ͱ͖·͢ ୯ͳΔҾ਺ͱ͢Δ͜ͱ΋Ͱ͖·͢
  81. Class class UserRepository( private val mutableUsernames: MutableList<String>, ) { var

    lastUsername: String? = null private set val usernames: List<String> get() = mutableUsernames constructor(usernames: List<String>) : this( mutableUsernames = usernames.toMutableList() ) { lastUsername = mutableUsernames.lastOrNull() println("Constructor block: $mutableUsernames") println("Constructor block: $lastUsername") } init { println("Init block: $mutableUsernames") println("Init block: $lastUsername") } fun addUsername(username: String) { mutableUsernames.add(username) lastUsername = mutableUsernames.lastOrNull() } } final class UserRepository { private var mutableUsernames: [String] private(set) var lastUsername: String? var usernames: [String] { mutableUsernames } init(usernames: [String]) { self.mutableUsernames = usernames self.lastUsername = usernames.last } func addUsername(username: String) { mutableUsernames += [username] lastUsername = mutableUsernames.last } } secondary constructor΋ఆٛͰ͖·͕͢ɺSwiftͷΑ͏ʹ extensionͰఆٛ͢Δ͜ͱ͸Ͱ͖·ͤΜ
  82. Class class UserRepository( private val mutableUsernames: MutableList<String>, ) { var

    lastUsername: String? = null private set val usernames: List<String> get() = mutableUsernames constructor(usernames: List<String>) : this( mutableUsernames = usernames.toMutableList() ) { lastUsername = mutableUsernames.lastOrNull() println("Constructor block: $mutableUsernames") println("Constructor block: $lastUsername") } init { println("Init block: $mutableUsernames") println("Init block: $lastUsername") } fun addUsername(username: String) { mutableUsernames.add(username) lastUsername = mutableUsernames.lastOrNull() } } final class UserRepository { private var mutableUsernames: [String] private(set) var lastUsername: String? var usernames: [String] { mutableUsernames } init(usernames: [String]) { self.mutableUsernames = usernames self.lastUsername = usernames.last } func addUsername(username: String) { mutableUsernames += [username] lastUsername = mutableUsernames.last } } constructorͷॲཧޙʹڞ௨Ͱݺ͹ΕΔinit block͕͋Γ·͢
  83. Class class UserRepository( private val mutableUsernames: MutableList<String>, ) { var

    lastUsername: String? = null private set val usernames: List<String> get() = mutableUsernames constructor(usernames: List<String>) : this( mutableUsernames = usernames.toMutableList() ) { lastUsername = mutableUsernames.lastOrNull() println("Constructor block: $mutableUsernames") println("Constructor block: $lastUsername") } init { println("Init block: $mutableUsernames") println("Init block: $lastUsername") } fun addUsername(username: String) { mutableUsernames.add(username) lastUsername = mutableUsernames.lastOrNull() } } final class UserRepository { private var mutableUsernames: [String] private(set) var lastUsername: String? var usernames: [String] { mutableUsernames } init(usernames: [String]) { self.mutableUsernames = usernames self.lastUsername = usernames.last } func addUsername(username: String) { mutableUsernames += [username] lastUsername = mutableUsernames.last } } Class಺ͰͷΈsetՄೳͳϝϯόʔΛఆٛͰ͖·͢
  84. Class class UserRepository( private val mutableUsernames: MutableList<String>, ) { var

    lastUsername: String? = null private set val usernames: List<String> get() = mutableUsernames constructor(usernames: List<String>) : this( mutableUsernames = usernames.toMutableList() ) { lastUsername = mutableUsernames.lastOrNull() println("Constructor block: $mutableUsernames") println("Constructor block: $lastUsername") } init { println("Init block: $mutableUsernames") println("Init block: $lastUsername") } fun addUsername(username: String) { mutableUsernames.add(username) lastUsername = mutableUsernames.lastOrNull() } } final class UserRepository { private var mutableUsernames: [String] private(set) var lastUsername: String? var usernames: [String] { mutableUsernames } init(usernames: [String]) { self.mutableUsernames = usernames self.lastUsername = usernames.last } func addUsername(username: String) { mutableUsernames += [username] lastUsername = mutableUsernames.last } } getterͷΈͷϝϯόʔΛఆٛͰ͖·͢
  85. Class class UserRepository( private val mutableUsernames: MutableList<String>, ) { var

    lastUsername: String? = null private set val usernames: List<String> get() = mutableUsernames constructor(usernames: List<String>) : this( mutableUsernames = usernames.toMutableList() ) { lastUsername = mutableUsernames.lastOrNull() println("Constructor block: $mutableUsernames") println("Constructor block: $lastUsername") } init { println("Init block: $mutableUsernames") println("Init block: $lastUsername") } fun addUsername(username: String) { mutableUsernames.add(username) lastUsername = mutableUsernames.lastOrNull() } } final class UserRepository { private var mutableUsernames: [String] private(set) var lastUsername: String? var usernames: [String] { mutableUsernames } init(usernames: [String]) { self.mutableUsernames = usernames self.lastUsername = usernames.last } func addUsername(username: String) { mutableUsernames += [username] lastUsername = mutableUsernames.last } } ࣗ਎ʹΞΫηε͢Δ৔߹͸thisΛར༻͠ɺࣗ਎ͷ ϝϯόʔ΍ؔ਺ʹΞΫηε͢Δ৔߹͸লུ΋Ͱ͖·͢
  86. Class class UserRepository( private val mutableUsernames: MutableList<String>, ) { var

    lastUsername: String? = null private set val usernames: List<String> get() = mutableUsernames constructor(usernames: List<String>) : this( mutableUsernames = usernames.toMutableList() ) { lastUsername = mutableUsernames.lastOrNull() println("Constructor block: $mutableUsernames") println("Constructor block: $lastUsername") } init { println("Init block: $mutableUsernames") println("Init block: $lastUsername") } fun addUsername(username: String) { mutableUsernames.add(username) lastUsername = mutableUsernames.lastOrNull() } } let usernames = NSMutableArray(array: [“marty", "suzuki"]) let repository = UserRepository(mutableUsernames: usernames) print(repository.lastUsername) // nil print(repository.usernames) // ["marty, "suzuki"] usernames.removeLastObject() print(repository.usernames) // [“marty”] let usernames = [“marty", "suzuki"] let repository = UserRepository(usernames: usernames) print(repository.lastUsername) // Optional("suzuki") print(repository.usernames) // ["marty, "suzuki"] 📦 shared.framework
  87. Class class UserRepository( private val mutableUsernames: MutableList<String>, ) { var

    lastUsername: String? = null private set val usernames: List<String> get() = mutableUsernames constructor(usernames: List<String>) : this( mutableUsernames = usernames.toMutableList() ) { lastUsername = mutableUsernames.lastOrNull() println("Constructor block: $mutableUsernames") println("Constructor block: $lastUsername") } init { println("Init block: $mutableUsernames") println("Init block: $lastUsername") } fun addUsername(username: String) { mutableUsernames.add(username) lastUsername = mutableUsernames.lastOrNull() } } let usernames = NSMutableArray(array: [“marty", "suzuki"]) let repository = UserRepository(mutableUsernames: usernames) print(repository.lastUsername) // nil print(repository.usernames) // ["marty, "suzuki"] usernames.removeLastObject() print(repository.usernames) // [“marty”] let usernames = [“marty", "suzuki"] let repository = UserRepository(usernames: usernames) print(repository.lastUsername) // Optional("suzuki") print(repository.usernames) // ["marty, "suzuki"] 📦 shared.framework __attribute__((swift_name("UserRepository"))) @interface SharedUserRepository : SharedBase - (instancetype)initWithUsernames:(NSArray<NSString *> *)usernames __attribute__((swift_name("init(usernames:)"))) __attribute__((objc_designated_initializer)); - (instancetype)initWithMutableUsernames:(NSMutableArray<NSString *> *)mutableUsernames __attribute__((swift_name(“init(mutableUsernames:)"))) __attribute__((objc_designated_initializer)); - (void)addUsernameUsername:(NSString *)username __attribute__((swift_name("addUsername(username:)"))); @property (readonly) NSString * _Nullable lastUsername __attribute__((swift_name("lastUsername"))); @property (readonly) NSArray<NSString *> *usernames __attribute__((swift_name("usernames"))); @end primary constructor͸MutableListͳͷͰ
 NSMutableArrayΛ౉ͯ͠ΠϯελϯεԽ͢Δ
  88. Class class UserRepository( private val mutableUsernames: MutableList<String>, ) { var

    lastUsername: String? = null private set val usernames: List<String> get() = mutableUsernames constructor(usernames: List<String>) : this( mutableUsernames = usernames.toMutableList() ) { lastUsername = mutableUsernames.lastOrNull() println("Constructor block: $mutableUsernames") println("Constructor block: $lastUsername") } init { println("Init block: $mutableUsernames") println("Init block: $lastUsername") } fun addUsername(username: String) { mutableUsernames.add(username) lastUsername = mutableUsernames.lastOrNull() } } let usernames = NSMutableArray(array: [“marty", "suzuki"]) let repository = UserRepository(mutableUsernames: usernames) print(repository.lastUsername) // nil print(repository.usernames) // ["marty, "suzuki"] usernames.removeLastObject() print(repository.usernames) // [“marty”] let usernames = [“marty", "suzuki"] let repository = UserRepository(usernames: usernames) print(repository.lastUsername) // Optional("suzuki") print(repository.usernames) // ["marty, "suzuki"] 📦 shared.framework ࢀরܕͳͷͰɺ֎͔Βมߋͯ͠΋൓ө͞ΕΔ
  89. Class class UserRepository( private val mutableUsernames: MutableList<String>, ) { var

    lastUsername: String? = null private set val usernames: List<String> get() = mutableUsernames constructor(usernames: List<String>) : this( mutableUsernames = usernames.toMutableList() ) { lastUsername = mutableUsernames.lastOrNull() println("Constructor block: $mutableUsernames") println("Constructor block: $lastUsername") } init { println("Init block: $mutableUsernames") println("Init block: $lastUsername") } fun addUsername(username: String) { mutableUsernames.add(username) lastUsername = mutableUsernames.lastOrNull() } } let usernames = NSMutableArray(array: [“marty", "suzuki"]) let repository = UserRepository(mutableUsernames: usernames) print(repository.lastUsername) // nil print(repository.usernames) // ["marty, "suzuki"] usernames.removeLastObject() print(repository.usernames) // [“marty”] let usernames = [“marty", "suzuki"] let repository = UserRepository(usernames: usernames) print(repository.lastUsername) // Optional("suzuki") print(repository.usernames) // ["marty, "suzuki"] 📦 shared.framework __attribute__((swift_name("UserRepository"))) @interface SharedUserRepository : SharedBase - (instancetype)initWithUsernames:(NSArray<NSString *> *)usernames __attribute__((swift_name("init(usernames:)"))) __attribute__((objc_designated_initializer)); @end secondary constructor͸ListͳͷͰ
 SwiftͷArrayΛ౉ͯ͠ΠϯελϯεԽͰ͖Δ
  90. Protocol interface Named { val name: String } interface Person

    : Named { val firstName: String val lastName: String override val name: String get() = "$firstName $lastName" } class PersonImpl( override val firstName: String, override val lastName: String, ) : Person protocol Named { var name: String { get } } protocol Person : Named { var firstName: String { get } var lastName: String { get } } extension Person { var name: String { "\(firstName) \(lastName)" } } class PersonImpl : Person { let firstName: String let lastName: String init( firstName: String, lastName: String ) { self.firstName = firstName self.lastName = lastName } }
  91. Protocol interface Named { val name: String } interface Person

    : Named { val firstName: String val lastName: String override val name: String get() = "$firstName $lastName" } class PersonImpl( override val firstName: String, override val lastName: String, ) : Person protocol Named { var name: String { get } } protocol Person : Named { var firstName: String { get } var lastName: String { get } } extension Person { var name: String { "\(firstName) \(lastName)" } } class PersonImpl : Person { let firstName: String let lastName: String init( firstName: String, lastName: String ) { self.firstName = firstName self.lastName = lastName } } protocolʹରԠ͢Δͷ͕interface
  92. Protocol interface Named { val name: String } interface Person

    : Named { val firstName: String val lastName: String override val name: String get() = "$firstName $lastName" } class PersonImpl( override val firstName: String, override val lastName: String, ) : Person protocol Named { var name: String { get } } protocol Person : Named { var firstName: String { get } var lastName: String { get } } extension Person { var name: String { "\(firstName) \(lastName)" } } class PersonImpl : Person { let firstName: String let lastName: String init( firstName: String, lastName: String ) { self.firstName = firstName self.lastName = lastName } } ଞͷinterface΍class౳ʹ࠾༻͢Δ͜ͱ΋Ͱ͖Δ
  93. Protocol interface Named { val name: String } interface Person

    : Named { val firstName: String val lastName: String override val name: String get() = "$firstName $lastName" } class PersonImpl( override val firstName: String, override val lastName: String, ) : Person protocol Named { var name: String { get } } protocol Person : Named { var firstName: String { get } var lastName: String { get } } extension Person { var name: String { "\(firstName) \(lastName)" } } class PersonImpl : Person { let firstName: String let lastName: String init( firstName: String, lastName: String ) { self.firstName = firstName self.lastName = lastName } } σϑΥϧτ࣮૷͢Δ͜ͱ΋Ͱ͖ɺ࣮૷ΫϥεͰ ର৅ͷϝϯόʔ΍ؔ਺Λఆٛ͠ͳͯ͘΋ྑ͘ͳΔ
  94. Protocol let named: Named = PersonImpl( firstName: "marty", lastName: “suzuki"

    ) print(named.name) // marty suzuki final class User : Person { let firstName: String let lastName: String let name: String init( firstName: String, lastName: String ) { self.firstName = firstName self.lastName = lastName self.name = "\(firstName) \(lastName)" } } 📦 shared.framework interface Named { val name: String } interface Person : Named { val firstName: String val lastName: String override val name: String get() = "$firstName $lastName" } class PersonImpl( override val firstName: String, override val lastName: String, ) : Person
  95. Protocol let named: Named = PersonImpl( firstName: "marty", lastName: “suzuki"

    ) print(named.name) // marty suzuki final class User : Person { let firstName: String let lastName: String let name: String init( firstName: String, lastName: String ) { self.firstName = firstName self.lastName = lastName self.name = "\(firstName) \(lastName)" } } 📦 shared.framework interface Named { val name: String } interface Person : Named { val firstName: String val lastName: String override val name: String get() = "$firstName $lastName" } class PersonImpl( override val firstName: String, override val lastName: String, ) : Person __attribute__((swift_name("PersonImpl"))) @interface SharedPersonImpl : SharedBase <SharedPerson> - (instancetype)initWithFirstName:(NSString *)firstName lastName:(NSString *)lastName __attribute__((swift_name(“init(firstName:lastName:)"))) __attribute__((objc_designated_initializer)); @property (readonly) NSString *firstName __attribute__((swift_name("firstName"))); @property (readonly) NSString *lastName __attribute__((swift_name("lastName"))); @end __attribute__((swift_name("Person"))) @protocol SharedPerson <SharedNamed> @required @property (readonly) NSString *firstName __attribute__((swift_name("firstName"))); @property (readonly) NSString *lastName __attribute__((swift_name("lastName"))); @end
  96. Protocol let named: Named = PersonImpl( firstName: "marty", lastName: “suzuki"

    ) print(named.name) // marty suzuki final class User : Person { let firstName: String let lastName: String let name: String init( firstName: String, lastName: String ) { self.firstName = firstName self.lastName = lastName self.name = "\(firstName) \(lastName)" } } 📦 shared.framework interface Named { val name: String } interface Person : Named { val firstName: String val lastName: String override val name: String get() = "$firstName $lastName" } class PersonImpl( override val firstName: String, override val lastName: String, ) : Person __attribute__((swift_name("Named"))) @protocol SharedNamed @required @property (readonly) NSString *name __attribute__((swift_name("name"))); @end σϑΥϧτ࣮૷ʹΞΫηεͰ͖Δ
  97. Protocol let named: Named = PersonImpl( firstName: "marty", lastName: “suzuki"

    ) print(named.name) // marty suzuki final class User : Person { let firstName: String let lastName: String let name: String init( firstName: String, lastName: String ) { self.firstName = firstName self.lastName = lastName self.name = "\(firstName) \(lastName)" } } 📦 shared.framework interface Named { val name: String } interface Person : Named { val firstName: String val lastName: String override val name: String get() = "$firstName $lastName" } class PersonImpl( override val firstName: String, override val lastName: String, ) : Person __attribute__((swift_name("Named"))) @protocol SharedNamed @required @property (readonly) NSString *name __attribute__((swift_name("name"))); @end __attribute__((swift_name("Person"))) @protocol SharedPerson <SharedNamed> @required @property (readonly) NSString *firstName __attribute__((swift_name("firstName"))); @property (readonly) NSString *lastName __attribute__((swift_name("lastName"))); @end KMPͰग़ྗ͞ΕͨprotocolΛSwiftͰఆٛͨ͠Ϋϥεʹ ࠾༻ͨ͠৔߹ɺσϑΥϧτ࣮૷Λར༻Ͱ͖ͳ͍
  98. Static class MyClass { companion object { val instance =

    MyClass() fun create(): MyClass { return MyClass() } } } final class MyClass { static let shared = MyClass() static func create() -> MyClass { return MyClass() } }
  99. Static class MyClass { companion object { val instance =

    MyClass() fun create(): MyClass { return MyClass() } } } final class MyClass { static let shared = MyClass() static func create() -> MyClass { return MyClass() } } Kotlinʹ͸staticͷ֓೦͕جຊతʹ͸ͳ͍ͷͰ companion objectΛར༻͢Δ
  100. Static 📦 shared.framework class MyClass { companion object { val

    instance = MyClass() fun create(): MyClass { return MyClass() } } } let myClass1 = MyClass.Companion.shared.create() let myClass2 = MyClass.companion.instance
  101. Static 📦 shared.framework class MyClass { companion object { val

    instance = MyClass() fun create(): MyClass { return MyClass() } } } let myClass1 = MyClass.Companion.shared.create() let myClass2 = MyClass.companion.instance __attribute__((swift_name("MyClass.Companion"))) @interface SharedMyClassCompanion : SharedBase @property (class, readonly, getter=shared) SharedMyClassCompanion *shared __attribute__((swift_name("shared"))); - (SharedMyClass *)create __attribute__((swift_name("create()"))); @property (readonly) SharedMyClass *instance __attribute__((swift_name("instance"))); @end MyClass.CompanionͷΫϥεͷstored propertyͷ ʮsharedʯʹΞΫηε͢Δ͜ͱͰɺcompanion object ͷϝϯόʔ΍ؔ਺ʹΞΫηεͰ͖·͢
  102. Static 📦 shared.framework class MyClass { companion object { val

    instance = MyClass() fun create(): MyClass { return MyClass() } } } __attribute__((swift_name("MyClass"))) @interface SharedMyClass : SharedBase @property (class, readonly, getter=companion) SharedMyClassCompanion *companion __attribute__((swift_name("companion"))); @end __attribute__((swift_name("MyClass.Companion"))) @interface SharedMyClassCompanion : SharedBase @property (readonly) SharedMyClass *instance __attribute__((swift_name("instance"))); @end let myClass1 = MyClass.Companion.shared.create() let myClass2 = MyClass.companion.instance MyClassͷΫϥεͷstored propertyͷʮcompanionʯʹ ΞΫηε͢Δ͜ͱͰɺcompanion objectͷϝϯόʔ΍ ؔ਺ʹΞΫηε͢Δ͜ͱ΋Ͱ͖·͢
  103. Static print(MyObject.shared.firstName) print(MyObject.shared.lastName) print(MyObject.shared.description()) // Anakin Skywalker 📦 shared.framework object

    MyObject { val firstName = "Anakin" var lastName = "Skywalker" override fun toString() = "$firstName $lastName" }
  104. Static print(MyObject.shared.firstName) print(MyObject.shared.lastName) print(MyObject.shared.description()) // Anakin Skywalker 📦 shared.framework object

    MyObject { val firstName = "Anakin" var lastName = "Skywalker" override fun toString() = "$firstName $lastName" } __attribute__((swift_name("MyObject"))) @interface SharedMyObject : SharedBase @property (class, readonly, getter=shared) SharedMyObject *shared __attribute__((swift_name("shared"))); - (NSString *)description __attribute__((swift_name("description()"))); @property (readonly) NSString *firstName __attribute__((swift_name("firstName"))); @property NSString *lastName __attribute__((swift_name("lastName"))); @end objectͱ͢Δ͜ͱͰɺγϯάϧτϯѻ͍ͳܕΛ ੜ੒͢Δ͜ͱ΋Ͱ͖Δ
  105. Static let anonymousObject: Any = FilenameKt.anonymousObject print(anonymousObject) // Luke Skywalker

    let anonymousNamesObject: Names = FilenameKt .anonymousNamesObject print(anonymousNamesObject.firstName) print(anonymousNamesObject.lastName) 📦 shared.framework val anonymousObject = object { val firstName = "Luke" var lastName = "Skywalker" override fun toString() = "$firstName $lastName" } interface Names { val firstName: String var lastName: String } val anonymousNamesObject = object : Names { override val firstName = "Luke" override var lastName = "Skywalker" override fun toString() = "$firstName $lastName" }
  106. Static let anonymousObject: Any = FilenameKt.anonymousObject print(anonymousObject) // Luke Skywalker

    let anonymousNamesObject: Names = FilenameKt .anonymousNamesObject print(anonymousNamesObject.firstName) print(anonymousNamesObject.lastName) 📦 shared.framework val anonymousObject = object { val firstName = "Luke" var lastName = "Skywalker" override fun toString() = "$firstName $lastName" } interface Names { val firstName: String var lastName: String } val anonymousNamesObject = object : Names { override val firstName = "Luke" override var lastName = "Skywalker" override fun toString() = "$firstName $lastName" } __attribute__((swift_name("FilenameKt"))) @interface SharedFilenameKt : SharedBase @property (class, readonly) id anonymousObject __attribute__((swift_name("anonymousObject"))); @end Anonymous objectΛఆٛ͢Δ͜ͱ΋Ͱ͖Δ͕ Swift͔Βࢀর͢Δͱ֘౰͢Δػೳ͕ͳ͍ͨΊ idܕͱͳͬͯ͠·͏
  107. Static let anonymousObject: Any = FilenameKt.anonymousObject print(anonymousObject) // Luke Skywalker

    let anonymousNamesObject: Names = FilenameKt .anonymousNamesObject print(anonymousNamesObject.firstName) print(anonymousNamesObject.lastName) 📦 shared.framework val anonymousObject = object { val firstName = "Luke" var lastName = "Skywalker" override fun toString() = "$firstName $lastName" } interface Names { val firstName: String var lastName: String } val anonymousNamesObject = object : Names { override val firstName = "Luke" override var lastName = "Skywalker" override fun toString() = "$firstName $lastName" } __attribute__((swift_name("FilenameKt"))) @interface SharedFilenameKt : SharedBase @property (class, readonly) id<SharedNames> anonymousNamesObject __attribute__((swift_name("anonymousNamesObject"))); @end @protocol SharedNames @required @property (readonly) NSString *firstName __attribute__((swift_name("firstName"))); @property NSString *lastName __attribute__((swift_name("lastName"))); @end interfaceʹ४ڌͨ͠Anonymous objectͷ৔߹͸ Swift͔Βࢀর͢Δͱ֘౰ͷintefaceͱͯ͠ΞΫηε Ͱ͖Δ
  108. Extension val Int.isEven: Boolean get() = this % 2 ==

    0 fun Int.isOdd(): Boolean { return !isEven } extension Int { var isEvent: Bool { self % 2 == 0 } func isOdd() -> Bool { !isEvent } }
  109. Extension val Int.isEven: Boolean get() = this % 2 ==

    0 fun Int.isOdd(): Boolean { return !isEven } extension Int { var isEvent: Bool { self % 2 == 0 } func isOdd() -> Bool { !isEvent } } Swiftͱಉ༷ʹ֦ுؔ਺ΛఆٛͰ͖Δ Ϋϥεͷதʹωετͤͯ͞ఆٛͨ͠Γ΋Ͱ͖Δ
  110. Extension PlatformKt.isEven(receiver: Int32) -> Bool PlatformKt.isOdd(receiver: Int32) -> Bool 📦

    shared.framework val Int.isEven: Boolean get() = this % 2 == 0 fun Int.isOdd(): Boolean { return !isEven }
  111. Extension PlatformKt.isEven(receiver: Int32) -> Bool PlatformKt.isOdd(receiver: Int32) -> Bool 📦

    shared.framework val Int.isEven: Boolean get() = this % 2 == 0 fun Int.isOdd(): Boolean { return !isEven } __attribute__((swift_name("FilenameKt"))) @interface SharedFilenameKt : SharedBase + (BOOL)isEven:(int32_t)receiver __attribute__((swift_name("isEven(_:)"))); + (BOOL)isOdd:(int32_t)receiver __attribute__((swift_name("isOdd(_:)"))); @end Primitiveͳ஋΍interfaceʹର͢Δ֦ு͸
 FilenameKtʹΫϥεؔ਺͕ੜ੒͞Ε ୈҰҾ਺ʹ֦ுͨ͠ܕͷΠϯελϯεΛ ౉͢͜ͱͰ֦ுؔ਺౳͕ར༻Ͱ͖·͢
  112. Struct data class User( val firstName: String, val lastName: String,

    val aka: String?, ) struct User { let firstName: String let lastName: String let aka: String? }
  113. Struct data class User( val firstName: String, val lastName: String,

    val aka: String?, ) struct User { let firstName: String let lastName: String let aka: String? } structʹ͍ۙ΋ͷ͸data classͱͳΓ·͢ equals͕ࣗಈੜ੒͞Ε಺෦ͷ஋ͰൺֱͰ͖ΔͳͲ ClassͰએݴͨ͠৔߹ͱڍಈ͕ҟͳΔ
  114. Struct let user = User( firstName: "Anakin", lastName: "Skywalker", aka:

    "Darth Vader" ) 📦 shared.framework data class User( val firstName: String, val lastName: String, val aka: String?, )
  115. Struct let user = User( firstName: "Anakin", lastName: "Skywalker", aka:

    "Darth Vader" ) 📦 shared.framework data class User( val firstName: String, val lastName: String, val aka: String?, ) __attribute__((swift_name("User"))) @interface SharedUser : SharedBase - (BOOL)isEqual:(id _Nullable)other __attribute__((swift_name("isEqual(_:)"))); - (NSUInteger)hash __attribute__((swift_name("hash()"))); - (NSString *)description __attribute__((swift_name("description()"))); @property (readonly) NSString * _Nullable aka __attribute__((swift_name("aka"))); @property (readonly) NSString *firstName __attribute__((swift_name("firstName"))); @property (readonly) NSString *lastName __attribute__((swift_name("lastName"))); @end Swift͔Βࢀরͨ͠৔߹ʹɺKotlinBaseͷαϒΫϥεͱ ͳΔͨΊࢀরܕͱͳΓ·͢
  116. Enum enum class Direction { North, South, West, East ;

    val isNorth: Boolean get() = this == North } val direction = Direction.East when (direction) { Direction.North -> println("North") Direction.South -> println("South") Direction.West -> println("West") Direction.East -> println("East") } enum Direction { case north case south case west case east var isNorth: Bool { self == .north } } let direction: Direction = .east switch direction { case .north: print("north") case .south: print("south") case .west: print("west") case .east: print("east") }
  117. Enum enum class Direction { North, South, West, East ;

    val isNorth: Boolean get() = this == North } val direction = Direction.East when (direction) { Direction.North -> println("North") Direction.South -> println("South") Direction.West -> println("West") Direction.East -> println("East") } enum Direction { case north case south case west case east var isNorth: Bool { self == .north } } let direction: Direction = .east switch direction { case .north: print("north") case .south: print("south") case .west: print("west") case .east: print("east") } enumʹରԠ͢Δͷ͸enum classͰ͢
  118. Enum enum class Direction { North, South, West, East ;

    val isNorth: Boolean get() = this == North } val direction = Direction.East when (direction) { Direction.North -> println("North") Direction.South -> println("South") Direction.West -> println("West") Direction.East -> println("East") } enum Direction { case north case south case west case east var isNorth: Bool { self == .north } } let direction: Direction = .east switch direction { case .north: print("north") case .south: print("south") case .west: print("west") case .east: print("east") } WhenจΛ࢖ͬͯ໢ཏతʹ෼ذͰ͖·͢
  119. Enum let direction: Direction = .east switch direction { case

    .north: print("north") case .south: print("south") case .west: print(“west") case .east: print("east") default: print("unknown") } 📦 shared.framework enum class Direction { North, South, West, East ; val isNorth: Boolean get() = this == North } val direction = Direction.East when (direction) { Direction.North -> println("North") Direction.South -> println("South") Direction.West -> println("West") Direction.East -> println("East") }
  120. Enum let direction: Direction = .east switch direction { case

    .north: print("north") case .east: print("east") case .south: print("south") case .west: print("west") default: print("unknown") } 📦 shared.framework enum class Direction { North, South, West, East ; val isNorth: Boolean get() = this == North } val direction = Direction.East when (direction) { Direction.North -> println("North") Direction.South -> println("South") Direction.West -> println("West") Direction.East -> println("East") } __attribute__((swift_name("Direction"))) @interface SharedDirection : SharedKotlinEnum<SharedDirection *> @property (class, readonly) SharedDirection *north __attribute__((swift_name("north"))); @property (class, readonly) SharedDirection *south __attribute__((swift_name("south"))); @property (class, readonly) SharedDirection *west __attribute__((swift_name("west"))); @property (class, readonly) SharedDirection *east __attribute__((swift_name("east"))); @end __attribute__((swift_name("KotlinEnum"))) @interface SharedKotlinEnum<E> : SharedBase <SharedKotlinComparable> @end NS_EnumͰग़ྗ͞ΕΔͷͰ͸ͳ͘ɺKotlinBaseΛܧঝͨ͠KotlinEnum ͱͯ͠ग़ྗ͞ΕΔͨΊɺྻڍࢠ͸Ϋϥεͷstored propertyͰఆٛ͞Ε·͢
  121. Enum let direction: Direction = .east switch direction { case

    .north: print("north") case .east: print("east") case .south: print("south") case .west: print("west") default: print("unknown") } 📦 shared.framework enum class Direction { North, South, West, East ; val isNorth: Boolean get() = this == North } val direction = Direction.East when (direction) { Direction.North -> println("North") Direction.South -> println("South") Direction.West -> println("West") Direction.East -> println("East") } ୯ͳΔNSObjectͷαϒΫϥεͷ෼ذʹͳΔͨΊ ໢ཏతͳ෼ذ͸Ͱ͖·ͤΜ
  122. Enum enum class Color( val rgb: String, ) { Red("0xFF0000"),

    Green("0x00FF00"), Blue("0x0000FF"), } enum Color: String { case red = "0xFF0000" case green = "0x00FF00" case blue = "0x0000FF" }
  123. Enum enum class Color( val rgb: String, ) { Red("0xFF0000"),

    Green("0x00FF00"), Blue("0x0000FF"), } enum Color: String { case red = "0xFF0000" case green = "0x00FF00" case blue = "0x0000FF" } SwiftͷenumͷrawValueͷΑ͏ʹ enum classʹϝϯόʔΛఆٛ͢Δ͜ͱͰ ஋Λ࣋ͬͨྻڍࢠΛఆٛͰ͖·͢
  124. Enum sealed interface Direction { data object North : Direction

    data object South : Direction data object West : Direction data object East : Direction val isNorth: Boolean get() = this is North } val direction: Direction = Direction.East when (direction) { Direction.North -> println("North") Direction.South -> println("South") Direction.West -> println("West") Direction.East -> println("East") } enum Direction { case north case south case west case east var isNorth: Bool { self == .north } } let direction: Direction = .east switch direction { case .north: print("north") case .south: print("south") case .west: print("west") case .east: print("east") }
  125. Enum sealed interface Direction { data object North : Direction

    data object South : Direction data object West : Direction data object East : Direction val isNorth: Boolean get() = this is North } val direction: Direction = Direction.East when (direction) { Direction.North -> println("North") Direction.South -> println("South") Direction.West -> println("West") Direction.East -> println("East") } enum Direction { case north case south case west case east var isNorth: Bool { self == .north } } let direction: Direction = .east switch direction { case .north: print("north") case .south: print("south") case .west: print("west") case .east: print("east") } ޙ΄ͲAssociated Value EnumͷηΫγϣϯͰ΋આ໌͠·͕͢ sealed interface / classͰ΋ಉ༷ͷఆٛΛ࣮ݱͰ͖·͢ enum classͱҧ͏෦෼ͱͯ͠ɺྻڍࢠʹ͋ͨΔ෦෼͕ಠࣗͷܕ ͱͳΔͨΊɺͦͷܕʹର͢Δݶఆతͳ֦ுΛ࣮૷Ͱ͖ͨΓ͠·͢
  126. Enum let direction: Direction = DirectionEast.shared switch direction { case

    is DirectionNorth: print("north") case is DirectionSouth: print("south") case is DirectionWest: print("west") case is DirectionEast: print("east") default: print("unknown") } 📦 shared.framework sealed interface Direction { data object North : Direction data object South : Direction data object West : Direction data object East : Direction val isNorth: Boolean get() = this is North } val direction: Direction = Direction.East when (direction) { Direction.North -> println("North") Direction.South -> println("South") Direction.West -> println("West") Direction.East -> println("East") }
  127. Enum let direction: Direction = DirectionEast.shared switch direction { case

    is DirectionNorth: print("north") case is DirectionSouth: print("south") case is DirectionWest: print("west") case is DirectionEast: print("east") default: print("unknown") } 📦 shared.framework sealed interface Direction { data object North : Direction data object South : Direction data object West : Direction data object East : Direction val isNorth: Boolean get() = this is North } val direction: Direction = Direction.East when (direction) { Direction.North -> println("North") Direction.South -> println("South") Direction.West -> println("West") Direction.East -> println("East") } __attribute__((swift_name("Direction"))) @protocol SharedDirection @required @end __attribute__((swift_name("DirectionEast"))) @interface SharedDirectionEast : SharedBase <SharedDirection> @property (class, readonly, getter=shared) SharedDirectionEast *shared __attribute__((swift_name("shared"))); @end __attribute__((swift_name("DirectionNorth"))) @interface SharedDirectionNorth : SharedBase <SharedDirection> @property (class, readonly, getter=shared) SharedDirectionNorth *shared __attribute__((swift_name("shared"))); @end __attribute__((swift_name("DirectionSouth"))) @interface SharedDirectionSouth : SharedBase <SharedDirection> @property (class, readonly, getter=shared) SharedDirectionSouth *shared __attribute__((swift_name("shared"))); @end __attribute__((swift_name("DirectionWest"))) @interface SharedDirectionWest : SharedBase <SharedDirection> @property (class, readonly, getter=shared) SharedDirectionWest *shared __attribute__((swift_name("shared"))); @end NSObjectͷαϒΫϥεʹͳͬͯ໢ཏతʹ෼ذͰ͖ͳ͍͜ͱ͸ಉ༷
  128. Associated Value Enum sealed interface BasicType { data class IntValue(

    val intValue: Int ) : BasicType data class StringValue( val stringValue: String ) : BasicType data class BooleanValue( val booleanValue: Boolean ) : BasicType } val basicType: BasicType = BasicType.IntValue(0) when (basicType) { is BasicType.IntValue -> println(basicType.intValue) is BasicType.StringValue -> println(basicType.stringValue) is BasicType.BooleanValue -> println(basicType.booleanValue) } enum BasicType { case int(intVal: Int) case string(stringVal: String) case bool(boolVal: Bool) } let basicType: BasicType = .int(intVal: 0) switch basicType { case let .int(intVal): print(intVal) case let .bool(boolVal): print(boolVal) case let .string(stringVal): print(stringVal) }
  129. Associated Value Enum sealed interface BasicType { data class IntValue(

    val intValue: Int ) : BasicType data class StringValue( val stringValue: String ) : BasicType data class BooleanValue( val booleanValue: Boolean ) : BasicType } val basicType: BasicType = BasicType.IntValue(0) when (basicType) { is BasicType.IntValue -> println(basicType.intValue) is BasicType.StringValue -> println(basicType.stringValue) is BasicType.BooleanValue -> println(basicType.booleanValue) } enum BasicType { case int(intVal: Int) case string(stringVal: String) case bool(boolVal: Bool) } let basicType: BasicType = .int(intVal: 0) switch basicType { case let .int(intVal): print(intVal) case let .bool(boolVal): print(boolVal) case let .string(stringVal): print(stringVal) } sealed interfaceͷ࣮૷Ϋϥεʹ֘౰ͷ஋Λ࣋ͨͤ·͢
  130. Associated Value Enum sealed interface BasicType { data class IntValue(

    val intValue: Int ) : BasicType data class StringValue( val stringValue: String ) : BasicType data class BooleanValue( val booleanValue: Boolean ) : BasicType } val basicType: BasicType = BasicType.IntValue(0) when (basicType) { is BasicType.IntValue -> println(basicType.intValue) is BasicType.StringValue -> println(basicType.stringValue) is BasicType.BooleanValue -> println(basicType.booleanValue) } enum BasicType { case int(intVal: Int) case string(stringVal: String) case bool(boolVal: Bool) } let basicType: BasicType = .int(intVal: 0) switch basicType { case let .int(intVal): print(intVal) case let .bool(boolVal): print(boolVal) case let .string(stringVal): print(stringVal) } isͰ໢ཏతʹSmart Castͯ͠ɺอ͍࣋ͯ͠Δ஋ʹΞΫηεͰ͖·͢
  131. Associated Value Enum let basicType: BasicType = BasicTypeIntValue(intValue: 0) switch

    basicType { case let value as BasicTypeIntValue: print(value.intValue) case let value as BasicTypeStringValue: print(value.stringValue) case let value as BasicTypeBooleanValue: print(value.booleanValue) default: print("unknown") } 📦 shared.framework sealed interface BasicType { data class IntValue( val intValue: Int ) : BasicType data class StringValue( val stringValue: String ) : BasicType data class BooleanValue( val booleanValue: Boolean ) : BasicType } val basicType: BasicType = BasicType.IntValue(0) when (basicType) { is BasicType.IntValue -> println(basicType.intValue) is BasicType.StringValue -> println(basicType.stringValue) is BasicType.BooleanValue -> println(basicType.booleanValue) }
  132. Associated Value Enum let basicType: BasicType = BasicTypeIntValue(intValue: 0) switch

    basicType { case let value as BasicTypeIntValue: print(value.intValue) case let value as BasicTypeStringValue: print(value.stringValue) case let value as BasicTypeBooleanValue: print(value.booleanValue) default: print("unknown") } 📦 shared.framework sealed interface BasicType { data class IntValue( val intValue: Int ) : BasicType data class StringValue( val stringValue: String ) : BasicType data class BooleanValue( val booleanValue: Boolean ) : BasicType } val basicType: BasicType = BasicType.IntValue(0) when (basicType) { is BasicType.IntValue -> println(basicType.intValue) is BasicType.StringValue -> println(basicType.stringValue) is BasicType.BooleanValue -> println(basicType.booleanValue) } __attribute__((swift_name("BasicType"))) @protocol SharedBasicType @required @end __attribute__((swift_name("BasicTypeBooleanValue"))) @interface SharedBasicTypeBooleanValue : SharedBase <SharedBasicType> - (instancetype)initWithBooleanValue:(BOOL)booleanValue __attribute__((swift_name("init(booleanValue:)"))) __attribute__((objc_designated_initializer)); @property (readonly) BOOL booleanValue __attribute__((swift_name("booleanValue"))); @end __attribute__((swift_name("BasicTypeIntValue"))) @interface SharedBasicTypeIntValue : SharedBase <SharedBasicType> - (instancetype)initWithIntValue:(int32_t)intValue __attribute__((swift_name("init(intValue:)"))) __attribute__((objc_designated_initializer)); @property (readonly) int32_t intValue __attribute__((swift_name("intValue"))); @end __attribute__((swift_name("BasicTypeStringValue"))) @interface SharedBasicTypeStringValue : SharedBase <SharedBasicType> - (instancetype)initWithStringValue:(NSString *)stringValue __attribute__((swift_name("init(stringValue:)"))) __attribute__((objc_designated_initializer)); @property (readonly) NSString *stringValue __attribute__((swift_name("stringValue"))); @end protocolʹωετͨ͠ܕΛ࣋ͯͳ͍ͨΊɺݸผͷܗͰग़ྗ͞Ε·͢
  133. Associated Value Enum let basicType: BasicType = BasicType.IntValue(intValue: 0) switch

    basicType { case let value as BasicType.IntValue: print(value.intValue) case let value as BasicType.StringValue: print(value.stringValue) case let value as BasicType.BooleanValue: print(value.booleanValue) default: print("unknown") } 📦 shared.framework sealed class BasicType { data class IntValue( val intValue: Int ) : BasicType() data class StringValue( val stringValue: String ) : BasicType() data class BooleanValue( val booleanValue: Boolean ) : BasicType() } val basicType: BasicType = BasicType.IntValue(0) when (basicType) { is BasicType.IntValue -> println(basicType.intValue) is BasicType.StringValue -> println(basicType.stringValue) is BasicType.BooleanValue -> println(basicType.booleanValue) }
  134. Associated Value Enum let basicType: BasicType = BasicType.IntValue(intValue: 0) switch

    basicType { case let value as BasicType.IntValue: print(value.intValue) case let value as BasicType.StringValue: print(value.stringValue) case let value as BasicType.BooleanValue: print(value.booleanValue) default: print("unknown") } 📦 shared.framework sealed class BasicType { data class IntValue( val intValue: Int ) : BasicType() data class StringValue( val stringValue: String ) : BasicType() data class BooleanValue( val booleanValue: Boolean ) : BasicType() } val basicType: BasicType = BasicType.IntValue(0) when (basicType) { is BasicType.IntValue -> println(basicType.intValue) is BasicType.StringValue -> println(basicType.stringValue) is BasicType.BooleanValue -> println(basicType.booleanValue) } sealed classͰ΋ಉ༷ͷఆ͕ٛͰ͖·͢
  135. Associated Value Enum let basicType: BasicType = BasicType.IntValue(intValue: 0) switch

    basicType { case let value as BasicType.IntValue: print(value.intValue) case let value as BasicType.StringValue: print(value.stringValue) case let value as BasicType.BooleanValue: print(value.booleanValue) default: print("unknown") } 📦 shared.framework sealed class BasicType { data class IntValue( val intValue: Int ) : BasicType() data class StringValue( val stringValue: String ) : BasicType() data class BooleanValue( val booleanValue: Boolean ) : BasicType() } val basicType: BasicType = BasicType.IntValue(0) when (basicType) { is BasicType.IntValue -> println(basicType.intValue) is BasicType.StringValue -> println(basicType.stringValue) is BasicType.BooleanValue -> println(basicType.booleanValue) } __attribute__((swift_name("BasicType"))) @interface SharedBasicType : SharedBase @end __attribute__((swift_name("BasicType.BooleanValue"))) @interface SharedBasicTypeBooleanValue : SharedBasicType - (instancetype)initWithBooleanValue:(BOOL)booleanValue __attribute__((swift_name("init(booleanValue:)"))) __attribute__((objc_designated_initializer)); @property (readonly) BOOL booleanValue __attribute__((swift_name("booleanValue"))); @end __attribute__((swift_name("BasicType.IntValue"))) @interface SharedBasicTypeIntValue : SharedBasicType - (instancetype)initWithIntValue:(int32_t)intValue __attribute__((swift_name("init(intValue:)"))) __attribute__((objc_designated_initializer)); @property (readonly) int32_t intValue __attribute__((swift_name("intValue"))); @end __attribute__((swift_name("BasicType.StringValue"))) @interface SharedBasicTypeStringValue : SharedBasicType - (instancetype)initWithStringValue:(NSString *)stringValue __attribute__((swift_name("init(stringValue:)"))) __attribute__((objc_designated_initializer)); @property (readonly) NSString *stringValue __attribute__((swift_name("stringValue"))); @end BasicType͕NSObjectͷαϒΫϥεʹͳΔͨΊ Swift͔Βࢀর͢Δ৔߹͸ωετͨ͠ܕʹͳΓ·͢
  136. Generic class Box<T>( val value: T ) { fun getVal():

    T = value } fun getBoxInt(): Box<Int> { return Box(100) } fun <T> genericFunction(value: T): Box<T> { return Box(value) } class Box<T> { let value: T init(_ value: T) { self.value = value } func getVal() -> T { return value } } func getBoxInt() -> Box<Int> { return Box(100) } func genericFunction<T>(value: T) -> Box<T> { return Box(value) }
  137. Generic class Box<T>( val value: T ) { fun getVal():

    T = value } fun getBoxInt(): Box<Int> { return Box(100) } fun <T> genericFunction(value: T): Box<T> { return Box(value) } class Box<T> { let value: T init(_ value: T) { self.value = value } func getVal() -> T { return value } } func getBoxInt() -> Box<Int> { return Box(100) } func genericFunction<T>(value: T) -> Box<T> { return Box(value) } Swiftͱಉ༷ͳఆ͕ٛͰ͖·͢
  138. Generic let box1 = Box(value: KotlinInt(int: 100)) let value1: KotlinInt?

    = box1.value let box2: Box<KotlinInt> = FilenameKt.getBoxInt() let value2: KotlinInt? = box2.value let box3: Box<AnyObject> = FilenameKt .genericFunction(value: Any?) let value3: AnyObject? = box3.value 📦 shared.framework class Box<T>( val value: T ) { fun getVal(): T = value } fun getBoxInt(): Box<Int> { return Box(100) } fun <T> genericFunction(value: T): Box<T> { return Box(value) }
  139. Generic let box1 = Box(value: KotlinInt(int: 100)) let value1: KotlinInt?

    = box1.value let box2: Box<KotlinInt> = FilenameKt.getBoxInt() let value2: KotlinInt? = box2.value let box3: Box<AnyObject> = FilenameKt .genericFunction(value: Any?) let value3: AnyObject? = box3.value 📦 shared.framework class Box<T>( val value: T ) { fun getVal(): T = value } fun getBoxInt(): Box<Int> { return Box(100) } fun <T> genericFunction(value: T): Box<T> { return Box(value) } __attribute__((swift_name("Box"))) @interface SharedBox<T> : SharedBase - (instancetype)initWithValue:(T _Nullable)value __attribute__((swift_name("init(value:)"))) __attribute__((objc_designated_initializer)); - (T _Nullable)getVal __attribute__((swift_name("getVal()"))); @property (readonly) T _Nullable value __attribute__((swift_name("value"))); @end Objective-CͷΫϥεͰ͸Lightweight Genericsར༻Ͱ͖·͢ ར༻͢Δ஋ࣗମ͸nullableͱͯ͠ग़ྗ͞Ε·͢
  140. Generic let box1 = Box(value: KotlinInt(int: 100)) let value1: KotlinInt?

    = box1.value let box2: Box<KotlinInt> = FilenameKt.getBoxInt() let value2: KotlinInt? = box2.value let box3: Box<AnyObject> = FilenameKt .genericFunction(value: Any?) let value3: AnyObject? = box3.value 📦 shared.framework class Box<T>( val value: T ) { fun getVal(): T = value } fun getBoxInt(): Box<Int> { return Box(100) } fun <T> genericFunction(value: T): Box<T> { return Box(value) } __attribute__((swift_name("FilenameKt"))) @interface SharedFilenameKt : SharedBase + (SharedBox<SharedInt *> *)getBoxInt __attribute__((swift_name("getBoxInt()"))); @end __attribute__((swift_name("KotlinInt"))) @interface SharedInt : SharedNumber - (instancetype)initWithInt:(int)value; + (instancetype)numberWithInt:(int)value; @end __attribute__((swift_name("KotlinNumber"))) @interface SharedNumber : NSNumber @end Objective-CͷLightweight GenericsͱͳΔͨΊ
 ܕύϥϝʔλʹNSObjectͷαϒΫϥεΛࢦఆ͢Δඞཁ͕͋Γ KotlinIntͱͯ͠ग़ྗ͞ΕΔ
  141. Generic let box1 = Box(value: KotlinInt(int: 100)) let value1: KotlinInt?

    = box1.value let box2: Box<KotlinInt> = FilenameKt.getBoxInt() let value2: KotlinInt? = box2.value let box3: Box<AnyObject> = FilenameKt .genericFunction(value: Any?) let value3: AnyObject? = box3.value 📦 shared.framework class Box<T>( val value: T ) { fun getVal(): T = value } fun getBoxInt(): Box<Int> { return Box(100) } fun <T> genericFunction(value: T): Box<T> { return Box(value) } __attribute__((swift_name("FilenameKt"))) @interface SharedFilenameKt : SharedBase + (SharedBox<id> *)genericFunctionValue:(id _Nullable)value __attribute__((swift_name("genericFunction(value:)"))); @end Objective-CͷLightweight GenericsͱͳΔͨΊ
 ΫϥεҎ֎Ͱ͸ܕύϥϝʔλΛར༻Ͱ͖ͳ͍ͷͰ
 idܕͱͳͬͯ͠·͍ɺSwift͔Β͸AnyObjectͱͳΔ
  142. Generic let box1 = NonnullBox(value: KotlinInt(int: 100)) let value1: KotlinInt

    = box1.value let box2: NonnullBox<KotlinInt> = FilenameKt .getNonnullBoxInt() let value2: KotlinInt = box2.value 📦 shared.framework class NonnullBox<T : Any>( val value: T ) { fun getVal(): T = value } fun getNonnullBoxInt(): NonnullBox<Int> { return NonnullBox(100) }
  143. Generic let box1 = NonnullBox(value: KotlinInt(int: 100)) let value1: KotlinInt

    = box1.value let box2: NonnullBox<KotlinInt> = FilenameKt .getNonnullBoxInt() let value2: KotlinInt = box2.value 📦 shared.framework class NonnullBox<T : Any>( val value: T ) { fun getVal(): T = value } fun getNonnullBoxInt(): NonnullBox<Int> { return NonnullBox(100) } __attribute__((swift_name("NonnullBox"))) @interface SharedNonnullBox<T> : SharedBase - (instancetype)initWithValue:(T)value __attribute__((swift_name("init(value:)"))) __attribute__((objc_designated_initializer)); - (T)getVal __attribute__((swift_name("getVal()"))); @property (readonly) T value __attribute__((swift_name("value"))); @end <T : Any>ͱ͢Δ͜ͱͰNullableͰ͸ͳ͘ͳΔͷͰ Swift͔ΒΞΫηε͢Δ৔߹΋nonnilͱͳΔ
  144. Generic let box1 = NonnullBox(value: KotlinInt(int: 100)) let value1: KotlinInt

    = box1.getVal() let box2: NonnullBox(value: KotlinInt(int: 100)) let value2: Any = box2.getVal() 📦 shared.framework class NonnullBox<T : Any>( val value: T ) { fun getVal(): T = value } class NonnullBox<T : Any>( val value: T ) fun <T : Any> NonnullBox<T>.getVal(): T { return value }
  145. Generic let box1 = NonnullBox(value: KotlinInt(int: 100)) let value1: KotlinInt

    = box1.getVal() let box2: NonnullBox(value: KotlinInt(int: 100)) let value2: Any = box2.getVal() 📦 shared.framework class NonnullBox<T : Any>( val value: T ) { fun getVal(): T = value } class NonnullBox<T : Any>( val value: T ) fun <T : Any> NonnullBox<T>.getVal(): T { return value } @interface SharedNonnullBox (Extensions) - (id)getVal __attribute__((swift_name("getVal()"))); @end Objective-CͷCategoryʹͳΔͨΊɺΫϥεͰ͋ͬͯ΋ ܕύϥϝʔλʹΞΫηεͰ͖ͳ͘ͳͬͯidܕͱͳΔ
  146. Generic sealed interface SealedInterfaceResult< out T, out U : Throwable

    > { data class Success<T>( val value: T ) : SealedInterfaceResult<T, Nothing> data class Failure<U: Throwable>( val exception: U ) : SealedInterfaceResult<Nothing, U> } sealed class SealedClassResult< out T, out U : Throwable > { data class Success<T>( val value: T ) : SealedClassResult<T, Nothing>() data class Failure<U: Throwable>( val exception: U ) : SealedClassResult<Nothing, U>() } enum Result<T, E: Error> { case success(T) case failure(E) }
  147. Generic sealed interface SealedInterfaceResult< out T, out U : Throwable

    > { data class Success<T>( val value: T ) : SealedInterfaceResult<T, Nothing> data class Failure<U: Throwable>( val exception: U ) : SealedInterfaceResult<Nothing, U> } let result: SealedInterfaceResult = SealedInterfaceResultSuccess( value: KotlinInt(value: 100) ) switch result { case let value as SealedInterfaceResultSuccess<KotlinInt>: print(value.value?.intValue) case let value as SealedInterfaceResultFailure<KotlinException>: print(value.exception) default: print("unknown") } 📦 shared.framework
  148. Generic sealed interface SealedInterfaceResult< out T, out U: Throwable >

    { data class Success<T>( val value: T ) : SealedInterfaceResult<T, Nothing> data class Failure<U: Throwable>( val exception: U ) : SealedInterfaceResult<Nothing, U> } let result: SealedInterfaceResult = SealedInterfaceResultSuccess( value: KotlinInt(value: 100) ) switch result { case let value as SealedInterfaceResultSuccess<KotlinInt>: print(value.value?.intValue) case let value as SealedInterfaceResultFailure<KotlinException>: print(value.exception) default: print("unknown") } 📦 shared.framework __attribute__((swift_name("SealedInterfaceResult"))) @protocol SharedSealedInterfaceResult @required @end __attribute__((swift_name("SealedInterfaceResultFailure"))) @interface SharedSealedInterfaceResultFailure<U> : SharedBase <SharedSealedInterfaceResult> - (instancetype)initWithException:(U)exception __attribute__((swift_name("init(exception:)"))) __attribute__((objc_designated_initializer)); @property (readonly) U exception __attribute__((swift_name("exception"))); @end __attribute__((swift_name("SealedInterfaceResultSuccess"))) @interface SharedSealedInterfaceResultSuccess<T> : SharedBase <SharedSealedInterfaceResult> - (instancetype)initWithValue:(T _Nullable)value __attribute__((swift_name("init(value:)"))) __attribute__((objc_designated_initializer)); @property (readonly) T _Nullable value __attribute__((swift_name("value"))); @end interface͸protocolʹରԠ͍ͯ͠Δ͕ɺObjective-Cͷprotocol
 ͕GenericsʹରԠ͍ͯ͠ͳ͍ͨΊɺܕ͕ফࣦ͢Δ
  149. Generic sealed class SealedClassResult< out T, out U : Throwable

    > { data class Success<T>( val value: T ) : SealedClassResult<T, Nothing>() data class Failure<U: Throwable>( val exception: U ) : SealedClassResult<Nothing, U>() } let result: SealedClassResult<KotlinInt, KotlinException> = SealedClassResultSuccess(value: KotlinInt(value: 100)) 📦 shared.framework
  150. Generic sealed class SealedClassResult< out T, out U: Throwable >

    { data class Success<T>( val value: T ) : SealedClassResult<T, Nothing>() data class Failure<U: Throwable>( val exception: U ) : SealedClassResult<Nothing, U>() } let result: SealedClassResult<KotlinInt, KotlinException> = SealedClassResultSuccess(value: KotlinInt(value: 100)) 📦 shared.framework Cannot assign value of type 'SealedClassResult<KotlinInt, KotlinNothing>' to type 'SealedClassResult<KotlinInt, KotlinException>' ܕ͕߹Θͳ͍ओࢫͷΤϥʔʹͳͬͯ͠·͏
  151. Generic sealed class SealedClassResult< out T, out U: Throwable >

    { data class Success<T>( val value: T ) : SealedClassResult<T, Nothing>() data class Failure<U: Throwable>( val exception: U ) : SealedClassResult<Nothing, U>() } let result: SealedClassResult<KotlinInt, KotlinException> = SealedClassResultSuccess(value: KotlinInt(value: 100)) 📦 shared.framework __attribute__((swift_name("SealedClassResult"))) @interface SharedSealedClassResult<__covariant T, __covariant U> : SharedBase @end __attribute__((swift_name("SealedClassResultFailure"))) @interface SharedSealedClassResultFailure<U> : SharedSealedClassResult<SharedKotlinNothing *, U> - (instancetype)initWithException:(U)exception __attribute__((swift_name("init(exception:)"))) __attribute__((objc_designated_initializer)); @property (readonly) U exception __attribute__((swift_name("exception"))); @end __attribute__((swift_name("SealedClassResultSuccess"))) @interface SharedSealedClassResultSuccess<T> : SharedSealedClassResult<T, SharedKotlinNothing *> - (instancetype)initWithValue:(T _Nullable)value __attribute__((swift_name("init(value:)"))) __attribute__((objc_designated_initializer)); @property (readonly) T _Nullable value __attribute__((swift_name("value"))); @end Objective-CͰ͸ӈล΋͘͠͸ࠨลʹผͳܕ͕ࢦఆ͞Εͨ
 ҧ͏ܕͱͯ͠ղऍ͞ΕΔ
  152. Generic class SealedClassResultFactory< T, U : Throwable > private constructor(

    val result: SealedClassResult<T, U> ) { constructor(value: T) : this( result = SealedClassResult .Success(value) ) constructor(exception: U) : this( result = SealedClassResult .Failure(exception) ) } let result: SealedClassResult<KotlinInt, KotlinException> = SealedClassResultFactory(value: KotlinInt(value: 100)).result switch result { case let value as SealedInterfaceResultSuccess<KotlinInt>: print(value.value?.intValue) case let value as SealedInterfaceResultFailure<KotlinException>: print(value.exception) default: print("unknown") } 📦 shared.framework
  153. Generic let result: SealedClassResult<KotlinInt, KotlinException> = SealedClassResultFactory(value: KotlinInt(value: 100)).result switch

    result { case let value as SealedInterfaceResultSuccess<KotlinInt>: print(value.value?.intValue) case let value as SealedInterfaceResultFailure<KotlinException>: print(value.exception) default: print("unknown") } 📦 shared.framework class SealedClassResultFactory< T, U: Throwable > private constructor( val result: SealedClassResult<T, U> ) { constructor(value: T) : this( result = SealedClassResult .Success(value) ) constructor(exception: U) : this( result = SealedClassResult .Failure(exception) ) } __attribute__((swift_name("SealedClassResultFactory"))) @interface SharedSealedClassResultFactory<T, U> : SharedBase - (instancetype)initWithValue:(T _Nullable)value __attribute__((swift_name("init(value:)"))) __attribute__((objc_designated_initializer)); - (instancetype)initWithException:(U)exception __attribute__((swift_name("init(exception:)"))) __attribute__((objc_designated_initializer)); @property (readonly) SharedSealedClassResult<T, U> *result __attribute__((swift_name("result"))); @end KotlinͰܕͷڞมੑ͕อͨΕ͍ͯΔͨΊɺ֘౰͢Δॲཧ͸ KotlinͰ࣮૷͢Δ Objective-CͰΫϥε͸ܕύϥϝʔλΛར༻Ͱ͖ΔͷͰ ͦΕΛ࢖ͬͯ֘౰ͷܕΛੜ੒͢Δ
  154. Generic let result: SealedClassResult<KotlinInt, KotlinException> = SealedClassResultFactory(value: KotlinInt(value: 100)).result switch

    result { case let value as SealedInterfaceResultSuccess<KotlinInt>: print(value.value?.intValue) case let value as SealedInterfaceResultFailure<KotlinException>: print(value.exception) default: print("unknown") } 📦 shared.framework class SealedClassResultFactory< T, U : Throwable > private constructor( val result: SealedClassResult<T, U> ) { constructor(value: T) : this( result = SealedClassResult .Success(value) ) constructor(exception: U) : this( result = SealedClassResult .Failure(exception) ) } Cast from 'SealedClassResult<KotlinInt, KotlinException>' to unrelated type 'SealedInterfaceResultSuccess<KotlinInt>' always fails ܕ͕߹ΘͣΩϟετͰ͖ͳ͍ओࢫͷϫʔχϯά͕ग़Δ
  155. Generic class SealedClassResultHandler< T : Any, U : Throwable, V

    : Any >( value: SealedClassResult<T, U>, onSuccess: (T) -> V, onFailure: (U) -> V, ) { val result: V = when (value) { is SealedClassResult.Success -> onSuccess(value.value) is SealedClassResult.Failure -> onFailure(value.exception) } } final class Box<T> { let value: T init(_ value: T) { self.value = value } } extension KotlinThrowable: Error {} let result = SealedClassResultFactory<KotlinInt, KotlinException>( value: KotlinInt(value: 100) ).result let swiftResult: Result<Int, KotlinException> = SealedClassResultHandler( value: result, onSuccess: { value in Box(Result.success(value.intValue)) }, onFailure: { exception in Box(Result.failure(exception)) } ).result.value switch swiftResult { case let .success(intValue): print(intValue) case let .failure(exception): print(exception) } 📦 shared.framework
  156. Generic class SealedClassResultHandler< T : Any, U : Throwable, V

    : Any >( value: SealedClassResult<T, U>, onSuccess: (T) -> V, onFailure: (U) -> V, ) { val result: V = when (value) { is SealedClassResult.Success -> onSuccess(value.value) is SealedClassResult.Failure -> onFailure(value.exception) } } final class Box<T> { let value: T init(_ value: T) { self.value = value } } extension KotlinThrowable: Error {} let result = SealedClassResultFactory<KotlinInt, KotlinException>( value: KotlinInt(value: 100) ).result let swiftResult: Result<Int, KotlinException> = SealedClassResultHandler( value: result, onSuccess: { value in Box(Result.success(value.intValue)) }, onFailure: { exception in Box(Result.failure(exception)) } ).result.value switch swiftResult { case let .success(intValue): print(intValue) case let .failure(exception): print(exception) } 📦 shared.framework __attribute__((swift_name("SealedClassResultHandler"))) @interface SharedSealedClassResultHandler<T, U, V> : SharedBase - (instancetype)initWithValue:(SharedSealedClassResult<T, U> *)value onSuccess:(V (^)(T))onSuccess onFailure:(V (^)(U))onFailure __attribute__((swift_name("init(value:onSuccess:onFailure:)"))) __attribute__((objc_designated_initializer)); @property (readonly) V result __attribute__((swift_name("result"))); @end KotlinͰڞมੑͱ໢ཏੑΛอͬͯॲཧ͢Δ͜ͱ͕Ͱ͖ΔͷͰ KotlinͰ࣮૷͢Δ Swift͔Β͸೚ҙͷܕʹม׵ͨ݁͠ՌΛར༻Ͱ͖ΔΑ͏ʹ͢Δ
  157. Generic class SealedClassResultHandler< T : Any, U : Throwable, V

    : Any >( value: SealedClassResult<T, U>, onSuccess: (T) -> V, onFailure: (U) -> V, ) { val result: V = when (value) { is SealedClassResult.Success -> onSuccess(value.value) is SealedClassResult.Failure -> onFailure(value.exception) } } final class Box<T> { let value: T init(_ value: T) { self.value = value } } extension KotlinThrowable: Error {} let result = SealedClassResultFactory<KotlinInt, KotlinException>( value: KotlinInt(value: 100) ).result let swiftResult: Result<Int, KotlinException> = SealedClassResultHandler( value: result, onSuccess: { value in Box(Result.success(value.intValue)) }, onFailure: { exception in Box(Result.failure(exception)) } ).result.value switch swiftResult { case let .success(intValue): print(intValue) case let .failure(exception): print(exception) } 📦 shared.framework KMPͰੜ੒͞ΕͨGenericsͳܕΛར༻͢Δ৔߹ʹ AnyObjectͰͳ͍ͱ͍͚ͳ͍ͨΊɺSwiftͰ࣮૷ͨ͠ܕͰϥοϓ͢Δ
  158. Generic class SealedClassResultHandler< T : Any, U : Throwable, V

    : Any >( value: SealedClassResult<T, U>, onSuccess: (T) -> V, onFailure: (U) -> V, ) { val result: V = when (value) { is SealedClassResult.Success -> onSuccess(value.value) is SealedClassResult.Failure -> onFailure(value.exception) } } final class Box<T> { let value: T init(_ value: T) { self.value = value } } extension KotlinThrowable: Error {} let result = SealedClassResultFactory<KotlinInt, KotlinException>( value: KotlinInt(value: 100) ).result let swiftResult: Result<Int, KotlinException> = SealedClassResultHandler( value: result, onSuccess: { value in Box(Result.success(value.intValue)) }, onFailure: { exception in Box(Result.failure(exception)) } ).result.value switch swiftResult { case let .success(intValue): print(intValue) case let .failure(exception): print(exception) } 📦 shared.framework ϥοϓͨ͠ܕ͔ΒSwiftͰར༻ͨ͠ܕΛऔΓग़ͯ͠໢ཏతʹ෼ذ͢Δ