Tip: That last challenge will require you to make a State instance in your EditView initializer – remember to use an underscore with the property name!
![]() | ![]() |
---|
State 변수인 isStandardMap
을 만들어 버튼을 클릭하면 hybrid 혹은 standard 모드로 변할 수 있게 설정했다.
VStack {
Spacer()
Button(isStandardMap ? "Change to hybrid" : "Change to standard") {
isStandardMap.toggle()
}
.padding()
.background(.white)
.clipShape(.capsule)
.buttonStyle(.plain)
}
alert의 isPresented에 사용할 변수 isShowingAlert
와 alert을 설정해서 face id를 사용할 수 없는 경우에 알림창을 띄웠다.
Button("Unlock places") {
viewModel.authenticate()
}
.buttonStyle(.borderedProminent)
.alert("Unable to use biometircs", isPresented: $viewModel.isShowingAlert) {
Button("Okay", role: .cancel) { }
} message: {
Text("Please check your settings.")
}
dismiss, onSave를 제외하고 모두 viewModel에서 변수와 함수를 설정하고 EditPlaceView에서는 viewModel로 모두 활용했다.
extension EditPlaceView {
enum LoadingState {
case loading, loaded, failed
}
@Observable
class ViewModel {
var location: Location
var name: String
var loadingState = LoadingState.loading
var pages = [Page]()
init(location: Location, name: String) {
self.location = location
self.name = location.name
}
func createNewLocation() -> Location {
var newLocation = self.location
newLocation.id = UUID()
newLocation.name = self.name
return newLocation
}
func fetchNearbyPlaces() async {
let urlString = "https://en.wikipedia.org/w/api.php?ggscoord=\(self.location.latitude)%7C\(self.location.longitude)&action=query&prop=coordinates%7Cpageimages%7Cpageterms&colimit=50&piprop=thumbnail&pithumbsize=500&pilimit=50&wbptterms=description&generator=geosearch&ggsradius=10000&ggslimit=50&format=json"
guard let url = URL(string: urlString) else {
print("Wrong url: \(urlString)")
return
}
do {
let (data, _) = try await URLSession.shared.data(from: url)
let decoded = try JSONDecoder().decode(Result.self, from: data)
self.pages = decoded.query.pages.values.sorted()
self.loadingState = .loaded
} catch {
self.loadingState = .failed
}
}
}
}