diff --git a/velibtracker.xcodeproj/project.pbxproj b/velibtracker.xcodeproj/project.pbxproj index 23ca91c..a8b5702 100644 --- a/velibtracker.xcodeproj/project.pbxproj +++ b/velibtracker.xcodeproj/project.pbxproj @@ -14,6 +14,7 @@ 2CDC317E2AA3654800BF98B9 /* VelibStationStruct.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2CDC317D2AA3654800BF98B9 /* VelibStationStruct.swift */; }; 2CDC31802AA3672600BF98B9 /* StationComponent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2CDC317F2AA3672600BF98B9 /* StationComponent.swift */; }; 2CDC31822AA387AB00BF98B9 /* fetchVelibData.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2CDC31812AA387AB00BF98B9 /* fetchVelibData.swift */; }; + 2CDC31892AA38B6000BF98B9 /* LocationManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2CDC31882AA38B6000BF98B9 /* LocationManager.swift */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ @@ -26,6 +27,7 @@ 2CDC317D2AA3654800BF98B9 /* VelibStationStruct.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VelibStationStruct.swift; sourceTree = ""; }; 2CDC317F2AA3672600BF98B9 /* StationComponent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StationComponent.swift; sourceTree = ""; }; 2CDC31812AA387AB00BF98B9 /* fetchVelibData.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = fetchVelibData.swift; sourceTree = ""; }; + 2CDC31882AA38B6000BF98B9 /* LocationManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocationManager.swift; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -58,6 +60,7 @@ 2C5BDABB2AA3611000DBEC93 /* velibtracker */ = { isa = PBXGroup; children = ( + 2CDC31832AA38AAE00BF98B9 /* utils */, 2CDC317C2AA3653200BF98B9 /* struct */, 2C5BDACB2AA3632C00DBEC93 /* components */, 2C5BDABC2AA3611000DBEC93 /* velibtrackerApp.swift */, @@ -65,7 +68,6 @@ 2C5BDAC02AA3611000DBEC93 /* Assets.xcassets */, 2C5BDAC22AA3611000DBEC93 /* velibtracker.entitlements */, 2C5BDAC32AA3611000DBEC93 /* Preview Content */, - 2CDC31812AA387AB00BF98B9 /* fetchVelibData.swift */, ); path = velibtracker; sourceTree = ""; @@ -94,6 +96,15 @@ path = struct; sourceTree = ""; }; + 2CDC31832AA38AAE00BF98B9 /* utils */ = { + isa = PBXGroup; + children = ( + 2CDC31812AA387AB00BF98B9 /* fetchVelibData.swift */, + 2CDC31882AA38B6000BF98B9 /* LocationManager.swift */, + ); + path = utils; + sourceTree = ""; + }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ @@ -166,6 +177,7 @@ files = ( 2CDC317E2AA3654800BF98B9 /* VelibStationStruct.swift in Sources */, 2C5BDABF2AA3611000DBEC93 /* ContentView.swift in Sources */, + 2CDC31892AA38B6000BF98B9 /* LocationManager.swift in Sources */, 2CDC31822AA387AB00BF98B9 /* fetchVelibData.swift in Sources */, 2CDC31802AA3672600BF98B9 /* StationComponent.swift in Sources */, 2C5BDABD2AA3611000DBEC93 /* velibtrackerApp.swift in Sources */, @@ -297,6 +309,7 @@ ENABLE_HARDENED_RUNTIME = YES; ENABLE_PREVIEWS = YES; GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_KEY_NSLocationWhenInUseUsageDescription = "Display Velib stations near your current location"; "INFOPLIST_KEY_UIApplicationSceneManifest_Generation[sdk=iphoneos*]" = YES; "INFOPLIST_KEY_UIApplicationSceneManifest_Generation[sdk=iphonesimulator*]" = YES; "INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents[sdk=iphoneos*]" = YES; @@ -335,6 +348,7 @@ ENABLE_HARDENED_RUNTIME = YES; ENABLE_PREVIEWS = YES; GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_KEY_NSLocationWhenInUseUsageDescription = "Display Velib stations near your current location"; "INFOPLIST_KEY_UIApplicationSceneManifest_Generation[sdk=iphoneos*]" = YES; "INFOPLIST_KEY_UIApplicationSceneManifest_Generation[sdk=iphonesimulator*]" = YES; "INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents[sdk=iphoneos*]" = YES; diff --git a/velibtracker/ContentView.swift b/velibtracker/ContentView.swift index 20e3f3f..9a08e0a 100644 --- a/velibtracker/ContentView.swift +++ b/velibtracker/ContentView.swift @@ -8,7 +8,31 @@ import SwiftUI struct ContentView: View { + @ObservedObject var locationManager = LocationManager() + @State private var isLocationAuthorized = false var body: some View { + VStack { + var latitude = locationManager.userLocation?.latitude + var longitude = locationManager.userLocation?.longitude + if locationManager.isLocationAuthorized { + // Afficher le contenu de l'application une fois que la localisation est autorisée + Text("Latitude: \(locationManager.userLocation?.latitude ?? 0), Longitude: \(locationManager.userLocation?.longitude ?? 0)") + } else { + // Afficher un message ou un bouton pour demander l'autorisation de localisation + Button("Autoriser la localisation") { + locationManager.onLocationUpdate = { + // Appel à la requête API lorsque la localisation est autorisée + } + } + } + } + .onAppear { + if locationManager.isLocationAuthorized { + // Appel à la requête API lorsque la localisation est déjà autorisée + fetchVelibDataLocation(lon: Double(locationManager.userLocation?.longitude ?? 0), lat: Double(locationManager.userLocation?.latitude ?? 0)) + print("State updated") + } + } NavigationView { ScrollView { ForEach(velibStations, id: \.stationcode) { station in @@ -18,11 +42,13 @@ struct ContentView: View { } .navigationBarTitle("Stations Vélib") } - + } + } + struct ContentView_Previews: PreviewProvider { static var previews: some View { ContentView() diff --git a/velibtracker/fetchVelibData.swift b/velibtracker/fetchVelibData.swift deleted file mode 100644 index 7d7f413..0000000 --- a/velibtracker/fetchVelibData.swift +++ /dev/null @@ -1,52 +0,0 @@ -// -// fetchVelibData.swift -// velibtracker -// -// Created by Louis Gallet on 02/09/2023. -// - -import Foundation - - -var velibStations: [VelibStation] = [] - -import Foundation - -func fetchVelibData() { - // L'URL de l'API Vélib - let apiUrl = URL(string: "https://opendata.paris.fr/api/explore/v2.1/catalog/datasets/velib-disponibilite-en-temps-reel/records?select=stationcode,name,capacity,numdocksavailable,numbikesavailable,mechanical,ebike,coordonnees_geo")! - - // Créez une session URLSession pour effectuer la requête - let session = URLSession.shared - - // Créez la tâche de requête - let task = session.dataTask(with: apiUrl) { (data, response, error) in - // Vérifiez s'il y a des erreurs - if let error = error { - print("Erreur de requête : \(error.localizedDescription)") - return - } - - // Vérifiez si les données sont présentes - guard let data = data else { - print("Aucune donnée reçue.") - return - } - - do { - // Décodez les données en utilisant le décodeur JSON - let decoder = JSONDecoder() - let velibResponse = try decoder.decode(VelibResponse.self, from: data) - - // Stockez les données dans la variable globale velibStations - velibStations = velibResponse.results - - print("Données Vélib récupérées avec succès.") - } catch { - print("Erreur lors du décodage JSON : \(error.localizedDescription)") - } - } - - // Lancez la tâche de requête - task.resume() -} diff --git a/velibtracker/utils/LocationManager.swift b/velibtracker/utils/LocationManager.swift new file mode 100644 index 0000000..848c4a8 --- /dev/null +++ b/velibtracker/utils/LocationManager.swift @@ -0,0 +1,32 @@ +// +// LocationManager.swift +// velibtracker +// +// Created by Louis Gallet on 02/09/2023. +// + +import Foundation + +import CoreLocation + +class LocationManager: NSObject, ObservableObject, CLLocationManagerDelegate { + private var locationManager = CLLocationManager() + @Published var userLocation: CLLocationCoordinate2D? + @Published var isLocationAuthorized = false + var onLocationUpdate: (() -> Void)? + + override init() { + super.init() + locationManager.delegate = self + locationManager.requestWhenInUseAuthorization() + locationManager.startUpdatingLocation() + } + + func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) { + if let location = locations.last { + userLocation = location.coordinate + isLocationAuthorized = true + onLocationUpdate?() // Appelé lorsque la localisation est mise à jour + } + } +} diff --git a/velibtracker/utils/fetchVelibData.swift b/velibtracker/utils/fetchVelibData.swift new file mode 100644 index 0000000..93ddd90 --- /dev/null +++ b/velibtracker/utils/fetchVelibData.swift @@ -0,0 +1,96 @@ +// +// fetchVelibData.swift +// velibtracker +// +// Created by Louis Gallet on 02/09/2023. +// + +import Foundation + + +var velibStations: [VelibStation] = [] + +import Foundation + +func fetchVelibData() { + // L'URL de l'API Vélib + let apiUrl = URL(string: "https://opendata.paris.fr/api/explore/v2.1/catalog/datasets/velib-disponibilite-en-temps-reel/records?select=stationcode,name,capacity,numdocksavailable,numbikesavailable,mechanical,ebike,coordonnees_geo")! + + // Créez une session URLSession pour effectuer la requête + let session = URLSession.shared + + // Créez la tâche de requête + let task = session.dataTask(with: apiUrl) { (data, response, error) in + // Vérifiez s'il y a des erreurs + if let error = error { + print("Erreur de requête : \(error.localizedDescription)") + return + } + + // Vérifiez si les données sont présentes + guard let data = data else { + print("Aucune donnée reçue.") + return + } + + do { + // Décodez les données en utilisant le décodeur JSON + let decoder = JSONDecoder() + let velibResponse = try decoder.decode(VelibResponse.self, from: data) + + // Stockez les données dans la variable globale velibStations + velibStations = velibResponse.results + + print("Données Vélib récupérées avec succès.") + } catch { + print("Erreur lors du décodage JSON : \(error.localizedDescription)") + } + } + + // Lancez la tâche de requête + task.resume() +} + + +func fetchVelibDataLocation(lon: Double, lat: Double) { + // L'URL de l'API Vélib + print(lon, lat) + let longitude = String(lon).replacingOccurrences(of: ",", with: ".") + print(longitude) + let apiUrl = URL(string: "https://opendata.paris.fr/api/explore/v2.1/catalog/datasets/velib-disponibilite-en-temps-reel/records?select=stationcode,name,capacity,numdocksavailable,numbikesavailable,mechanical,ebike,coordonnees_geo&where=distance(coordonnees_geo%2C%20geom%27POINT(\(lon)%20\(lat)%27%2C%2015km)")! + + // Créez une session URLSession pour effectuer la requête + let session = URLSession.shared + + // Créez la tâche de requête + let task = session.dataTask(with: apiUrl) { (data, response, error) in + // Vérifiez s'il y a des erreurs + if let error = error { + print("Erreur de requête : \(error.localizedDescription)") + return + } + + // Vérifiez si les données sont présentes + guard let data = data else { + print("Aucune donnée reçue.") + return + } + + do { + // Décodez les données en utilisant le décodeur JSON + let decoder = JSONDecoder() + let velibResponse = try decoder.decode(VelibResponse.self, from: data) + + // Stockez les données dans la variable globale velibStations + velibStations = velibResponse.results + print(velibStations) + + print("Données Vélib récupérées avec succès.") + } catch { + print("Erreur lors du décodage JSON : \(error.localizedDescription)") + } + } + + // Lancez la tâche de requête + task.resume() +} diff --git a/velibtracker/velibtrackerApp.swift b/velibtracker/velibtrackerApp.swift index 0941808..412120b 100644 --- a/velibtracker/velibtrackerApp.swift +++ b/velibtracker/velibtrackerApp.swift @@ -16,5 +16,5 @@ struct velibtrackerApp: App { } init() { fetchVelibData() - } + } }