랜드마크의 카테고리 뷰에서는 각각의 카테고리 마다 세로 방향으로 스크롤이 가능하게 나열됩니다. 각각의 카테고리에서는 랜드마크들을 가로로 스크롤하여 볼 수 있습니다.
이번 듀토리얼에서는 구성된 뷰가 어떻게 다양한 크기와 방향을 갖는 디바이스에 적용되는지 볼 수 있습니다.

프로젝트의 Views 그룹 안에 Categories 그룹을 추가해줍니다.
CategoryHome.swift 라는 이름의 SwiftUI view를 만들어 주고, 아래와 같이 내비게이션 뷰를 추가해줍니다.
**// CategoryHome.swift
import SwiftUI
struct CategoryHome: View {
var body: some View {
NavigationView {
Text("Hello, World!")
.navigationTitle("Featured")
}
}
}
struct CategoryHome_Previews: PreviewProvider {
static var previews: some View {
CategoryHome()
}
}**


Landmark.swift 파일에 다음과 같이 카테고리에 관한 열거형 프로퍼티를 추가해줍니다.
**// Landmark.swift**
import Foundation
import SwiftUI
import CoreLocation
// landmarkData.json 파일의 키:값에 맞는 구조체를 정의해준다.
// Codable 프로토콜 : 구조체와 데이터 파일 간에 데이터를 더 쉽게 이동할 수 있게 해준다. Codable의 컴포넌트인 Decodable을 사용해서 파일로부터 데이터를 읽어올 수 있다.
// Identifiable : 데이터가 identifiable하도록 준수하는 프로토콜
struct Landmark: Hashable, Codable, Identifiable {
var id: Int
var name: String
var park: String
var state: String
var description: String
var isFavorite: Bool // 즐겨찾기 여부 프로퍼티
**var category: Category
enum Category: String, CaseIterable, Codable {
case lakes = "Lakes"
case rivers = "Rivers"
case mountains = "Mountains"
}**
private var imageName: String // 이미지 데이터의 이름을 불러오기 위한 프로퍼티
var image: Image {
Image(imageName)
}
// 좌표 속성
private var coordinates: Coordinates
// MapKit 프레임워크와 상호작용 하기 좋도록 좌표 프로퍼티를 처리해준다.
var locationCoordinate: CLLocationCoordinate2D {
CLLocationCoordinate2D(
latitude: coordinates.latitude,
longitude: coordinates.longitude)
}
struct Coordinates: Hashable, Codable {
var latitude: Double
var longitude: Double
}
}
ModelData.swift 파일에 다음과 같이 처리된 카테고리 딕셔너리를 추가해줍니다.
**// ModelData.swift**
import Foundation
import Combine
// Combine 프레임워크의 ObservableObject 프로토콜을 준수하는 새로운 모델 타입을 정의합니다.
final class ModelData: ObservableObject {
// landmarkData.json 파일을 불러와서 배열로 저장합니다.
// Observable 객체는 SwiftUI가 변경사항을 감지할 수 있도록 @Published 키워드를 붙여줍니다.
@Published var landmarks: [Landmark] = load("landmarkData.json")
// hikeData.json 파일을 불러와서 배열로 저장합니다. (이후 수정할 일이 없기 때문에 @Published 키워드 안붙여도 됨)
var hikes: [Hike] = load("hikeData.json")
**// 각 카테고리의 이름을 key로 갖는 카테고리 딕셔너리를 만들어줍니다.
var categories: [String: [Landmark]] {
Dictionary( // 주어진 컬렉션을 그룹화하여 딕셔너리로 변환하는 함수
grouping: landmarks,
by: { $0.category.rawValue }
)
}**
}
코드 설명

CategoryHome.swift 파일에서 ModelData의 environment 객체를 활용하여 카테고리 리스트를 만들어줍니다.
**// CategoryHome.swift**
import SwiftUI
struct CategoryHome: View {
**@EnvironmentObject var modelData: ModelData // ModelData의 environment객체를 만들어준다.**
var body: some View {
**NavigationView {
List {
ForEach(modelData.categories.keys.sorted(), id: \.self) { key in
Text(key)
}
}
.navigationTitle("Featured")
}**
}
}
struct CategoryHome_Previews: PreviewProvider {
static var previews: some View {
CategoryHome()
**.environmentObject(ModelData())**
}
}
코드 설명

