feat(location): enable user location input
This commit is contained in:
@@ -255,6 +255,8 @@
|
|||||||
DEVELOPMENT_TEAM = SSJBLTMP95;
|
DEVELOPMENT_TEAM = SSJBLTMP95;
|
||||||
ENABLE_PREVIEWS = YES;
|
ENABLE_PREVIEWS = YES;
|
||||||
GENERATE_INFOPLIST_FILE = YES;
|
GENERATE_INFOPLIST_FILE = YES;
|
||||||
|
INFOPLIST_KEY_NSLocationAlwaysAndWhenInUseUsageDescription = "We need to access your location to set starting point of your route";
|
||||||
|
INFOPLIST_KEY_NSLocationWhenInUseUsageDescription = "We need to access your location to set starting point of your route";
|
||||||
INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES;
|
INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES;
|
||||||
INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;
|
INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;
|
||||||
INFOPLIST_KEY_UILaunchScreen_Generation = YES;
|
INFOPLIST_KEY_UILaunchScreen_Generation = YES;
|
||||||
@@ -284,6 +286,8 @@
|
|||||||
DEVELOPMENT_TEAM = SSJBLTMP95;
|
DEVELOPMENT_TEAM = SSJBLTMP95;
|
||||||
ENABLE_PREVIEWS = YES;
|
ENABLE_PREVIEWS = YES;
|
||||||
GENERATE_INFOPLIST_FILE = YES;
|
GENERATE_INFOPLIST_FILE = YES;
|
||||||
|
INFOPLIST_KEY_NSLocationAlwaysAndWhenInUseUsageDescription = "We need to access your location to set starting point of your route";
|
||||||
|
INFOPLIST_KEY_NSLocationWhenInUseUsageDescription = "We need to access your location to set starting point of your route";
|
||||||
INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES;
|
INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES;
|
||||||
INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;
|
INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;
|
||||||
INFOPLIST_KEY_UILaunchScreen_Generation = YES;
|
INFOPLIST_KEY_UILaunchScreen_Generation = YES;
|
||||||
|
|||||||
@@ -5,11 +5,13 @@
|
|||||||
// Created by Oliver Hnát on 23.11.2024.
|
// Created by Oliver Hnát on 23.11.2024.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
import CoreLocation
|
||||||
import MapKit
|
import MapKit
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
|
|
||||||
struct ContentView: View {
|
struct ContentView: View {
|
||||||
@ObservedObject var viewModel = ViewModel()
|
@ObservedObject var viewModel = ViewModel()
|
||||||
|
@StateObject var locationManager = LocationManager()
|
||||||
|
|
||||||
@State private var position = MapCameraPosition.automatic
|
@State private var position = MapCameraPosition.automatic
|
||||||
@State private var showSearch: Bool = true
|
@State private var showSearch: Bool = true
|
||||||
@@ -25,17 +27,37 @@ struct ContentView: View {
|
|||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
Map(position: $position) {
|
Map(position: $position) {
|
||||||
ForEach(0..<directions.count) { i in
|
ForEach(0..<directions.count) { i in
|
||||||
MapPolyline(directions[i].polyline)
|
MapPolyline(directions[i].polyline)
|
||||||
.stroke(Constants.routeColor[i], lineWidth: Constants.routeWidth)
|
.stroke(Constants.routeColor[i], lineWidth: Constants.routeWidth)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.sheet(
|
.sheet(
|
||||||
isPresented: $showSearch,
|
isPresented: $showSearch,
|
||||||
content: {
|
content: {
|
||||||
SearchView(directions: $directions)
|
SearchView(directions: $directions, locationManager: locationManager)
|
||||||
.ignoresSafeArea()
|
.ignoresSafeArea()
|
||||||
})
|
}
|
||||||
|
)
|
||||||
|
.mapControls {
|
||||||
|
MapUserLocationButton()
|
||||||
|
.onTapGesture {
|
||||||
|
locationManager.requestAuthorization()
|
||||||
|
locationManager.requestLocation()
|
||||||
|
if let userLocation = locationManager.location {
|
||||||
|
position = .camera(
|
||||||
|
MapCamera(centerCoordinate: userLocation, distance: 1000))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.onAppear {
|
||||||
|
locationManager.requestAuthorization()
|
||||||
|
locationManager.requestLocation()
|
||||||
|
if let userLocation = locationManager.location {
|
||||||
|
position = .camera(MapCamera(centerCoordinate: userLocation, distance: 1000))
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
// Text("This is what's set: \(viewModel.test)")
|
// Text("This is what's set: \(viewModel.test)")
|
||||||
// Button(action: {
|
// Button(action: {
|
||||||
// save(value: "te5t3")
|
// save(value: "te5t3")
|
||||||
|
|||||||
57
StepMap/LocationManager.swift
Normal file
57
StepMap/LocationManager.swift
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
//
|
||||||
|
// LocationManager.swift
|
||||||
|
// StepMap
|
||||||
|
//
|
||||||
|
// Created by Oliver Hnát on 25.11.2024.
|
||||||
|
//
|
||||||
|
|
||||||
|
import CoreLocation
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
class LocationManager: NSObject, ObservableObject, CLLocationManagerDelegate {
|
||||||
|
let manager = CLLocationManager()
|
||||||
|
|
||||||
|
@Published var location: CLLocationCoordinate2D?
|
||||||
|
|
||||||
|
override init() {
|
||||||
|
super.init()
|
||||||
|
manager.delegate = self
|
||||||
|
}
|
||||||
|
|
||||||
|
func requestLocation() {
|
||||||
|
manager.requestLocation()
|
||||||
|
}
|
||||||
|
|
||||||
|
func requestAuthorization() {
|
||||||
|
manager.requestWhenInUseAuthorization()
|
||||||
|
}
|
||||||
|
|
||||||
|
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
|
||||||
|
location = locations.first?.coordinate
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension LocationManager {
|
||||||
|
func locationManager(
|
||||||
|
_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus
|
||||||
|
) {
|
||||||
|
switch status {
|
||||||
|
case .notDetermined:
|
||||||
|
print("Authorization not determined")
|
||||||
|
case .restricted:
|
||||||
|
print("Authorization restricted")
|
||||||
|
case .denied:
|
||||||
|
print("Authorization denied")
|
||||||
|
case .authorizedAlways:
|
||||||
|
print("Authorization always authorized")
|
||||||
|
case .authorizedWhenInUse:
|
||||||
|
print("Authorization when in use authorized")
|
||||||
|
@unknown default:
|
||||||
|
print("Authorization went wrong")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func locationManager(_ manager: CLLocationManager, didFailWithError error: any Error) {
|
||||||
|
print(error)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -74,10 +74,10 @@ struct SearchItemView: View {
|
|||||||
|
|
||||||
func findDirections() {
|
func findDirections() {
|
||||||
let directionsRequest = MKDirections.Request()
|
let directionsRequest = MKDirections.Request()
|
||||||
// directionsRequest.source = MKMapItem.forCurrentLocation()
|
directionsRequest.source = MKMapItem.forCurrentLocation()
|
||||||
directionsRequest.source = MKMapItem.init(
|
// directionsRequest.source = MKMapItem.init(
|
||||||
placemark: MKPlacemark(
|
// placemark: MKPlacemark(
|
||||||
coordinate: CLLocationCoordinate2D(latitude: 52.3676, longitude: 4.9041)))
|
// coordinate: CLLocationCoordinate2D(latitude: 52.3676, longitude: 4.9041)))
|
||||||
directionsRequest.destination = location
|
directionsRequest.destination = location
|
||||||
directionsRequest.transportType = .walking
|
directionsRequest.transportType = .walking
|
||||||
directionsRequest.requestsAlternateRoutes = false // TODO: make alternative routes available
|
directionsRequest.requestsAlternateRoutes = false // TODO: make alternative routes available
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ struct SearchView: View {
|
|||||||
@State private var query: String = "airport"
|
@State private var query: String = "airport"
|
||||||
@State private var locations: [MKMapItem] = []
|
@State private var locations: [MKMapItem] = []
|
||||||
@Binding var directions: [MKRoute]
|
@Binding var directions: [MKRoute]
|
||||||
|
var locationManager: LocationManager
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
VStack {
|
VStack {
|
||||||
@@ -43,28 +44,6 @@ struct SearchView: View {
|
|||||||
.presentationBackgroundInteraction(.enabled(upThrough: .large))
|
.presentationBackgroundInteraction(.enabled(upThrough: .large))
|
||||||
}
|
}
|
||||||
|
|
||||||
func findDirections(to place: MKMapItem) {
|
|
||||||
let directionsRequest = MKDirections.Request()
|
|
||||||
// directionsRequest.source = MKMapItem.forCurrentLocation()
|
|
||||||
directionsRequest.source = MKMapItem.init(
|
|
||||||
placemark: MKPlacemark(
|
|
||||||
coordinate: CLLocationCoordinate2D(latitude: 52.3676, longitude: 4.9041)))
|
|
||||||
directionsRequest.destination = place
|
|
||||||
directionsRequest.transportType = .walking
|
|
||||||
directionsRequest.requestsAlternateRoutes = false // TODO: make alternative routes available
|
|
||||||
directionsRequest.departureDate = .now
|
|
||||||
|
|
||||||
let searchDirections = MKDirections(request: directionsRequest)
|
|
||||||
searchDirections.calculate { (response, error) in
|
|
||||||
guard let response = response else {
|
|
||||||
print(error ?? "")
|
|
||||||
print("Error while searching for directions")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
self.directions = response.routes
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func search(for text: String) {
|
func search(for text: String) {
|
||||||
let searchRequest = MKLocalSearch.Request()
|
let searchRequest = MKLocalSearch.Request()
|
||||||
searchRequest.naturalLanguageQuery = text
|
searchRequest.naturalLanguageQuery = text
|
||||||
@@ -78,7 +57,7 @@ struct SearchView: View {
|
|||||||
var items: [MKMapItem] = []
|
var items: [MKMapItem] = []
|
||||||
for item in response.mapItems {
|
for item in response.mapItems {
|
||||||
if let name = item.name,
|
if let name = item.name,
|
||||||
let location = item.placemark.location
|
let location = item.placemark.location
|
||||||
{
|
{
|
||||||
print(
|
print(
|
||||||
"\(name): \(location.coordinate.latitude),\(location.coordinate.longitude)")
|
"\(name): \(location.coordinate.latitude),\(location.coordinate.longitude)")
|
||||||
|
|||||||
Reference in New Issue
Block a user