Shield Customisation Not Applying

Hi, I've been attempting to implement a customised shield based on the WWDC contents and documentation; however, while my configuration appears correct only the default "Restricted - You cannot use X app because it's restricted" ever displays.

A quick summary of what I have done:

  1. Created a ShieldConfigurationExtension
  2. Ensured suitable Info.plist values - below
  3. Defined custom Shield within the configuration() methods - application example below

Any suggestions on what might not be implemented correctly?

Info.plist

<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>NSExtension</key>
	<dict>
		<key>NSExtensionPointIdentifier</key>
		<string>com.apple.ManagedSettingsUI.shield-configuration-service</string>
		<key>NSExtensionPrincipalClass</key>
		<string>$(PRODUCT_MODULE_NAME).ShieldConfigurationExtension</string>
	</dict>
</dict>
</plist>

Configuration

import ManagedSettings
import ManagedSettingsUI
import UIKit

class ShieldConfigurationExtension: ShieldConfigurationDataSource {
   
  override func configuration(shielding application: Application) -> ShieldConfiguration {
    // Customize the shield as needed for applications.
    return ShieldConfiguration(
      backgroundBlurStyle: UIBlurEffect.Style.systemThickMaterial,
      backgroundColor: UIColor.white,
      icon: UIImage(systemName: "stopwatch"),
      title: ShieldConfiguration.Label(text: "No app for you", color: .yellow),
      subtitle: ShieldConfiguration.Label(text: "Sorry, no apps for you", color: .white),
      primaryButtonLabel: ShieldConfiguration.Label(text: "Ask for a break?", color: .white),
      secondaryButtonLabel: ShieldConfiguration.Label(text: "Quick Quick", color: .white)
    )
  }
}

In ShieldConfigurationExtension you are overriding only the function which is responsible only for individually blocked applications. Maybe you are blocking applications based on category? Or blocking a webdomain?

Check the other functions available in ShieldConfigurationDataSource which you can override: https://developer.apple.com/documentation/managedsettingsui/shieldconfigurationdatasource

The application category shield: https://developer.apple.com/documentation/managedsettingsui/shieldconfigurationdatasource/configuration(shielding:in:)-ia14

Hope it might help, I just started experimenting with the screen time api as well!

Hi jerobern, thanks for commenting 🙂

Interesting, I have tried setting for all blocking types - application, application category, webdomain and webdomain category. I just provided a single example to keep things more concise initially, but probably not such a good approach in hindsight. That said, your comments have drawn attention to the fact that I'm using a probably less-standard method for applying the shield .all(), so wonder whether this might be causing some side effects and limiting the shield config from applying.

Use of ".all()" to shield

import Foundation
import DeviceActivity
import ManagedSettings

extension ManagedSettingsStore.Name {
  static let social = Self("social")
}

func setShieldSettingsForAll() {
    let store = ManagedSettingsStore(named: .social)
    store.shield.applicationCategories = .all()
    store.shield.webDomainCategories = .all()
    logger.log("All Applications Set")
  }

Entire Sheild Config

import ManagedSettings
import ManagedSettingsUI
import UIKit

class ShieldConfigurationExtension: ShieldConfigurationDataSource {
   
  override func configuration(shielding application: Application) -> ShieldConfiguration {
    // Customize the shield as needed for applications.
    return ShieldConfiguration(
      backgroundBlurStyle: UIBlurEffect.Style.systemThickMaterial,
      backgroundColor: UIColor.white,
      icon: UIImage(systemName: "stopwatch"),
      title: ShieldConfiguration.Label(text: "No app for you", color: .yellow),
      subtitle: ShieldConfiguration.Label(text: "Sorry, no apps for you", color: .white),
      primaryButtonLabel: ShieldConfiguration.Label(text: "Ask for a break?", color: .white),
      secondaryButtonLabel: ShieldConfiguration.Label(text: "Quick Quick", color: .white)
    )
  }
   
  override func configuration(shielding application: Application, in category: ActivityCategory) -> ShieldConfiguration {
    // Customize the shield as needed for applications shielded because of their category.
    return ShieldConfiguration(
      backgroundBlurStyle: UIBlurEffect.Style.systemThickMaterial,
      backgroundColor: UIColor.white,
      icon: UIImage(systemName: "stopwatch"),
      title: ShieldConfiguration.Label(text: "No app for you", color: .yellow),
      subtitle: ShieldConfiguration.Label(text: "Sorry, no apps for you", color: .white),
      primaryButtonLabel: ShieldConfiguration.Label(text: "Ask for a break?", color: .white),
      secondaryButtonLabel: ShieldConfiguration.Label(text: "Quick Quick", color: .white)
    )
  }

  override func configuration(shielding webDomain: WebDomain) -> ShieldConfiguration {
    // Customize the shield as needed for web domains.
    return ShieldConfiguration(
      backgroundBlurStyle: UIBlurEffect.Style.systemThickMaterial,
      backgroundColor: UIColor.white,
      icon: UIImage(systemName: "stopwatch"),
      title: ShieldConfiguration.Label(text: "No app for you", color: .yellow),
      subtitle: ShieldConfiguration.Label(text: "Sorry, no apps for you", color: .white),
      primaryButtonLabel: ShieldConfiguration.Label(text: "Ask for a break?", color: .white),
      secondaryButtonLabel: ShieldConfiguration.Label(text: "Quick Quick", color: .white)
    )
  }

  override func configuration(shielding webDomain: WebDomain, in category: ActivityCategory) -> ShieldConfiguration {
    // Customize the shield as needed for web domains shielded because of their category.
    return ShieldConfiguration(
      backgroundBlurStyle: UIBlurEffect.Style.systemThickMaterial,
      backgroundColor: UIColor.white,
      icon: UIImage(systemName: "stopwatch"),
      title: ShieldConfiguration.Label(text: "No app for you", color: .yellow),
      subtitle: ShieldConfiguration.Label(text: "Sorry, no apps for you", color: .white),
      primaryButtonLabel: ShieldConfiguration.Label(text: "Ask for a break?", color: .white),
      secondaryButtonLabel: ShieldConfiguration.Label(text: "Quick Quick", color: .white)
    )
  }
}

I will try tweaking my shielding method and see if that changes things 🤞

Hey! I just matched the ShieldConfigurationExtension's iOS version to the main App's iOS version and it started working

you save my day. Tks

In my case, my icon was a PDF image. I resized it and used a PNG instead...Believe it or not, the correct shield configuration appeared.

Shield Customisation Not Applying
 
 
Q