Slide 1

Slide 1 text

ະ஌ͷϑΝΠϧܗࣜΛ
 CodableͰಡΈॻ͖͢Δͷʹ໾ཱͭςΫχοΫ iOSDC Japan 2021 גࣜձࣾZOZOςΫϊϩδʔζ ςοΫϦʔυ ͹Μ͡ΎΜ🍓 / @banjun Copyright © ZOZO Technologies, Inc. ʰApple Watchͷจࣈ൫ϑΝΠϧʱ ⌚

Slide 2

Slide 2 text

© ZOZO Technologies, Inc. גࣜձࣾZOZOςΫϊϩδʔζ ςοΫϦʔυ ZOZOTOWN iOS ͹Μ͡ΎΜ🍓 / @banjun 2 -PWF-JWFS NBD04 $SFBUF-JWF1IPUPTGSPN.PWJFT 'MJDL4,, J04 +BQBOFTF$VTUPN,FZCPBSE&YUFOTJPO ݸਓϓϩδΣΫτɾ1PEDBTU ͖ͷ͜ΔΤϑΤϜX!USFCZ͖ͷ͜Δ

Slide 3

Slide 3 text

© ZOZO Technologies, Inc. https://zozo.jp/ ● ೔ຊ࠷େڃͷϑΝογϣϯ௨ൢαΠτ ● 1,400Ҏ্ͷγϣοϓɺ8,200Ҏ্ͷϒϥϯυͷऔΓѻ͍ʢͱ΋ʹ 2021೥3݄຤࣌఺ʣ ● ৗ࣌83ສ఺Ҏ্ͷ঎඼ΞΠςϜ਺ͱຖ೔ฏۉ2,900఺Ҏ্ͷ৽ண ঎඼Λܝࡌ ● ίεϝઐ໳ϞʔϧʮZOZOCOSMEʯ΍ۺͷઐ໳Ϟʔϧ ʮZOZOSHOESʯɺϥάδϡΞϦʔˍσβΠφʔζκʔϯ ʮZOZOVILLAʯΛల։ ● ଈ೔഑ૹαʔϏε ● ΪϑτϥοϐϯάαʔϏε ● πέ෷͍ ͳͲ 3

Slide 4

Slide 4 text

© ZOZO Technologies, Inc. 4

Slide 5

Slide 5 text

© ZOZO Technologies, Inc. 5 ͸͡Ίʹ

Slide 6

Slide 6 text

© ZOZO Technologies, Inc. 6 ະ஌ͷϑΝΠϧܗࣜΛ ʰApple Watchͷจࣈ൫ϑΝΠϧʱ ⌚ 
 CodableͰಡΈॻ͖͢Δͷʹ໾ཱͭςΫχοΫ ࠓճͷ͓͸ͳ͠

Slide 7

Slide 7 text

© ZOZO Technologies, Inc. 7 ʰApple Watchͷจࣈ൫ϑΝΠϧʱ ⌚ ະ஌ͷϑΝΠϧܗࣜΛ 
 CodableͰ ख๏ɾ࣮૷ɾςΫχοΫ ର৅ (ղੳର৅) ۩ମࣄྫ ࠓճͷ͓͸ͳ͠

Slide 8

Slide 8 text

© ZOZO Technologies, Inc. 8 ◆ Codableͱ͸ʁʰApple Watchͷจࣈ൫ʱͱ͸ʁ ◆ ͳͥͦΕΛղੳ͢Δͷ͔ʁ ◆ ݁Ռͳʹ͕Ͱ͖͔ͨʁ ... banjun/WatchFaceDumper ◆ Ͳ͏΍ͬͨͷ͔ʁ ◆ CodableΛͲ͏࢖͏ͱྑ͔͔ͬͨʁ ࣄྫͱରॲ ࠓճͷ͓͸ͳ͠

Slide 9

Slide 9 text

© ZOZO Technologies, Inc. 9 Codable

Slide 10

Slide 10 text

© ZOZO Technologies, Inc. 10 Codable - Έͳ͞Μ͝ଘ஌ͷΞϨɾɾɾͰ͕͢ ✅ API௨৴ͰJSONΛѻ͏ͷ͕ఆ൪ͷ࢖ΘΕ͔ͨɻએݴతͰಡΈ΍͍͢ɻ 📝 Swiftͷ֎ͷੈքͷදݱܗࣜΛSwiftͰදݱ͢Δܕ ❗ API௨৴ͷࣗಈੜ੒ͳΒͱ΋͔͘ ͦΕҎ֎ͷ࢖͍ํͰ͸ɼର৅ͷղੳɾཧղ͕ඞཁෆՄܽ

Slide 11

Slide 11 text

© ZOZO Technologies, Inc. 11 Codable - Έͳ͞Μ͝ଘ஌ͷΞϨɾɾɾͰ͕͢ ղੳ (࠶ܝ)

Slide 12

Slide 12 text

© ZOZO Technologies, Inc. 12 Apple Watchͷจࣈ൫

Slide 13

Slide 13 text

