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

チームでSwiftUIを書くために / After Party iOSDC Japan 2021 SwiftUI

Atsuya Sato
October 01, 2021

チームでSwiftUIを書くために / After Party iOSDC Japan 2021 SwiftUI

2021/10/1に開催されたAfter Party iOSDC Japan 2021の登壇資料です

Atsuya Sato

October 01, 2021
Tweet

More Decks by Atsuya Sato

Other Decks in Technology

Transcript

  1. νʔϜͰSwiftUIΛॻͨ͘Ίʹ


    ~ಡΈ΍͘͢อक͠΍͍͢SwiftUIͷઃܭʹ͍ͭͯߟ͑ͨ͜ͱ~
    After Party iOSDC Japan 2021 / Atsuya Sato

    View Slide

  2. ࠤ౻ ರ໵ (͋ͭ΍)
    @n_atmark
    • iOS / Android ΤϯδχΞ
    • ݱࡏ͸ΫοΫύουAndroidΞϓϦͷʮ͔͍΋ͷʯλϒΛӶҙ։ൃத
    2019/04
    2021/01
    • ΫοΫύου৽ଔೖࣾ
    • ങ෺ࣄۀຊ෦ ങ෺ϓϩμΫτ։ൃ෦
    • ΫοΫύουϚʔτͷྲྀ௨޲͚ͷαʔϏε։ൃɺϋʔυ΢ΣΞ։ൃͳͲʹैࣄ
    • ΫοΫύουࣄۀຊ෦ ങ෺αʔϏε։ൃ෦
    • ΫοΫύουiOSΞϓϦͷʮ͔͍΋ͷʯλϒͷ։ൃʹैࣄ

    View Slide

  3. ΞδΣϯμ
    ● എܠ


    ● ։ൃ͍ͯ͠ΔϓϩμΫτͷ঺հ


    ● νʔϜ΍ϓϩμΫτͷن໛ײ


    ● SwiftUIΛ༻͍ͯ1೥ؒ։ൃͯ͠Έͯ


    ● ಡΈ΍ͯ͘͢อक͠΍͍͢ઃܭʹ͍ͭͯߟ͑ͨࣄ


    ● ౷Ұͨ͠ॻ͖ํͰϨΠΞ΢τΛઃܭ͢ΔͨΊʹ


    ● ෳࡶɾଟ༷ͳ৚݅ʹରॲ͢Δ


    ● ྑ͍ઃܭ΁ͷҙࣝΛνʔϜ΁ਁಁ͢ΔͨΊʹ


    ● ·ͱΊ

    View Slide

  4. ։ൃ͍ͯ͠ΔϓϩμΫτͷ঺հ
    ● എܠ


    ● ։ൃ͍ͯ͠ΔϓϩμΫτͷ঺հ


    ● νʔϜ΍ϓϩμΫτͷن໛ײ


    ● SwiftUIΛ༻͍ͯ1೥ؒ։ൃͯ͠Έͯ

    View Slide

  5. ΫοΫύουΞϓϦʮങ͍෺ػೳʯͷ঺հ

    View Slide

  6. ΫοΫύουΞϓϦʮങ͍෺ػೳʯͷ঺հ

    View Slide

  7. ΫοΫύουΞϓϦʮങ͍෺ػೳʯͷ঺հ
    ৯ࡐ͔ΒϨγϐ͕୳ͤΔ
    ৯ࡐΛങͬͨਓ͕


    ࣮ࡍʹ࡞ͬͨྉཧ


    ΛࢀߟʹͰ͖Δ

    View Slide

  8. ΫοΫύουΞϓϦʮങ͍෺ػೳʯͷ঺հ
    レシピから必要な⾷材
    を購⼊できる

    View Slide

  9. νʔϜ΍ϓϩμΫτͷن໛ײ
    ● എܠ


    ● ։ൃ͍ͯ͠ΔϓϩμΫτͷ঺հ


    ● νʔϜ΍ϓϩμΫτͷن໛ײ


    ● SwiftUIΛ༻͍ͯ1೥ؒ։ൃͯ͠Έͯ

    View Slide

  10. νʔϜͱ։ൃ͍ͯ͠ΔϓϩμΫτʹ͍ͭͯ
    ● ങ෺αʔϏε։ൃ෦


    ● ʮϨγϐʯ×ʮങ͍෺ʯʹΑͬͯ৽ͨͳՁ஋ΛੜΈ
    ग़͢௅ઓ


    ● ΫοΫύουiOSΞϓϦͷʮങ͍෺ػೳʯ


    ● ΤϯδχΞ6ਓ (iOS 3ɺαʔόʔαΠυ3)


    ● + ඇఆظͰΠϯλʔϯੜ͕νʔϜʹδϣΠϯ

    View Slide

  11. ΫοΫύουΞϓϦʮങ͍෺ػೳʯͷ։ൃ
    ● ϚϧνϞδϡʔϧԽ͞Ε͍ͯΔΫοΫύουΞϓϦͷ
    Feature ModuleͷҰͭͱͯ͠ػೳ։ൃ

    (KaimonoϞδϡʔϧ)

    View Slide

  12. https://speakerdeck.com/giginet/da-gui-mo-naapurifalsemarutimoziyurugou-cheng-falseshi-jian
    ⼤規模なアプリのマルチモジュール構成の実践

    View Slide

  13. ΫοΫύουΞϓϦʮങ͍෺ػೳʯͷ։ൃ
    ● ΄΅શͯSwiftUIͰ։ൃத


    ● VIPERΞʔΩςΫνϟͷ͏ͪɺView෦෼ͷΈͰ
    SwiftUIΛར༻͢Δઃܭ

    View Slide

  14. https://techlife.cookpad.com/entry/2021/01/18/kaimono-swift-ui
    SwiftUI を活⽤した「レシピ」×「買い物」の新機能開発

    View Slide

  15. ΫοΫύουΞϓϦʮങ͍෺ػೳʯͷ։ൃ
    ● Feature ModuleͷҰͭͱͯ͠ػೳ։ൃ


    ● VIPERΞʔΩςΫνϟͷ͏ͪɺView෦෼ͷΈͰSwiftUI
    Λར༻͢Δઃܭ


    ● 2020೥3݄͔Β։ൃ (2020೥10݄ʹҰൠϦϦʔε)


    ● ࠷௿αϙʔτOS͸iOS 13.3

    View Slide

  16. ΫοΫύουΞϓϦʮങ͍෺ػೳʯͷ։ൃ
    ● Kaimono Ϟδϡʔϧ഑Լͷίʔυߦ਺


    ● 45,953ߦ (ΫοΫύουiOSશମͷ໿15%)


    ● UIHostingViewControllerͰϥοϓ͞ΕͨRootView


    ● 35ը໘


    ● ผϑΝΠϧʹ੾Γग़͞ΕͨSwiftUIίϯϙʔωϯτ


    ● 149ݸ

    View Slide

  17. View Slide

  18. SwiftUIΛ༻͍ͯ1೥ؒ։ൃͯ͠Έͯ
    ● എܠ


    ● ։ൃ͍ͯ͠ΔϓϩμΫτͷ঺հ


    ● νʔϜ΍ϓϩμΫτͷن໛ײ


    ● SwiftUIΛ༻͍ͯ1೥ؒ։ൃͯ͠Έͯ

    View Slide

  19. 1೥લͷঢ়گ
    ● iOSDC Japan 2020Ͱൃදͨ͠λΠϛϯά … ͪΐ͏Ͳങ
    ͍෺ػೳϦϦʔε࣌ظͩͬͨ

    View Slide

  20. https://speakerdeck.com/yujif/iosdc-japan-2020-day-2-cookpad
    クックパッドが、⾰新的な⽅法でまったく新しい買い物体験を皆様にお届けします

    View Slide

  21. View Slide

  22. 1೥લͷঢ়گ
    ● SwiftUIͷϝϦοτΛײ͍ͯͨ͡෦෼


    ● ίʔυྔ͕ݮΔ


    ● ෳࡶɾଟ༷ͳ৚݅ʹରͯ͠෼͔Γ΍͘͢ॻ͚Δ


    ● ίϯϙʔωϯτ୯ҐͰ࢖͍ճ͠ɾվม͕͠΍͍͢

    View Slide

  23. ΞϓϦΛϦϦʔε͔ͯ͠Β1೥։ൃ͍ͯ͘͠தͰͷมԽ
    ● ίʔυϕʔεͷڊେԽ


    ● Feature ModuleͷதͰ͸ίʔυߦ਺΋VIPERγʔϯ਺΋࠷େʹ


    ● iOS 14ɾiOS 15ͷϦϦʔε


    ● iOS 13ɺ14ɺ15ͷ3όʔδϣϯαϙʔτʹ


    ● νʔϜͷ֦େ


    ● ϝΠϯͰ։ൃ͢ΔΤϯδχΞ΋૿͑ͨ


    ● Πϯλʔϯੜ΋ܞΘΔΑ͏ʹ

    View Slide

  24. 1೥։ൃͯ͠Έͯײ͍ͯ͡Δ՝୊
    ● iOS 13ରԠʹΑΔফ໣͸গͳ͔Βͣൃੜ͢Δ


    ● iOS 13͚ͩڍಈ͕ҧ͏෦෼͕গͳ͔Βͣ͋Δ


    ● ύϑΥʔϚϯεΛ٘ਜ਼ʹ͍ͯ͠ΔՕॴ΋݁ߏ͋Δ


    ● LazyV/HStackɺLazyV/HGrid͸࢖͑ͯͳ͍😢

    View Slide

  25. 1೥։ൃͯ͠Έͯײ͍ͯ͡Δ՝୊
    ● ॊೈੑ͕ߴ͍ͨΊɺUIͷ૊Έํ͕ਓʹΑͬͯมΘΔ


    ● ྫ: ཁૉΛॏͶ͍ͨͱ͖ͷZStackɺbackgroundɺ
    overlayͷ࢖͍෼͚


    ● ྫ: εϖʔεͷ։͚ํ


    ● ίϯϙʔωϯτ෼ׂͷཻ౓

    View Slide

  26. Q: ࠓޙ΋SwiftUIΛऔΓೖΕͨ։ൃ
    Λ͢Δʁ
    ৭ʑফ໣΋


    ײͯͦ͡͏͚ͩͲ…?

    View Slide

  27. Q: ࠓޙ΋SwiftUIΛऔΓೖΕͨ։ൃ
    Λ͢Δʁ


    A: Yes

    View Slide

  28. ࠓޙ΋SwiftUIΛऔΓೖΕͨ։ൃΛ͢Δʁ
    ෆ֬ఆͳϢʔβʔମݧΛ͍ͪૣཱ֬͘͢ΔͨΊʹ


    ʮ࡞Γ΍͍͢ɾյ͠΍͍͢ʯͷ͸ॏཁ


    SwiftUIΛ࢖͏͜ͱͰ໌Β͔ʹ͜ͷ෦෼͸ૣ͘ͳ͍ͬͯΔ

    View Slide

  29. ࠓޙ΋SwiftUIΛऔΓೖΕͨ։ൃΛ͢Δʁ
    ࠓޙ΋νʔϜͰSwiftUIΛ࠾༻͍ͯͨ͘͠Ίʹ…


    SwiftUIΛ࢖ͬͯײ͍ͯ͡Δ՝୊Λ


    ҰͭͣͭऔΓআ͍͍͖͍ͯͨ💪

    View Slide

  30. ಡΈ΍ͯ͘͢อक͠΍͍͢


    SwiftUIͷઃܭʹ͍ͭͯߟ͑Δ

    View Slide

  31. 今⽇のトピックでは取り扱いません

    View Slide

  32. αʔϏεಛੑΛߟ͑Δ
    ● ʮ͔͍΋ͷʯλϒͷߏ੒͸جຊ͸ॎεΫϩʔϧͷը໘


    ● Viewߏஙͷࡍͷجຊܗͱͯ͠ScrollViewͷதʹཁૉ
    Λ٧Ί͍ͯ͘ը໘͕΄ͱΜͲ

    View Slide

  33. αʔϏεಛੑΛߟ͑Δ
    ● ෳࡶଟ༷ͳঢ়ଶ


    ● ྫ: ঎඼஫จޙͷड͚औΓʹؔ͢Δঢ়ଶ

    View Slide

  34. αʔϏεಛੑʹجͮ͘՝୊
    ● ը໘͕ॎʹ௕͘ͳΓ΍͍͢


    ● ίϯϙʔωϯτͷཻ౓΍ॻ
    ͖ํ͕౷Ұ͞Εͯͳ͍ͱಡ
    Έʹ͍͘


    ● ঢ়ଶ͕૿͑Δͱɺ෼ذ΋ͦͷ
    ෼૿͑Δ

    View Slide

  35. ಡΈ΍͘͢อक͠΍͍͢ઃܭ
    ● ઃܭʹݸਓ͕ࠩ͋·Γग़ͳ͍Α͏ʹ͍ͨ͠


    ● ৚͕݅ෳࡶʹͳͬͯ΋ಡΊΔΑ͏ʹ͓͖͍ͯͨ͠


    ● ৚͕݅ෳࡶͳը໘ͷอकΛ༰қʹ͍ͨ͠


    ● ྑ͍ઃܭ΁ͷҙࣝΛνʔϜʹਁಁ͍ͤͨ͞

    View Slide

  36. ౷Ұͨ͠ॻ͖ํͰϨΠΞ΢τΛઃܭ͢ΔͨΊʹ
    ● ಡΈ΍ͯ͘͢อक͠΍͍͢ઃܭʹ͍ͭͯߟ͑ͨࣄ


    ○ ౷Ұͨ͠ॻ͖ํͰϨΠΞ΢τΛઃܭ͢ΔͨΊʹ


    ○ ෳࡶɾଟ༷ͳ৚݅ʹରॲ͢Δ


    ○ ྑ͍ઃܭ΁ͷҙࣝΛνʔϜ΁ਁಁ͢ΔͨΊʹ


    View Slide

  37. ౷Ұͨ͠ॻ͖ํͰϨΠΞ΢τΛઃܭ͢ΔͨΊʹ
    ● RootViewͷbodyʹॻ͘΂͖಺༰Λఆ͍ٛͨ͠


    ● ίϯϙʔωϯτԽͷཻ౓ʹؔͯ͠ڞ௨ೝࣝΛͱΓ͍ͨ

    View Slide

  38. ϨΠΞ΢τ૊Έʹؔͯ͠
    struct KaimonoCartView: View {


    var body: some View {


    ScrollView {


    orderDeliverySection


    cartPriceSection


    pickupNameSettingSection


    deliveryInformationSection


    pickupStepsSection


    }


    }


    }


    View Slide

  39. ϨΠΞ΢τ૊Έʹؔͯ͠
    ● ը໘Λҙຯͷ͋Δ·ͱ·ΓͰSectionʹ෼ׂ


    ● ෳ਺ίϯϙʔωϯτΛͱΓ·ͱΊΔ


    ● ίϯϙʔωϯτؒͷϚʔδϯௐ੔Λ

    ߦ͏ͨΊͷϨΠϠʔ

    View Slide

  40. ϨΠΞ΢τ૊Έʹؔͯ͠
    ● ը໘Λҙຯͷ͋Δ·ͱ·ΓͰSectionʹ෼ׂ


    ● ෼ׂͨ͠Section͸RootViewʹඥͮ͘

    (ෳ਺ը໘Ͱར༻͠ͳ͍)


    ● SectionΛෳ਺ը໘Ͱ࢖͍ͨ͘ͳͬͨ
    ΒίϯϙʔωϯτԽͷཻ౓Λݟ௚͢

    View Slide

  41. Sectionͷ෼ׂҐஔͷܾΊํ
    ● σβΠφʔͱ૬ஊ͠ͳ͕ΒηΫγϣϯ෼ׂҐஔ
    ΛܾΊΔΑ͏ʹ͢Δ


    ● Figma্Ͱ΋σβΠϯελΠϧʹԊͬͯάϧʔ
    ϐϯά͞Ε͍ͯΔͷͰɺσβΠφʔͷҙਤΛ൓
    өͭͭ͠Section෼ׂ

    View Slide

  42. View Slide

  43. Atoms Molecules Moleculesͷू߹ମ Organisms
    ProductTile ProductsGrid PopularProductsSection

    View Slide

  44. ίϯϙʔωϯτʹؔͯ͠
    ● ίϯϙʔωϯτԽ͢Δ΋ͷʹؔͯ͠͸ผϑΝΠϧʹ੾Γग़͠


    ● ཻ౓


    ● ΞτϛοΫσβΠϯͰݴ͏Molecules


    ● ୯ମMoleculesΛෳ਺ฒ΂ͨঢ়ଶͷ΋ͷ※ΛίϯϙʔωϯτԽ


    ● AtomsϨϕϧͷίϯϙʔωϯτԽ͸ͯ͠·ͤΜ

    View Slide

  45. ίϯϙʔωϯτʹؔͯ͠
    ● ίϯϙʔωϯτͷཻ౓ʹؔͯ͠νʔϜ಺Ͱೝ͕ࣝऔΕ͍ͯΔͱί
    ϛϡχέʔγϣϯ͕ͱΓ΍͍͢


    ● Sectionͱͯ͠RootViewʹඥͮ͘ܗͰ༻ҙ͢΂͖΋ͷ


    ● ίϯϙʔωϯτͱͯ͠੾Γग़͢΂͖΋ͷ


    ● ίϯϙʔωϯτͱͯ͠੾Γग़͢৔߹


    ● Ͳ͜·Ͱࡉ͔͘෼ׂ͢Δͷ͔

    View Slide

  46. ෳࡶɾଟ༷ͳ৚݅ʹରॲ͢Δ
    ● ಡΈ΍ͯ͘͢อक͠΍͍͢ઃܭʹ͍ͭͯߟ͑ͨࣄ


    ○ ౷Ұͨ͠ॻ͖ํͰϨΠΞ΢τΛઃܭ͢ΔͨΊʹ


    ○ ෳࡶɾଟ༷ͳ৚݅ʹରॲ͢Δ


    ○ ྑ͍ઃܭ΁ͷҙࣝΛνʔϜ΁ਁಁ͢ΔͨΊʹ


    View Slide

  47. ෳࡶɾଟ༷ͳ৚݅ʹରॲ͢Δ

    View Slide

  48. ෳࡶɾଟ༷ͳ৚݅ʹରॲ͢Δ
    struct KaimonoDeliveryDetailView: View {


    var body: some View {


    ScrollView {


    switch dataSource.delivery.deliveryStatus {


    case .accepting:


    headerSection


    pickupNameSection


    orderedProductsSection


    if shouldShowPickupGuide { pickupGuideSection } // Sectionͷτϧπϝ


    acceptedButtonSection


    ordersSection


    case .preparing:


    // ུ


    }


    }


    }


    }


    View Slide

  49. ෳࡶɾଟ༷ͳ৚݅ʹରॲ͢Δ
    ● RootViewͷbodyʹSectionΛྻڍ͢ΔΑ͏ʹͨ͜͠ͱͰ
    ݟ௨͕͠ྑ͍


    ● ঢ়ଶʹԠͨ͡Sectionͷग़͠෼͚΍ɺಛఆ৚݅ʹԠ͡
    ͨSectionͷτϧπϝ΋෼͔Γ΍͍͢


    ● body͕ը໘ϨΠΞ΢τͷઃܭਤͱͯ͠ػೳ͢Δ

    View Slide

  50. ਖ਼֬ʹಈ࡞ͤ͞ΔͨΊʹ
    ● ίʔυ্Ͱͷݟ௨͠͸͠΍͘͢ͳ͕ͬͨ…


    ● ෳ਺ͷ৚݅Λߟྀͨ͠ը໘ʹ͓͚ΔϢʔβʔঢ়ଶͷ࠶ݱ
    ͸೉͍͠


    ● ը໘͕յΕ͍ͯͳ͍͜ͱΛಈ࡞֬ೝ͢Δ


    ● ࣮૷ʹೖΔ·Ͱʹ֘౰ը໘ΛදࣔͰ͖ΔΑ͏ʹͳΔ
    ·Ͱ͕͔͔࣌ؒΔ

    View Slide

  51. ਖ਼֬ʹಈ࡞ͤ͞ΔͨΊͷऔΓ૊Έ

    View Slide

  52. https://speakerdeck.com/aomathwift/ji-neng-gotonidong-zuo-
    suruminiapuridepurebiyusaikuruwobao-su-nisitahua
    機能ごとに動作するミニアプリでプレビューサイクルを爆速にした話

    View Slide

  53. ਖ਼֬ʹಈ࡞ͤ͞ΔͨΊͷऔΓ૊Έ

    View Slide

  54. ਖ਼֬ʹಈ࡞ͤ͞ΔͨΊͷऔΓ૊Έ
    extension SandboxScene {


    static let kaimonoTopForJustSetupCompleted = SandboxScene(sceneName: "τοϓʢडऔ৔ॴઃఆࡁɾະ஫จʣ") { initializer in


    let environment = StubbableEnvironment()


    initializer.initialize(environment)


    environment.registerClientResponses(fixtures, overrideFixtures: [


    .orders(.empty),


    .userOrderedDeliveries(.empty),


    ])


    ɹ let viewController = KaimonoTopViewBuilder.build(environment: environment)


    return viewController


    }


    static let kaimonoTopForDeliveriesUnavailable = SandboxScene(sceneName: "τοϓʢ௚ۙͷ഑ૹͳ͠ʣ") { initializer in


    // ུ


    }


    }
    private let fixtures: [Fixture] = [


    .cart(.normal),


    .promotedDeliveryProducts(.ordinary),


    .me(.userLocation),


    .feature(.popularProducts),


    // ུ


    ]

    View Slide

  55. ਖ਼֬ʹಈ࡞ͤ͞ΔͨΊͷऔΓ૊Έ
    private let fixtures: [Fixture] = [


    .cart(.normal),


    .promotedDeliveryProducts(.ordinary),


    .me(.userLocation),


    .feature(.popularProducts),


    // ུ


    ]


    environment.registerClientResponses(fixtures, overrideFixtures: [


    .orders(.empty),


    .userOrderedDeliveries(.empty),


    ])
    ● ը໘දࣔʹඞཁͳϨεϙϯεελϒΛFixtureԽ


    ● ϕʔεͷFixtureͱɺ৚݅͝ͱͷoverrideFixturesΛ༻ҙ


    ● ϛχΞϓϦͷ৚݅͝ͱͷը໘දࣔΛ؆୯ʹఆٛͰ͖ΔΑ͏ʹ

    View Slide

  56. ྑ͍ઃܭ΁ͷҙࣝΛνʔϜ΁ਁಁ͢ΔͨΊʹ
    ● ಡΈ΍ͯ͘͢อक͠΍͍͢ઃܭʹ͍ͭͯߟ͑ͨࣄ


    ○ ౷Ұͨ͠ॻ͖ํͰϨΠΞ΢τΛઃܭ͢ΔͨΊʹ


    ○ ෳࡶɾଟ༷ͳ৚݅ʹରॲ͢Δ


    ○ ྑ͍ઃܭ΁ͷҙࣝΛνʔϜ΁ਁಁ͢ΔͨΊʹ


    View Slide

  57. ྑ͍ઃܭ΁ͷҙࣝΛνʔϜ΁ਁಁ͢ΔͨΊʹ
    ● υΩϡϝϯτԽ


    ● υΩϡϝϯτ੔උձ


    ● ஌ݟ·ͱΊࣾ಺ϒϩά


    ● SwiftUIϨΠΞ΢τʹؔ͢Δௐࠪ


    ● ઃܭʹ͍ͭͯޠΔձ

    View Slide

  58. ྑ͍ઃܭ΁ͷҙࣝΛνʔϜ΁ਁಁ͢ΔͨΊʹ

    View Slide

  59. ྑ͍ઃܭ΁ͷҙࣝΛνʔϜ΁ਁಁ͢ΔͨΊʹ

    View Slide

  60. ྑ͍ઃܭ΁ͷҙࣝΛνʔϜ΁ਁಁ͢ΔͨΊʹ

    View Slide

  61. ྑ͍ઃܭ΁ͷҙࣝΛνʔϜ΁ਁಁ͢ΔͨΊʹ

    View Slide

  62. ྑ͍ઃܭ΁ͷҙࣝΛνʔϜ΁ਁಁ͢ΔͨΊʹ

    View Slide

  63. ·ͱΊ
    ● ౷Ұͨ͠ॻ͖ํͰϨΠΞ΢τΛઃܭ͢ΔͨΊʹ


    ● ϨΠΞ΢τઃܭΛ౷ҰԽ


    ● ίϯϙʔωϯτԽͷཻ౓Λ໌֬ʹ


    ● ෳࡶɾଟ༷ͳ৚݅ʹରॲ͢Δ


    ● ը໘ϨΠΞ΢τͷઃܭਤͱͯ͠RootViewͷbodyΛར༻


    ● ಈ࡞֬ೝͷͨΊʹϛχΞϓϦΛ׆༻


    ● ྑ͍ઃܭ΁ͷҙࣝΛνʔϜ΁ਁಁ͢ΔͨΊʹ


    ● ఆظతʹઃܭʹ͍ͭͯٞ࿦͢Δ৔Λઃ͚Δ


    ● υΩϡϝϯτԽ͢Δ͜ͱʹΑͬͯڞ௨ೝࣝΛऔΔ

    View Slide