Slide 1

Slide 1 text

CA.swift #17 ٯҾ͖Kotlin Multiplatform
 ʙSwiftʹରԠ͢ΔKotlinͷػೳͱɺKMPʹΑΔม׵ޙͷ࣮ଶʙ

Slide 2

Slide 2 text

ࣗݾ঺հ 🏢ɹגࣜձࣾαΠόʔΤʔδΣϯτ ɹɹmarty-suzuki 👨💻ɹϞόΠϧΞϓϦΤϯδχΞ ɹɹmarty_suzuki 🏌ɹSTEALTH 2 / VENTUS TR 6-S

Slide 3

Slide 3 text

Training Project

Slide 4

Slide 4 text

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)")

Slide 5

Slide 5 text

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ͱಉ༷ͳ༷ࣜͰলུ΋Ͱ͖Δ

Slide 6

Slide 6 text

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}

Slide 7

Slide 7 text

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Ͱม਺ͷએݴΛ͢Δ

Slide 8

Slide 8 text

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)

Slide 9

Slide 9 text

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ͱಉ༷ʹσϑΥϧτҾ਺ΛఆٛͰ͖Δ ࠷ޙʹఆٛͨ͠Ҿ਺ͷʮ,ʯΛলུ΋Ͱ͖Δ

Slide 10

Slide 10 text

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) { … }ͰׅΒͣʹɺʮ=ʯͰ݁ՌΛฦ͢ॻ͖ํ΋Ͱ͖Δ

Slide 11

Slide 11 text

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) Ҿ਺໊͸লུ΋Ͱ͖Δ ࠷ޙͷҾ਺ͷʮ,ʯΛলུ΋Ͱ͖Δ

Slide 12

Slide 12 text

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

Slide 13

Slide 13 text

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͔Βࢀরͨ͠ͱ͖ͷݟ͑ํ

Slide 14

Slide 14 text

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

Slide 15

Slide 15 text

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ͷ໋໊نଇͰΫϥε͕ੜ੒͞Ε ͦͷΫϥεؔ਺ͱͯ͠ग़ྗ͞ΕΔ

Slide 16

Slide 16 text

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͔Β͸୯ମͰ ΠϯελϯεԽ͢Δ͜ͱ͕Ͱ͖ͳ͍Ϋϥε

Slide 17

Slide 17 text

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 ͪͳΈʹ਺஋ܕͷϚοϐϯά͸࣍ͷΑ͏ʹͳΓ·͢

Slide 18

Slide 18 text

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

Slide 19

Slide 19 text

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 }

Slide 20

Slide 20 text

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ͱରԠ͢Δ એݴͷ࢓ํ͸جຊతʹಉ͡

Slide 21

Slide 21 text

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ʯͰΞΫηε͢Δ

Slide 22

Slide 22 text

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)")

Slide 23

Slide 23 text

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)") ( )Λলུ͢Δ͜ͱ͸Ͱ͖ͳ͍

Slide 24

Slide 24 text

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จ಺Ͱ஋Λฦͯ͠ఆ਺ɾม਺ʹ୅ೖ͢Δ͜ͱ͕Ͱ͖Δ

Slide 25

Slide 25 text

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)")

Slide 26

Slide 26 text

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จ

Slide 27

Slide 27 text

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ߦͷ৔߹͸{ }Λলུ΋Ͱ͖Δ

Slide 28

Slide 28 text

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จಉ༷ʹఆ਺ɾม਺ʹ஋Λ୅ೖͰ͖Δ

Slide 29

Slide 29 text

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)") }

Slide 30

Slide 30 text

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Λ౤͛Δ

Slide 31

Slide 31 text

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ͰғΘͳ͍ͱΤϥʔʹͳΔػߏ͸ͳ͍

Slide 32

Slide 32 text

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 }

Slide 33

Slide 33 text

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ͰΞϓϦ͕Ϋϥογϡ͢Δ

Slide 34

Slide 34 text

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 }

Slide 35

Slide 35 text

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Ͱ͖ΔΑ͏ʹͳΔ

Slide 36

Slide 36 text

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

Slide 37

Slide 37 text

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ͰΞϓϦ͕Ϋϥογϡ͢ΔͷͰ஫ҙ

Slide 38

Slide 38 text