© ZOZO Technologies, Inc. 13 Apple Watchͷจࣈ൫ ⌚ ࣌ࠁΛදࣔ͢Δجຊతͳը໘ͷ͜ͱ ⚙ ͍ΖΜͳछྨ͕͋Δ͏͑ʹΧελϜͰ͖Δ 🙋 Έͳ͞Μ͸ͲΜͳจࣈ൫Λ࢖͍ͬͯ·͔͢ʁ 
 WWDC21ʹΑΕ͹ࣸਅจࣈ൫͕ਓؾΒ͍͠

Slide 14

Slide 14 text

© ZOZO Technologies, Inc. 14 จࣈ൫ Λ۷ΓԼ͛Α͏

Slide 15

Slide 15 text

© ZOZO Technologies, Inc. 15 จࣈ൫͸࡞ΕΔʁ࡞Εͳ͍ʁ Developerͱͯ͠ؾʹͳΔ͜ͱ watchOSΞϓϦͱ͸ҧ͍ɼจࣈ൫ͦͷ΋ͷΛΞϓϦͷΑ͏ ʹ࡞Δ͜ͱ͸Ͱ͖ͳ͍ Ϣʔβʔ͕Ͱ͖Δ͜ͱ ϏϧτΠϯͷจࣈ൫ͷΧελϜઃఆ ΞϓϦ͕ఏڙ͢Δύʔπ(Complications)ͷ഑ஔ ࢓૊Έ͸͚ͬ͜͏ൿີײ͕͋Δ https://developer.apple.com/design/human-interface-guidelines/watchos/overview/complications/

Slide 16

Slide 16 text

© ZOZO Technologies, Inc. 16 ʰจࣈ൫ϑΝΠϧʱ͸ଘࡏ͢Δ watchOS 7͔Β͸ଞͷਓͱจࣈ൫Λ ڞ༗Ͱ͖ΔΑ͏ʹͳͬͨ ͭ·Γɼจࣈ൫ϑΝΠϧ͕σόΠεΛ ཭Εͯଘࡏ͢Δ͸ͣ https://www.apple.com/jp/watchos/watchos-7/

Slide 17

Slide 17 text

© ZOZO Technologies, Inc. 17 ʰจࣈ൫ϑΝΠϧʱ͸ଘࡏ͢Δ

Slide 18

Slide 18 text

© ZOZO Technologies, Inc. 18 ͳͥจࣈ൫Λ 
 ղੳ͢Δͷ͔

Slide 19

Slide 19 text

© ZOZO Technologies, Inc. 19 ͳͥจࣈ൫Λղੳ͢Δͷ͔ ◆໾ʹཱͭ (࣮ར) ϥΠϒϑΥτ࠶ੜ৚݅ͷ࣮ݧ͕ḿΔྫ ◆৽نੑʂͩΕ΋΍ͬͯͳ͍ʂ githubͷapple watchface repoݕࡧௐ΂ ◆ָ͍͠ʂղੳͨͷ͍͠ʂ Ԡ༻ࣄྫ͸noteʹ͋ΔΑ

Slide 20

Slide 20 text

© ZOZO Technologies, Inc. 20 จࣈ൫ ߏ଄ཧղ ͱ͸͍͑…

Slide 21

Slide 21 text

© ZOZO Technologies, Inc. 21 ͋·Γʹ΋ 
 ׳Ε͍ͯͳͯ͘෼͔ΓͮΒ͍ର৅ ͩͱࢥ͏ͷͰ

Slide 22

Slide 22 text

© ZOZO Technologies, Inc. 22 ͩΜͩΜղੳ͍ͯ͘͠ ͱ͍͏ΑΓ͸ ౴͑ͷ෼͔͍ͬͯΔେ࿮͔Β 
 આ໌͠·͢

Slide 23

Slide 23 text

© ZOZO Technologies, Inc. 23 จࣈ൫ϑΝΠϧ(.watchface)֓ཁ iPhone͔ΒAirDropͰऔΓग़ͨ͠จࣈ ൫͸zip͞Ε͍ͯΔͷͰ·ͣunzipͯ͠ த਎ΛΈΔ unzip

Slide 24

Slide 24 text

© ZOZO Technologies, Inc. 24 จࣈ൫ϑΝΠϧ(.watchface)֓ཁ ϑΥϧμߏ଄(υΩϡϝϯτύοέʔδ) ෳ਺ͷjson, plist, Ϧιʔε(png, jpg, mov)ΛؚΉ ࠶zip͢Ε͹iPhoneʹૹΓฦͤΔ

Slide 25

Slide 25 text

© ZOZO Technologies, Inc. 25 จࣈ൫ϑΝΠϧ(.watchface)֓ཁ complicationData … ίϯϓϦέʔγϣϯͰ࢖͏Ϧιʔε face.json … จࣈ൫ͷछྨɾΧελϜઃఆ஋ metadata.json … ίϯϓϦέʔγϣϯͷ໊લ΍Ґஔ Resources … ը૾ɾಈըϑΝΠϧ Resources/Images.plist … ͦͷը૾ɾಈըͷϝλσʔλ

Slide 26

Slide 26 text

