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

Flutter研修【MIXI 24新卒技術研修】

Flutter研修【MIXI 24新卒技術研修】

本スライドは、MIXIの2023年度新卒向け技術研修で使用された資料です。

<科目名>
Flutter研修

<研修資料>
動画▶ https://youtu.be/GWq4-Xfv9dM
リポジトリ▶ https://github.com/mixigroup/2024FlutterTraining

※お願い※ 〜 資料・動画・リポジトリのご利用について〜
公開している資料や動画は、是非、勉強会や社内の研修などにご自由にお使いいただければと思いますが、以下のような場でのご利用はご遠慮ください。
- 受講者から参加費や授業料など金銭を集めるような場での利用
(会場費や飲食費など勉強会の運営に必要な実費を集める場合は問題ありません)
- 出典を削除または改変しての利用

Avatar for MIXI ENGINEERS

MIXI ENGINEERS

July 22, 2024
Tweet

Video

More Decks by MIXI ENGINEERS

Other Decks in Technology

Transcript

  1. ࣄલ४උ w 'MVUUFS4%,ͷΠϯετʔϧ w IUUQTEPDT fl VUUFSEFWHFUTUBSUFEJOTUBMM w J04ಈ͔͍ͨ͠ਓ w

    9DPEFͷΠϯετʔϧ͓ΑͼղౚʢJ04ݚम؀ڥͱಉ౳ʣ w "OESPJEಈ͔͍ͨ͠ਓ w "OESPJE4UVEJP*HVBOBͷΠϯετʔϧ͓Αͼղౚʢ"OESPJEݚम؀ڥͱಉ౳ʣ
  2. ࣄલ४උ $ flutter doctor Doctor summary (to see all details,

    run flutter doctor -v): [✓] Flutter (Channel stable, 3.19.6, on macOS 13.6.1 22G313 darwin- arm64, locale ja-JP) [✓] Android toolchain - develop for Android devices (Android SDK version 34.0.0) [✓] Xcode - develop for iOS and macOS (Xcode 15.2) [✓] Chrome - develop for the web [✓] Android Studio (version 2023.2) [✓] VS Code (version 1.87.2) [✓] Connected device (3 available) [✓] Network resources • No issues found!
  3. ຊ೔ͷ͓඼ॻ͖ 1 2 3 'MVUUFSͱ͸ʁ ΞϓϦΛ࡞ͬͯΈΑ͏ʂ ΞϓϦͷத਎Λݟ͍ͯ͜͏ʂ 7 ωοτϫʔΫ௨৴ͯ͠ΈΑ͏ʂ 4

    4UBUFͬͯͳΜͩΖ͏ʁ 5 5FYU'JMFEΛ࢖ͬͯΈΑ͏ʂ 6 8 νʔϜͰνϟϨϯδʂʂʂ ͓ΘΓʙ
  4. 'MVUUFSͱ͸ʁ w ϚϧνϓϥοτϑΥʔϜ։ൃ͕ՄೳͳϑϨʔϜϫʔΫ w ϞόΠϧɾXFCɾσεΫτοϓɾ૊ΈࠐΈγεςϜΛαϙʔτ w 'MVUUFSΛ࢖༻ͯ͠ެ։͞ΕͨΞϓϦ͸ສΛ௒͑ͨʢ೥݄຤࣌఺ʣ w 'JSFCBTFͷػೳΛαϙʔτ w

    (FNJOJ(PPHMF"*%BSU4%,͕ϦϦʔε͞ΕΞϓϦʹ૊ΈࠐΊΔΑ͏ʹ 'MVUUFS'PSXBSEIUUQTXXXZPVUVCFDPNXBUDI W[,2:(,"F8 'MVUUFSެࣜIUUQT fl VUUFSEFW 8IBU`TOFXJO'MVUUFSIUUQTNFEJVNDPN fl VUUFSXIBUTOFXJO fl VUUFSCBBFE *NQSPWJOHJOGPUBJONFOUTZTUFNTBU5PZPUBXJUI'MVUUFSIUUQT fl VUUFSEFWTIPXDBTFUPZPUB
  5. w %BSUͱ͍͏ίϯύΠϧܕݴޠͰ࣮૷ w (PPHMF͕+BWB4DSJQUͷ໰୊఺Λվળͨ͠୅ସݴޠͱͯ͠೥ʹ։ൃͨ͠΋ͷ w /VMM4BGFUZ΍ίϨΫγϣϯεϓϨουԋࢉࢠΛ࢖ͬͨ6*ͷߏங͕ՄೳʢผϖʔδͰઆ໌ʣ w "05ίϯύΠϧΛ௨ͯ͡ωΠςΟϒͷػցޠʹม׵͞ΕΔ w ͜ΕʹΑΓωΠςΟϒΞϓϦέʔγϣϯͱͯ͠௚઀࣮ߦ͞ΕΔʢิ଍ࢿྉͰઆ໌ʣ

    w ϨϯμϦϯάΤϯδϯ΋ࣗલʢJ04Ͱ͸*NQFMMFS͕σϑΥϧτʹʣ w એݴత6*Ͱॻ͘͜ͱ͕ՄೳʢผϖʔδͰઆ໌ʣ w 4UPSZCPBSEΛ࢖ͬͨ4XJGUͷίʔυΑΓ3FBDUͷํ͕ࣅͯΔ͔΋ 'MVUUFSͱ͸ʁ 'MVUUFSͷΞʔΩςΫνϟIUUQTEPDT fl VUUFSEFWSFTPVSDFTBSDIJUFDUVSBMPWFSWJFX )PXEPFT'MVUUFSSVONZDPEFPOJ04 IUUQTEPDT fl VUUFSEFWSFTPVSDFTGBRSVOJPT *NQFMMFSʹ͍ͭͯIUUQTEPDT fl VUUFSEFWQFSGJNQFMMFS EBTI܅ʹ͍ͭͯIUUQTEPDT fl VUUFSEFWEBTI
  6. ࣮ߦ࣌ʹOVMMͷΤϥʔͰ མͪΔ͜ͱ͸ͳ͘ͳΔ /VMM4BGFUZͬͯʁ جຊతʹOVMM࢖ͬͪΌμϝ ࢖͍͍ͨ࣌͸ Λ͚ͭΔ int a = 100;

    int? b = null; a = 100; print(a + b); // Τϥʔ if (b != null) { print(a + b); } print(a + b!); C͕OVMMͷ࣌͸ ආ͚ͯ͘ΕΔͷͰ҆৺ OVMMTBGFUZʹ͍ͭͯIUUQTEBSUEFWOVMMTBGFUZ
  7. label = UILabel() label.text = “Babu~” label.textColor = .black label.textAlignment

    = .center view.addSubview(label) Text( “Babu~", style: TextStyle(color: Colors.black), textAlign: TextAlign.center, ), ໋ྩతʢ4XJGUʣ એݴత6*ͬͯʁ એݴతʢ%BSUʣ ϥϕϧΛ࡞Εʂ ϥϕϧͷςΩετ͸όϒʙͰ͋Εʂ ৭͸ࠇͰ͋ΕʂਅΜதدͤͰ͋Εʂ ͦͷϥϕϧΛ7JFXʹ௥Ճͤ͑ʂ
  8. label = UILabel() label.text = “Babu~” label.textColor = .black label.textAlignment

    = .center view.addSubview(label) Text( “Babu~", style: TextStyle(color: Colors.black), textAlign: TextAlign.center, ), ໋ྩతʢ4XJGUʣ એݴత6*ͬͯʁ એݴతʢ%BSUʣ զ͸όϒʙͱ͍͏ࠇ৭ͷ ਅΜதدͤςΩετͰ͋Δʂ
  9. ΞϓϦΛ࡞ͬͯΈΑ͏ $ flutter create <<ϓϩδΣΫτͷ໊લ>> $ cd <<ϓϩδΣΫτͷ໊લ>> $ open

    iOS/Runner.xcworkspace // ios ͷਓͷΈ $ flutter run "OESPJEͷਓ͸࣮ػબ୒΋͘͠͸ "OESPJEελδΦ্ཱͪ͛ͯΤϛϡબ୒ ϓϩδΣΫτ໊͸ΞϯμʔόʔͰܨ͕ͳ͍ͱ ʰzϓϩδΣΫτ໊zJTOPUBWBMJE%BSUQBDLBHF OBNFʱ ͬͯΤϥʔుౖ͍ͯΒΕΔ
  10. )PUSFMPBESFTUBSUͱ͸ʁ )PUSFMPBE )PUSFTUBSU ͍͍ͪͪDUSMDͰࢭΊ͔ͯΒ fl VUUFSSVO͠ͳͯ͘େৎ෉ʂʂʂʂ λʔϛφϧͰ3Λԡ͢ ΄΅Ϧηοτ͞ΕΔ λʔϛφϧͰSΛԡ͢ 5FYU΍৭ͳͲ΢ΟδΣοτΛ

    มߋͨ͠Β൓ө͞ΕΔ 4UBUF͸ͦͷ·· ʢ4UBUFʹؔͯ͠͸ޙͰઆ໌ʣ fl VUUFSSVO ωΠςΟϒίʔυ͔Β ࣮ߦ͠௚͢ ˞)PU3FMPBE͕Ͱ͖Δͷ͸σόοάϏϧυ࣌ʢ+*5ίϯύΠϧ࣌ʣͷΈ
  11. ඪ४΢ΟδΣοτΛ࢖ͬͯΈΑ͏ w ϥΠϒίʔσΟϯά͍ͯ͘͠ͷͰҰॹʹॻ͍ͯΈΑ͏ʂ w ࢖༻૝ఆ΢ΟδΣοτ w 5FYU w $FOUFS w

    $PMVNO w 3PX w 4J[FE#PY w $PMPSFE#PY IUUQTHJUIVCDPNNJYJHSPVQ'MVUUFS5SBJOJOHQVMM
  12. $PMVNOͷதʹ-JTU7JFXΛೖΕΔͱ͖͸஫ҙʂ w -JTU7JFX΋޿͕Ζ͏ͱͯ͘͠Δੑ࣭Λ࣋ͭͷͰΤϥʔʹͳΓ·͢ 5IFGPMMPXJOH3FOEFS0CKFDUXBTCFJOHQSPDFTTFEXIFOUIFFYDFQUJPOXBT fi SFE 3FOEFS7JFXQPSUD/&&%4-":065/&&%41"*/5/&&%4$0.104*5*/(#*5461%"5& OFFETDPNQPTJUJOH DSFBUPS7JFXQPSUˡ*HOPSF1PJOUFS<(MPCBM,FZBEC>ˡ4FNBOUJDTˡ-JTUFOFSˡ @(FTUVSF4FNBOUJDTˡ

    3BX(FTUVSF%FUFDUPS<-BCFMFE(MPCBM,FZ3BX(FTUVSF%FUFDUPS4UBUFD>ˡ-JTUFOFSˡ @4DSPMMBCMF4DPQF ˡ@4DSPMM4FNBOUJDT<(MPCBM,FZB>ˡ/PUJ fi DBUJPO-JTUFOFS4DSPMM.FUSJDT/PUJ fi DBUJPOˡ 4DSPMMBCMFˡ1SJNBSZ4DSPMM$POUSPMMFSˡl QBSFOU%BUBOPOF DBOVTFTJ[F  DPOTUSBJOUT#PY$POTUSBJOUT X I*O fi OJUZ  ɽɽɽ
  13. $PMVNOͷதʹ-JTU7JFXΛೖΕΔͱ͖͸஫ҙʂ w -JTU7JFX΋޿͕Ζ͏ͱͯ͘͠Δੑ࣭Λ࣋ͭͷͰΤϥʔʹͳΓ·͢ 5IFGPMMPXJOH3FOEFS0CKFDUXBTCFJOHQSPDFTTFEXIFOUIFFYDFQUJPOXBT fi SFE 3FOEFS7JFXQPSUD/&&%4-":065/&&%41"*/5/&&%4$0.104*5*/(#*5461%"5& OFFETDPNQPTJUJOH DSFBUPS7JFXQPSUˡ*HOPSF1PJOUFS<(MPCBM,FZBEC>ˡ4FNBOUJDTˡ-JTUFOFSˡ @(FTUVSF4FNBOUJDTˡ

    3BX(FTUVSF%FUFDUPS<-BCFMFE(MPCBM,FZ3BX(FTUVSF%FUFDUPS4UBUFD>ˡ-JTUFOFSˡ @4DSPMMBCMF4DPQF ˡ@4DSPMM4FNBOUJDT<(MPCBM,FZB>ˡ/PUJ fi DBUJPO-JTUFOFS4DSPMM.FUSJDT/PUJ fi DBUJPOˡ 4DSPMMBCMFˡ1SJNBSZ4DSPMM$POUSPMMFSˡl QBSFOU%BUBOPOF DBOVTFTJ[F  DPOTUSBJOUT#PY$POTUSBJOUT X I*O fi OJUZ  ɽɽɽ *O fi OJUZʂʂ
  14. w ৽͍͠4UBUFΛఆٛ w ഒ͢ΔϝιουΛఆٛ w ഒ͢ΔϝιουΛݺͿϘλϯΛ௥Ճ ഒʹͳ͍ͬͯ͘ϘλϯΛ௥Ճ͠Α͏ void _twice() {

    setState(() { _counter2 = _counter2 * 2; }); } FloatingActionButton( onPressed: () { _twice(); }, IUUQTHJUIVCDPNNJYJHSPVQ'MVUUFS5SBJOJOHQVMM
  15. w (JU)VCͷϦϙδτϦҰཡΛऔಘ͢Δ"1*Λୟ͍ͯΈΑ͏ʂ w IUUQTEPDTHJUIVCDPNKBSFTUSFQPTSFQPT BQJ7FSTJPOMJTU SFQPTJUPSJFTGPSBVTFS w ·ͣ͸DVSMίϚϯυͰୟ͍ͯΈΑ͏ ωοτϫʔΫ௨৴ͯ͠ΈΑ͏ʂ $

    curl -L https://api.github.com/users/<<ࣗ෼ͷ github id>>/repos ϦϙδτϦҰཡ ͍ͩ͘͞ʙ <\ JE  OPEF@JEIPHF  OBNF)FMMP8PSME  ʜ ωοτϫʔΫ௨৴ ΫϥΠΞϯτ "1*
  16. ඇಉظॲཧʢBTZODBXBJUʣͷྫ Future<void> fetchUserData() async { // ϢʔβʔσʔλΛඇಉظͰऔಘ final response =

    await http.get( Uri.parse('https://api.example.com/user'), ); debugPrint('εςʔλείʔυ͸: ${response.statusCode}'); }
  17. ඇಉظॲཧʢBTZODBXBJUʣͷྫ Future<void> fetchUserData() async { // ϢʔβʔσʔλΛඇಉظͰऔಘ final response =

    await http.get( Uri.parse('https://api.example.com/user'), ); debugPrint('εςʔλείʔυ͸: ${response.statusCode}'); } BTZODΩʔϫʔυ͸ ؔ਺͕ඇಉظͰ͋Δ͜ͱΛࣔ͢
  18. ඇಉظॲཧʢBTZODBXBJUʣͷྫ Future<void> fetchUserData() async { // ϢʔβʔσʔλΛඇಉظͰऔಘ final response =

    await http.get( Uri.parse('https://api.example.com/user'), ); debugPrint('εςʔλείʔυ͸: ${response.statusCode}'); } BTZODΛ෇͚ͨؔ਺͸ ಺෦ͰBXBJUΛ࢖༻͢Δ͜ͱ͕Ͱ͖Δ  ৗʹ'VUVSFΦϒδΣΫτΛฦ͢ BTZODΩʔϫʔυ͸ ؔ਺͕ඇಉظͰ͋Δ͜ͱΛࣔ͢
  19. ඇಉظॲཧʢBTZODBXBJUʣͷྫ Future<void> fetchUserData() async { // ϢʔβʔσʔλΛඇಉظͰऔಘ final response =

    await http.get( Uri.parse('https://api.example.com/user'), ); debugPrint('εςʔλείʔυ͸: ${response.statusCode}'); } BXBJUͰ଴ͬͯ͋͛Δʂ
  20. w ϨεϙϯεͷKTPOΛQBSTFͯ͠ϦϙδτϦ໊͚ͩऔಘ͠Α͏ w ࢖༻ύοέʔδ w IUUQTQVCEFWQBDLBHFTKTPO@TFSJBMJ[BCMF w IUUQTQVCEFWQBDLBHFTCVJME@SVOOFS w ίϚϯυ

    ϦϙδτϦͷ໊લ͚ͩදࣔͯ͠ΈΑ͏ʂ $ flutter pub run build_runner build IUUQTHJUIVCDPNNJYJHSPVQ'MVUUFS5SBJOJOHQVMM
  21. "[VSF0QFO"*4FSWJDFͱ͸ʁ w .JDSPTPGU"[VSF͕ఏڙ͢Δ"*αʔϏεͷͭ w 0QFO"*͕ࣾ։ൃͨ͠"*ϞσϧΛ.JDSPTPGU"[VSF্Ͱར༻Մೳ w ೖྗσʔλ͕"*ͷֶशσʔλʹར༻͞Εͳ͍ w .JDSPTPGU"[VSFͷηΩϡϦςΟػೳΛ࢖༻Ͱ͖ΔͨΊاۀͰͷར༻ʹ޲͍ͯΔ w

    "*Ϟσϧ͸0QFO"*͕ࣾఏڙ͍ͯ͠Δ$IBU(15Ͱ࢖ΘΕ͍ͯΔϞσϧͱಉ͡ʂ w ࣗવݴޠʹΑΔ࣭ٙԠ౴΍຋༁ɼձٞͷཁ໿ɾίʔυͷੜ੒ͳͲ༷ʑͳλεΫΛ࣮ߦՄೳ w ͪͳΈʹ$IBU(15ͱҧͬͯ8FCαʔϏε͕ແ͘"1*ར༻ͷΈ
  22. 5$"[VSF0QFO"*ͱ઀ଓ w "[VSF0QFO"*"1*LFZ͸QBTTXPSEʹ͋Γ·͢ʂ w ઈର(JUʹQVTI͠ͳ͍Ͱʂʂʂ w ·ͣDVSMͰ౤͛ΕΔ͔֬ೝͯ͠ΈΑ͏ʂ w ެࣜυΩϡϝϯτIUUQTMFBSONJDSPTPGUDPNKBKQB[VSFBJTFSWJDFTPQFOBJ RVJDLTUBSU

    UBCTDPNNBOEMJOF$QZUIPOOFXQJWPUTSFTUBQJ curl ‘<<ΤϯυϙΠϯτURL>>/openai/deployments/<<σϓϩΠ໊>>/chat/completions? api-version=2024-02-15-preview' \ -H 'Content-Type: application/json' \ -H ‘api-key: <<ೝূ৘ใ>>' \ -d '{"messages": [{“role":"user","content":"͜Μʹͪ͸ʂ"}]}'
  23. 5$"[VSF0QFO"*ͱ઀ଓ w EBSUEF fi OFίϚϯυΛ࢖ͬͯ஋Λ౉ͯ͋͛͠Α͏ʂ w EBSUEF fi OFίϚϯυ͔Βड͚औΔ࣌͸͜͏ʂ flutter

    run —-dart-define=API_URL=<<ΤϯυϙΠϯτURL>> -—dart- define=DEPLOY_NAME=<<σϓϩΠ໊>> —-dart-define=API_KEY=<<ೝূ৘ใ>> const apiUrl = String.fromEnvironment('API_URL');
  24. 5$จ຺Λཧղͤ͞Α͏ w 0QFO"*͸จ຺΋ཧղͯ͠ฦ౴ͯ͘͠ΕΔ w NFTTBHFTʹࠓ·ͰͷNFTTBHFΛ٧ΊࠐΉ͜ͱͰՄೳ w ࢦࣔޠΛ࢖ͬͨΓ͠ΓͱΓΛ͢Δͱจ຺ཧղͯ͠Δ͔֬ೝͰ͖Δ curl ‘<<ΤϯυϙΠϯτURL>>/openai/deployments/<<σϓϩΠ໊>>/chat/completions?api- version=2024-02-15-preview'

    \ -H 'Content-Type: application/json’ \ -H 'api-key: <<ೝূ৘ใ>>' \ -d '{"messages": [{“role":"user","content":"͠ΓͱΓ͠Α͏"}, {“content":"ָͦ͠͏Ͱ͢ͶʂͦΕͰ͸ɺ࢝Ί·͢ɻ\n\nʲϦϯΰʳ", “role”:"assistant"}, {“role":"user","content":"͝·"}]}'
  25. 5$ঢ়ଶ؅ཧʹ͍ͭͯ஌Ζ͏ w 4UBUFGVM8JEHFU w 8JEHFUͦͷ΋ͷʹঢ়ଶʢTUBUFʣΛ͍࣋ͬͯΔ w TFU4UBUFΛ໌ࣔతʹߦ͏͜ͱͰ࠶ඳը͞ΕΔͷͰΘ͔Γ΍͍͢ w ଞͷ8JEHFUͰঢ়ଶʹมԽ͕͋ͬͨ࣌ʹ൓өͰ͖ͳ͘ɼখن໛ϓϩδΣΫτ޲͖ w

    3JWFSQPE w ঢ়ଶΛ೚ҙͷ৔ॴ͔ΒΞΫηεՄೳʹ͢Δґଘؔ܎஫ೖϑϨʔϜϫʔΫ w #MPD w ΠϕϯτΛ࢖༻ͯ͠ঢ়ଶͷมߋΛτϦΨʔ͠ෳࡶͳঢ়ଶͷϑϩʔΛ؅ཧͰ͖ΔϥΠϒϥϦ w ϏδωεϩδοΫͱ6*Λ؆୯ʹ෼཭Ͱ͖ςετ͕؆୯ʹ