Tuple fun getPair(): Pair { 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)")

Slide 39

Slide 39 text

Tuple fun getPair(): Pair { 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ͱ͍͏δΣωϦοΫͳܕ

Slide 40

Slide 40 text

Tuple fun getPair(): Pair { 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ͰΞΫηεͰ͖Δ

Slide 41

Slide 41 text

Tuple fun getPair(): Pair { 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)") ෼͚ͯऔΓग़͢͜ͱ΋Ͱ͖Δ

Slide 42

Slide 42 text

Tuple fun getPair(): Pair { 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ͱ͍͏ผͳܕΛ࢖͏

Slide 43

Slide 43 text

Tuple let pair: KotlinPair = FilenameKt.getPair() let first = pair.first as String? let second = pair.second?.intValue 📦 shared.framework fun getPair(): Pair { 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}")

Slide 44

Slide 44 text

Tuple let pair: KotlinPair = FilenameKt.getPair() let first = pair.first as String? let second = pair.second?.intValue 📦 shared.framework fun getPair(): Pair { 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͕ඞཁʹͳΔͨΊ Ͱ͸ͳ͘ʹͳΔ

Slide 45

Slide 45 text

Tuple let pair: KotlinPair = FilenameKt.getPair() let first = pair.first as String? let second = pair.second?.intValue 📦 shared.framework fun getPair(): Pair { 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 *)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

Slide 46

Slide 46 text

Tuple let pair: KotlinPair = FilenameKt.getPair() let first = pair.first as String? let second = pair.second?.intValue 📦 shared.framework fun getPair(): Pair { 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ʹͳΔ

Slide 47

Slide 47 text

Array val strings: List = listOf( "back", "to", "the", "future" ) println("strings = $strings") val strings2: List = 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)")

Slide 48

Slide 48 text

Array val strings: List = listOf( "back", "to", "the", "future" ) println("strings = $strings") val strings2: List = 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ͰΠϯελϯεԽ͠·͢

Slide 49

Slide 49 text

Array val strings: List = listOf( "back", "to", "the", "future" ) println("strings = $strings") val strings2: List = 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ͰΠϯελϯεԽ΋Ͱ͖·͢

Slide 50

Slide 50 text

Array val strings: List = listOf( "back", "to", "the", "future" ) println("strings = $strings") val strings2: List = 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)") ഑ྻಉ࢜ͷ݁߹΋Ͱ͖·͢

Slide 51

Slide 51 text

Array val mutableStrings: MutableList = 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)")

Slide 52

Slide 52 text

Array val mutableStrings: MutableList = 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 ͰΠϯελϯεԽ͠·͢

Slide 53

Slide 53 text

Array val mutableStrings: MutableList = 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ͱಉ༷ͳ഑ྻૢ࡞͕Ͱ͖·͢

Slide 54

Slide 54 text

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" )

Slide 55

Slide 55 text

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 *strings __attribute__((swift_name("strings"))); @end

Slide 56

Slide 56 text

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 *mutableStrings __attribute__((swift_name("mutableStrings"))); @end NSMutableArrayͱͯ͠ग़ྗ͞Ε·͢
 KotlinͷList͕΋ͱ΋ͱࢀরܕͳͷͰɺଞͷม਺ʹ୅ೖͯ͠ ഑ྻૢ࡞Λߦͬͨͱͯ͠΋ɺมߋ͕ద༻͞Ε·͢

Slide 57

Slide 57 text

Dictionary val map: Map = 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)”)

Slide 58

Slide 58 text

Dictionary val map: Map = 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ͰΠϯελϯεԽ͠·͢

Slide 59

Slide 59 text

Dictionary val map: Map = 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)”) ΩʔࢦఆͰ஋ΛऔಘͰ͖Δ

Slide 60

Slide 60 text

Dictionary val map: Map = 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ͩͬͨ৔߹ʹ σϑΥϧτ஋Λฦ͢͜ͱ΋Ͱ͖Δ

Slide 61

Slide 61 text

Dictionary val map: Map = 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ಉ࢜ͷ݁߹΋Ͱ͖Δ

Slide 62

Slide 62 text

Dictionary val mutableMap: MutableMap = 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)")

Slide 63

Slide 63 text

