Issue with Universal Links and App Extension (ShieldAction Handler)

Issue with Universal Links and App Extension (ShieldAction Handler)

I'm currently working on a POC app using the FamilyControls framework and facing an issue when trying to open a Universal Link from an app extension, specifically from a ShieldAction handler.

When I try to open a Universal Link, I encounter the following error:

Failed to open URL https://sixteen-server-c008110f8759.herokuapp.com/.well-known/apple-app-site-association: Error Domain=FBSOpenApplicationServiceErrorDomain Code=1 "The request to open 'com.apple.mobilesafari' failed." UserInfo={BSErrorCodeDescription=RequestDenied, NSUnderlyingError=0x14f2d90b0 {Error Domain=FBSOpenApplicationErrorDomain Code=3 "Application com.sixteen.life is neither visible nor entitled, so may not perform un-trusted user actions." UserInfo={BSErrorCodeDescription=Security, NSLocalizedFailureReason=Application com.sixteen.life is neither visible nor entitled, so may not perform un-trusted user actions.}} Context: I’m using a ShieldAction handler as part of an App Extension to trigger the action (e.g., "Break in Shield") in my app.

The app extension (ShieldAction handler) is responsible for trying to open the Universal Link.

I’m encountering the error because the app is not visible or entitled to perform this action, which seems to be related to security restrictions when using App Extensions.

Questions: App Extension and Universal Link Interaction: Is it possible for an App Extension (like ShieldAction handler) to open a Universal Link or trigger an external app, such as Safari, even though it is not the foreground app?

Entitlements for App Extensions: Are there any specific entitlements or permissions required to allow an app extension (ShieldAction handler) to open Universal Links or perform actions like opening Safari from the background?

App Visibility and State: How can I ensure that my app is in the right state (visible/active) and has the necessary entitlements to trigger these actions when running in the context of an app extension?

Workaround: If this behavior is restricted due to app extension limitations, what would be the recommended workaround to handle launching external apps (like Safari) or Universal Links from within an app extension?

Thank you for providing detailed information regarding the issue you are encountering with Universal Links and App Extensions. Let us address your inquiries:

Family controls impose security restrictions that prevent them from directly opening URLs, particularly when the application is not in the foreground. This design ensures user security and prevents unauthorized actions. Have you examined the swcutil_show.txt file for the registration? Can the device access the URL? If the device is unable to download the AASA file, the file will not be registered.

App Extensions operate within a restricted environment and lack the same permissions as the primary application, especially for actions involving launching other applications or handling Universal Links.

Given that the error indicates visibility and entitlement concerns, it is likely preventing the action. Is the application concealed or restricted by FamilyControls? The error below illustrates a restriction.

Due to security constraints, App Extensions cannot directly open URLs or Universal Links when running in the background. The recommended approach is to delegate the task to the main application using NSUserActivity, enabling the primary application to handle the URL with the appropriate permissions. This ensures that your Universal Links are opened correctly without encountering visibility or entitlement issues. Additionally, ensure that the AASA file is accessible and not restricted.

Furthermore, a minor detail. Your AASA file is utilizing the outdated format; I recommend updating to the new AASA format.

{
  "applinks": {
    "apps": [],
    "details": [
      {
        "appID": "WCG22C6287.com.sixteen.life",
        "paths": [
          "/launch/sixteen"
        ]
      }
    ]
  }
}

You can find a template here: https://developer.apple.com/documentation/technotes/tn3155-debugging-universal-links

Feel free to ask if you need further clarification or additional help with the implementation!

Albert Pascual
  Worldwide Developer Relations.

Still, I haven’t had any luck opening the app.

My Link: https://sixteen-server-c008110f8759.herokuapp.com/.well-known/apple-app-site-association/

Method to open the link: static void onReceiveDarwinNotification(CFNotificationCenterRef center, void *observer, CFStringRef name, const void *object, CFDictionaryRef userInfo) { dispatch_async(dispatch_get_main_queue(), ^{ NSURL *url = [NSURL URLWithString:@"https://sixteen-server-c008110f8759.herokuapp.com/launch/sixteen"]; if ([[UIApplication sharedApplication] canOpenURL:url]) { [[UIApplication sharedApplication] openURL:url options:@{} completionHandler:^(BOOL success) { NSLog(@"🔗 Opened universal link: %d", success); }]; } else { NSLog(@"❌ Cannot open URL"); } }); }

I'm using a Darwin notification from the Shield extension to communicate with the main app, and that communication works perfectly. I also tried using NSUserActivity, but had no success. I’m stuck with the following errors: ...retrieving pasteboard named com.apple.UIKit.pboard.general failed with error: Error Domain=PBErrorDomain Code=10 "Pasteboard com.apple.UIKit.pboard.general is not available at this time." UserInfo={NSLocalizedDescription=Pasteboard com.apple.UIKit.pboard.general is not available at this time.}

Failed to open URL https://sixteen-server-c008110f8759.herokuapp.com/launch/sixteen: Error Domain=FBSOpenApplicationServiceErrorDomain Code=4 "(null)" UserInfo={NSUnderlyingError=0x14f3b25e0 {Error Domain=FBSOpenApplicationErrorDomain Code=3 "Request is not trusted." UserInfo={BSErrorCodeDescription=Security, NSLocalizedFailureReason=Request is not trusted.}}, NSLocalizedFailure=The request to open "com.apple.mobilesafari" failed., FBSErrorContext=147937300, BSErrorCodeDescription=InvalidRequest}

