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
Kotlin エンジニアへ送る:Swift 案件に参加させられる日に備えて~似てるけど色々違う...
Search
Elvis Shi
June 24, 2025
Programming
1
280
Kotlin エンジニアへ送る:Swift 案件に参加させられる日に備えて~似てるけど色々違う Swift の仕様 / from Kotlin to Swift
Elvis Shi
June 24, 2025
Tweet
Share
More Decks by Elvis Shi
See All by Elvis Shi
ゼロから始めるPreferenceの実装 / Let's implement Preferences from scratch
lovee
0
74
個人アプリを2年ぶりにアプデしたから褒めて / I just updated my personal app, praise me!
lovee
0
490
How did I build an Open-Source SwiftUI Toast Library
lovee
1
110
SwiftUIで使いやすいToastの作り方 / How to build a Toast system which is easy to use in SwiftUI
lovee
3
1k
SwiftUIで二重スクロール作ってみた / When I tried to make a dual-scroll-ish view in SwiftUI
lovee
1
320
Observation のあれこれ / A brief introduction about Observation
lovee
3
390
ChatGPT 時代の勉強 / Learning under ChatGPT era
lovee
27
8.8k
属人化しない為の勉強会作り / To make tech meetups with less personal dependencies
lovee
0
330
偏見と妄想で語るスクリプト言語としての Swift / Swift as a Scripting Language
lovee
2
880
Other Decks in Programming
See All in Programming
顧客の画像データをテラバイト単位で配信する 画像サーバを WebP にした際に起こった課題と その対応策 ~継続的な取り組みを添えて~
takutakahashi
4
1.4k
抽象化という思考のツール - 理解と活用 - / Abstraction-as-a-Tool-for-Thinking
shin1x1
1
900
Jakarta EE Meets AI
ivargrimstad
0
540
Claude Code派?Gemini CLI派? みんなで比較LT会!_20250716
junholee
1
780
React 使いじゃなくても知っておきたい教養としての React
oukayuka
18
5k
大規模FlutterプロジェクトのCI実行時間を約8割削減した話
teamlab
PRO
0
410
あまり知られていない MCP 仕様たち / MCP specifications that aren’t widely known
ktr_0731
0
170
MCP連携で加速するAI駆動開発/mcp integration accelerates ai-driven-development
bpstudy
0
240
バイブコーディング超えてバイブデプロイ〜CloudflareMCPで実現する、未来のアプリケーションデリバリー〜
azukiazusa1
3
770
状態遷移図を書こう / Sequence Chart vs State Diagram
orgachem
PRO
3
320
0から始めるモジュラーモノリス-クリーンなモノリスを目指して
sushi0120
0
250
Flutterと Vibe Coding で個人開発!
hyshu
1
200
Featured
See All Featured
Fight the Zombie Pattern Library - RWD Summit 2016
marcelosomers
234
17k
Chrome DevTools: State of the Union 2024 - Debugging React & Beyond
addyosmani
7
770
Fantastic passwords and where to find them - at NoRuKo
philnash
51
3.4k
Scaling GitHub
holman
461
140k
The Cult of Friendly URLs
andyhume
79
6.5k
Designing Dashboards & Data Visualisations in Web Apps
destraynor
231
53k
XXLCSS - How to scale CSS and keep your sanity
sugarenia
248
1.3M
How to Ace a Technical Interview
jacobian
278
23k
The Pragmatic Product Professional
lauravandoore
36
6.8k
Dealing with People You Can't Stand - Big Design 2015
cassininazir
367
26k
Adopting Sorbet at Scale
ufuk
77
9.5k
The Cost Of JavaScript in 2023
addyosmani
51
8.7k
Transcript
ࣅͯΔ͚Ͳ৭ʑҧ͏4XJGUͷ༷ forϞόνΩʙ.PCJMF5JQTڞ༗ձʙ ,PUMJOΤϯδχΞૹΔɿ4XJGUҊ݅ʹࢀՃͤ͞ΒΕΔʹඋ͑ͯʙ
} var employedBy = "YUMEMI Inc." var job = "iOS
Developer" var organizerOf = "HAKATA.swift" var favoriteLanguage = "Swift" var twitter = "@lovee" var qiita = "lovee" var github = "el-hoshino" var additionalInfo = """ ࠓ͔Β iPhone ͰϚΠφϯόʔΧʔυ͕ ͑ΔΑ͏ʹͳͬͨΑʂ iOS 26 Developer Beta 2 ϦϦʔεͨ͠Αʂ """ final class Me: Developable, Talkable {
͓͓ɺ,PUMJO׳Εͨํ͕4XJGUॻ͘ͱ͜Μͳͱ͜ΖͰ,PUMJOͷश׳͕ݱΕΔΜͩ Ͷʂ 13ϨϏϡʔʜ ڵຯ͋Δ͔ΒΓ·͢! "OESPJEͱ,.1Ϧιʔε༨༟͋Δ͔Β୭͔J04ʹՃ͢Δਓ͍ͳ͍͔ʁ J04ͷ୲ऀগͳ͍͔Βਐ͕ͪΐͬͱ͍ͳʜ
%JTDMBJNFS w հྫ͕ͯࣗ͢ίʔυϨϏϡʔͷࡍʹग़ձͬͨίʔυͰ͢ ʢΦϦδφϧͰͳ͘ษڧձʹ߹Θͤͨมߋ͋Γʣ w ͦͷͨΊͯ͢Ϗϧυ௨Δ͚Ͳɺ4XJGUతʹ͋·Γ͜͏͠ͳ͍Αɺ ͱ͍͏ࡉ͔͍ͱ͜ΖΛϑΥʔΧεͨ͠ҧ͍Λհ͠·͢ w ·ͨશͯͷҧ͍ΛཏͰ͖ͯΔΘ͚Ͱͳ͍͜ͱΛѱ͔͠Βͣ
if (isUserValid) { // do something } 4XJGUجຊAifAจͷ݅ͰA()Aॻ͔ͳ͍͜ͱ͕ओྲྀͰ͢
if isUserValid { // do something }
enum LoginMethod { case userId case sns } 4XJGUීஈશ෦େจࣈΛ͏ུশ͕DBNFM$BTFʹೖΔ࣌ɺ େจࣈখจࣈΛଗ͑·͢
IUUQTXXXTXJGUPSHEPDVNFOUBUJPOBQJEFTJHOHVJEFMJOFTHFOFSBMDPOWFOUJPOT
enum LoginMethod { case userID case sns } IUUQTXXXTXJGUPSHEPDVNFOUBUJPOBQJEFTJHOHVJEFMJOFTHFOFSBMDPOWFOUJPOT //
શͯେจࣈͷུশͷ߹ var utf8Bytes: [UTF8.CodeUnit] var isRepresentableAsASCII = true var userSMTPServer: SecureSMTPServer // ಄จࣈ͚ͩେจࣈͷུশͷ߹ var radarDetector: RadarScanner var enjoysScubaDiving = true
enum LoginMethod { case userID case sns } func login(method:
LoginMethod) { // do something } login(method: LoginMethod) 4XJGUͷϝιουҾʹϥϕϧΛ༩Ͱ͖·͢ɺ ͦΕʹΑΓݺͼग़͕͠ಡΈ͘͢ͳΔ͜ͱ͕ଟ͍Ͱ͢
enum LoginMethod { case userID case sns } func login(with
method: LoginMethod) { // do something } login(with: LoginMethod)
enum LoginMethod { case userID case sns } func login(with
method: LoginMethod) { // do something } login(with: LoginMethod.userID) 4XJGUܕ͕ਪͰ͖Δ߹ɺ Θ͟Θ͟ܕΛॻ͔ͳͯ͘େৎͰ͢
enum LoginMethod { case userID case sns } func login(with
method: LoginMethod) { // do something } login(with: .userID)
struct ConnectionOption: OptionSet { // ... static let customDnsIpTable: Self
// ... } struct ConnectionOption: OptionSet { // ... static let customDNSipTable: Self // ... } struct ConnectionOption: OptionSet { // ... static let customDNSIPtable: Self // ... } struct ConnectionOption: OptionSet { // ... static let customDNSIPTable: Self // ... } ΫΠζ 4XJGU"1*%FTJHO(VJEFMJOFTʹԊͬͨม໊ʁ
struct ConnectionOption: OptionSet { // ... static let customDnsIpTable: Self
// ... } struct ConnectionOption: OptionSet { // ... static let customDNSipTable: Self // ... } struct ConnectionOption: OptionSet { // ... static let customDNSIPtable: Self // ... } struct ConnectionOption: OptionSet { // ... static let customDNSIPTable: Self // ... } ΫΠζ ͑߹Θͤ
func handle(option: ConnectionOption) { if (option.contains(ConnectionOption.customDNSIPTable)) { // ... }
} ಡΈ͍͢ϥϕϧΛ ͚ͭΒΕΔ ׅހ͕ඞཁͳ͍ ਪͰ͖Δ͔ΒܕཁΒͳ͍ ΫΠζ Լهͷ࣮ΛΑΓ4XJGUΒ͘͢͠Δʹʁ
func handle(_ option: ConnectionOption) { if option.contains(.customDNSIPTable) { // ...
} } ΫΠζ ͑߹Θͤ
func handle(_ option: ConnectionOption) { if option.contains(.customDNSIPTable) { // ...
} } let userOption: ConnectionOption = // ... handle(userOption) ΫΠζ ͑߹Θͤ
ࢀߟࢿྉ w IUUQTXXXTXJGUPSHEPDVNFOUBUJPOBQJEFTJHOHVJEFMJOFT
struct UserData { internal func doSomething() { // ... }
} 4XJGUσϑΥϧτείʔϓ͕JOUFSOBM͔ͩΒ جຊΘ͟Θ͟internal͚ͭΔඞཁͳ͍
struct UserData { func doSomething() { // ... } }
public struct UserData { func doSomething() { // ... }
} QVCMJDએݴͷܕͷதͰಉ͘͡ σϑΥϧτείʔϓJOUFSOBMͰ͢
public struct UserData { // ... } public extension UserData
{ internal func doSomething() { // ... } } །Ұͷྫ֎QVCMJDͳ֦ு͚ͩ σϑΥϧτείʔϓQVCMJDͰ͢ ͕ʜΘ͟Θ͟͜Μͳ͜ͱΔʜʁ
public struct UserData { // ... } extension UserData {
func doSomething() { // ... } } ͜ΕͰ͍͍ΑͶʜʁ
struct UserData { let nickName: String let level: Int }
structͷϓϩύςΟʔ جຊvarએݴͰͳ͍
ʮࢀরܕʯͱʮܕʯ w ʮࢀরܕʯͱɺೖ࣌ʹΠϯελϯεͷࢀরΛίϐʔͯ͠ೖ ͢Δܕͷ͜ͱ w ʮܕʯͱɺೖ࣌ʹΠϯελϯεͷͦͷͷΛίϐʔͯ͠ ೖ͢Δܕͷ͜ͱ w ࢀরܕࢀর͕ڞ༗͞ΕΔͷͰɺೖޙͷͷมߋڞ༗͞ΕΔ w
ܕࢀর͕ڞ༗͞Εͳ͍ͷͰɺೖޙͷͷมߋڞ༗͞Εͳ͍
ࢀরܕͷ߹ " A = SomeThing() ࢀর
ࢀরܕͷ߹ " B = A # ࢀর
ࢀরܕͷ߹ " B.property = new # #ʹର͢Δมߋ͕"ʹ ө͞Εͯ͠·͏ ࢀর
ΠϛϡʔλϒϧΫϥε
ࢀর ࢀরܕʢEBUBDMBTTʣͷ߹ A = SomeThing() " ࢀর
ࢀর ࢀরܕʢEBUBDMBTTʣͷ߹ B = A.copy(property = new) #ʹର͢Δมߋ #ʹཹ·Δ "
ࢀর #
# ܕͷ߹ " A = SomeThing()
# ܕͷ߹ " B = A
ܕͷ߹ " B.property = new # #ʹର͢Δมߋ #ʹཹ·Δ
struct UserData { var nickName: String var level: Int }
struct UserData { var nickName: String var level: Int }
struct UserView: View { @State private var userData: UserData = //... var body: some View { VStack { TextField("Nick Name", text: $userData.nickName) } } } @Stateͷঢ়ଶʹର͠$Ͱ؆୯ʹ ํόΠϯσΟϯά͕࡞ΕΔ
w IUUQT[FOOEFWLPIFSBSUJDMFTTXJGUTUSVDUJNNVUBCJMJUZ w IUUQTRJJUBDPNPNPDIJNFUBSVJUFNTFCDDC ࢀߟࢿྉ
ܕɺΠϛϡʔλϒϧΫϥεͱ΄΅ಉՁ
struct UserData { let id: UUID var nickName: String var
level: Int } ݸਓతྫ֎ มߋ͍ͨ͠໌ࣔతʹΠϯελϯεΛ࠶ੜͯ͠΄͍͠ ϓϩύςΟʔʹ͚ͩletΛ͍·͢
struct UserData { let id: UUID var nickName: String var
level: Int } struct UserView: View { @State private var userData: UserData = // var body: some View { VStack { TextField("Nick Name", text: $userData.nickName) TextField("ID", text: $userData.id) } } } $BOOPUBTTJHOUPQSPQFSUZJEJTBMFUDPOTUBOU
One more thing...
None
4XJGU6*Ͱɺ7JFX.PEFMΛ࡞Βͳ͍͍ͯ͘ w +FUQBDL$PNQPTFͱҧͬͯɺͦͦViewModelجఈΫϥεͷ Α͏ͳͷ༻ҙ͞Ε͍ͯͳ͍ w Ұൠతͳ.77.ͷViewModelɺઃܭͱͯ͠ϥΠϑαΠΫϧ Viewʹґଘ͍ͯ͠Δ͕ɺ4XJGU6*ʹ͓͚ΔViewͨͩͷܕͰ ʮϥΠϑαΠΫϧʯͷ֓೦͢Βͳ͍ w ը໘ͷϥΠϑαΠΫϧ4XJGU6*Τϯδϯ͕ࣗཧ͍ͯ͠Δ͕ɺ
ͦ͜ʹViewModel͕հࡏ͢Δ༨͕ͳ͍ w ͦͦ4XJGU6*ͷViewɺฆΕͳ͘7JFX.PEFMͰ͋Δ w w w w w w w w w w w w w w w w w
4XJGU6*ʹ͓͍ͯɺ ը໘ॲཧViewʹॻ͍ͯΑΖ͍͠ɻ
ࢀߟࢿྉʢफڭઓ૪ʣ w IUUQTYDPNB[BNTIBSQTUBUVT w IUUQTRJJUBDPNLBSBNBHFJUFNTBDDB⒎EFC w IUUQTEFWFMPQFSBQQMFDPNGPSVNTUISFBE
એ IUUQTIBLBUBTXJGUDPOOQBTTDPNFWFOU