© ZOZO Technologies, Inc. jsonͱplist … ͦΕͧΕCodableͰಡΈॻ͖ ϑΥϧμߏ଄ͱ͔ͦͷதͷϑΝΠϧ … ↑ͷ Codableʹ߹ΘͤͯಡΈॻ͖ ͦΕҎ֎ͷݻఆͷϑΝΠϧ … ୯ʹಡΈॻ͖ 26 ղੳͯ͠CodableͰ࣮૷͍ͨ͠

Slide 27

Slide 27 text

© ZOZO Technologies, Inc. 27 ղੳͯ͠CodableͰ࣮૷͍ͨ͠… jsonͱplist … ͦΕͧΕCodableͰಡΈॻ͖ ϑΥϧμߏ଄ͱ͔ͦͷதͷϑΝΠϧ … ↑ͷ Codableʹ߹ΘͤͯಡΈॻ͖ ͦΕҎ֎ͷݻఆͷϑΝΠϧ … ୯ʹಡΈॻ͖ struct Watchface: Codable

Slide 28

Slide 28 text

© ZOZO Technologies, Inc. 28 ղੳͯ͠CodableͰ࣮૷͍ͨ͠…ͦ͏͍͑͹CfP… jsonͱplist … ͦΕͧΕCodableͰಡΈॻ͖ ϑΥϧμߏ଄ͱ͔ͦͷதͷϑΝΠϧ … ↑ͷ Codableʹ߹ΘͤͯಡΈॻ͖ ͦΕҎ֎ͷݻఆͷϑΝΠϧ … ୯ʹಡΈॻ͖ struct Watchface: Codable CfPͰ͸͜ͷCodableΛ͢Δͱॻ͍͍ͯΔͷ͕ͩ

Slide 29

Slide 29 text

© ZOZO Technologies, Inc. 29 ղੳͯ͠CodableͰ࣮૷͍ͨ͠… jsonͱplist … ͦΕͧΕCodableͰಡΈॻ͖ ϑΥϧμߏ଄ͱ͔ͦͷதͷϑΝΠϧ … ↑ͷ Codableʹ߹ΘͤͯಡΈॻ͖ ͦΕҎ֎ͷݻఆͷϑΝΠϧ … ୯ʹಡΈॻ͖ struct Watchface: Codable CfPͰ͸͜ͷCodableΛ͢Δͱॻ͍͍ͯΔͷ͕ͩ ʰ1ݸͷCodableʱ͸΍Ίͯɼ͜ͷ໾ׂ͸ผʹಀ͕͠·͢🙇

Slide 30

Slide 30 text

© ZOZO Technologies, Inc. 30 ղੳͯ͠Codable + NSFileWrapperͰ࣮૷ jsonͱplist … ͦΕͧΕCodableͰಡΈॻ͖ ϑΥϧμߏ଄ͱ͔ͦͷதͷϑΝΠϧ … ↑ͷ Codableʹ߹Θͤͯอ࣋ ͦΕҎ֎ͷݻఆͷϑΝΠϧ … ୯ʹอ࣋ struct Watchface NSFileWrapper υΩϡϝϯτ ύοέʔδ Ϛοϐϯά https://developer.apple.com/library/archive/documentation/CoreFoundation/Conceptual/CFBundles/DocumentPackages/DocumentPackages.html init(…) init(…)

Slide 31

Slide 31 text

© ZOZO Technologies, Inc. 31 ղੳͯ͠Codable + NSFileWrapperͰ࣮૷ jsonͱplist … ͦΕͧΕCodableͰಡΈॻ͖ ϑΥϧμߏ଄ͱ͔ͦͷதͷϑΝΠϧ … ↑ͷ Codableʹ߹Θͤͯอ࣋ ͦΕҎ֎ͷݻఆͷϑΝΠϧ … ୯ʹอ࣋ struct Watchface NSFileWrapper Ϛοϐϯά zip/unzip υΩϡϝϯτ ύοέʔδ

Slide 32

Slide 32 text

© ZOZO Technologies, Inc. 32 ৄࡉߏ଄͸ৄ͘͠͸ղઆ͠·ͤΜ͕ ͦΕ΄ͲෳࡶͰ͸ͳ͍ͱ͍͏ ײ֮Λ͔ͭΜͰ΄͍͠ͷͰ ͬ͟ͱݟ͍͖ͯ·͢ (6ϖʔδ)

Slide 33

Slide 33 text

© ZOZO Technologies, Inc. 33 τοϓϨϕϧ struct Watchface struct Watchface { var face: Face var metadata: Metadata var snapshot: Data var no_borders_snapshot: Data var resources: Resources? typealias ComplicationData 
 = Metadata.ComplicationPositionDictionary<[String: Data]> var complicationData: ComplicationData? = nil } ✅ FileWrapper͕͋ΔલఏͩͱɼDataͱCodable structΛϑΥϧμߏ଄Ͳ͓Γฒ΂Δ͚ͩ

Slide 34

Slide 34 text