Dictionary val mutableMap: MutableMap = 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 ͰΠϯελϯεԽ͠·͢

Slide 64

Slide 64 text

Dictionary val mutableMap: MutableMap = 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ͱಉ༷ͳࣙॻ഑ྻૢ࡞͕Ͱ͖·͢

Slide 65

Slide 65 text

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

Slide 66

Slide 66 text

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

Slide 67

Slide 67 text

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

Slide 68

Slide 68 text

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)")

Slide 69

Slide 69 text

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ͱͯ͠ѻ͏͜ͱ͕Ͱ͖·͢

Slide 70

Slide 70 text

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ʹࢦఆ͢Δ͜ͱͰ ؔ਺΍ϝϯόʔʹΞΫηεͰ͖·͢

Slide 71

Slide 71 text

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)")

Slide 72

Slide 72 text

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ʹࢦఆ͢Δ͜ͱͰ ڧ੍తʹؔ਺΍ϝϯόʔʹΞΫηεͰ͖·͢

Slide 73

Slide 73 text

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ΛϋϯυϦϯάͰ͖·͢

Slide 74

Slide 74 text

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

Slide 75

Slide 75 text

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Ͱ͸ͳ͍ ͜ͱΛอূͯ͘͠ΕΔ

Slide 76

Slide 76 text

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Ͱ͸ͳ͍͜ͱΛอূͯ͘͠ΕΔ

Slide 77

Slide 77 text

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 ͱಉ༷ͷૢ࡞͕Ͱ͖Δ

Slide 78

Slide 78 text

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 = emptyList() var map: Map = emptyMap()

Slide 79

Slide 79 text

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 = emptyList() var map: Map = emptyMap() __attribute__((swift_name("FilenameKt"))) @interface SharedFilenameKt : SharedBase @property (class) NSString * _Nullable optionalString __attribute__((swift_name("optionalString"))); @end NullableͳNSStringͱͯ͠ग़ྗ͞ΕɺObjectiveCBridgeable
 ʹΑΔ҉໧తͳม׵ʹΑͬͯSwiftͷOptionalʹม׵͞ΕΔ

Slide 80

Slide 80 text

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 = emptyList() var map: Map = emptyMap() __attribute__((swift_name("FilenameKt"))) @interface SharedFilenameKt : SharedBase @property (class) NSArray *list __attribute__((swift_name("list"))); @end ޙ΄ͲGenericͷηΫγϣϯͰ΋આ໌͠·͕͢ɺList͸interface Ͱ͕͢Objective-Cͷprotocol͕GenericʹରԠ͍ͯ͠ͳ͍ͨΊ idܕʹม׵͞ΕΔ͜ͱͰɺ[Any]ͱͳͬͯ͠·͍·͢

Slide 81

Slide 81 text

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 = emptyList() var map: Map = emptyMap() __attribute__((swift_name("FilenameKt"))) @interface SharedFilenameKt : SharedBase @property (class) NSDictionary *map __attribute__((swift_name("map"))); @end ޙ΄ͲGenericͷηΫγϣϯͰ΋આ໌͠·͕͢ɺMap͸interface Ͱ͕͢Objective-Cͷprotocol͕GenericʹରԠ͍ͯ͠ͳ͍ͨΊ Idܕʹม׵͞ΕΔ͜ͱͰɺ[AnyHashable: Any]ͱͳͬͯ͠·͍·͢

Slide 82

Slide 82 text

Class class UserRepository( private val mutableUsernames: MutableList, ) { var lastUsername: String? = null private set val usernames: List get() = mutableUsernames constructor(usernames: List) : 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 } }

Slide 83

Slide 83 text