This is a React Native app with a native Swift module used to integrate the FamilyControls framework. please help me to come out of this blocker.

Family controls impose security restrictions that prevent them from directly opening URLs, particularly when the application is not in the foreground.

Thanks for your feedback!

Could you elaborate exactly what privacy concerns this addresses?

I can’t think of any.

A user pressing a button in a piece of UI that is owned by our app should be allowed to open the parent app without bringing up any security or privacy concerns.

The error you pasted here is exactly why the URL won’t open from the shield action extension; the system does not allow to open URLs from background processes.

Application com.sixteen.life is neither visible nor entitled, so may not perform un-trusted user actions.

I understand and agree that opening URLs directly from background processes (like app extensions) is restricted by design for privacy and security reasons.

However, in our case, we are trying to handle a specific user interaction: When the user taps the primary button inside an App Extension (specifically, an App Shield), we want to open the main (parent) app.

Here’s what we’ve tried so far:

Custom URL Schemes

Universal Links

NSUserActivity

Darwin Notifications

Kingfisher-style runtime access to UIApplication.shared

Other commonly suggested workarounds found in developer threads and documentation

None of these approaches successfully triggered the parent app from within the extension in our case.

We’re looking for guidance on the correct and supported way to handle this: How can we properly launch the main app from an App Extension in response to a user-initiated tap?

Any official direction or best practice would be greatly appreciated.

Thank you!

@DTS Engineer We've been waiting a long time for this issue. Please help us with the queries mentioned above.

Different DTS Engineer here. Albert is unexpectedly out of the office for an extended period of time.

I’m not sure I fully understand the issue, so let me me recap. It seems that you’re trying to open a URL from your shield action extension, that is, the app extension that implements the ShieldActionDelegate protocol. Is that right?

If you tried to do this from your shield action extension, you might write code like this:

class ShieldActionExtension: ShieldActionDelegate {

    override func handle(action: ShieldAction, for application: ApplicationToken, completionHandler: @escaping (ShieldActionResponse) -> Void) {
        … lots of other code …
        let url = URL(string: "http://example.com")!
        UIApplication.shared.open(url)
                   // ^ 'shared' is unavailable in application extensions for iOS …
        … lots of other code …
    }
    
    …
}

When you do this it fails to compile, with the error I’ve included above. This error is pretty clear. App extensions are not apps and thus are not allowed to use UIApplication.

You’re trying to get around this by:

  1. Posting a Darwin notification in your appex.
  2. Catching that Darwin notification in your container app.
  3. Opening the URL from your container app.

Is that right?

If so, that’s not going to work. There are actually two concerns here:

  • Your container app is not at the front, and thus it can’t open URLs.
  • Even if it were, there’s no guarantee that the container app is running at the point that you send this notification [1]. It could be terminated or suspended.

That first point is fundamental. Appexes are not allowed to change the foreground app (at least not in the general case) and that’s why UIApplication is blocked. You can’t get around that limitation by bouncing through your container app.

One approach that folks have used successfully in the past is to post a user notification. If the user taps on it, that brings the container app to the front. This is allowed, because the user is in control.

I’m not sure if that approach is compatible with the whole Family Controls thing. I haven’t had a chance to try it.

If that doesn’t then my only advice is that you file an enhancement request for a supported way to bring your container app to the front from this context. Make sure to include a detailed explanation of why you’re doing this and what you’d like the UI to look like.

If you do file an ER, please your bug number, just for the record.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

[1] I suspect that you’re not seeing that problem in development because you have Xcode attached to the container app, and Xcode’s debugger prevents the system from suspending your app after it moves to the background.

Clarification on Opening Parent App from Shield Extension

Hi @DTS Engineer ,

Based on your response, can I confirm that currently Apple does not provide a supported API to directly open the main (container) app from a Shield Action extension?

I’m trying to understand the correct way to handle this use case:

When the user taps the primary button in the shield UI, we’d like to open the parent app. Apps like Wellspent and JOMO appear to have achieved this behavior, so I’m wondering what mechanism they might be using that is compliant with Apple’s guidelines.

I’ve already tried using Darwin notifications to signal the container app to open a URL, but I now understand this won’t work reliably due to app suspension and background limitations. I also experimented with App Intents, but that didn’t work either within the Shield Action extension context.

Can you please advise on the proper or recommended method to achieve this behavior, if any? If it’s not currently possible, I’d appreciate guidance on how to file an enhancement request, and whether Apple is aware of any workarounds being used by other apps that comply with App Store guidelines.

Thanks for your time and support.

I’m not able to comment on other developer’s app.

I will say that, in general, there can be a gap between what’s supported and what works. There are lots of things that DTS doesn’t support because, in our judgement, they rely on implementation details that don’t make for long-term binary compatibility.

IMPORTANT The above is a general statement and says nothing about this specific issue.

Anyway, Quappi just opened a new thread about this — Open Parent App From ShieldActionDelegate — and I think that thread is the right path forward here (because this thread is tangled up with failed implementation attempts).

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Issue with Universal Links and App Extension (ShieldAction Handler)
 
 
Q