© ZOZO Technologies, Inc. 34 Watchface.Face extension Watchface { struct Face: Codable { var version: Int = 4 var face_type: FaceType var resource_directory: Bool? = true var customization: Customization var complications: Complications? } } ✅ face.jsonʹ͸ɼจࣈ൫ͷ छྨ͕͋Δ ࣸਅɾສ՚ڸɾΠϯϑΥά ϥϑͳͲ ৽͍͠จࣈ൫Λղੳ͢Δͱ ௥Ճ͢Δ͜ͱʹͳΔ ✅ ίϯϓϦέʔγϣϯͷ UserActivity͕͋Δͱ͖͸͜ ͜ʹೖΔ enum FaceType: String, Codable { /// has [top, bottom] case photos /// has [top-left, top-right, bottom-center] case kaleidoscope /// aka infograph case whistler_analog = "whistler-analog" }

Slide 35

Slide 35 text

© ZOZO Technologies, Inc. 35 Watchface.Metadata struct Metadata: Codable { var version: Int = 2 var device_size = 2 // 38mm, 42mm? var complication_sample_templates: ComplicationPositionDictionary var complications_names: ComplicationPositionDictionary var complications_item_ids: ComplicationPositionDictionary var complications_bundle_ids: ComplicationPositionDictionary? } ✅ metadata.jsonʹ͸ίϯϓϦέʔγϣϯ͕͋ΔɻͦͷBundle ID͸com.apple.HeartRate ͳͲ͕ೖΔ {"top": … , "bottom-left": …} ͳͲɼ഑ஔ͢ΔҐஔΛΩʔͱͯ͠هड़͞Ε͍ͯΔ

Slide 36

Slide 36 text

© ZOZO Technologies, Inc. 36 Watchface.Metadata.ComplicationTemplate enum ComplicationTemplate: Codable { case utilitarianSmallFlat(CLKComplicationTemplateUtilitarianSmallFlat) case utilitarianLargeFlat(CLKComplicationTemplateUtilitarianLargeFlat) case circularSmallSimpleText(CLKComplicationTemplateCircularSmallSimpleText) : ✅ ίϯϓϦέʔγϣϯʹ͸͞·͟·ͳλΠϓ͕͋ΓҰ࿈ͷΫϥεͰදݱ͞Ε͍ͯΔ ໨ʹݟ͑Δ෦෼ͷछྨ͸ɼςΩετɾΠϝʔδɾήʔδͷproviderͱͯ͠ग़ݱ͢Δ struct CLKComplicationTemplateUtilitarianSmallFlat: Codable { static let `class` = "CLKComplicationTemplateUtilitarianSmallFlat" var `class`: String = Self.class var version: Int = 30000 var creationDate: Double = Date().timeIntervalSince1970 var textProvider: CLKTextProvider = .date(.init()) }

Slide 37

Slide 37 text

© ZOZO Technologies, Inc. 37 Watchface.Metadata.CLKTextProvider enum CLKTextProvider: Codable { case simple(CLKSimpleTextProvider) case date(CLKDateTextProvider) case time(CLKTimeTextProvider) case compound(CLKCompoundTextProvider) case relativeDate(CLKRelativeDateTextProvider) } ✅ ςΩετͷදࣔʹ΋छྨ͕͋ͬͯɼγϯϓϧͳςΩετࢦఆͷ΄͔ɾ೔෇ɾ࣌ؒΛ࣋ ͭ΋ͷ΍ɼͦΕΒΛෳ߹ͯ͠υοτܨ͗͢ΔͳͲͷϑΥʔϚοτ͕Ͱ͖ΔΑ͏Ͱ͢

Slide 38

Slide 38 text

© ZOZO Technologies, Inc. 38 Watchface.Resources struct Resources { var images: Metadata var files: [String: Data] // filename -> content } ✅ Resources͸ϑΥϧμߏ଄ɻResources.Metadata.Item͕ը૾ϑΝΠϧ͝ͱͷϝλσʔ λɻϝλσʔλʹ͸ΫϩοϓɾΤϑΣΫτɾϥΠϒϑΥτͷ࠶ੜҐஔؚ͕·Ε͍ͯΔɻ f ilesͰͷϑΝΠϧͷϚοϐϯάʹ͸FileWrapperΛ࢖͏ (ʮϦιʔεϑΝΠϧࢀরʯͰޙड़) struct Metadata: Codable { var imageList: [Item] var version: Int = 1 }

Slide 39

Slide 39 text

© ZOZO Technologies, Inc. 39 Ͷʁ ͜Ε͕ެࣜAPIͰఏڙ͞ΕͯͨΒ ؆୯ͦ͏ʹݟ͑Δ͘Β͍ Ͱ͠ΐ͏ʁ

Slide 40

Slide 40 text

© ZOZO Technologies, Inc. 40 ղੳͯ͠structʹ࣮૷͍ͯ͘͠ ͷ΋Α͍͕ ΋͏ͻͱͭ ΍ͬͨ΄͏͕ྑ͍͜ͱ͕͋Δ

Slide 41

Slide 41 text

© ZOZO Technologies, Inc. 41 MacΞϓϦͰ 
 ViewerΛͭ͘Δ

Slide 42

Slide 42 text

© ZOZO Technologies, Inc. 42 ղੳ࡞ۀͷޮ཰Խͱه࿥ ⌚ 📱 unzip zip Θͨ͠

Slide 43

Slide 43 text

© ZOZO Technologies, Inc. 43 ղੳ࡞ۀͷޮ཰Խͱه࿥ ⌚ 📱 unzip zip Θͨ͠

Slide 44

Slide 44 text

© ZOZO Technologies, Inc. 44 ղੳ࡞ۀͷޮ཰Խͱه࿥ ⌚ 📱 unzip zip Θͨ͠ ղੳͯ͠ಡΈॻ͖

Slide 45

Slide 45 text

© ZOZO Technologies, Inc. 45 ղੳ࡞ۀͷޮ཰Խͱه࿥ ⌚ 📱 unzip zip Θͨ͠ ֬ೝ ղੳͯ͠ಡΈॻ͖ ⚠Τϥʔग़ͯΔʂ ϊ΢ϋ΢
 ϝϞ ίʔυ
 ɾ ΞϓϦ

Slide 46

Slide 46 text

© ZOZO Technologies, Inc. 46 MacΞϓϦ WatchFaceDumper.app ·ͩجຊతʹViewer watchfaceϑΝΠϧΛಡΈࠐΜͰද ࣔ͢Δ͜ͱͰɼCodableͷσίʔυ ࣮૷͕ਖ਼͍͜͠ͱ͕෼͔Δ ը૾Ϧιʔε෦෼͸EditͰ͖Δ ϥΠϒϑΥτ࡞੒ʹ΋ରԠ

Slide 47

Slide 47 text

© ZOZO Technologies, Inc. 47 MacΞϓϦ WatchFaceDumper.app

Slide 48

Slide 48 text

© ZOZO Technologies, Inc. 48 MacΞϓϦ WatchFaceDumper.app

Slide 49

Slide 49 text

© ZOZO Technologies, Inc. 49 MacΞϓϦ WatchFaceDumper.app MacΞϓϦ͔ΒAirDropͰ௚઀iOSʹૹ৴ͯ֬͠ೝ (Watch SimulatorͰ͸ಈ͔ͳ͍)

Slide 50

Slide 50 text

© ZOZO Technologies, Inc. 50 Document-BasedΞϓϦ Document-BasedͰॻ͍͓ͯ ͘ͱ෼͔Γ΍͍͢ NewɾOpenɾSaveɾ ResumeͳͲMacͷࣗવͳ ػೳʹରԠ͠΍͍͢ NSDocumentʹWatchfaceΛ ࣋ͨͤɼ1΢Πϯυ΢ 1watchfaceʹ͢Δ

Slide 51

Slide 51 text

© ZOZO Technologies, Inc. 51 Document-BasedΞϓϦ jsonͱplist … ͦΕͧΕCodableͰಡΈॻ͖ ϑΥϧμߏ଄ͱ͔ͦͷதͷϑΝΠϧ … ↑ͷ Codableʹ߹Θͤͯอ࣋ ͦΕҎ֎ͷݻఆͷϑΝΠϧ … ୯ʹอ࣋ struct Watchface NSFileWrapper Ϛοϐϯά zip/unzip υΩϡϝϯτ ύοέʔδ

Slide 52

Slide 52 text

© ZOZO Technologies, Inc. 52 Document-BasedΞϓϦ jsonͱplist … ͦΕͧΕCodableͰಡΈॻ͖ ϑΥϧμߏ଄ͱ͔ͦͷதͷϑΝΠϧ … ↑ͷ Codableʹ߹Θͤͯอ࣋ ͦΕҎ֎ͷݻఆͷϑΝΠϧ … ୯ʹอ࣋ struct Watchface NSFileWrapper Ϛοϐϯά zip/unzip υΩϡϝϯτ ύοέʔδ NSDocument ViewController WindowController App

Slide 53

Slide 53 text

© ZOZO Technologies, Inc. 53 MacΞϓϦ͕͋ΔղੳαΠΫϧ ViewerΛ௨ͯ͠ݟΔ App struct Watchface ɾɾɾɾɾɾ unzip ղੳͨ͠಺༰Λ࣮૷௥Ճ͢Δ ະ஌ͷܗࣜΛղੳ͢Δ Θͨ͠

Slide 54

Slide 54 text

© ZOZO Technologies, Inc. 54 ͜ͷΑ͏ʹͯ͠ ࣸਅจࣈ൫ ͱ ΠϯϑΥάϥϑจࣈ൫ ͷجຊߏ଄Λղੳͨ͠

Slide 55

Slide 55 text

© ZOZO Technologies, Inc. 55 Apple Watchʹ͸ଟ࠼ͳจࣈ൫͕༻ҙ ͞Ε͓ͯΓɺͦͷ΄ͱΜͲ͸ΧελϚΠζͰ͖·͢ 
 — Apple WatchϢʔβΨΠυ https://support.apple.com/ja-jp/guide/watch/apde9218b440/watchos

Slide 56

Slide 56 text

© ZOZO Technologies, Inc. 56 ͋ͱ40छྨ͔ͳ… 
 — ͹Μ͡ΎΜ

Slide 57

Slide 57 text

© ZOZO Technologies, Inc. 57 CodableΛͲ͏࢖͏ͱྑ͔͔ͬͨʁ ࣄྫͱରॲ

Slide 58

Slide 58 text

© ZOZO Technologies, Inc. 58 ʮ;ͭ͏ͷCodableʯ͡Όͳ͍watchface 😈 JSONΩʔ໊(Ξϯεί۠੾ΓɾϋΠϑϯ۠੾Γɾεϖʔε۠੾Γ) 😈 `class`໊Ͱߏ଄෼ذ 😈 ϦιʔεϑΝΠϧࢀর 😈 ͙ۙ͘͢ʹ͋Δ1970λΠϜελϯϓͱ2001λΠϜελϯϓ 😈 JSONʹNSKeyedArchiver 😈 ࣗ༝ܗࣜʹΈ͑Δ͕[String: V]΄Ͳࣗ༝Ͱ΋ͳ͍ࣙॻ

Slide 59

Slide 59 text

© ZOZO Technologies, Inc. 59 JSONΩʔ໊ (Ξϯεί۠੾ΓɾϋΠϑϯ۠੾Γɾεϖʔε۠੾Γ) 😈 watchfaceʹొ৔͢Δ୯ޠ۠੾Γܗࣜ͸͞·͟· "face type": "whistler-analog", "complications": { "slot 1": { "slot1": { "creationDate": 1601048354 "imageProvider": { "bezel": "ΧϨϯμʔ", "top-left": "ఱؾ", "top-right": "৺ഥ਺", "device_size": 2, "complications_bundle_ids": { camelCase Ξϯεί۠੾Γ ϋΠϑϯ۠੾Γ εϖʔε۠੾Γ

Slide 60

Slide 60 text

© ZOZO Technologies, Inc. 60 JSONΩʔ໊ (Ξϯεί۠੾ΓɾϋΠϑϯ۠੾Γɾεϖʔε۠੾Γ) ✅ ݸผʹCodingKeysͰखͰࢦఆ͍ͯ͘͠ͷ͕࣮͔֬ͭ୯७ private enum CodingKeys: String, CodingKey { case version case customization case complications case face_type = "face type" case resource_directory = "resource directory" } "face type": "whistler-analog", "complications": { "slot 1": {

Slide 61

Slide 61 text

© ZOZO Technologies, Inc. 61 `class`໊Ͱߏ଄෼ذ 😈 OpenAPIͰ͍͏ͱ͜ΖͷoneOfΈ͍ͨͳߏ଄͕ͩɼͦͷ෼ذ͸த਎ͷ`class`Ωʔͷ஋ ʹΑͬͯߦͳΘΕΔ API࢓༷Ͱ΋ͨ·ʹݟ͔͚Δ … Έͳ͞Μ͸Ͳ͏ͯ͠·͔͢ʁ "textProvider": { "date": 496285770, "class": "CLKDateTextProvider", "_uppercase": true, "calendarUnits": 528 }, "textProvider": { "class": "CLKSimpleTextProvider", "text": "ϤΨ" }, ೔෇ΛϑΥʔϚοτͯ͠දࣔ จࣈྻͦͷ··දࣔ

Slide 62

Slide 62 text

© ZOZO Technologies, Inc. 62 `class`໊Ͱߏ଄෼ذ enum CLKTextProvider: Codable { case date(CLKDateTextProvider) case time(CLKTimeTextProvider) case compound(CLKCompoundTextProvider) case simple(CLKSimpleTextProvider) case relativeDate(CLKRelativeDateTextProvider) init(from decoder: Decoder) throws { let anyProvider = try CLKTextProviderAny(from: decoder) switch anyProvider.class { case CLKDateTextProvider.class: self = .date(try .init(from: decoder)) case CLKTimeTextProvider.class: self = .time(try .init(from: decoder)) : default: DecodingError.dataCorrupted(…) } } private struct CLKTextProviderAny: Codable { var `class`: String } ✅ ڞ௨ߏ଄ͷ͋ΔoneOf…ͱ͍͏͜ͱͰڞ௨ͷAnyͰ`class`ΛઌಡΈͯ͠෼ذ ະ஌ύλʔϯ͕ग़ͯ΋ػցతʹ(޻෉ͳ͘࡞ۀతʹ)௥ՃͰ͖Δͱخ͍͠ʂ

Slide 63

Slide 63 text

© ZOZO Technologies, Inc. 63 ϦιʔεϑΝΠϧࢀর 😈 plistʹϑΝΠϧ໊͚ͩॻ͔Ε͍࣮ͯͯσʔλ͸plistͷྡʹ͋Δύλʔϯ ෼͔Γ΍͍͢͠ฤू͠΍͍͢ͱ΋͍͑Δͷ͕ͩ…

Slide 64

Slide 64 text

© ZOZO Technologies, Inc. 64 ϦιʔεϑΝΠϧࢀর ✅ ϑΥϧμ֊૚ΛstructͰڬΜͰ͓͘ɻ͜͜Ͱ͸ϑΥϧμ໊͕ResourcesͳͷͰͦͷ··࠾༻ Codableର৅ϑΝΠϧ͸Codableɼ୯ͳΔϦιʔε͸ϑΝΠϧ໊ͱίϯςϯπͷࣙॻͰ࣋ͭ 🤷 Codable͚ͩͰॲཧ͢ΔͱෳࡶʹͳΓͦ͏… extension Watchface { struct Resources { var images: Metadata var files: [String: Data] struct Metadata: Codable { var imageList: [Item] plistͷCodable images.plist [ϑΝΠϧ໊: ίϯςϯπ] mapValues {FileWrapper(regularFileWithContents: $0)} NSFileWrapperʹ
 ܨ͗΍͘͢

Slide 65

Slide 65 text

© ZOZO Technologies, Inc. 65 1970λΠϜελϯϓͱ2001λΠϜελϯϓ 😈 ೋͭͷdateλΠϜελϯϓ͸ى఺͕ҟͳΔ ͓෼͔Γ͍͚ͨͩͨͩΖ͏͔… "complication_sample_templates": { "top": { "creationDate": 1623277757.787668, "textProvider": { "date": 496285770, "class": "CLKDateTextProvider", "_uppercase": true, "calendarUnits": 528 }, "class": "CLKComplicationTemplateUtilitarianSmallFlat", "version": 30000 } }, λΠϜελϯϓ ͜Ε΋λΠϜελϯϓ

Slide 66

Slide 66 text

© ZOZO Technologies, Inc. 66 1970λΠϜελϯϓͱ2001λΠϜελϯϓ 📝 NSDateͷى఺͸ೋछྨ UNIXతͳ1970೥ͷଞʹɼreference dateͱ͍͏2001೥͕͋Δ Core DataͰ͸2001೥ى఺ͷอଘ͕ߦͳΘΕ͍ͯΔͷͰݟ͔͚ͨਓ΋͍Δ͸ͣ CodableσϑΥϧτͰ਺஋ΛNSDateʹ͢Δͱ͖͸2001೥ى఺

Slide 67

Slide 67 text

© ZOZO Technologies, Inc. 67 1970λΠϜελϯϓͱ2001λΠϜελϯϓ ✅ ଞʹܾΊख͕ͳ͍ͱ͖͸CodableσϑΥϧτΛ࠾༻ 1970೥ͷ΄͏͸Doubleͱ͠Codable૚ͷม׵ͳ͠ͱ͢Δ ΑΓ໌ࣔతʹ͚ͨ͠Ε͹ɼ1970೥ͷΠϯλʔϑΣʔε͔࣋ͨ͠ͳ͍ઐ༻ͷܕΛஔ͘ struct CLKComplicationTemplateUtilitarianSmallFlat: Codable { : var creationDate: Double = Date().timeIntervalSince1970 var textProvider: CLKTextProvider = .date(.init()) } struct CLKDateTextProvider: Codable { : var date: Date = .init() : } ͬͪ͜͸1970೥ ͬͪ͜͸2001೥

Slide 68

Slide 68 text

© ZOZO Technologies, Inc. 68 JSONʹNSKeyedArchiver 😈 NSKeyedArchiverͰarchiveͯ͠base64EncodedStringͨ͠΋ͷ͕ೖͬ ͍ͯΔέʔε΋ɻ࠷৽൛Ͱ͸ݮ͕ͬͨUAUserActivity(ະղੳ)͕͋Γͦ͏ɻ "complication_sample_templates": { "top": "YnBsaXN0MDDUAQIDBAUGBwpYJHZlcnNpb25ZJGFyY2hpdmVyVCR0b3BYJG9ia mVj\r\ndHM... bplist00... Base64Ͱσίʔυ ͭ·Γplist

Slide 69

Slide 69 text

© ZOZO Technologies, Inc. 69 JSONʹNSKeyedArchiver ✅ ಉ໊ͷobjcΫϥεΛ࡞ͬͯ NSCodingͰಡΉ ✅ Ϋϥε໊΍Ωʔ໊͸plistΛ ಡΈղ͘ @objc(CLKComplicationTemplate) class CLKComplicationTemplate: NSObject, NSCoding { override init() {super.init()} required init?(coder: NSCoder) {} func encode(with coder: NSCoder) {} } @objc(CLKComplicationTemplateUtilitarianSmallFlat) final class CLKComplicationTemplateUtilitarianSmallFlat: CLKComplicationTemplate { : var textProvider: CLKTextProvider? = .init() : override init() {super.init()} required init?(coder: NSCoder) { : self.textProvider = coder.decodeObject(forKey: "textProvider") as? CLKTextProvider super.init(coder: coder) } override func encode(with coder: NSCoder) { :

Slide 70

Slide 70 text

© ZOZO Technologies, Inc. 70 ࣗ༝ܗࣜʹΈ͑Δ͕[String: V]΄Ͳࣗ༝Ͱ΋ͳ͍ࣙॻ "complications_names": { "slot3": "ఱؾ", "bottom-right": "ΞΫςΟϏςΟ", "slot2": "Ξετϩϊϛʔ", "bezel": "ΧϨϯμʔ", "top-left": "ఱؾ", "top-right": "৺ഥ਺", "bottom-left": "ϛϡʔδοΫ" }, 😈 ίϯϓϦέʔγϣϯͷҐஔʹ͸ݻ༗ͷ໊લ͕෇͍͍ͯΔΑ͏͕ͩɼࣗ༝ͳײ͕͋͡ Δɻจࣈ൫ͷछྨ͕มΘΔͱ৽͍͠Ωʔ΋ݟ͔ͭΔ͔΋ʁ

Slide 71

Slide 71 text

© ZOZO Technologies, Inc. 71 ࣗ༝ܗࣜʹΈ͑Δ͕[String: V]΄Ͳࣗ༝Ͱ΋ͳ͍ࣙॻ 🚫 String enumΛΩʔͱ͢Δࣙॻ͸CodableͰύʔεෆՄ https://bugs.swift.org/browse/SR-7788 ͱͯ͠ط஌ͷ੍໿ struct Metadata: Codable { var complications_names: [Position: String] enum Position: String, Codable { case top, bottom, top_left, top_right case slot1, slot2, slot3 } } try JSONDecoder().decode(Metadata.self, from: "{\"complications_names\": {\"top\": \"τοϓ\"}}".data(using: .utf8)!) 💥 "Expected to decode Array but found a dictionary instead." ࣙॻͷΩʔΛenumʹ͕ͨ͠…?

Slide 72

Slide 72 text

© ZOZO Technologies, Inc. 72 ࣗ༝ܗࣜʹΈ͑Δ͕[String: V]΄Ͳࣗ༝Ͱ΋ͳ͍ࣙॻ ✅ ۪௚ʹɼϝϯόͷܕ͕શ෦ಉ͡structΛ࡞Δ 👍 WatchFaceDumperͰ͸ɼ͞ΒʹGenericsʹ͍ͯ͠Δ struct ComplicationPositionDictionary: Codable struct Metadata: Codable { var complications_names: Position struct Position: Codable { var top: String? var bottom: String? var top_left: String? var top_right: String? var slot1: String? var slot2: String? var slot3: String? } } 💡 CodableͰ্ख͍͔͘ͳ͍ͱ͖͸1ஈ্ ͷ֊૚ΛΈΔͱղܾͰ͖Δ͔΋ ࣙॻͷΩʔͰ͸ͳࣙ͘ॻͦͷ΋ͷ 💡 ͦ΋ͦ΋ࣙॻ͸શϝϯόͷܕ͕ಉ͡Ͱ Optionalʹͳ͍ͬͯΔstructͱྨࣅͷߏ଄

Slide 73

Slide 73 text

© ZOZO Technologies, Inc. 73 .watchface 
 Codable + FileWrapper 
 ϥΠϒϥϦ

Slide 74

Slide 74 text

© ZOZO Technologies, Inc. 74 watchfaceͷCodableϥΠϒϥϦ banjun/WatchFaceDumperͷCodableͱFileWrapperͷ෦෼͸ϥΠϒϥϦʹͨ͠ 🍫 pod "WatchFace" structΛϥΠϒϥϦʹ͢Δͱ͖ɼpublic memberwise init͕ཉ͍͠ ⚗ ͜ͷinit͸ra1028/swift-modͰίʔυੜ੒ σϑΥϧτ஋෇͚͓ͯ͘ͱݺͼଆ͔Βଟগ࢖͍΍͍͢ ΄Μͱ͸structͱ͸ผϑΝΠϧͷ΄͏͕ಡΈ΍͍͔͢΋…

Slide 75

Slide 75 text

© ZOZO Technologies, Inc. 75 ͓ΘΓʹ

Slide 76

Slide 76 text

© ZOZO Technologies, Inc. 76 ͓ΘΓʹ 🥳 ະ஌ϑΝΠϧΛղੳָ͍ͯ͜͠͠ͱΛ͠·͠ΐ͏ 📝 ղੳͨ͜͠ͱΛ࣮૷ͱͯ͠ه࿥͓ͯ͘͠ͷʹCodable͕΂ΜΓ Ͱ͢ɻςΫ͸ࢥΘ͵ͱ͜ΖͰ໾ʹཱ͔ͭ΋ʁ ⌚ ʰApple Watchͷจࣈ൫ϑΝΠϧʱ͕ͲΜͳܗ͔ࣜ஌͍ͬͯ ΔϨΞͳਓʹͳΕ·ͨ͠Ͷʂ 🌈 banjun/WatchFaceDumper͕ະղੳͷจࣈ൫λΠϓ͕ͨ͘͞ Μ͋Γ·͢ɻղੳ݁ՌΛఏڙͯ͘͠ΕͨΒ͏Ε͍͠Ͱ͢ʂ ശೣϚοΫε͘Μ / ZOZO

Slide 77

Slide 77 text

77