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.6k
快適なUIを持つアプリを作るために できること
Muukii
May 15, 2018
Tweet
Share
More Decks by Muukii
See All by Muukii
Pairs iOSとトレンドの技術
muukii0803
0
890
Thoughts about build flow
muukii0803
2
280
スマホアプリ開発で大切なこと
muukii0803
3
140
エンジニアとして働くために
muukii0803
0
160
Q. Textureは部分的に導入できますか?
muukii0803
3
2.3k
安定したチャットを実現するための アプリとAPI設計
muukii0803
17
7.8k
iOS エンジニアが考える Webアプリ開発
muukii0803
3
460
AutoLayout以外の選択肢
muukii0803
13
5.2k
Decodable - Pairs Taiwan
muukii0803
1
910
Other Decks in Programming
See All in Programming
動作確認やテストで漏れがちな観点3選
starfish719
6
1k
JavaScriptツール群「UnJS」を5分で一気に駆け巡る!
k1tikurisu
10
1.8k
2,500万ユーザーを支えるSREチームの6年間のスクラムのカイゼン
honmarkhunt
6
5.1k
社内フレームワークとその依存性解決 / in-house framework and its dependency management
vvakame
1
550
“あなた” の開発を支援する AI エージェント Bedrock Engineer / introducing-bedrock-engineer
gawa
11
1.8k
Grafana Loki によるサーバログのコスト削減
mot_techtalk
1
110
WebDriver BiDiとは何なのか
yotahada3
1
140
昭和の職場からアジャイルの世界へ
kumagoro95
1
350
2024年のWebフロントエンドのふりかえりと2025年
sakito
1
230
SwiftUIで単方向アーキテクチャを導入して得られた成果
takuyaosawa
0
260
第3回 Snowflake 中部ユーザ会- dbt × Snowflake ハンズオン
hoto17296
4
360
AIの力でお手軽Chrome拡張機能作り
taiseiue
0
170
Featured
See All Featured
個人開発の失敗を避けるイケてる考え方 / tips for indie hackers
panda_program
99
18k
Build your cross-platform service in a week with App Engine
jlugia
229
18k
A Modern Web Designer's Workflow
chriscoyier
693
190k
The Myth of the Modular Monolith - Day 2 Keynote - Rails World 2024
eileencodes
20
2.4k
ReactJS: Keep Simple. Everything can be a component!
pedronauck
666
120k
For a Future-Friendly Web
brad_frost
176
9.5k
Building Flexible Design Systems
yeseniaperezcruz
328
38k
[RailsConf 2023 Opening Keynote] The Magic of Rails
eileencodes
28
9.3k
Exploring the Power of Turbo Streams & Action Cable | RailsConf2023
kevinliebholz
29
4.6k
Docker and Python
trallard
44
3.3k
Design and Strategy: How to Deal with People Who Don’t "Get" Design
morganepeng
129
19k
Improving Core Web Vitals using Speculation Rules API
sergeychernyshev
8
270
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