expo-app-blocker 0.1.66 → 0.1.67

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -203,11 +203,15 @@ public class ExpoAppBlockerModule: Module {
203
203
 
204
204
  Function("drainPendingIntercepts") { () -> [[String: Any]] in
205
205
  guard let defaults = self.sharedDefaults else { return [] }
206
+ // Refresh the cached suite so writes made by the (separate) shield
207
+ // extension process are visible to this long-lived app process.
208
+ defaults.synchronize()
206
209
  let queue = defaults.array(forKey: self.pendingInterceptsKey) as? [[String: Any]] ?? []
207
210
  if !queue.isEmpty {
208
211
  defaults.removeObject(forKey: self.pendingInterceptsKey)
209
212
  defaults.synchronize()
210
213
  }
214
+ NSLog("[appblocker] drainPendingIntercepts: returning \(queue.count)")
211
215
  return queue
212
216
  }
213
217
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "expo-app-blocker",
3
- "version": "0.1.66",
3
+ "version": "0.1.67",
4
4
  "description": "Expo module for cross-platform app blocking. Android: UsageStatsManager + Overlay. iOS: Screen Time API (FamilyControls + ManagedSettings + DeviceActivity).",
5
5
  "main": "src/index.ts",
6
6
  "types": "src/index.ts",
@@ -53,10 +53,19 @@ class ShieldConfigurationExtension: ShieldConfigurationDataSource {
53
53
  private let maxPendingIntercepts = 200
54
54
 
55
55
  private func recordIntercept(appName: String) {
56
- guard let defaults = UserDefaults(suiteName: appGroupIdentifier) else { return }
56
+ guard let defaults = UserDefaults(suiteName: appGroupIdentifier) else {
57
+ NSLog("[appblocker] recordIntercept: no app-group defaults")
58
+ return
59
+ }
60
+ // The extension is a short-lived process; pull a fresh view before
61
+ // read-modify-write so we don't clobber the app's drain.
62
+ defaults.synchronize()
57
63
  let nowMs = Date().timeIntervalSince1970 * 1000.0
58
64
  let lastMs = defaults.double(forKey: lastInterceptTsKey)
59
- if lastMs > 0, (nowMs - lastMs) < interceptDebounceMs { return }
65
+ if lastMs > 0, (nowMs - lastMs) < interceptDebounceMs {
66
+ NSLog("[appblocker] recordIntercept: debounced")
67
+ return
68
+ }
60
69
 
61
70
  var queue = defaults.array(forKey: pendingInterceptsKey) as? [[String: Any]] ?? []
62
71
  queue.append(["appName": appName, "interceptedAt": nowMs])
@@ -65,6 +74,10 @@ class ShieldConfigurationExtension: ShieldConfigurationDataSource {
65
74
  }
66
75
  defaults.set(queue, forKey: pendingInterceptsKey)
67
76
  defaults.set(nowMs, forKey: lastInterceptTsKey)
77
+ // Force a flush to cfprefsd — the OS may suspend/kill the extension
78
+ // immediately after rendering, before an unflushed write persists.
79
+ defaults.synchronize()
80
+ NSLog("[appblocker] recordIntercept: queued \(appName), depth=\(queue.count)")
68
81
  }
69
82
 
70
83
  private func makeConfig(appName: String) -> ShieldConfiguration {