Slide 1

Slide 1 text

ίʔυͷฏ४ԽΛ໨ࢦͯ͠ for ୈճ)","5"TXJGU

Slide 2

Slide 2 text

} var employedBy = "YUMEMI Inc." var job = "iOS Tech Lead" var favoriteLanguage = "Swift" var twitter = "@lovee" var qiita = "lovee" var github = "el-hoshino" var additionalInfo = """ ࡓ͑Χϊөը࠷ߴʹྑ͔ͬͨ """ final class Me: Developable, Talkable {

Slide 3

Slide 3 text

J045FDI-FBE5FBNͷ࢓ࣄ ⠸

Slide 4

Slide 4 text

J045FDI-FBE5FBNͷ࢓ࣄ w ϓϩδΣΫτԣஅͷ13ϨϏϡʔ w νʔϜԣஅͷٕज़ࢧԉ΍$*$%ͷಋೖࢧԉ w ։ൃඪ४Խʗฏ४Խͷ໛ࡧ

Slide 5

Slide 5 text

։ൃඪ४Խʗฏ४Խ ˣ ଐਓԽΛ๷͙

Slide 6

Slide 6 text

IUUQTOMBCJUNFEJBDPKQOMBSUJDMFTOFXTIUNM

Slide 7

Slide 7 text

༗څऔΓ์୊੍౓ w ͍ͭͰ΋ɺ͍ͭ·Ͱ΋ɺ༗څ͕औΕΔ w ࣗ෼ͷইප w Ո଒ͷհޢҭࣇ w ϦϑϨογϡ w FUD w ͍ͭͰ΋ɺ୭Ͱ΋ɺٸʹٳΉՄೳੑ͕͋Δ w ಛఆͷਓ͕͍ͳ͍ͱ࢓ࣄ͕ճΒͳ͔ͬͨΒΞ΢τ w ඞͣ୭͔୅ΘΓʹͳΔਓ͕͍ͳͯ͘͸ͳΒͳ͍

Slide 8

Slide 8 text

։ൃඪ४Խʗฏ४Խ

Slide 9

Slide 9 text

w ඪ४Խ w ։ൃ؀ڥ΍ϚχϡΞϧΛڞ௨Խ͢Δ w ಉ͡ϥΠϒϥϦʔΛར༻͢Δ w ಉ͡ϑΝΠϧΛྲྀ༻͢Δ w ಉ͡ઃܭΛద༻͢Δ w ΫϥΠΞϯτͷ౎߹͕͋Γɺݶք͕͋Δ w ฏ४Խ w ΤϯδχΞಉ࢜ͷ͹Β͖ͭΛ཈੍͢Δ  w ୭Ͱ΋͙͢ʹಡΊΔίʔυΛॻ͘ w ୭Ͱ΋͙͢ʹอकͰ͖ΔίʔυΛॻ͘ w ୭Ͱ΋͙͢ʹ௥Ճ࣮૷Ͱ͖ΔίʔυΛॻ͘ w ΫϥΠΞϯτͷ౎߹ʹΑΒͣɺશͯͷϓϩδΣΫτʹ࢖͑Δ ɿ੡଄ۀʹ͓͚Δʮฏ४Խʯͷҙຯͱ͸ͪΐͬͱҧ͏͕ɺʮ͹Β͖ͭΛ཈੍ʯͱ͍͏ҙຯͰ͸ಉ͡ΞϓϩʔνͰ͋Δ

Slide 10

Slide 10 text

ฏ४Խ w ୭Ͱ΋͙͢ʹಡΊΔίʔυΛॻ͘ w ୭Ͱ΋͙͢ʹอकͰ͖ΔίʔυΛॻ͘ w ୭Ͱ΋͙͢ʹ௥Ճ࣮૷Ͱ͖ΔίʔυΛॻ͘

Slide 11

Slide 11 text

୭Ͱ΋͙͢ʹಡΊΔίʔυΛॻ͘ • Ϧʔμϒϧίʔυʂ • ໊લͱ࣮૷ΛҰகͤ͞Δ • ᐆດͳදݱΛආ͚Δ • ڊେͳ࣮૷Λ෼ׂ͢Δ • etc...

Slide 12

Slide 12 text

let searchEngineURL = "https://www.google.com" 63-ͱݴͬͯ·͕͢ த਎͸4USJOH ໊લͱ࣮૷ΛҰகͤ͞Δ

Slide 13

Slide 13 text

let searchEngineURLString = "https://www.google.com" ໊લΛ63-4USJOHʹ௚͢ ໊લͱ࣮૷ΛҰகͤ͞Δ

Slide 14

Slide 14 text

extension String { func isZeroPrefix() -> Bool { return !hasPrefix("0") } } ;FSPͰ࢝·ΔͬͯݴͬͯΔ͕ ઌ಄ͷจࣈ͸Ͱͳ͍ͱฦͯ͠Δ ໊લͱ࣮૷ΛҰகͤ͞Δ

Slide 15

Slide 15 text

extension String { func isNotBeginningWith0() -> Bool { return !hasPrefix("0") } } ໊લΛͰ࢝·͍ͬͯͳ͍ʹ௚͢ ໊લͱ࣮૷ΛҰகͤ͞Δ

Slide 16

Slide 16 text

func isForceUpdateVersion() -> Bool ࣗ෼ͷόʔδϣϯ͕ڧ੍Ξοϓσʔτର৅ͳͷʁ ࠓ഑৴தͷόʔδϣϯ͕ڧ੍Ξοϓσʔτόʔδϣϯͳͷʁ ᐆດͳදݱΛආ͚Δ

Slide 17

Slide 17 text

func isForceUpdateRequired() -> Bool ͱʹ͔͘ڧ੍όʔδϣϯΞοϓ͕ඞཁͩͱࣔ͢ ᐆດͳදݱΛආ͚Δ

Slide 18

Slide 18 text

IUUQTXXXBNB[PODPKQEQ

Slide 19

Slide 19 text

IUUQTTQFBLFSEFDLDPNMPWFFTFMGEPDVNFOUJOHGBMTFTVTVNF

Slide 20

Slide 20 text

5*14 w %BOHFSʷ4XJGU-JOUͰϑΥʔϚοτͷ੔͑ͨ ಡΈ΍͍͢ίʔυΛ w ໋໊͸ίʔυ͕ԿΛ΍ͬͯΔ͔Ͱ͸ͳ͘ɺ ͋ͳ͕ͨԿΛ͍͔ͨ͠ w ໊͍͍લ͕ࢥ͍͔ͭͳ͔ͬͨͱ͖ w (PPHMF຋༁ w 8FCMJP࿨ӳࣙయ w (JU)VC୯ޠݕࡧ w DPEJDKQ

Slide 21

Slide 21 text

୭Ͱ΋͙͢ʹอकͰ͖ΔίʔυΛॻ͘ • ςετʂʂʂ • ৽نͷίʔυ͸ͱΓ͋͑ͣςετΛॻ͘ • ςετ͕ॻ͚ΔΑ͏ʹ෭࡞༻౳Λࣗવʹ஫ҙͰ͖Δ • طଘͷίʔυʹςετΛ௥Ճ͍ͯ͘͠ • ςετॻ͚Δ΋ͷ͔ΒͰ͍͍ͷͰͱΓ͋͑ͣॻ͘ • ಺༰͕׬ᘳʹͰ͖ͳͯ͘΋ͱΓ͋͑ͣॻ͚Δ΋ͷΛॻ͘ • ςετίʔυॻ͍ͯΔ͚ͩͰؾ෇͚Δόά΋͋Δ

Slide 22

Slide 22 text

No content

Slide 23

Slide 23 text

No content

Slide 24

Slide 24 text

No content

Slide 25

Slide 25 text

IUUQTXXXBNB[PODPKQEQ

Slide 26

Slide 26 text

IUUQTQFBLTDDJ04@UFTUJOH

Slide 27

Slide 27 text

୭Ͱ΋͙͢ʹ௥Ճ࣮૷Ͱ͖ΔίʔυΛॻ͘ • ֤छݪଇΛकΔʂʂʂ • SOLID • CQS • DRY • KISS • PIE • etc...

Slide 28

Slide 28 text

4JOHMF3FTQPOTJCJMJUZ1SJODJQMF Ϋϥεʹมߋ͕ى͜Δཧ༝͸ɺҰ͚ͭͩͰͳ͚Ε͹ͳΒͳ͍ class ViewController: UIViewController { let tableView: UITableView var viewModel: ViewModel! @IBAction func fetch(sender: UIButton) { viewModel.fetchData() } } class ViewModel { unowned let viewController: ViewController func fetchData() { // Fetch Data viewController.tableView.reloadData() } } 7JFX.PEFMͷมߋཧ༝ʢ੹຿ʣ͸ɺ ࣗ਎ͷσʔλఏڙ͚ͩͰͳ͘ɺ ը໘ͷඳը·Ͱؚ·Εͯ͠·͏

Slide 29

Slide 29 text

4JOHMF3FTQPOTJCJMJUZ1SJODJQMF Ϋϥεʹมߋ͕ى͜Δཧ༝͸ɺҰ͚ͭͩͰͳ͚Ε͹ͳΒͳ͍ class ViewController: UIViewController { let tableView: UITableView var viewModel: ViewModel! override func viewDidLoad() { // ... NotificationCenter.default.addObserver(/* */) } @IBAction func fetch(sender: UIButton) { viewModel.fetchData() } @objc func onDidFetchData(sender: Notification) { tableView.reloadData() } } class ViewModel { func fetchData() { // Fetch Data NotificationCenter.default.post(/* */) } } σʔλऔಘऴྃͷ ௨஌͚ͩग़͢ σʔλऔಘޙͷඳը͸ 7$ͷ੹຿ʹด͡Δ

Slide 30

Slide 30 text

%FQFOEFODZ*OWFSTJPO1SJODJQMF ্ҐϞδϡʔϧ͸ԼҐϞδϡʔϧʹґଘͯ͠͸ͳΒͳ͍ɺ྆ํந৅ʹґଘ͢΂͖ class ViewController: UIViewController { var viewModel: ViewModel! @IBAction func fetch(sender: UIButton) { viewModel.fetchData() } } class ViewModel { func fetchData() { // Fetch Data } } ্Ґͷ7JFX$POUSPMMFS͸ɺ ԼҐͷ7JFX.PEFMͷ࣮૷ʹ ґଘ͍ͯ͠Δ

Slide 31

Slide 31 text

%FQFOEFODZ*OWFSTJPO1SJODJQMF ্ҐϞδϡʔϧ͸ԼҐϞδϡʔϧʹґଘͯ͠͸ͳΒͳ͍ɺ྆ํந৅ʹґଘ͢΂͖ // ViewController protocol DataViewModelProtocol: AnyObject { func fetchData() } class ViewController: UIViewController { var dataViewModel: DataViewModelProtocol! @IBAction func fetch(sender: UIButton) { dataViewModel.fetchData() } } // ViewModel class ViewModel { } extension ViewModel: DataViewModelProtocol { func fetchData() { // Fetch Data } } 7$Ͱ͸ඞཁͱ͢Δ 7.ͷػೳ͚ͩநग़ͨ͠ ந৅Խʹґଘ 7.Ͱ͸ந৅Խͨ͠ ϓϩτίϧΛద߹͢Δ͚ͩ

Slide 32

Slide 32 text

$PNNBOE2VFSZ4FQBSBUJPO ϝιου͸ɺΞΫγϣϯΛ࣮ߦ͢Δ͔ɺσʔλΛฦ͔͢ͷ͍ͣΕ͔ยํͰ͋Δ΂͖ class DataStore { var data: [Int] = [] func getLatestData() -> [Int] { // αʔό͔Β࠷৽σʔλΛऔಘ data = latestData return data } } HFU-BUFTU%BUB͸໭Γ஋Λฦ͢ ΫΤϦͰ͋Γͳ͕Β ࠷৽σʔλΛऔಘͯ͠ ஋Ληοτ͢ΔίϚϯυͰ΋͋Δ

Slide 33

Slide 33 text

$PNNBOE2VFSZ4FQBSBUJPO ϝιου͸ɺΞΫγϣϯΛ࣮ߦ͢Δ͔ɺσʔλΛฦ͔͢ͷ͍ͣΕ͔ยํͰ͋Δ΂͖ class DataStore { var data: [Int] = [] func fetchLatestData() { // αʔό͔Β࠷৽σʔλΛऔಘ data = latestData } func getLatestData() -> [Int] { return data } } ࠷৽ͷσʔλΛऔಘͯ͠ ஋Ληοτ͢Δ͚ͩͷίϚϯυ ݱࡏͷσʔλͷ஋Λฦ͚ͩ͢ͷΫΤϦ

Slide 34

Slide 34 text

IUUQTTXJGUPSHEPDVNFOUBUJPOBQJEFTJHOHVJEFMJOFTVTFUFSNJOPMPHZXFMM

Slide 35

Slide 35 text

%POU3FQFBU:PVSTFMG ஌ࣝ͸γεςϜʹ͓͍ͯ୯ҰͰɺᐆດ͕͞ͳ͘ɺ৴པͰ͖ΔදݱͰͳͯ͘͸ͳΒͳ͍ class ViewController: UIViewController { override func viewDidLoad() { // ... titleLabel.font = UIFont.systemFont(ofSize: UIFont.labelFontSize) titleLabel.textColor = UIColor.label authorLabel.font = UIFont.systemFont(ofSize: UIFont.labelFontSize) authorLabel.textColor = UIColor.label } @IBAction func resetLabelTextVisual() { titleLabel.font = UIFont.systemFont(ofSize: UIFont.labelFontSize) titleLabel.textColor = UIColor.label authorLabel.font = UIFont.systemFont(ofSize: UIFont.labelFontSize) authorLabel.textColor = UIColor.label } } ಉ͡ϥϕϧͷςΩετඳըઃఆ͕ Օॴʹ෼͔Ε͍ͯΔ

Slide 36

Slide 36 text

%POU3FQFBU:PVSTFMG ஌ࣝ͸γεςϜʹ͓͍ͯ୯ҰͰɺᐆດ͕͞ͳ͘ɺ৴པͰ͖ΔදݱͰͳͯ͘͸ͳΒͳ͍ class ViewController: UIViewController { override func viewDidLoad() { // ... resetLabelTextVisual(sender: self) } @IBAction func resetLabelTextVisual(sender: Any) { titleLabel.font = UIFont.systemFont(ofSize: UIFont.labelFontSize) titleLabel.textColor = UIColor.label authorLabel.font = UIFont.systemFont(ofSize: UIFont.labelFontSize) authorLabel.textColor = UIColor.label } } ϥϕϧͷςΩετඳըઃఆΛ ௚઀ݺͼग़ͯ͠ॏෳΛආ͚Δ

Slide 37

Slide 37 text

%POU3FQFBU:PVSTFMG ஌ࣝ͸γεςϜʹ͓͍ͯ୯ҰͰɺᐆດ͕͞ͳ͘ɺ৴པͰ͖ΔදݱͰͳͯ͘͸ͳΒͳ͍ class ViewController: UIViewController { override func viewDidLoad() { // ... resetLabelTextVisual(sender: self) } func setTitleLabelTextVisual(on label: UILabel) { label.font = UIFont.systemFont(ofSize: UIFont.labelFontSize) label.textColor = UIColor.label } @IBAction func resetLabelTextVisual(sender: Any) { setTitleLabelTextVisual(on: titleLabel) setTitleLabelTextVisual(on: authorLabel) } } ιʔείʔυͷ಺༰͸ಉ͕ͩ͡ɺ ஌ࣝ͸ҧ͏

Slide 38

Slide 38 text

%POU3FQFBU:PVSTFMG ஌ࣝ͸γεςϜʹ͓͍ͯ୯ҰͰɺᐆດ͕͞ͳ͘ɺ৴པͰ͖ΔදݱͰͳͯ͘͸ͳΒͳ͍ class ViewController: UIViewController { enum LabelType { case title case author var font: UIFont { /* */ } var textColor: UIColor { /* */ } } func setLabelTextVisual(on label: UILabel, as type: LabelType) { label.font = type.font label.textColor = type.textColor } @IBAction func resetLabelTextVisual(sender: Any) { setLabelTextVisual(on: titleLabel, as: .title) setLabelTextVisual(on: authorLabel, as: .author) } } ஌ࣝʹԠͨ͡੾Γସ͑Λఆٛ ॏෳίʔυΛ࡟ݮ

Slide 39

Slide 39 text

IUUQTRJJUBDPNMPWFFJUFNTEDFDFCFC

Slide 40

Slide 40 text

ʲએ఻ʳ

Slide 41

Slide 41 text

גࣜձࣾΏΊΈɺΤϯδχΞઈࢍืूத IUUQSFDSVJUZVNFNJDPKQ 䱰⾂ ؽ٨ضٌ ✌؜猳

Slide 42

Slide 42 text

IUUQTIBLBUBTXJGUDPOOQBTTDPNFWFOU