Class class UserRepository( private val mutableUsernames: MutableList, ) { var lastUsername: String? = null private set val usernames: List get() = mutableUsernames constructor(usernames: List) : 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ʹϝϯόʔΛ ࣋ͨͤΔ͜ͱ͕Ͱ͖·͢ ୯ͳΔҾ਺ͱ͢Δ͜ͱ΋Ͱ͖·͢

Slide 84

Slide 84 text

Class class UserRepository( private val mutableUsernames: MutableList, ) { var lastUsername: String? = null private set val usernames: List get() = mutableUsernames constructor(usernames: List) : 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Ͱఆٛ͢Δ͜ͱ͸Ͱ͖·ͤΜ

Slide 85

Slide 85 text

Class class UserRepository( private val mutableUsernames: MutableList, ) { var lastUsername: String? = null private set val usernames: List get() = mutableUsernames constructor(usernames: List) : 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͕͋Γ·͢

Slide 86

Slide 86 text

Class class UserRepository( private val mutableUsernames: MutableList, ) { var lastUsername: String? = null private set val usernames: List get() = mutableUsernames constructor(usernames: List) : 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ՄೳͳϝϯόʔΛఆٛͰ͖·͢

Slide 87

Slide 87 text

Class class UserRepository( private val mutableUsernames: MutableList, ) { var lastUsername: String? = null private set val usernames: List get() = mutableUsernames constructor(usernames: List) : 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ͷΈͷϝϯόʔΛఆٛͰ͖·͢

Slide 88

Slide 88 text

Class class UserRepository( private val mutableUsernames: MutableList, ) { var lastUsername: String? = null private set val usernames: List get() = mutableUsernames constructor(usernames: List) : 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Λར༻͠ɺࣗ਎ͷ ϝϯόʔ΍ؔ਺ʹΞΫηε͢Δ৔߹͸লུ΋Ͱ͖·͢

Slide 89

Slide 89 text

Class class UserRepository( private val mutableUsernames: MutableList, ) { var lastUsername: String? = null private set val usernames: List get() = mutableUsernames constructor(usernames: List) : 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

Slide 90

Slide 90 text

Class class UserRepository( private val mutableUsernames: MutableList, ) { var lastUsername: String? = null private set val usernames: List get() = mutableUsernames constructor(usernames: List) : 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 *)usernames __attribute__((swift_name("init(usernames:)"))) __attribute__((objc_designated_initializer)); - (instancetype)initWithMutableUsernames:(NSMutableArray *)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 *usernames __attribute__((swift_name("usernames"))); @end primary constructor͸MutableListͳͷͰ
 NSMutableArrayΛ౉ͯ͠ΠϯελϯεԽ͢Δ

Slide 91

Slide 91 text

Class class UserRepository( private val mutableUsernames: MutableList, ) { var lastUsername: String? = null private set val usernames: List get() = mutableUsernames constructor(usernames: List) : 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 ࢀরܕͳͷͰɺ֎͔Βมߋͯ͠΋൓ө͞ΕΔ

Slide 92

Slide 92 text

Class class UserRepository( private val mutableUsernames: MutableList, ) { var lastUsername: String? = null private set val usernames: List get() = mutableUsernames constructor(usernames: List) : 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 *)usernames __attribute__((swift_name("init(usernames:)"))) __attribute__((objc_designated_initializer)); @end secondary constructor͸ListͳͷͰ
 SwiftͷArrayΛ౉ͯ͠ΠϯελϯεԽͰ͖Δ

Slide 93

Slide 93 text

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 } }

Slide 94

Slide 94 text

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

Slide 95

Slide 95 text

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౳ʹ࠾༻͢Δ͜ͱ΋Ͱ͖Δ

Slide 96

Slide 96 text

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 } } σϑΥϧτ࣮૷͢Δ͜ͱ΋Ͱ͖ɺ࣮૷ΫϥεͰ ର৅ͷϝϯόʔ΍ؔ਺Λఆٛ͠ͳͯ͘΋ྑ͘ͳΔ

Slide 97

Slide 97 text

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

Slide 98

Slide 98 text

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 - (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 @required @property (readonly) NSString *firstName __attribute__((swift_name("firstName"))); @property (readonly) NSString *lastName __attribute__((swift_name("lastName"))); @end

Slide 99

Slide 99 text

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 σϑΥϧτ࣮૷ʹΞΫηεͰ͖Δ

Slide 100

Slide 100 text

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 @required @property (readonly) NSString *firstName __attribute__((swift_name("firstName"))); @property (readonly) NSString *lastName __attribute__((swift_name("lastName"))); @end KMPͰग़ྗ͞ΕͨprotocolΛSwiftͰఆٛͨ͠Ϋϥεʹ ࠾༻ͨ͠৔߹ɺσϑΥϧτ࣮૷Λར༻Ͱ͖ͳ͍

Slide 101

Slide 101 text

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() } }

Slide 102

Slide 102 text

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Λར༻͢Δ

Slide 103

Slide 103 text

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

Slide 104

Slide 104 text

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 ͷϝϯόʔ΍ؔ਺ʹΞΫηεͰ͖·͢

Slide 105

Slide 105 text

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ͷϝϯόʔ΍ ؔ਺ʹΞΫηε͢Δ͜ͱ΋Ͱ͖·͢

Slide 106

Slide 106 text

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" }

Slide 107

Slide 107 text

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ͱ͢Δ͜ͱͰɺγϯάϧτϯѻ͍ͳܕΛ ੜ੒͢Δ͜ͱ΋Ͱ͖Δ

Slide 108

Slide 108 text

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" }

Slide 109

Slide 109 text

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ܕͱͳͬͯ͠·͏

Slide 110

Slide 110 text

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 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ͱͯ͠ΞΫηε Ͱ͖Δ

Slide 111

Slide 111 text

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 } }

Slide 112

Slide 112 text

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ͱಉ༷ʹ֦ுؔ਺ΛఆٛͰ͖Δ Ϋϥεͷதʹωετͤͯ͞ఆٛͨ͠Γ΋Ͱ͖Δ

Slide 113

Slide 113 text

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 }

