Skip to content

Two UIApplication.shared.open(_:) calls keep GutenbergKit from building extension-safe #731

Description

@jkmassel

Two places open an external URL through UIApplication.shared.open(_:), and they're the only thing stopping GutenbergKit from building as app-extension-safe code.

Detail

ios/Sources/GutenbergKit/Sources/EditorViewController.swift:1206 sends an external main-frame navigation to the system browser:

if let url = navigationAction.request.url {
    Logger.navigation.debug("Opening external URL in system browser: \(url.absoluteString)")
    await UIApplication.shared.open(url)
}

ios/Sources/GutenbergKit/Sources/Services/LockdownModeMonitor.swift:162 backs the Lockdown Mode sheet's "Learn more" button:

onLearnMore: {
    // Open support article directly to the exclusion section using text fragment
    if let url = URL(string: "https://support.apple.com/en-us/105120#:~:text=…") {
        UIApplication.shared.open(url)
    }
}

How it bites

UIApplication.shared is unavailable in app extensions. Building the GutenbergKit scheme with APPLICATION_EXTENSION_API_ONLY=YES fails on exactly these two lines:

LockdownModeMonitor.swift:162:35: error: 'shared' is unavailable in application extensions for iOS: Use view controller based solutions where appropriate instead.
EditorViewController.swift:1206:33: error: 'shared' is unavailable in application extensions for iOS: Use view controller based solutions where appropriate instead.

With both lines commented out, the same build succeeds, so these are the whole list. While they're here, a host can't embed the editor in an app extension (a share extension, say).

Beyond extensions, library code shouldn't reach for an app-wide global it doesn't own when a view- or scene-scoped API does the same job. #669 removed a third use for the same reason (the upload server's background-task assertion, now a ProcessInfo expiring activity). These two don't share that one's main-thread problem — both already run on the main actor.

Suggested fix

  • LockdownModeSheet: open the link with SwiftUI's @Environment(\.openURL) inside the sheet, instead of passing an onLearnMore closure that calls UIApplication.
  • EditorViewController: open through the editor's own scene, view.window?.windowScene?.open(url, options: nil).

Both compile under -application-extension. Whether either actually opens anything at runtime inside an extension is a separate question, since extensions generally can't hand a URL to the browser. If we want real extension support, the navigation case probably wants an EditorViewControllerDelegate method so the host decides — hosts may prefer an in-app browser anyway.

Found while reviewing #669. Pre-existing; that PR does not touch these paths.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    [Type] BugAn existing feature does not function as intended[Type] Code QualityIssues or PRs that relate to code qualityiOS

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions