์ธ๋„ค์ผ [Swift] Cannot convert value of type 'ModelData' to expected argument type 'EnvironmentObject<ModelData>' ์•„๋ž˜ ์ฝ”๋“œ๋ฅผ ๋ณด๊ณ  ๋ฌธ๋“ ๊ถ๊ธˆํ•ด์กŒ๋‹ค. envirionmentObject๋„ ๊ทธ๋ƒฅ property์ฒ˜๋Ÿผ ๋„ฃ์œผ๋ฉด ์–ด๋–ป๊ฒŒ ๋ ๊นŒ?? struct LandmarkList_Previews: PreviewProvider { static var previews: some View { LandmarkList() .environmentObject(ModelData()) } } ๊ทธ๋ž˜์„œ ์—๋Ÿฌ๋ฅผ ํ•œ๋ฒˆ ๋งŒ๋“ค์–ด๋ณด์•˜๋‹ค. LandmarkList_Previews์—์„œ LandmarkList(modelData: ModelData)๋กœ ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒ์„ฑํ•˜๋ ค๊ณ  ํ•˜๋ฉด ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•˜๋Š” ์ด์œ ๋Š” @EnvironmentObject ์†์„ฑ์€ ํ™˜๊ฒฝ(environment)์— ์žˆ๋Š” ๊ฐ์ฒด๋ฅผ ๊ฐ€์ ธ์™€ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•œ ์†์„ฑ(property) ๋ž˜ํผ์ด๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. ๋”ฐ๋ผ์„œ ๊ฐ์ฒด๋ฅผ ์ง..
์ธ๋„ค์ผ [Swift] how to create multiple preview import SwiftUI struct LandmarkList: View { var body: some View { NavigationView { List(landmarks) { landmark in NavigationLink { LandmarkDetail(landmark: landmark) } label: { LandmarkRow(landmark: landmark) } } .navigationTitle("Landmarks") } } } struct LandmarkList_Previews: PreviewProvider { static var previews: some View { ForEach(["iPhone SE (2nd generation)", "iPhone XS Max"], id: \.self) {..
์ธ๋„ค์ผ [Swift] ๋ฐ˜๋ณต๋ฌธ์—์„œ id: \.id ์˜ ์˜๋ฏธ 1. id ์•ž์— \. ์ด ๋ถ™๋Š” ์ด์œ , ๋ฐ˜๋ณต๋ฌธ์„ ์ด์šฉํ•ด์„œ ๋ฆฌ์ŠคํŠธ๋ฅผ ๋งŒ๋“ค๋•Œ Key๋ฅผ ์ฐธ์กฐํ•˜๋Š”๋ฒ• List(landmarks, id: \.id) { landmark in LandmarkRow(landmark: landmark) } ํ•˜์ง€๋งŒ Landmark ์ฝ”๋“œ์— struct Landmark: Hashable, Codable, Identifiable { ๋‹ค์Œ๊ณผ ๊ฐ™์ด Identifiable์„ ์ถ”๊ฐ€ํ•ด์ฃผ๋ฉด id key path๋Š” ์‚ญ์ œํ•ด๋„ ๋œ๋‹ค. Identifiable ํ”„๋กœํ† ์ฝœ์„ ๊ตฌํ˜„ํ•˜๋Š” ๊ฒฝ์šฐ id ํ”„๋กœํผํ‹ฐ๋ฅผ ์ง์ ‘ ์ง€์ •ํ•˜์ง€ ์•Š์•„๋„ List์—์„œ ์š”์†Œ๋ฅผ ์‹๋ณ„ํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋˜์–ด, key path๋ฅผ ๋”ฐ๋กœ ์ง€์ •ํ•  ํ•„์š”๊ฐ€ ์—†๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค! List(landmarks) { landmark in LandmarkRow(landmark: la..
์ธ๋„ค์ผ [Swift] load(_:) method (fetching JSON data) ๋œฏ์–ด๋ณด๊ธฐ import Foundation //Create an array of landmarks that you initialize from landmarkData.json. var landmarks: [Landmark] = load("landmarkData.json") func load(_ filename: String) -> T { let data: Data guard let file = Bundle.main.url(forResource: filename, withExtension: nil) else { fatalError("Couldn't find \(filename) in main bundle.") } do { // Data(contentsOf:) ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํŒŒ์ผ์˜ ๋‚ด์šฉ์„ Data ๊ฐ์ฒด๋กœ ์ฝ์–ด์˜จ๋‹ค...
์ธ๋„ค์ผ [Swift] Swift ์—์„œ Hashable, Codable์€ ๋ญ˜๊นŒ? Protocol ์•Œ์•„๋ณด๊ธฐ swiftui tutorial ์˜ ์˜ˆ์‹œ ์ฝ”๋“œ๋ฅผ ๊ณต๋ถ€ํ•˜๋‹ค๋ณด๋ฉด, Struct ๋’ค์— ~able ๋กœ ๋ถ™์€ ๊ฒƒ๋“ค์ด ๋ณด์ธ๋‹ค. ์ด๊ฑด ๋ฌด์—‡์ด๋ฉฐ ๊ฐ๊ฐ ์–ด๋–ค ์—ญํ• ์„ ํ• ๊นŒ? Hashable๊ณผ Codable์€ ์Šค์œ„ํ”„ํŠธ ์–ธ์–ด์—์„œ ํ”„๋กœํ† ์ฝœ(Protocol)์ด๋‹ค. ์˜ˆ์‹œ์ฝ”๋“œ์—์„œ ๊ฐ๊ฐ์˜ ์˜๋ฏธ 1. Hashable: Hashable ํ”„๋กœํ† ์ฝœ์€ ๊ฐ์ฒด๋ฅผ ๊ณ ์œ ํ•œ ํ•ด์‹œ๊ฐ’์œผ๋กœ ๋งคํ•‘ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ด์ฃผ๋Š” ํ”„๋กœํ† ์ฝœ์ด๋‹ค. ํ•ด์‹œ๊ฐ’์€ ๊ฐ์ฒด๋ฅผ ์‹๋ณ„ํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋˜๋ฉฐ, ํ•ด์‹œ ํ•จ์ˆ˜๋ฅผ ํ†ตํ•ด ๊ณ„์‚ฐ๋œ๋‹ค. Hashable ํ”„๋กœํ† ์ฝœ์„ ์ฑ„ํƒํ•˜๋ฉด ํ•ด๋‹น ๊ฐ์ฒด๋ฅผ Set์ด๋‚˜ Dictionary์˜ ํ‚ค๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค. ๋˜ํ•œ, Hashable ํ”„๋กœํ† ์ฝœ์„ ์ค€์ˆ˜ํ•˜๋Š” ๊ฐ์ฒด๋Š” ์ง‘ํ•ฉ(Set)๊ณผ ๊ฐ™์€ ์ž๋ฃŒ ๊ตฌ์กฐ์—์„œ ์ค‘๋ณต๋œ ์š”์†Œ๋ฅผ ์ œ๊ฑฐํ•  ์ˆ˜ ์žˆ๋‹ค. Landmark ๊ตฌ์กฐ์ฒด์˜ ์ธ์Šคํ„ด์Šค๊ฐ€ Hasha..
์ธ๋„ค์ผ [SwiftUI] ํ—ท๊น”๋ฆฌ๋Š” State, Binding, ObservedObject, EnvironmentObject ์ด์ •๋ฆฌ SwiftUI์—์„œ์˜ Single Source of Truth(SSOT, ๋‹จ์ผ ์ง„์‹ค ๊ณต๊ธ‰์›)๋ž€ ๋ฐ์ดํ„ฐ์˜ ์ผ๊ด€์„ฑ๊ณผ ์ •ํ™•์„ฑ์„ ์œ ์ง€ํ•˜๊ธฐ ์œ„ํ•œ ์ค‘์š”ํ•œ ๊ฐœ๋…์ด๋‹ค. ์ •๋ณด ์‹œ์Šคํ…œ์— ๋Œ€ํ•œ SSOT(Single Source Of Truth) ์•„ํ‚คํ…์ฒ˜ ๋˜๋Š” SPOT(Single Point Of Truth) ์•„ํ‚คํ…์ฒ˜๋Š” ๋ชจ๋“  ๋ฐ์ดํ„ฐ ์š”์†Œ๊ฐ€ ๋งˆ์Šคํ„ฐ(๋˜๋Š” ํŽธ์ง‘)๋˜๋„๋ก ์ •๋ณด ๋ฐ ๋ชจ๋ธ ๊ด€๋ จ ๋ฐ์ดํ„ฐ ์Šคํ‚ค๋งˆ๋ฅผ ๊ตฌ์„ฑํ•˜๋Š” ๊ด€ํ–‰์ด๋‹ค. ํ•œ ๊ณณ์—์„œ๋งŒ ์ •๊ทœ ํ˜•์‹์œผ๋กœ ๋ฐ์ดํ„ฐ ์ •๊ทœํ™”๋ฅผ ์ œ๊ณตํ•œ๋‹ค. ์ด ๋ฐ์ดํ„ฐ ์š”์†Œ์— ๋Œ€ํ•œ ๋ชจ๋“  ๊ฐ€๋Šฅํ•œ ์—ฐ๊ฒฐ์€ ์ฐธ์กฐ์šฉ์ด๋‹ค. ๋ฐ์ดํ„ฐ์˜ ๋‹ค๋ฅธ ๋ชจ๋“  ์œ„์น˜๋Š” "source of truth" ์œ„์น˜๋ฅผ ๋‹ค์‹œ ์ฐธ์กฐํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๊ธฐ๋ณธ ์œ„์น˜์˜ ๋ฐ์ดํ„ฐ ์š”์†Œ์— ๋Œ€ํ•œ ์—…๋ฐ์ดํŠธ๋Š” ์ „์ฒด ์‹œ์Šคํ…œ์— ์ „ํŒŒ๋˜์–ด ํšจ์œจ์„ฑ/์ƒ์‚ฐ์„ฑ ํ–ฅ์ƒ, ์ž˜๋ชป๋œ ๋ถˆ์ผ์น˜์˜ ์‰ฌ์šด ๋ฐฉ์ง€ ๊ฐ™..
์ธ๋„ค์ผ [SwiftUI Tutorials] SwiftUI Essentials - Creating and Combining Views Creating and Combining Views | Apple Developer Documentation This tutorial guides you through building Landmarks — an app for discovering and sharing the places you love. You’ll start by building the view that shows a landmark’s details. developer.apple.com - SwiftUI ์•ฑ ์ˆ˜๋ช… ์ฃผ๊ธฐ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์•ฑ์€ ์•ฑ ํ”„๋กœํ† ์ฝœ์„ ์ค€์ˆ˜ํ•˜๋Š” ๊ตฌ์กฐ๋ฅผ ๊ฐ€์ง. - ์ด ๊ตฌ์กฐ์˜ body ์†์„ฑ์€ ํ•˜๋‚˜ ์ด์ƒ์˜ Scene์„ ๋ฐ˜ํ™˜ํ•˜๊ณ  ํ‘œ์‹œํ•  ์ฝ˜ํ…์ธ ๋ฅผ ์ œ๊ณต. - @main ์†์„ฑ์€ ์•ฑ์˜ entry point๋ฅผ ์‹๋ณ„. - ๊ธฐ๋ณธ์ ์œผ๋กœ Swi..
์ธ๋„ค์ผ iOS ์•ฑ๊ฐœ๋ฐœ ์ฑ… ์ถ”์ฒœ : Doit! ์Šค์œ„ํ”„ํŠธ๋กœ ์•„์ดํฐ์•ฑ ๋งŒ๋“ค๊ธฐ ๐Ÿƒ๐Ÿป‍โ™€๏ธ ๋ฐ”์˜๋‹ค๋ฐ”๋น  ํ˜„๋Œ€์‚ฌํšŒ์ธ์„ ์œ„ํ•œ ์ดํ‰ - ํ•„์ž๋Š” ์ปดํ“จ๊ณตํ•™๊ณผ ํ•™์ƒ, ์›น์•ฑ ๋ถ„์•ผ ๊ฒฝํ—˜์ด ์–ด๋Š์ •๋„ ์žˆ์Œ (ํ”Œ๋Ÿฌํ„ฐ, ๋ฆฌ์•กํŠธ ๋“ฑ) - ์ „๊ณต์ž ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ๋น„์ „๊ณต์ž๋„ ์ „~ํ˜€ ๋ฌด๋ฆฌ ์—†์ด ๊ณต๋ถ€ํ•  ์ˆ˜ ์žˆ์„ ๊ฒƒ ๊ฐ™์€ ์„ธ์‹ฌํ•˜๊ณ  ์นœ์ ˆํ•จ์ด ๋ฌป์–ด์žˆ๋Š” ์ฑ…! - ์•ฑ๊ฐœ๋ฐœ ์•„๋ฌด๊ฒƒ๋„ ๋ชฐ๋ผ๋„ ์ฑ…์ด (๋„ˆ.......๋ฌด!) ์นœ์ ˆํ•ด์„œ ์–ด๋ ต์ง€ ์•Š์„๊ฑฐ๋ผ๊ณ  ๋ณด์žฅํ•  ์ˆ˜ ์žˆ์Œ ๐Ÿ‘ ์• ํ”Œ์•„์นด๋ฐ๋ฏธ๋ฅผ ํ•ฉ๊ฒฉํ–ˆ์ง€๋งŒ ๋‚˜๋Š” ์Šค์œ„ํ”„ํŠธ๋ฅผ ๊ณต๋ถ€ํ•ด๋ณธ ์ ์ด ์—†๋‹ค. ๊ทธ๋ž˜์„œ 2์›” ํ•œ ๋‹ฌ ๊ฐ„ ๊ณต๋ถ€+๋ฏธ๋‹ˆํ”„๋กœ์ ํŠธ ํ•˜๋‚˜๋ฅผ ํ•ด์„œ ๊ฐˆ ๊ณ„ํš์ด์—ˆ๋‹ค. ๋‚œ ์ฃผ๋กœ ๊ณต์‹๋ฌธ์„œ ๋˜๋Š” ์œ ํŠœ๋ธŒ/์ธํ„ฐ๋„ท ๊ฐ•์˜๋ฅผ ๋“ค์œผ๋ฉฐ ๋“ฃ๋Š” ํŽธ์ด๊ณ , ๋ฐ”๋กœ ์ฝ”๋“œ๋ฅผ ์งœ๋ฉฐ ๋ฌด์ž‘์ • ํ”„๋กœ์ ํŠธ๋ฅผ ์‹œ์ž‘ํ•˜๋Š” ํŽธ์ด๋ผ, ์ฑ…์œผ๋กœ ๊ณต๋ถ€ํ•ด๋ณธ ์ ์€ ์—†์—ˆ๋‹ค. ๊ฐ์‚ฌํ•˜๊ฒŒ๋„ ๊ทธ ์™€์ค‘์— ์ด์ง€์Šคํผ๋ธ”๋ฆฌ์‹ฑ์—์„œ ์ฑ…์„ ์ œ๊ณตํ•ด์ฃผ์…”์„œ ์ด๋ฒˆ์—” ์ฑ…์œผ๋กœ ๊ณต๋ถ€ํ•ด๋ณด๊ธฐ๋กœ ํ–ˆ๋‹ค!..