UIͷϒϥοΫϘοΫεΛ୳ΔiOSDC23 day1 Track B noppe1
View Slide
noppe @noppefoxwolf• DeNA Co., Ltd.• Pococha• Indie app• vear• Editormode• Nigh;ox DAWN for mastodon2
ϓϨϏϡʔ@DeNAϒʔε3
ࠓ͢͜ͱ4
UIͷϒϥοΫϘοΫεͱ5
UIͷϒϥοΫϘοΫε = ҉ͷ༷6
ΧελϜUIͷඞཁੑ• ಛఆͷૢ࡞Λ࠷దԽ͍ͨ͠• ΧϨϯμʔɾը૾ϏϡʔΞ• ΞϓϦͷΞΠσϯςΟςΟΛߏங͍ͨ͠• طଘͷUIͷϦσβΠϯ7
ΧελϜUIͷ࣭• AppleͷUIͱൺΔͱѱ͘ͳΓ͕ͪ• όϥϯε͕ѱ͍• ৮Γ৺͕ѱ͍• ͍ʹ͍͘• ...etc8
ΧελϜφϏήʔγϣϯόʔͷྫ9
10
Bad UI͕ग़དྷͯ͠·͏ཧ༝• γεςϜͷ͓࡞๏Λແࢹͯ͠͠·͏͔Β• ΧελϜUIγεςϜUIͷ্Ͱ࡞Δ͖ʢԫʣ• ͓࡞๏Λແࢹͯ͠UIΛ࡞Δʢ੨ʣͱɺҧײ͕ൃੜ11
͓࡞๏ΛΔʹ12
͓࡞๏ΛΔʹ1• Human Interface Guidelines• جຊతͳ͓࡞๏͜Ε• ϑΥϯταΠζɾϘλϯαΠζͳͲͷϕετϓϥΫςΟε• UIKit, Swi8UI͜Εʹ४ڌ͍ͯ͠Δ13
͓࡞๏ΛΔʹ2• γεςϜίϯϙʔωϯτΛੳ͢Δ• HIGʹॻ͔Ε͍ͯͳ͍͓࡞๏• ࣭ͷཧ• γεςϜίϯϙʔωϯτ• AppleͷΞϓϦ• UIKitSwi/UIͷUIίϯϙʔωϯτ14
UIΛੳ͢Δ15
UIΛੳ͢Δ؍• ϏδϡΞϧ!• ΠϯλϥΫγϣϯ"16
ϏδϡΞϧ17
ϏδϡΞϧ• αΠζɾ৭ɾܗͳͲʹݟ͑Δͷ• HIGʹॻ͔Ε͍ͯΔͷ͋Δ18
ϏδϡΞϧͷద༻ྫ19
αΠζ• ΞΠίϯɾ༨നɾจࣈαΠζɾؙ֯• εΫγϣΛࡱӨ͠ଌΔ• SketchPhotoshopͳͲͷRulerػೳ• จࣈαΠζͷ߹ɺεΫγϣΛಁ໌ʹͯ͠ॏͶͯൺֱ• ๏ଇੑΛݟ͚ͭΒΕΔͱGood20
αΠζͱΞΫηγϏϦςΟ• ΞΫηγϏϦςΟʮ֦େදࣔʯઃఆʹΑͬͯɺαΠζ͕มԽ͢ΔͷͰҙ• Dynamic Type࠷େ࠷খ͕ܾ·͍ͬͯΔ߹͋Δ21
Χϥʔ• ಛఆͷҙຯΛ࣋ͭΧϥʔʹ• ΧϥʔϐοΧʔΛར༻͢Δ• Digital Color Meter, Sip, ColorSlurp• ΧϥʔεϖʔεΛ߹Θ͓ͤͯ͘22
Χϥʔͷྫ• ϔϧεέΞͰΘΕ͍ͯΔ৭Λ͏ࣄͰɺHealthKitͱ࿈ܞ͢ΔϘλϯͰ͋Δ͜ͱΛೝࣝ͘͢͠ͳΔ• Ϣʔβʔʹ৭ͰҙຯΛ͑Δ• ਤͷւͷ੨৭• εΠονͷ৭23
μʔΫϞʔυͱΧϥʔ• ݅ʹΑͬͯ৭͕มΘΔ͜ͱ͕͋Δ• μʔΫϞʔυ• ৭స• Smart invert• ΞΫηϯτΧϥʔͷઃఆ24
୯৭Ͱͳ͍έʔε୯৭Ͱແ͍߹৭ΛऔΓग़ͤͳ͍ͷͰҙΊʹ৭ΛऔΓग़ͯ͠ɺϜϥ͕ͳ͍͔͔֬ΊΔͷྑ͍Ͱ͠ΐ͏• ϒϥʔ, άϥσʔγϣϯ, ಁա25
Ξχϝʔγϣϯ• dura&on, curve, &ming• iOS Simulator• Slow Anima&ons• εΫϦʔϯϨίʔυΛίϚૹΓͯ֬͠ೝ• QuickTime Player, iina26
ߴͳϏδϡΞϧͷੳ27
View Hierachy Debugger• αΠζΛ֬ೝͰ͖Δ• Xcode• h(ps://lookin.work• OSS• ίϯιʔϧػೳ͕༏ल• h(ps://revealapp.com• Paid App• UIViewͷߏݟΕΔ28
Apple Map UI-ComponentClone Challenge• AppleͷMapΞϓϦΛ࠶ݱͯ͠ΈΔ• ӈ্ͷϘλϯͷͱ͜Ζ• RevealΛͬͯɺUIΛੳ͢Δ29
RevealͷΈ• ΞϓϦͷதͰಈ࡞͢ΔαʔόʔΛ্ཱͪ͛ͯɺmacͷΞϓϦͱ௨৴͢Δ• ΞϓϦʹRevealServer.frameworkΛΈࠐΉඞཁ͕͋Δ• Lookinಉ༷ͷ༷• ࣗલͷΞϓϦͰ͔͠ಈ࡞Ͱ͖ͳ͍30
Reveal runs anywhere• ΞϓϦىಈதʹ֎͔ΒRevealServerΛload͢Δ• fridaΛ͏ͱ؆୯31
Fridah"ps://frida.re• ൚༻తͳϦαʔνπʔϧ• εΫϦϓτͷΠϯδΣΫτ• ϝιουίʔϧͷࢹ• rootʹΠϯετʔϧՄೳ• iPhoneͷroot͕ඞཁ32
Frida scriptloader.jslet loaderPath = "~/RevealServer.framework/RevealServer"Module.load(loaderPath)33
Load framework using Frida# 1. frida-psͰUSBͰଓͨ͠iPhone͔ΒϓϩηεIDΛ୳͢$ frida-ps --usb | grep Map2537 Maps# 2. fridaͰPIDʹରͯ͠εΫϦϓτΛ࣮ߦ͢Δ$ frida --usb --load loader.js --attach-pid 253734
35
36
37
38
39
Ϋϥε໊͔ΒϔομʔΛ୳͢• ktool, DyldExtractor• h1ps://github.com/0cyn/sdk-builder• APIઃܭΛֶͿ• FridaLLDBͰϝιουΛ࣮ߦ࣮ͯ͠ݧ͢Δ40
UIΛੳ͢Δ؍• ϏδϡΞϧ!• ΠϯλϥΫγϣϯ"41
ΠϯλϥΫγϣϯ42
ΠϯλϥΫγϣϯͰେࣄͳ͜ͱͨΓલͷૢ࡞Λ͔ͬ͠Γఏڙ͢Δ• ࣗʹͱͬͯͷͨΓલͰͳ͘ɺϢʔβʔʹͱͬͯͷͨΓલΛ࣮͢Δ• δΣενϟʔʹΑΔೖྗ• ΩʔϘʔυϙΠϯλʔσόΠεʹΑΔೖྗ• ϑΟʔυόοΫ43
δΣενϟʔ• Ϗϡʔ͕ͲΜͳδΣενϟʔʹରԠ͍ͯ͠Δ͔֬ೝ͢Δ• ෳͷδΣενϟʔΛಉ࣌ʹ͏͜ͱ͋Δ• ઌೖ؍Λࣺͯͯ৮ͬͯΈΔ• ݟಀ͕ͪ͠ͳͷΛ͍͔ͭ͘հ44
Case1. ิॿδΣενϟʔ• λοϓͰOn,OffͷΓସ͑• ύϯͰิॿతʹΓସ͕͑Ͱ͖Δ45
Case2. ෆՄࢹτϦΨʔ• ͋ΔఔݟͨͰ͍ํ͕͔Δͷ͕΄ͱΜͲ• ͔͠͠ɺෆՄࢹͷτϦΨʔ͋Δ• γΣΠΫɺϚϧνλοϓɺ3DλονͳͲ46
Case3. ᮢ• ࣮ࡍͷݟͨΑΓζϨͨҐஔʹఆ͕͋Δ߹͋Δ47
֎෦σόΠε͔Βͷೖྗ• ϋʔυΣΞΩʔϘʔυ• γϣʔτΧοτʹରԠ͍ͯ͠Δ͔• ϙΠϯλʔσόΠε• ϙΠϯλ͕ϗόʔͨ࣌͠ͷڍಈ48
ϑΟʔυόοΫ• ϏδϡΞϧϑΟʔυόοΫ• αϯυ• ϋϓςΟΫε• ϘΠεΦʔόʔ49
αϯυ• ૹ৴Իɺ௨ԻɺΫϦοΫԻͳͲ• Իͷ͞ɺԻͷେ͖͕͞ࢀߟʹͳΔ• ipaΛղౚͯ͠ɺaifϑΝΠϧΛऔΓग़͢50
ϋϓςΟΫε• ίϯςΩετϝχϡʔɺPull to Refresh• ͚ͯͳ͍ͱ͜ΖΛҙࣝ͢Δ• λϒͷҠಈͳͲ51
ϘΠεΦʔόʔ• ઃఆ → ΞΫηγϏϦςΟ → ϘΠεΦʔόʔ• ϘΠεΦʔόʔ͕ಡΈ্͛ΔจষΛ֬ೝ͢Δ• HIGࢀর22 h$ps://developer.apple.com/jp/design/human-interface-guidelines/accessibility#VoiceOver52
ΧελϜUIΛ࡞Δ্Ͱͷώϯτ53
UIͷղऍҰக͢ΔͱݶΒͳ͍• ࢀߟʹͨ͠UI৭ʹઃܭࢥ͕͋Δ• ໌֬ͳҙਤͷ্Ͱ࣮͞Ε͍ͯΔ• ҆қʹਅࣅͯ͠ɺຊདྷͷࢥͱҟͳΔ͍ํʹͳΔ͜ͱ͋Δ• ΞϓϦ௨ʹAirPodsͷΑ͏ͳHUDΛ͏ͱɺϢʔβʔצҧ͍͠ͳ͍͔ʁ54
࣮ʹ࠷దͳUIAPIΛબͿ• UIKitʹطʹ͋ΔͷΛ࠶࣮͠ͳ͍• εΫϩʔϧͷ׳ੑΛ࣮͠ͳ͍ɻUIScrollViewΛ͏• ϘλϯͰྑ͍ͳΒTapGestureͰ࣮͠ͳ͍55
σβΠϯͷैίετ• OSͷΞοϓσʔτʹΑͬͯσβΠϯ͕มΘΔ• ͔࣮ͤͬͨ͘͠UI͕ݹष͘ݟ͑Δ͜ͱ• σβΠϯͷैίετ͕ൃੜ͢Δ56
Φϑʹग़དྷΔ͜ͱΕͣʹ• ΞΫηγϏϦςΟͰແޮʹग़དྷΔ͜ͱ• Shake to Undo• Reduce Mo1on• ࣗલͰ࣮ͨ͠ΒɺΓସ͑ߟྀ͢Δ͜ͱ57
ݱ࣮తʹग़དྷͳ͍͜ͱ͋Δ• ΧελϜUI࣭͕མͪΔ͜ͱΛલఏʹ• τϨʔυΦϑΛҙࣝͯ͠ɺແବʹΧελϜUI࡞Βͳ͍ͷ͕ίπ• Ұճݟͨͷྑ͍ͷΛ࡞͔ͬͯΒͤͳ͍• ΞϓϦͷίΞόϦϡʔʹߜ࣮ͬͯͯ͠Έͯ58
See also• h#ps://github.com/scenee/Floa6ngPanel• h#ps://github.com/iDevelopper/PBPopupController• h#ps://github.com/omaralbeik/Drops• h#ps://github.com/SvenTiigi/WhatsNewKit• h#ps://github.com/usagimaru/Floa6ngSwitch• h#ps://github.com/noppefoxwolf/ColorPicker59
͓ΘΓ60