Merge branch 'feat/watch-outdoor' of https://git.nexus.hypnotruck.ch/sylvain/coach-ios into feat/watch-outdoor
This commit is contained in:
@@ -15,7 +15,8 @@ Instructions pour Claude Code sur ce projet. Lis ce fichier en début de session
|
|||||||
## 🔒 Règles non négociables
|
## 🔒 Règles non négociables
|
||||||
|
|
||||||
1. **Le code web n'est PAS ici** — pour modifier l'UI/UX, c'est `coach_sportif/web/`. Ce repo ne touche QUE le natif (Swift, Kotlin, plugins Capacitor, config).
|
1. **Le code web n'est PAS ici** — pour modifier l'UI/UX, c'est `coach_sportif/web/`. Ce repo ne touche QUE le natif (Swift, Kotlin, plugins Capacitor, config).
|
||||||
2. **Cookie inject AppDelegate** (iOS) : mécanisme critique pour l'auth WKWebView. Toute modif `AppDelegate.swift` doit préserver ce flux.
|
2. **Cookie inject AppDelegate** (iOS) : mécanisme critique pour l'auth WKWebView. Toute modif `AppDelegate.swift` doit préserver ce flux. Il vit dans `didFinishLaunchingWithOptions`, qui **reste appelé** en cycle de vie par scènes et **avant** la connexion de la scène — Apple documente la séquence, l'ordre cookie → WebView est donc garanti.
|
||||||
|
2bis. **⚠️ Cycle de vie UIScene depuis le 22/09/2026** (obligatoire iOS 27, Capacitor ≥ 8.5.2). Trois callbacks ont quitté `AppDelegate.swift` pour `SceneDelegate.swift`, et UIKit **ne les appelle plus sur l'AppDelegate même si on les y remet** : retour OAuth Google (`scene(_:openURLContexts:)`), Universal Links (`scene(_:continue:)`), flush des saisies widget (`sceneDidBecomeActive`). Aucun ne produit d'erreur de compilation s'il est mal placé — la panne est silencieuse. Le `SceneDelegate` instancie **`MainViewController`**, jamais un `CAPBridgeViewController` nu comme le template Capacitor : la sous-classe porte l'enregistrement des plugins et la config WKWebView. ⛔ Ne pas lancer `npx cap migrate` sur ce projet (le guide officiel exclut les AppDelegate à gestion d'URL personnalisée), ni `npm audit fix --force` (il redescend le CLI en v7 et supprime le support UIScene).
|
||||||
3. **Health Connect Android** : nécessite la privacy policy URL dans le manifest (validation Play Console).
|
3. **Health Connect Android** : nécessite la privacy policy URL dans le manifest (validation Play Console).
|
||||||
4. **Pas d'extrapolation** : root cause vérifiable avant tout fix natif. iOS+Android = doubles surfaces de bug.
|
4. **Pas d'extrapolation** : root cause vérifiable avant tout fix natif. iOS+Android = doubles surfaces de bug.
|
||||||
5. **Default yes** : décider et exécuter (sauf actions destructives).
|
5. **Default yes** : décider et exécuter (sauf actions destructives).
|
||||||
|
|||||||
@@ -71,6 +71,7 @@
|
|||||||
E547F675B2F61C3475D2A787 /* LiveActivityManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = B93DA6B121E94B11DF938C90 /* LiveActivityManager.swift */; };
|
E547F675B2F61C3475D2A787 /* LiveActivityManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = B93DA6B121E94B11DF938C90 /* LiveActivityManager.swift */; };
|
||||||
F1ABCDEF0123456789AB0001 /* CoachHealthRoute.swift in Sources */ = {isa = PBXBuildFile; fileRef = F1ABCDEF0123456789AB0002 /* CoachHealthRoute.swift */; };
|
F1ABCDEF0123456789AB0001 /* CoachHealthRoute.swift in Sources */ = {isa = PBXBuildFile; fileRef = F1ABCDEF0123456789AB0002 /* CoachHealthRoute.swift */; };
|
||||||
F1ABCDEF0123456789AB0003 /* CoachSleep.swift in Sources */ = {isa = PBXBuildFile; fileRef = F1ABCDEF0123456789AB0004 /* CoachSleep.swift */; };
|
F1ABCDEF0123456789AB0003 /* CoachSleep.swift in Sources */ = {isa = PBXBuildFile; fileRef = F1ABCDEF0123456789AB0004 /* CoachSleep.swift */; };
|
||||||
|
60BB59C4096F4C8EB22DE183 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = B82F240520FD4C6CB4A80522 /* SceneDelegate.swift */; };
|
||||||
/* End PBXBuildFile section */
|
/* End PBXBuildFile section */
|
||||||
|
|
||||||
/* Begin PBXContainerItemProxy section */
|
/* Begin PBXContainerItemProxy section */
|
||||||
@@ -195,6 +196,7 @@
|
|||||||
F1ABCDEF0123456789AB0004 /* CoachSleep.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CoachSleep.swift; sourceTree = "<group>"; };
|
F1ABCDEF0123456789AB0004 /* CoachSleep.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CoachSleep.swift; sourceTree = "<group>"; };
|
||||||
F6BEAEF6F6274D61CAF22636 /* CoachWatchApp.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = CoachWatchApp.swift; sourceTree = "<group>"; };
|
F6BEAEF6F6274D61CAF22636 /* CoachWatchApp.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = CoachWatchApp.swift; sourceTree = "<group>"; };
|
||||||
FBFCA969A1B083CD3178D9B2 /* Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
FBFCA969A1B083CD3178D9B2 /* Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||||
|
B82F240520FD4C6CB4A80522 /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = "<group>"; };
|
||||||
/* End PBXFileReference section */
|
/* End PBXFileReference section */
|
||||||
|
|
||||||
/* Begin PBXFileSystemSynchronizedBuildFileExceptionSet section */
|
/* Begin PBXFileSystemSynchronizedBuildFileExceptionSet section */
|
||||||
@@ -208,7 +210,18 @@
|
|||||||
/* End PBXFileSystemSynchronizedBuildFileExceptionSet section */
|
/* End PBXFileSystemSynchronizedBuildFileExceptionSet section */
|
||||||
|
|
||||||
/* Begin PBXFileSystemSynchronizedRootGroup section */
|
/* Begin PBXFileSystemSynchronizedRootGroup section */
|
||||||
880A76D4302B601000F582D5 /* CoachWatchWidgets */ = {isa = PBXFileSystemSynchronizedRootGroup; exceptions = (880A76E2302B601100F582D5 /* PBXFileSystemSynchronizedBuildFileExceptionSet */, ); explicitFileTypes = {}; explicitFolders = (); path = CoachWatchWidgets; sourceTree = "<group>"; };
|
880A76D4302B601000F582D5 /* CoachWatchWidgets */ = {
|
||||||
|
isa = PBXFileSystemSynchronizedRootGroup;
|
||||||
|
exceptions = (
|
||||||
|
880A76E2302B601100F582D5 /* PBXFileSystemSynchronizedBuildFileExceptionSet */,
|
||||||
|
);
|
||||||
|
explicitFileTypes = {
|
||||||
|
};
|
||||||
|
explicitFolders = (
|
||||||
|
);
|
||||||
|
path = CoachWatchWidgets;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
/* End PBXFileSystemSynchronizedRootGroup section */
|
/* End PBXFileSystemSynchronizedRootGroup section */
|
||||||
|
|
||||||
/* Begin PBXFrameworksBuildPhase section */
|
/* Begin PBXFrameworksBuildPhase section */
|
||||||
@@ -330,6 +343,7 @@
|
|||||||
6030BD533EBC2D1D26DB9479 /* LiveStore.swift */,
|
6030BD533EBC2D1D26DB9479 /* LiveStore.swift */,
|
||||||
340B99D5EA4DB985D7DFDA10 /* CoachLiveView.swift */,
|
340B99D5EA4DB985D7DFDA10 /* CoachLiveView.swift */,
|
||||||
B93DA6B121E94B11DF938C90 /* LiveActivityManager.swift */,
|
B93DA6B121E94B11DF938C90 /* LiveActivityManager.swift */,
|
||||||
|
B82F240520FD4C6CB4A80522 /* SceneDelegate.swift */,
|
||||||
);
|
);
|
||||||
path = App;
|
path = App;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@@ -589,6 +603,7 @@
|
|||||||
548F8BFA06417B35474BD69E /* CoachLiveView.swift in Sources */,
|
548F8BFA06417B35474BD69E /* CoachLiveView.swift in Sources */,
|
||||||
D1384CFA4960060CDBF05FC3 /* CoachLiveActivityAttributes.swift in Sources */,
|
D1384CFA4960060CDBF05FC3 /* CoachLiveActivityAttributes.swift in Sources */,
|
||||||
E547F675B2F61C3475D2A787 /* LiveActivityManager.swift in Sources */,
|
E547F675B2F61C3475D2A787 /* LiveActivityManager.swift in Sources */,
|
||||||
|
60BB59C4096F4C8EB22DE183 /* SceneDelegate.swift in Sources */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,12 +1,11 @@
|
|||||||
import UIKit
|
import UIKit
|
||||||
import Capacitor
|
import Capacitor
|
||||||
#if canImport(GoogleSignIn)
|
|
||||||
import GoogleSignIn
|
|
||||||
#endif
|
|
||||||
|
|
||||||
@UIApplicationMain
|
@UIApplicationMain
|
||||||
class AppDelegate: UIResponder, UIApplicationDelegate {
|
class AppDelegate: UIResponder, UIApplicationDelegate {
|
||||||
|
|
||||||
|
// Conservée comme dans le template Capacitor 8.5. En cycle par scènes,
|
||||||
|
// c'est le SceneDelegate qui possède la fenêtre affichée.
|
||||||
var window: UIWindow?
|
var window: UIWindow?
|
||||||
|
|
||||||
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
|
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
|
||||||
@@ -47,28 +46,30 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
|
|||||||
HTTPCookieStorage.shared.setCookie(cookie)
|
HTTPCookieStorage.shared.setCookie(cookie)
|
||||||
}
|
}
|
||||||
|
|
||||||
func applicationWillResignActive(_ application: UIApplication) {}
|
// ─── Cycle de vie par scènes (obligatoire iOS 27) ───────────────────
|
||||||
func applicationDidEnterBackground(_ application: UIApplication) {}
|
//
|
||||||
func applicationWillEnterForeground(_ application: UIApplication) {}
|
// ⚠️ Depuis l'adoption du `UIApplicationSceneManifest`, UIKit n'appelle
|
||||||
func applicationDidBecomeActive(_ application: UIApplication) {
|
// PLUS `applicationDidBecomeActive`, `application(_:open:options:)` ni
|
||||||
// Les saisies faites depuis le widget (eau, café) attendent dans l'App
|
// `application(_:continue:restorationHandler:)` — « even if you keep them
|
||||||
// Group : une extension n'a ni session ni droit de tenir une requête.
|
// implemented » (Apple, *Transitioning to the UIKit scene-based life
|
||||||
// On les transmet ici, à chaque retour au premier plan.
|
// cycle*). Les trois ont déménagé dans `SceneDelegate.swift` :
|
||||||
Task { await CoachQuickSync.flush() }
|
//
|
||||||
|
// applicationDidBecomeActive -> sceneDidBecomeActive (CoachQuickSync)
|
||||||
|
// application(_:open:options:) -> scene(_:openURLContexts:) (OAuth Google)
|
||||||
|
// application(_:continue:…) -> scene(_:continue:) (Universal Links)
|
||||||
|
//
|
||||||
|
// Elles ne sont pas conservées ici en doublon : une méthode morte qui a
|
||||||
|
// l'air vivante est exactement ce qui fait chercher la panne au mauvais
|
||||||
|
// endroit. Les callbacks de notification distante, eux, restent sur
|
||||||
|
// l'AppDelegate — `UISceneDelegate` n'en a aucun équivalent.
|
||||||
|
func application(_ application: UIApplication,
|
||||||
|
configurationForConnecting connectingSceneSession: UISceneSession,
|
||||||
|
options: UIScene.ConnectionOptions) -> UISceneConfiguration {
|
||||||
|
let config = UISceneConfiguration(name: "Default Configuration",
|
||||||
|
sessionRole: connectingSceneSession.role)
|
||||||
|
config.delegateClass = SceneDelegate.self
|
||||||
|
return config
|
||||||
}
|
}
|
||||||
|
|
||||||
func applicationWillTerminate(_ application: UIApplication) {}
|
func applicationWillTerminate(_ application: UIApplication) {}
|
||||||
|
|
||||||
func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey: Any] = [:]) -> Bool {
|
|
||||||
#if canImport(GoogleSignIn)
|
|
||||||
// Retour du flux OAuth Google (reversed client id URL scheme).
|
|
||||||
if GIDSignIn.sharedInstance.handle(url) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
return ApplicationDelegateProxy.shared.application(app, open: url, options: options)
|
|
||||||
}
|
|
||||||
|
|
||||||
func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool {
|
|
||||||
return ApplicationDelegateProxy.shared.application(application, continue: userActivity, restorationHandler: restorationHandler)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -50,6 +50,25 @@
|
|||||||
<string>location</string>
|
<string>location</string>
|
||||||
<string>fetch</string>
|
<string>fetch</string>
|
||||||
</array>
|
</array>
|
||||||
|
<key>UIApplicationSceneManifest</key>
|
||||||
|
<dict>
|
||||||
|
<key>UIApplicationSupportsMultipleScenes</key>
|
||||||
|
<false/>
|
||||||
|
<key>UISceneConfigurations</key>
|
||||||
|
<dict>
|
||||||
|
<key>UIWindowSceneSessionRoleApplication</key>
|
||||||
|
<array>
|
||||||
|
<dict>
|
||||||
|
<key>UISceneConfigurationName</key>
|
||||||
|
<string>Default Configuration</string>
|
||||||
|
<key>UISceneDelegateClassName</key>
|
||||||
|
<string>$(PRODUCT_MODULE_NAME).SceneDelegate</string>
|
||||||
|
<key>UISceneStoryboardFile</key>
|
||||||
|
<string>Main</string>
|
||||||
|
</dict>
|
||||||
|
</array>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
<key>UILaunchStoryboardName</key>
|
<key>UILaunchStoryboardName</key>
|
||||||
<string>LaunchScreen</string>
|
<string>LaunchScreen</string>
|
||||||
<key>UIMainStoryboardFile</key>
|
<key>UIMainStoryboardFile</key>
|
||||||
|
|||||||
81
ios/App/App/SceneDelegate.swift
Normal file
81
ios/App/App/SceneDelegate.swift
Normal file
@@ -0,0 +1,81 @@
|
|||||||
|
import UIKit
|
||||||
|
import Capacitor
|
||||||
|
#if canImport(GoogleSignIn)
|
||||||
|
import GoogleSignIn
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/// Cycle de vie par scènes, **obligatoire** depuis iOS 27 : « apps built with
|
||||||
|
/// the latest SDK must adopt the scene-based life cycle or they fail to launch »
|
||||||
|
/// (Apple, *Transitioning to the UIKit scene-based life cycle*). Sans ce
|
||||||
|
/// fichier et le `UIApplicationSceneManifest` de l'Info.plist, l'app ne démarre
|
||||||
|
/// pas du tout — c'est un assert au lancement, pas un avertissement.
|
||||||
|
///
|
||||||
|
/// ⚠️ **Ce qui arrive ici arrive en SILENCE.** Une fois le manifeste en place,
|
||||||
|
/// UIKit cesse d'appeler `application(_:open:options:)`,
|
||||||
|
/// `application(_:continue:restorationHandler:)` et `applicationDidBecomeActive`
|
||||||
|
/// sur l'AppDelegate — « even if you keep them implemented » (Apple). Rien ne
|
||||||
|
/// casse à la compilation : le retour OAuth Google part vers Safari et ne
|
||||||
|
/// revient jamais, et les saisies du widget restent bloquées dans l'App Group.
|
||||||
|
/// Les trois sont donc repris ci-dessous.
|
||||||
|
///
|
||||||
|
/// Ce que la migration NE change PAS, et c'est ce qui la rendait acceptable :
|
||||||
|
/// `application(_:didFinishLaunchingWithOptions:)` reste appelé, et toujours
|
||||||
|
/// **avant** que la scène ne se connecte — donc avant que la WKWebView charge.
|
||||||
|
/// L'injection du cookie d'auth garde son ordre (Apple documente la séquence :
|
||||||
|
/// launch → création des scènes → `scene(_:willConnectTo:)`). Les callbacks de
|
||||||
|
/// notification distante ne bougent pas non plus : `UISceneDelegate` n'a aucun
|
||||||
|
/// équivalent, et ils ne sont pas dépréciés.
|
||||||
|
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
|
||||||
|
var window: UIWindow?
|
||||||
|
|
||||||
|
func scene(_ scene: UIScene,
|
||||||
|
willConnectTo session: UISceneSession,
|
||||||
|
options connectionOptions: UIScene.ConnectionOptions) {
|
||||||
|
guard let windowScene = scene as? UIWindowScene else { return }
|
||||||
|
|
||||||
|
// Le manifeste déclare `UISceneStoryboardFile = Main` : UIKit a donc
|
||||||
|
// déjà chargé Main.storyboard et instancié `MainViewController`, qui
|
||||||
|
// porte l'enregistrement des plugins natifs et la config WKWebView.
|
||||||
|
//
|
||||||
|
// Le template de Capacitor pose ici un `CAPBridgeViewController()` nu.
|
||||||
|
// L'appliquer tel quel remplacerait notre sous-classe et ferait perdre
|
||||||
|
// cette configuration **sans erreur visible**. On ne crée donc la
|
||||||
|
// fenêtre que si le storyboard ne l'a pas fait, et avec notre
|
||||||
|
// contrôleur.
|
||||||
|
if window == nil {
|
||||||
|
let fenetre = UIWindow(windowScene: windowScene)
|
||||||
|
fenetre.rootViewController = MainViewController()
|
||||||
|
window = fenetre
|
||||||
|
fenetre.makeKeyAndVisible()
|
||||||
|
}
|
||||||
|
|
||||||
|
SceneDelegateProxy.shared.scene(scene, willConnectTo: session, options: connectionOptions)
|
||||||
|
}
|
||||||
|
|
||||||
|
func scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>) {
|
||||||
|
// Retour du flux OAuth Google. `handle(url)` prend UNE url alors que la
|
||||||
|
// scène en livre un ensemble : on laisse à Capacitor ce que Google n'a
|
||||||
|
// pas consommé, plutôt que de tout lui passer ou de tout lui cacher.
|
||||||
|
var restants = URLContexts
|
||||||
|
#if canImport(GoogleSignIn)
|
||||||
|
restants = URLContexts.filter { !GIDSignIn.sharedInstance.handle($0.url) }
|
||||||
|
#endif
|
||||||
|
guard !restants.isEmpty else { return }
|
||||||
|
SceneDelegateProxy.shared.scene(scene, openURLContexts: restants)
|
||||||
|
}
|
||||||
|
|
||||||
|
func scene(_ scene: UIScene, continue userActivity: NSUserActivity) {
|
||||||
|
// Universal Links : les .widgetURL des widgets, de la Live Activity et
|
||||||
|
// des complications Watch passent par là. Sans ce relais, ils
|
||||||
|
// ouvriraient Safari, où le cookie injecté dans la WKWebView n'existe
|
||||||
|
// pas.
|
||||||
|
SceneDelegateProxy.shared.scene(scene, continue: userActivity)
|
||||||
|
}
|
||||||
|
|
||||||
|
func sceneDidBecomeActive(_ scene: UIScene) {
|
||||||
|
// Reprend `applicationDidBecomeActive`, qu'UIKit n'appelle plus. Les
|
||||||
|
// saisies faites depuis le widget (eau, café) attendent dans l'App
|
||||||
|
// Group : une extension n'a ni session ni droit de tenir une requête.
|
||||||
|
Task { await CoachQuickSync.flush() }
|
||||||
|
}
|
||||||
|
}
|
||||||
40
package-lock.json
generated
40
package-lock.json
generated
@@ -9,12 +9,12 @@
|
|||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
"license": "UNLICENSED",
|
"license": "UNLICENSED",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@capacitor/android": "^8.3.1",
|
"@capacitor/android": "^8.5.2",
|
||||||
"@capacitor/app": "^8.1.0",
|
"@capacitor/app": "^8.1.0",
|
||||||
"@capacitor/core": "^8.3.1",
|
"@capacitor/core": "^8.5.2",
|
||||||
"@capacitor/geolocation": "^8.2.0",
|
"@capacitor/geolocation": "^8.2.0",
|
||||||
"@capacitor/haptics": "^8.0.2",
|
"@capacitor/haptics": "^8.0.2",
|
||||||
"@capacitor/ios": "^8.3.1",
|
"@capacitor/ios": "^8.5.2",
|
||||||
"@capacitor/local-notifications": "^8.0.2",
|
"@capacitor/local-notifications": "^8.0.2",
|
||||||
"@capacitor/push-notifications": "^8.0.3",
|
"@capacitor/push-notifications": "^8.0.3",
|
||||||
"@capacitor/splash-screen": "^8.0.1",
|
"@capacitor/splash-screen": "^8.0.1",
|
||||||
@@ -24,7 +24,7 @@
|
|||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@capacitor/assets": "^3.0.5",
|
"@capacitor/assets": "^3.0.5",
|
||||||
"@capacitor/cli": "^8.3.1"
|
"@capacitor/cli": "^8.5.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@babel/code-frame": {
|
"node_modules/@babel/code-frame": {
|
||||||
@@ -51,12 +51,12 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@capacitor/android": {
|
"node_modules/@capacitor/android": {
|
||||||
"version": "8.3.1",
|
"version": "8.5.2",
|
||||||
"resolved": "https://registry.npmjs.org/@capacitor/android/-/android-8.3.1.tgz",
|
"resolved": "https://registry.npmjs.org/@capacitor/android/-/android-8.5.2.tgz",
|
||||||
"integrity": "sha512-hjskIG8YcBEh3X4yaTXvE9gcqpdcxunTgFruSKnuPxtMxAUzEK4Oq25x0Z1g3cz+MQPc+lRG09R7Ovc+ydKsNw==",
|
"integrity": "sha512-rtiaz78egCcS+vs29wkWCL3C+RhazKMSygXcjutwWP8NmO6r5UBxOvGf3Wjz5+ahobyQ723tn9gCePwRwcNDZQ==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@capacitor/core": "^8.3.0"
|
"@capacitor/core": "^8.5.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@capacitor/app": {
|
"node_modules/@capacitor/app": {
|
||||||
@@ -452,10 +452,11 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/@capacitor/cli": {
|
"node_modules/@capacitor/cli": {
|
||||||
"version": "8.3.1",
|
"version": "8.5.2",
|
||||||
"resolved": "https://registry.npmjs.org/@capacitor/cli/-/cli-8.3.1.tgz",
|
"resolved": "https://registry.npmjs.org/@capacitor/cli/-/cli-8.5.2.tgz",
|
||||||
"integrity": "sha512-1sPGW4THTDfR6YjXwZ0jM7oAfAtciPOHN00qs/3sNAQx1kKrrEYSfDPwCm1/xlAgi0OeL69SiRfw314Ans+1sw==",
|
"integrity": "sha512-O2kpA5ZPJUAmliDCcmpMf8xnJwMezxlFPUrlyOAjbL3U9MFNY3l4ZpPI/UXwvyPmR8ETcVF9pFr+VdWq61rqTQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@ionic/cli-framework-output": "^2.2.8",
|
"@ionic/cli-framework-output": "^2.2.8",
|
||||||
"@ionic/utils-subprocess": "^3.0.1",
|
"@ionic/utils-subprocess": "^3.0.1",
|
||||||
@@ -473,6 +474,7 @@
|
|||||||
"semver": "^7.6.3",
|
"semver": "^7.6.3",
|
||||||
"tar": "^7.5.3",
|
"tar": "^7.5.3",
|
||||||
"tslib": "^2.8.1",
|
"tslib": "^2.8.1",
|
||||||
|
"xcode": "^3.0.1",
|
||||||
"xml2js": "^0.6.2"
|
"xml2js": "^0.6.2"
|
||||||
},
|
},
|
||||||
"bin": {
|
"bin": {
|
||||||
@@ -484,9 +486,10 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@capacitor/core": {
|
"node_modules/@capacitor/core": {
|
||||||
"version": "8.3.1",
|
"version": "8.5.2",
|
||||||
"resolved": "https://registry.npmjs.org/@capacitor/core/-/core-8.3.1.tgz",
|
"resolved": "https://registry.npmjs.org/@capacitor/core/-/core-8.5.2.tgz",
|
||||||
"integrity": "sha512-UF8ItlHguU1Z6GXfPTeT2gakf+ctNI8pAS1kwSBQlsJMlfD4OPoto/SmKnOxKCQvnF4WRcdWeg6C0zREUNaAQg==",
|
"integrity": "sha512-agnQbGdhGw/KZFuLf7H9SY2o+oE7upkr/WPQsYaokXP6f9chaE8iVmbKkfN6SVl4w3pmz7oZ3Ur1hbkmy1hx+w==",
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"tslib": "^2.1.0"
|
"tslib": "^2.1.0"
|
||||||
}
|
}
|
||||||
@@ -511,11 +514,12 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@capacitor/ios": {
|
"node_modules/@capacitor/ios": {
|
||||||
"version": "8.3.1",
|
"version": "8.5.2",
|
||||||
"resolved": "https://registry.npmjs.org/@capacitor/ios/-/ios-8.3.1.tgz",
|
"resolved": "https://registry.npmjs.org/@capacitor/ios/-/ios-8.5.2.tgz",
|
||||||
"integrity": "sha512-BEhLyYYHWJLib4mpaPMaaylbC8meqgxbNYwQJH2svsSLW7yo/hFie+Zoo66a44XnqcMd2tvmAuzimWunXZi/xA==",
|
"integrity": "sha512-eOT2S67AfTFG7KN0T3oxwAajrJz4rSye+ODfvChiwrk0F/+kWufFM1qU6cDjGJUOfwdAoeuEpZyWHSwZlu4GFg==",
|
||||||
|
"license": "MIT",
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@capacitor/core": "^8.3.0"
|
"@capacitor/core": "^8.5.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@capacitor/local-notifications": {
|
"node_modules/@capacitor/local-notifications": {
|
||||||
|
|||||||
@@ -15,12 +15,12 @@
|
|||||||
"author": "Sylvain Bettinelli",
|
"author": "Sylvain Bettinelli",
|
||||||
"license": "UNLICENSED",
|
"license": "UNLICENSED",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@capacitor/android": "^8.3.1",
|
"@capacitor/android": "^8.5.2",
|
||||||
"@capacitor/app": "^8.1.0",
|
"@capacitor/app": "^8.1.0",
|
||||||
"@capacitor/core": "^8.3.1",
|
"@capacitor/core": "^8.5.2",
|
||||||
"@capacitor/geolocation": "^8.2.0",
|
"@capacitor/geolocation": "^8.2.0",
|
||||||
"@capacitor/haptics": "^8.0.2",
|
"@capacitor/haptics": "^8.0.2",
|
||||||
"@capacitor/ios": "^8.3.1",
|
"@capacitor/ios": "^8.5.2",
|
||||||
"@capacitor/local-notifications": "^8.0.2",
|
"@capacitor/local-notifications": "^8.0.2",
|
||||||
"@capacitor/push-notifications": "^8.0.3",
|
"@capacitor/push-notifications": "^8.0.3",
|
||||||
"@capacitor/splash-screen": "^8.0.1",
|
"@capacitor/splash-screen": "^8.0.1",
|
||||||
@@ -30,6 +30,6 @@
|
|||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@capacitor/assets": "^3.0.5",
|
"@capacitor/assets": "^3.0.5",
|
||||||
"@capacitor/cli": "^8.3.1"
|
"@capacitor/cli": "^8.5.2"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user