Slide 114

Slide 114 text

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ʹΫϥεؔ਺͕ੜ੒͞Ε ୈҰҾ਺ʹ֦ுͨ͠ܕͷΠϯελϯεΛ ౉͢͜ͱͰ֦ுؔ਺౳͕ར༻Ͱ͖·͢

Slide 115

Slide 115 text

Extension KotlinException().nonnullCause() 📦 shared.framework fun Exception.nonnullCause(): Throwable { return cause ?: this }

Slide 116

Slide 116 text

Extension KotlinException().nonnullCause() 📦 shared.framework fun Exception.nonnullCause(): Throwable { return cause ?: this } Classʹؔͯ͠͸ɺ֦ுؔ਺౳ʹ௚઀ΞΫηεͰ͖Δ

Slide 117

Slide 117 text

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

Slide 118

Slide 118 text

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Ͱએݴͨ͠৔߹ͱڍಈ͕ҟͳΔ

Slide 119

Slide 119 text

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?, )

Slide 120

Slide 120 text

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ͷαϒΫϥεͱ ͳΔͨΊࢀরܕͱͳΓ·͢

Slide 121

Slide 121 text

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") }

Slide 122

Slide 122 text

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Ͱ͢

Slide 123

Slide 123 text

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จΛ࢖ͬͯ໢ཏతʹ෼ذͰ͖·͢

Slide 124

Slide 124 text

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") }

Slide 125

Slide 125 text

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 @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 : SharedBase @end NS_EnumͰग़ྗ͞ΕΔͷͰ͸ͳ͘ɺKotlinBaseΛܧঝͨ͠KotlinEnum ͱͯ͠ग़ྗ͞ΕΔͨΊɺྻڍࢠ͸Ϋϥεͷstored propertyͰఆٛ͞Ε·͢

Slide 126

Slide 126 text

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ͷαϒΫϥεͷ෼ذʹͳΔͨΊ ໢ཏతͳ෼ذ͸Ͱ͖·ͤΜ

Slide 127

Slide 127 text

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" }

Slide 128

Slide 128 text

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ʹϝϯόʔΛఆٛ͢Δ͜ͱͰ ஋Λ࣋ͬͨྻڍࢠΛఆٛͰ͖·͢

Slide 129

Slide 129 text

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") }

Slide 130

Slide 130 text

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ͱҧ͏෦෼ͱͯ͠ɺྻڍࢠʹ͋ͨΔ෦෼͕ಠࣗͷܕ ͱͳΔͨΊɺͦͷܕʹର͢Δݶఆతͳ֦ுΛ࣮૷Ͱ͖ͨΓ͠·͢

Slide 131

Slide 131 text

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") }

Slide 132

