Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
快適なUIを持つアプリを作るために できること
Search
Muukii
May 15, 2018
Programming
12
2.7k
快適なUIを持つアプリを作るために できること
Muukii
May 15, 2018
Tweet
Share
More Decks by Muukii
See All by Muukii
Problem Solving from the Abstraction Layer
muukii0803
1
38
Pairs iOSとトレンドの技術
muukii0803
0
990
Thoughts about build flow
muukii0803
2
330
スマホアプリ開発で大切なこと
muukii0803
3
170
エンジニアとして働くために
muukii0803
0
200
Q. Textureは部分的に導入できますか?
muukii0803
3
2.5k
安定したチャットを実現するための アプリとAPI設計
muukii0803
17
8.3k
iOS エンジニアが考える Webアプリ開発
muukii0803
3
510
AutoLayout以外の選択肢
muukii0803
13
5.4k
Other Decks in Programming
See All in Programming
大規模Cloud Native環境におけるFalcoの運用
owlinux1000
0
230
Go コードベースの構成と AI コンテキスト定義
andpad
0
150
新卒エンジニアのプルリクエスト with AI駆動
fukunaga2025
0
240
はじめてのカスタムエージェント【GitHub Copilot Agent Mode編】
satoshi256kbyte
0
130
Rubyで鍛える仕組み化プロヂュース力
muryoimpl
0
250
AI前提で考えるiOSアプリのモダナイズ設計
yuukiw00w
0
210
Findy AI+の開発、運用におけるMCP活用事例
starfish719
0
1.9k
TestingOsaka6_Ozono
o3
0
230
Spinner 軸ズレ現象を調べたらレンダリング深淵に飲まれた #レバテックMeetup
bengo4com
1
210
從冷知識到漏洞,你不懂的 Web,駭客懂 - Huli @ WebConf Taiwan 2025
aszx87410
2
3.2k
안드로이드 9년차 개발자, 프론트엔드 주니어로 커리어 리셋하기
maryang
1
150
ThorVG Viewer In VS Code
nors
0
460
Featured
See All Featured
The Art of Programming - Codeland 2020
erikaheidi
56
14k
The Limits of Empathy - UXLibs8
cassininazir
1
200
Between Models and Reality
mayunak
0
150
How to Get Subject Matter Experts Bought In and Actively Contributing to SEO & PR Initiatives.
livdayseo
0
36
Tell your own story through comics
letsgokoyo
0
770
Abbi's Birthday
coloredviolet
0
4k
We Analyzed 250 Million AI Search Results: Here's What I Found
joshbly
0
350
Optimizing for Happiness
mojombo
379
70k
The #1 spot is gone: here's how to win anyway
tamaranovitovic
1
880
Groundhog Day: Seeking Process in Gaming for Health
codingconduct
0
67
How To Stay Up To Date on Web Technology
chriscoyier
791
250k
Information Architects: The Missing Link in Design Systems
soysaucechin
0
720
Transcript
շదͳUIΛ࣋ͭΞϓϦΛ࡞ΔͨΊʹ Ͱ͖Δ͜ͱ Muukii Pairs Global Team eureka, Inc.
About Me • Muukii <Hiroshi Kimura> • iOS Engineer at
eureka, Inc. • Pairs Global Team • GitHub : @muukii • https://muukii.me ☕ ⌚
None
1BJSTʹ͍ͭͯ !4
4PVUI,PSFB Japan Taiwan No.1 2017 release No.1 !5 1BJSTʹ͍ͭͯ ల։ࠃ
̐ͭͷϓϥοτϑΥʔϜ CONFIDENTIAL INFORMATION: Not for Public Distribution - Do Not Copy
None
Agenda • Pairs Global iOS νʔϜɾϓϩδΣΫτͱͯ͠ • շదͳUIΛ࣋ͭΞϓϦΛ࡞ΔͨΊʹ͍ͬͯΔ͜ͱ • ߈Ί
- Improve • ߴʹಈ࡞͢ΔUI ɾ ҆ఆͨ͠UI • कΓ - Maintain • ߈ΊʹΑ࣮ͬͯݱͨ͠UIͷ࣭Λܧଓͤ͞Δ
Improve
ࢦ͖࣭͢ • Ϣʔβʔʹͱͬͯͷී௨Facebook, InstagramϨϕϧͷಈ࡞ • ൴ΒΞϓϦͱ͍͏Ϟϊͱͯ͠ͷࠜຊతͳج४Λ࡞Γ্͍͛ͯΔ • εϜʔζͳ͍৺ • εΫϩʔϧ࣌ɾը໘ભҠ࣌ͷύϑΥʔϚϯε
• ঢ়ଶɾใΛ҆ఆతʹਖ਼͘͠දࣔ
UI࣮ͷΞϓϩʔν • InterfaceBuilderҰ༻ͤͣίʔυϨΠΞτ • AutoLayoutEasyPeasyͱ͍͏ϥΠϒϥϦΛ༻த • UIͷಈ࡞ύϑΥʔϚϯεʹ͓͚ΔϘτϧωοΫAutoLayoutؔ࿈Ͱൃੜ͢Δ͜ͱ͋Δ • TextureGroup/TextureΛ༻ (Pinterest͕։ൃ͠ɺ൴ΒͷϓϩμΫτͰશ໘తʹ༻͍ͯ͠Δ)
• పఈతʹඇಉظॲཧԽ͠ɺUI͕ඇৗʹߴʹͳΔେ͖ͳϥΠϒϥϦ • AutoLayoutͱͦͷସखஈʹ͍ͭͯൃදࢿྉ͕͋ΔͷͰΑ͚Ε͝ཡ͍ͩ͘͞ https://speakerdeck.com/muukii0803/autolayoutyi-wai-falsexuan-ze-zhi
ঢ়ଶΛਖ਼͘͠දࣔ͢Δ • UIͷಈ࡞ॏཁ͕ͩɺݱࡏͷঢ়ଶΛਖ਼͘͠දࣔ͢Δ͜ͱॏཁ • 1ճͰҰॠͰؒҧͬͨঢ়ଶΛදࣔ͢ΕϢʔβʔࠞཚ͢Δ • Fluxͷ֓೦Λར༻͢Δ͜ͱͰෳࡶͳঢ়ଶΛ͑ͯViewʹදࣔ͢Δ͜ͱ͕Ͱ͖Δ • ͦΕͱಉ࣌ʹϝϯςφϯεੑͷ্ظͰ͖Δ
࣮ࡍͷΞϓϦͷಈ͖ • on iPhone7 • ࣸਅදࣔͤͣɺϓϩϑΟʔϧใμϛʔʹࠩ͠ସ͍͑ͯ·͢ɻ • ΄ͱΜͲͷಈ࡞ʹ͓͍ͯ60fpsʹ͍ۙΒ͔͕࣮͞ݱͰ͖͍ͯΔɻ
Maintain
UIͷෆ۩߹ͱݺΔͷ • ظ௨Γಈ͍͍ͯͳ͍ (͜Εવ) • ॲཧʹ͕͔͔࣌ؒΓUI͕ݻ·ͬͯ͠·͏ • UI͕ॠ࣌ʹԿ͔ΓସΘͬͯ͠·͏Α͏ͳνϥπΩ • σβΠϯ่Ε
• ࢹೝੑɾใઃܭΛߟ͑ͯͷσβΠϯͰ͋ΔͨΊɺ่Ε͍ͯΕUIͱͯ͠ຊདྷͷػೳΛఏڙͰ͖ͯ ͍ͳ͍ͱݴ͑Δ • ը૾ͷΞεϖΫτൺ͕ؒҧ͍ͬͯΔ • Not ϐΫηϧύʔϑΣΫτ • ΞΠίϯͷҰ෦͕͚ܽͯදࣔ͞Ε͍ͯΔ
ෆ۩߹Λى͜͞ͳ͍ͨΊʹ • ෆ۩߹ώϡʔϚϯΤϥʔʹΑͬͯى͜Δ͜ͱ͋Δ • ͦͷதʹʮಈ࡞֬ೝ͕໘ʯʹΑΔͷؚ·Εͯ͘Δ • ʮಈ࡞֬ೝͷͨΊʹ४උ͢Δ͜ͱ͕ଟ͍ɻʯͱ͔ • ؆୯ʹಈ࡞֬ೝΛߦ͑ΔΑ͏ʹ͢Δ͜ͱͰෆ۩߹ΛݮΒͤΔ •
खؒͷഉআ • QAͷਓḿΔ
։ൃऀϝχϡʔ ΞϓϦαΠυ • ΞϓϦىಈ࣌ʹΞϓϦͷಈ࡞ํ๏ڥΛબ͢Δը໘Λදࣔ
None
ଓ͢ΔαʔόʔΛબ • ຊ൪αʔόʔ ؖࠃɾ • ։ൃ༻αʔόʔ ؖࠃɾ • ϩʔΧϧ (localhost:8000ͳͲ)
• ϚϧνϩάΠϯՄೳͳΞϓϦઃܭʹ͍ͯ͠ΔͨΊɺෳϢʔβʔͷϩ άΠϯঢ়ଶΛอ࣋Մೳ & ϥϯλΠϜͰΓସ͑Մೳ • ڥมߋͷͨͼʹϏϧυ͢͠ඞཁͳ͠
ը໘αΠζͷมߋ • Application.windowͷαΠζΛڧҾʹมߋ͢Δػೳ • શ࠶ݱͰ͖ͳ͍͕ɺ5.5inchͷσόΠεΛ༻͠ͳ͕Β4inch ͷը໘ͰUIΛ֬ೝ͢Δ͜ͱ͕Ͱ͖Δ • খ͍͞ը໘Ͱจࣈ͕Ε͍ͯͨΓɺ σβΠϯ͕ཚΕ͍ͯΔ͜ͱʹؾ͚ͮΔ
Ϗϧυʹؔ͢Δใ • ͕֬ೝ͞Εͨ߹ʹใࠂΛߦ͍͘͢͢ΔͨΊ • Ϗϧυ࣌ʹJSONΛ࡞ΓɺΞϓϦʹόϯυϧ͢Δख๏Λͱ͍ͬͯΔ Script: https://gist.github.com/muukii/cc655b0cf0d7986421725a5493c7f3d8
։ൃऀϝχϡʔ ϏδωεϩδοΫαΠυ
• ΞϓϦΛར༻͠ͳ͕ΒαʔόʔͷϏδωεϩδοΫΛݺͼग़͢ (։ൃڥͷΈ) • ϢʔβʔΛԡ͠ -> Ϣʔβʔ(૬ख)ʹؔ͢ΔϝχϡʔΛදࣔ • ࣗʹʮ͍͍ͶʂʯΛૹ৴ •
ࣗʹϝοηʔδΛૹ৴ • σόΠεΛγΣΠΫ -> Ϣʔβʔ(ࣗ)ʹؔ͢ΔϝχϡʔΛදࣔ • ձһঢ়ଶͷมߋ (ແྉɾ༗ྉ) • ͦͷଞ ঢ়ଶมߋ ։ൃऀϝχϡʔ ϏδωεϩδοΫαΠυ
GitHub PRʹ.appΛΞοϓϩʔυ • GitHubʹPR͕࡞͞ΕΔͱCI͕γϛϡϨʔλ༻ͷappΛϏϧυ • PRʹappϑΝΠϧͷμϯϩʔυϦϯΫ͕షΓ͚ΒΕΔ • μϯϩʔυͨ͠appϑΝΠϧγϛϡϨʔλʹυϥοά&υϩοϓͰΠϯετʔϧՄೳ • ίʔυϨϏϡʔͰΘ͔Βͳ͍࣮ࡍͷಈ࡞ݟͨΛ֬ೝ͢Δ·Ͱͷૢ࡞͕ॖͰ͖Δ
• γϛϡϨʔλෳىಈՄೳʹͳ͍ͬͯΔͷͰσόΠε͝ͱͷ֬ೝ؆୯ʹ • ؔ࿈هࣄ : https://bit.ly/2IhHOgl • CIϏϧυΛ͘ߦ͍͍ͨͷͰࣾͷmac proͰಈ͔͍ͯ͠Δ • JenkinsͰΑ͔͚ͬͨͲɺڵຯຊҐͰ࡞ͬͨSwiftͷCIΛ༻த… • https://github.com/eure/tower • (Jenkins, Travis, Bitrise, CircleCIͱ͔Ͱ͍͍ͱࢥ͏)
GitHub PRʹ.appΛΞοϓϩʔυ appϑΝΠϧͷμϯϩʔυϦϯΫ
γϛϡϨʔλ༻appϑΝΠϧΛ࡞Δ lane :simulator_build do base_path = `xcodebuild -workspace ../pairs-global.xcworkspace -scheme
Pairs - arch x86_64 -sdk iphonesimulator -configuration Debug -showBuildSettings | grep - m 1 "CONFIGURATION_BUILD_DIR" | grep -oEi "\/.*"`.chomp() result = xcbuild( workspace: 'pairs-global.xcworkspace', scheme: 'Pairs', xcargs: '-arch x86_64 -sdk iphonesimulator -configuration Debug' ) File.join(base_path, "Pairs.app") end FastlaneΛͬͨྫ ϏϧυΛߦ͍ɺ.appͷύε͕ฦ٫͞ΕΔlane
GitHubͷPRΛ୳͢Query query FindPullRequest( $owner: String!, $name: String!, $branch: String!) {
repository(owner:$owner, name:$name) { pullRequests(first: 1, headRefName:$branch) { nodes { id, number }, totalCount, } } } { "owner" : "eure", "name" : "pairs-gl-ios", "branch" : "#{branch_name}" } GitHub API v4 GraphQL
ൃੜ͍ͯ͠Δෆ۩߹ʹؾͮͨ͘Ίʹ • ΞϓϦΛϦϦʔε͢Δ·Ͱʹग़དྷΔ͜ͱͨ͘͞Μ͋Δ͕ɺͦΕͰෆ۩߹ΛؚΜͩ··ϦϦʔε ͞Εͯ͠·͏͜ͱ͋Δ • ϦϦʔεޙɺϢʔβʔͷखݩͰൃੜ͍ͯ͠ΔʹϢʔβʔ͔Βͷ͓͍߹ΘͤͰͳ͘ɺͪ͜Β ͔ΒݕͰ͖ΔΑ͏ʹ͓͕ͯ͘͠ॏཁ
CrashlyticsʹNon-Fatal-Errorͱͯ͠ΫϥογϡܥҎ֎ͷΤ ϥʔΛૹ৴͢Δ func log(error: Error) { Crashlytics.sharedInstance().recordError(error, withAdditionalUserInfo: nil) }
CrashlyticsʹNon-Fatal-Errorͱͯ͠ΠϕϯτΛૹ৴͢Δίʔυྫ CrashlyticsࣗಈͰΫϥογϡϩάΛૹ৴͢ΔSDK͕ͩɺ։ൃऀ͕ࢦఆͨ͠ΠϕϯτΛΫϦςΟΧϧ Ͱͳ͍͕ͷ͋ΔΤϥʔ(Non-Fatal-Error)ͱͯ͠ૹ৴͢Δػೳ͍࣋ͬͯΔ
՝ۚ͠ͳ͚Εϝοηʔδͷ ༰ݟΕͳ͍ɻ ϝοηʔδΛ։෧ϘλϯΛԡ ͢͜ͱ͕Ͱ͖Δ ։෧ϘλϯΛԡ͢ͱɺ՝ۚը ໘͕දࣔ͞ΕΔ(Ϟʔμϧ) ՝ۚͯ͠՝ۚը໘Λด͡Δͱ ϝοηʔδ͕දࣔ͞ΕΔ (σʔλͷ࠶ಡΈࠐΈ) ঢ়ଶ
: ແྉձһ ঢ়ଶ : ༗ྉձһ
ԡͤͳ͍ͣͷϘλϯ͕ԡ͞Εͨ͜ͱΛݕ͢Δ let error = ..."ϝοηʔδ։෧Ͱ͖͍ͯΔ͔ͣͩΒ Ϙλϯԡͤͳ͍ͣ" log(error: error) ϘλϯΛλοϓ͞ΕͨλΠϛϯάͰঢ়ଶΛ֬ೝͯ͠ΤϥʔΛૹ৴͓ͯ͘͠ ྫ͑ɺʮ༗ྉձһͷϢʔβʔ͕։෧ϘλϯΛԡͯ͠͠·ͬͨʯ
͔͠͠ɺຊདྷϝοηʔδͷ༰͕දࣔ͞Ε͍ͯΔͣͳͷͰɺϘλϯԡͤͳ͍ͣɻ ErrorΦϒδΣΫτCustomNSError ͱ, LocalizedErrorΛ࣮͢Δͱྑ͍
None
ϢʔβʔͷखݩͰൃੜ͍ͯ͠Δྫ֎ʹؾ͚ͮΔΑ͏ʹ ͳΔ • UIςετΛॻ͘ͷΞϦ͕ͩɺͦΕͰϢʔβʔͷखݩͰԿ͕ى͖Δ͔Θ͔Βͳ͍ͷ͕ΞϓϦ։ ൃͷޣຯ • UIςετͰݕͰ͖ͳ͍ͷ͋Δ • γφϦΦΛࣗͨͪͰ࡞͍ͬͯΔ͔Β •
ϥϯλΠϜͰϢʔβʔ͕ߦͳͬͨಈ࡞͕༷͔Β֎Ε͍ͯͳ͍͔ΛνΣοΫ͢ΔΑ͏ʹ͓ͯ͘͠ͱ ྑ͍ • ݕॲཧ͕େ͖ͳෛՙʹͳΒͳ͍Α͏ʹؾΛ͚ͭΔ
ϢʔβʔͷखݩͰൃੜ͍ͯ͠Δྫ֎ʹؾ͚ͮΔΑ͏ʹ ͳΔ • ҆ఆͨ͠UIΛ࣮ݱ͢ΔͨΊʹFluxͳͲͷ࣮ઃܭͰՄೳ • ͔͠͠ɺͦΕͰෆ۩߹ൃੜ͢Δ • ϦϞʔτͰྫ֎ΛϩΪϯά͢Δ͜ͱͰؾ͚ͮΔ • ಈ࡞ݕূ͕࿙Εͯෆ۩߹ݕ·Ͱͷ͕࣌ؒ͘Ͱ͖Δ
• ෆ۩߹͕ൃੜ͢Δͷํͷͳ͍͜ͱɻͦͷΘΓૣ͘ؾ͖ͮɺਝʹमਖ਼Ͱ͖Δମ੍Λ࡞ͬ ͓ͯ͘ɻ
ෆ۩߹Λత֬ʹमਖ਼͢ΔͨΊʹ • ྫ֎ΠϕϯτΛCrashlyticsʹૹ৴͢Δ͜ͱʹΑΓɺ͕ൃੜ͍ͯ͠Δ͜ͱʹؾ͚ͮΔΑ͏ʹ ͳͬͨ • ͦͷ࣍ؾ͍ͨΛత֬ʹमਖ਼͢ΔͨΊʹɺͳ͕ͥൃੜ͍ͯ͠Δͷ͔ɺͲͷΑ͏ʹͯ͠ ͕ى͖ͨͷ͔ΛΔඞཁ͕͋Δ
CrashlyticsʹϩάΛૹ৴͓ͯ͘͠ • Crashlyticsʹίϯιʔϧϩάʹදࣔ͢ΔΑ͏ͳϩάΛૹ৴͢Δػೳ͕͋ΓɺCrashΠϕϯτ Non-Fatal-ErrorΠϕϯτͱඥ͚ͮͯ͘ΕΔ func log(string: String) { CLSLogv("%@", getVaList([string]))
} CrashlyticsʹϩάΛૹ৴͢Δίʔυྫ
None
ϩάͱͯ͠ૹ৴͍ͯ͠Δ༰ • શͯͷը໘ભҠΛࣗಈͰϩΪϯά • ViewControllerͷϥΠϑαΠΫϧΛτϥοΩϯά • https://github.com/muukii/ApplicationMonitor • Fluxϕʔεͷ࣮ͳͷͰݺͼग़͞ΕͨΞΫγϣϯΛࣗಈͰϩΪϯά •
ͦͷଞ ࣮ߦ͞ΕͨॲཧͷதͰॏཁͳͷ͕͋ΕadhocͰϩάΛࠐΉ
ෆ۩߹ൃੜʹࢸΔ·Ͱͷߦಈ͕ಡΊΔΑ͏ʹͳΔ • Ϣʔβʔ͕ߦͳͬͨૢ࡞Λϩάͱͯ͢͜͠ͱ͕Ͱ͖Εɺ ։ൃऀͷखݩͰ࠶ݱͰ͖ɺૉૣ͘मਖ਼Ͱ͖ΔΑ͏ʹͳΔՄೳੑ͕ߴ·Δ • ࠶ݱ͕͔ͬͨ͠Γใ͕Γͳ͚Εɺ৽͘͠ϩάΛऔΕΔΑ͏ʹमਖ਼͠ɺ͙͢ʹϦϦʔεΛߦ ͏ • ख͕͔Γ͕ͳ͍ෆ۩߹΄Ͳਏ͍ͷͳ͍
Thank you