Slide 1

Slide 1 text

$PNQPTF.VMUJQMBUGPSNͰ #MVFTLZͷΫϥΠΞϯτ࡞ͬͯΈͨ yanzm

Slide 2

Slide 2 text

ZBO[Nʢ΍Μ͟Ήʣ w !ZBO[NCTLZTPDJBM w ݹʢ͍ʹ͑͠ʣͷ"OESPJEFS w ݄೔ʹ,PKJSB͞Μʹট଴ίʔυ΋ΒͬͯCMVFTLZ͸͡Ί·ͨ͠ɻ৽ถͰ ͢ɻ

Slide 3

Slide 3 text

,PUMJO w ʢ΋ͱ΋ͱ͸ʣ+7.ݴޠ w CFUUFS+BWBతͳ w ೥͔Β"OESPJEͷެࣜαϙʔτݴޠͷҰͭ

Slide 4

Slide 4 text

,PUMJO.VMUJQMBUGPSN ,.1 w ,PUMJOͷίʔυΛXFC +T ͱ͔OBUJWF EFTLUPQ ͱ͔ͷόΠφϦʹϏϧυ w ಉ͡,PUMJOͷίʔυͰෳ਺ͷ1MBUGPSNʹରԠ w J04΋ରԠ w ͨͩ͠ɺ6*͸ͦΕͧΕͷ1MBUGPSN/BUJWFͳ෦෼Ͱ࣮૷

Slide 5

Slide 5 text

+FUQBDL$PNQPTF w "OESPJEͷωΠςΟϒ6*Λߏங͢ΔͨΊͷ࠷৽ͷπʔϧΩοτ w એݴత6* Row { Icon( imageVector = Icons.Default.Star, contentDescription = null ) Column { Text( text = "username" ) Text( text = "description" ) } Button( onClick = onClickFollow ) { Text("follow") } }

Slide 6

Slide 6 text

$PNQPTFGPS%FTLUPQ w ೥݄ w +FUQBDL$PNQPTFͰ,PUMJO.VMUJQMBUGPSNͷEFTLUPQͷ6*͕࡞ΕΔ

Slide 7

Slide 7 text

$PNQPTF.VUMJQMBUGPSN6*'SBNFXPSL w IUUQTXXXKFUCSBJOTDPNMQDPNQPTFNVMUJQMBUGPSN w ೥݄೔ͷ,PUMJO$POGͰൃද w EFTLUPQ͚ͩ͡Όͳ͘J04 "MQIB ,PUMJO/BUJWF ΍8FC &YQFSJNFOUBM ,PUMJO8BTN ΋αϙʔτ

Slide 8

Slide 8 text

#MVFTLZͷΫϥΠΞϯτΞϓϦΛ $PNQPTF.VMUJQMBUGPSNͰ࡞Δ https://github.com/yanzm/Rayleigh

Slide 9

Slide 9 text

4UFQϕʔεͷϓϩδΣΫτΛ࡞Δ w +FU#SBJOTͷHJUIVCʹDPNQPTFNVMUJQMBUGPSNͷςϯϓϨʔτ͕͋Δ w IUUQTHJUIVCDPN+FU#SBJOTDPNQPTFNVMUJQMBUGPSNJPTBOESPJE UFNQMBUF

Slide 10

Slide 10 text

4UFQ௨৴Ͱ͖ΔΑ͏ʹ͢Δ w 4FJVO͞Μ͸3FUSP fi UΛ࢖͍͚ͬͯͨͲ,.1Ͱ͸࢖͑ͳ͍ w ,UPS w IUUQTLUPSJP w ,PUMJO$POG`ͷηογϣϯͰग़͖ͯͨ$PNQPTF.VMUJQMBUGPSNͰνϟο τ͢ΔΞϓϦ͕ࢀߟʹͳͬͨ w IUUQTHJUIVCDPNTWUL,$$IBU"QQ w ,UPS,PUMJOY4FSJBMJ[BUJPOͱ͔

Slide 11

Slide 11 text

4UFQϩάΠϯը໘ͷ6*Λ࡞Δ

Slide 12

Slide 12 text

4UFQϩάΠϯը໘ͷ6*Λ࡞Δ w SEQBSUZDMJFOU͸"QQ1BTTXPSEͰϩάΠϯ͢ΔΑ͏ʹͳ͔ͬͨΒɺΞΧ ΢ϯτͷ࡞੒ϩάΠϯ΍"QQ1BTTXPSEͷ࡞੒͸ϒϥ΢βΛ։͍ͯIUUQT TUBHJOHCTLZBQQΛද͍ࣔͨ͠ w "OESPJE J04ͦΕͧΕͷQMBUGPSNͷॲཧ͕ඞཁ

Slide 13

Slide 13 text

@Composable fun App( onOpenBrowser: (String) -> Unit = {} ) { RayleighTheme { … LoginScreen( viewModel = viewModel, onOpenBrowser = onOpenBrowser, ) } } shared/commonMain

Slide 14

Slide 14 text

class MainActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContent { MainView( onOpenBrowser = { startActivity( Intent(Intent.ACTION_VIEW, Uri.parse(it)) ) } ) } } @Composable fun MainView( onOpenBrowser: (String) -> Unit ) { App( onOpenBrowser = onOpenBrowser ) } androidApp/ shared/androidMain Android

Slide 15

Slide 15 text

struct ComposeView: UIViewControllerRepresentable { func makeUIViewController(context: Context) -> UIViewController { Main_iosKt.MainViewController( onOpenBrowser: { let url = URL(string:$0)! UIApplication.shared.open(url, options: [:], completionHandler: nil) } ) } func updateUIViewController(_ uiViewController: UIViewController, context: Context) {} } fun MainViewController( onOpenBrowser: (String) -> Unit ) = ComposeUIViewController { App( onOpenBrowser = onOpenBrowser ) } iosApp/iosApp/ContentView.swift shared/iosMain iOS

Slide 16

Slide 16 text

4UFQϩάΠϯ͢Δ w "1*Λୟ͍ͯฦ͖ͬͯͨUPLFOΛอଘ͠ͳ͍ͱ͍͚ͳ͍ w NVMUJQMBUGPSNTFUUJOHTΛ࢖͏͜ͱʹ͢Δ w IUUQTHJUIVCDPNSVTTIXPMGNVMUJQMBUGPSNTFUUJOHT w ϓϥοτϑΥʔϜ͝ͱʹ4FUUJOHTͷੜ੒Πϯελϯε͕ҟͳΔ w %*͕ͳ͍ͱͭΒ͍

Slide 17

Slide 17 text

4UFQ%FQFOEFODZ*OKFDUJPO w "OESPJEͰ͸EBHHFSIJMU͕σϑΝΫτ͕ͩ,.1Ͱ͸࢖͑ͳ͍ w ,PJO w LPJODPSF͸,.1ʹରԠ͍ͯ͠Δ͕ w LPJODPNQPTF͸$PNQPTF.VMUJQMBUGPSNʹ·ͩରԠ͍ͯ͠ͳ͍ w l$PVMEOPU fi OEJPJOTFSULPJOLPJODPNQPTFJPTBSNzͱౖΒΕ Δ w IUUQTJOTFSULPJOJPEPDTSFGFSFODFLPJODPNQPTFNVMUJQMBUGPSN͸ 8*1

Slide 18

Slide 18 text

class AppComponent : KoinComponent { val authRepository: AuthRepository by inject() } shared/commonMain @Composable fun App( appComponent: AppComponent, onOpenBrowser: (String) -> Unit = {} ) { RayleighTheme { val appViewModel = remember { AppViewModel(appComponent.authRepository) } … } }

Slide 19

Slide 19 text

class MainActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContent { MainView( appComponent = AppComponent(), onOpenBrowser = { startActivity( Intent(Intent.ACTION_VIEW, Uri.parse(it)) ) @Composable fun MainView( appComponent: AppComponent, onOpenBrowser: (String) -> Unit ) { App( appComponent = appComponent, onOpenBrowser = onOpenBrowser ) } androidApp/ shared/androidMain Android

Slide 20

Slide 20 text

struct ComposeView: UIViewControllerRepresentable { let appComponent = AppComponent() func makeUIViewController(context: Context) -> UIViewController { Main_iosKt.MainViewController( appComponent: appComponent, onOpenBrowser: { let url = URL(string:$0)! UIApplication.shared.open(url, options: [:], completionHandler: nil) } ) } fun MainViewController( appComponent: AppComponent, onOpenBrowser: (String) -> Unit ) = ComposeUIViewController { App( appComponent = appComponent, onOpenBrowser = onOpenBrowser ) } iosApp/iosApp/ContentView.swift shared/iosMain iOS

Slide 21

Slide 21 text

4UFQλΠϜϥΠϯΛऔಘ͢Δ w ϩάΠϯ࣌ʹऔಘͨ͠5PLFOΛCFBSFSBVUIFOUJDBUJPOʹηοτ͢Δ w ,UPSͷ"VUIQMVHJO࢖͏͚ͩ w IUUQTLUPSJPEPDTCFBSFSDMJFOUIUNM w UZQFͰΦϒδΣΫτ͕มΘΔ3FDPSEͱ͔͸$MBTTEJTDSJNJOBUPSGPS QPMZNPSQIJTN࢖͏ w IUUQTHJUIVCDPN,PUMJOLPUMJOYTFSJBMJ[BUJPOCMPCNBTUFSEPDT KTPONEDMBTTEJTDSJNJOBUPSGPSQPMZNPSQIJTN

Slide 22

Slide 22 text

No content

Slide 23

Slide 23 text

·ͱΊࠓޙ w /BWJHBUJPOͲ͏ͨ͠Β͍͍ͷͩʜ w %FDPNQPTF IUUQTHJUIVCDPNBSLJWBOPW%FDPNQPTF w %*͕ͭΒ͍ʜ w LPJODPNQPTF͕ରԠͨ͠ΒָʹͳΔ͔΋ʁ w 5FYU'JFMEͷڍಈ͕J044JNVMBUPSͰ͓͔͍͠ʜ w $PNQPTFͰී௨ʹJ04ͷ6*͕Ͱ͖͍ͯ͢͝ͷͰɺ͍Ζ͍Ζ΍Γ͍ͨ