As per our code, we have the apps to be shielded whenever the threshold is reached. According to this use-case, our code in DeviceActivityExtension looks something like:
override func eventDidReachThreshold(_ event: DeviceActivityEvent.Name, activity: DeviceActivityName) {
super.eventDidReachThreshold(event, activity: activity)
defaults?.setValue(event.rawValue, forKey: "appLimitEventName")
defaults?.setValue(true, forKey: "appLimitReached")
defaults?.synchronize()
// using darwinNotificationCenter to trigger callback in the application
let darwinNotificationCenter = DarwinNotificationsManager.sharedInstance()
darwinNotificationCenter.postNotification(withName: "nextAppLimitInitiated")
// using Notifications to debug since print doesn't work
scheduleNotification(with: "interval threshold reached")
}
And in our application, we have the shielding logic in place,
init() {
let darwinNotificationCenter = DarwinNotificationsManager.sharedInstance()
darwinNotificationCenter.register(forNotificationName: "nextAppLimitInitiated"){
print("callback received")
let appLimitReached = self.defaults?.bool(forKey: "appLimitReached")
let appLimitEventName = self.defaults?.string(forKey: "appLimitEventName")
if appLimitReached ?? false, appLimitEventName != "" {
// this sends the notification when callback is received
self.scheduleNotification(with: "init start")
self.defaults?.setValue(false, forKey: "appLimitReached")
guard var dataArray = self.defaults?.array(forKey: "appLimitdataArray"), !dataArray.isEmpty else {
return
}
let appLimitData = dataArray.first as! NSDictionary
let appLimitKey = appLimitData["appLimitId"] as! String
let data = self.getSchedule(key: appLimitEventName ?? "")
if let appTokens = data?.applicationTokens {
for token in appTokens {
if !self.applicationTokens.contains(appTokens) {
self.applicationTokens.insert(token)
}
}
}
self.store.shield.applications = self.applicationTokens
self.store.shield.applicationCategories = ShieldSettings.ActivityCategoryPolicy.specific(self.categoryTokens, except: Set())
dataArray.removeFirst()
//dataArray.append(appLimitData)
self.defaults?.set(dataArray, forKey: "appLimitdataArray")
self.initiateMonitoring(initiateAgain: true)
self.scheduleNotification(with: "init end")
}
}
}
This works as expected for multiple App Limits but only when the device is connected to the Xcode. If we disconnect the device from Xcode/ stop application from Xcode/ try in release mode, the callback is not received from extension to the app/init block.
When the device is connected to Xcode, if the apps hit the threshold, they are shielded automatically. But if the device is disconnected/ app is in release mode, the apps are not shielded automatically even after the threshold is reached. It is shielded later only after opening our app once.
Please let me know if I'm doing anything wrong in receiving callback or in my shielding logic. If I need to place the shielding logic in the extension, please tell me how I can handle multiple appTokens.