Slide 132 text

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 @property (class, readonly, getter=shared) SharedDirectionEast *shared __attribute__((swift_name("shared"))); @end __attribute__((swift_name("DirectionNorth"))) @interface SharedDirectionNorth : SharedBase @property (class, readonly, getter=shared) SharedDirectionNorth *shared __attribute__((swift_name("shared"))); @end __attribute__((swift_name("DirectionSouth"))) @interface SharedDirectionSouth : SharedBase @property (class, readonly, getter=shared) SharedDirectionSouth *shared __attribute__((swift_name("shared"))); @end __attribute__((swift_name("DirectionWest"))) @interface SharedDirectionWest : SharedBase @property (class, readonly, getter=shared) SharedDirectionWest *shared __attribute__((swift_name("shared"))); @end NSObjectͷαϒΫϥεʹͳͬͯ໢ཏతʹ෼ذͰ͖ͳ͍͜ͱ͸ಉ༷

Slide 133

Slide 133 text

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) }

Slide 134

Slide 134 text

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ͷ࣮૷Ϋϥεʹ֘౰ͷ஋Λ࣋ͨͤ·͢

Slide 135

Slide 135 text

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ͯ͠ɺอ͍࣋ͯ͠Δ஋ʹΞΫηεͰ͖·͢

Slide 136

Slide 136 text

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) }

Slide 137

Slide 137 text

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 - (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 - (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 - (instancetype)initWithStringValue:(NSString *)stringValue __attribute__((swift_name("init(stringValue:)"))) __attribute__((objc_designated_initializer)); @property (readonly) NSString *stringValue __attribute__((swift_name("stringValue"))); @end protocolʹωετͨ͠ܕΛ࣋ͯͳ͍ͨΊɺݸผͷܗͰग़ྗ͞Ε·͢

Slide 138

Slide 138 text

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) }

Slide 139

Slide 139 text

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Ͱ΋ಉ༷ͷఆ͕ٛͰ͖·͢

Slide 140

Slide 140 text

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͔Βࢀর͢Δ৔߹͸ωετͨ͠ܕʹͳΓ·͢

Slide 141

Slide 141 text

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

Slide 142

Slide 142 text

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

Slide 143

Slide 143 text

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

Slide 144

Slide 144 text

Generic let box1 = Box(value: KotlinInt(int: 100)) let value1: KotlinInt? = box1.value let box2: Box = FilenameKt.getBoxInt() let value2: KotlinInt? = box2.value let box3: Box = FilenameKt .genericFunction(value: Any?) let value3: AnyObject? = box3.value 📦 shared.framework class Box( val value: T ) { fun getVal(): T = value } fun getBoxInt(): Box { return Box(100) } fun genericFunction(value: T): Box { return Box(value) } __attribute__((swift_name("Box"))) @interface SharedBox : 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ͱͯ͠ग़ྗ͞Ε·͢

Slide 145

Slide 145 text

Generic let box1 = Box(value: KotlinInt(int: 100)) let value1: KotlinInt? = box1.value let box2: Box = FilenameKt.getBoxInt() let value2: KotlinInt? = box2.value let box3: Box = FilenameKt .genericFunction(value: Any?) let value3: AnyObject? = box3.value 📦 shared.framework class Box( val value: T ) { fun getVal(): T = value } fun getBoxInt(): Box { return Box(100) } fun genericFunction(value: T): Box { return Box(value) } __attribute__((swift_name("FilenameKt"))) @interface SharedFilenameKt : SharedBase + (SharedBox *)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ͱͯ͠ग़ྗ͞ΕΔ

Slide 146

Slide 146 text

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

Slide 147

Slide 147 text

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

Slide 148

Slide 148 text

Generic let box1 = NonnullBox(value: KotlinInt(int: 100)) let value1: KotlinInt = box1.value let box2: NonnullBox = FilenameKt .getNonnullBoxInt() let value2: KotlinInt = box2.value 📦 shared.framework class NonnullBox( val value: T ) { fun getVal(): T = value } fun getNonnullBoxInt(): NonnullBox { return NonnullBox(100) } __attribute__((swift_name("NonnullBox"))) @interface SharedNonnullBox : 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 ͱ͢Δ͜ͱͰNullableͰ͸ͳ͘ͳΔͷͰ Swift͔ΒΞΫηε͢Δ৔߹΋nonnilͱͳΔ

Slide 149

Slide 149 text

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( val value: T ) { fun getVal(): T = value } class NonnullBox( val value: T ) fun NonnullBox.getVal(): T { return value }

Slide 150

Slide 150 text

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( val value: T ) { fun getVal(): T = value } class NonnullBox( val value: T ) fun NonnullBox.getVal(): T { return value } @interface SharedNonnullBox (Extensions) - (id)getVal __attribute__((swift_name("getVal()"))); @end Objective-CͷCategoryʹͳΔͨΊɺΫϥεͰ͋ͬͯ΋ ܕύϥϝʔλʹΞΫηεͰ͖ͳ͘ͳͬͯidܕͱͳΔ

Slide 151

Slide 151 text

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

Slide 152

Slide 152 text

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

Slide 153

Slide 153 text

Generic sealed interface SealedInterfaceResult< out T, out U: Throwable > { data class Success( val value: T ) : SealedInterfaceResult data class Failure( val exception: U ) : SealedInterfaceResult } let result: SealedInterfaceResult = SealedInterfaceResultSuccess( value: KotlinInt(value: 100) ) switch result { case let value as SealedInterfaceResultSuccess: print(value.value?.intValue) case let value as SealedInterfaceResultFailure: print(value.exception) default: print("unknown") } 📦 shared.framework __attribute__((swift_name("SealedInterfaceResult"))) @protocol SharedSealedInterfaceResult @required @end __attribute__((swift_name("SealedInterfaceResultFailure"))) @interface SharedSealedInterfaceResultFailure : SharedBase - (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 : SharedBase - (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ʹରԠ͍ͯ͠ͳ͍ͨΊɺܕ͕ফࣦ͢Δ

Slide 154

Slide 154 text

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

Slide 155

Slide 155 text

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

Slide 156

Slide 156 text

Generic sealed class SealedClassResult< out T, out U: Throwable > { data class Success( val value: T ) : SealedClassResult() data class Failure( val exception: U ) : SealedClassResult() } let result: SealedClassResult = 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 : SharedSealedClassResult - (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 : SharedSealedClassResult - (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Ͱ͸ӈล΋͘͠͸ࠨลʹผͳܕ͕ࢦఆ͞Εͨ
 ҧ͏ܕͱͯ͠ղऍ͞ΕΔ

Slide 157

Slide 157 text

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

Slide 158

Slide 158 text

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

Slide 159

Slide 159 text

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

Slide 160

Slide 160 text

Generic class SealedClassResultHandler< T : Any, U : Throwable, V : Any >( value: SealedClassResult, 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 { let value: T init(_ value: T) { self.value = value } } extension KotlinThrowable: Error {} let result = SealedClassResultFactory( value: KotlinInt(value: 100) ).result let swiftResult: Result = 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

Slide 161

Slide 161 text

Generic class SealedClassResultHandler< T : Any, U : Throwable, V : Any >( value: SealedClassResult, 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 { let value: T init(_ value: T) { self.value = value } } extension KotlinThrowable: Error {} let result = SealedClassResultFactory( value: KotlinInt(value: 100) ).result let swiftResult: Result = 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 : SharedBase - (instancetype)initWithValue:(SharedSealedClassResult *)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͔Β͸೚ҙͷܕʹม׵ͨ݁͠ՌΛར༻Ͱ͖ΔΑ͏ʹ͢Δ

Slide 162

Slide 162 text

Generic class SealedClassResultHandler< T : Any, U : Throwable, V : Any >( value: SealedClassResult, 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 { let value: T init(_ value: T) { self.value = value } } extension KotlinThrowable: Error {} let result = SealedClassResultFactory( value: KotlinInt(value: 100) ).result let swiftResult: Result = 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Ͱ࣮૷ͨ͠ܕͰϥοϓ͢Δ

Slide 163

Slide 163 text

Generic class SealedClassResultHandler< T : Any, U : Throwable, V : Any >( value: SealedClassResult, 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 { let value: T init(_ value: T) { self.value = value } } extension KotlinThrowable: Error {} let result = SealedClassResultFactory( value: KotlinInt(value: 100) ).result let swiftResult: Result = 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Ͱར༻ͨ͠ܕΛऔΓग़ͯ͠໢ཏతʹ෼ذ͢Δ

Slide 164

Slide 164 text

Advanced

Slide 165

Slide 165 text

CA.swift #17 ͝੩ௌ͋Γ͕ͱ͏͍͟͝·ͨ͠