Skip to content

Conversation

@APshenkin
Copy link
Contributor

@APshenkin APshenkin commented Nov 6, 2025

Description

Provides support for universal links on macOS. https://developer.apple.com/documentation/xcode/supporting-universal-links-in-your-app

Wails already had support for custom scheme deeplinks, however to support universal links it requires additional handling in AppDelegate

Type of change

Please select the option that is relevant.

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • This change requires a documentation update

How Has This Been Tested?

Please describe the tests that you ran to verify your changes. Provide instructions so we can reproduce. Please also list any relevant details for your test configuration using wails doctor.

  • Windows
  • macOS
  • Linux

Test Configuration

# Wails
Version | v2.10.2


# System
┌────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
| OS           | MacOS                                                                                                                       |
| Version      | 26.0.1                                                                                                                      |
| ID           | 25A362                                                                                                                      |
| Branding     |                                                                                                                             |
| Go Version   | go1.24.0                                                                                                                    |
| Platform     | darwin                                                                                                                      |
| Architecture | arm64                                                                                                                       |
| CPU 1        | Apple M4 Max                                                                                                                |
| CPU 2        | Apple M4 Max                                                                                                                |
| GPU          | Chipset Model: Apple M4 Max Type: GPU Bus: Built-In Total Number of Cores: 40 Vendor: Apple (0x106b) Metal Support: Metal 4 |
| Memory       | 128GB                                                                                                                       |
└────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘

# Dependencies
┌────────────────────────────────────────────────────────────────────────┐
| Dependency                | Package Name | Status    | Version         |
| Xcode command line tools  | N/A          | Installed | 2412            |
| Nodejs                    | N/A          | Installed | 22.14.0         |
| npm                       | N/A          | Installed | 10.9.2          |
| *Xcode                    | N/A          | Installed | 26.0.1 (17A400) |
| *upx                      | N/A          | Available |                 |
| *nsis                     | N/A          | Available |                 |
|                                                                        |
└─────────────────────── * - Optional Dependency ────────────────────────┘

Checklist:

  • I have updated website/src/pages/changelog.mdx with details of this PR
  • My code follows the general coding style of this project
  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation
  • My changes generate no new warnings
  • I have added tests that prove my fix is effective or that my feature works
  • New and existing unit tests pass locally with my changes

Summary by CodeRabbit

  • New Features

    • Added macOS universal link support: the app can now receive and handle web URLs when continuing user activities and system link events.
  • Documentation

    • Changelog updated to note macOS universal link support.
    • Guide updated with macOS universal link setup steps (entitlements, Info.plist keys, associated-domain configuration).

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 6, 2025

Walkthrough

Adds macOS universal link handling: AppDelegate now continues NSUserActivity of type BrowsingWeb, extracts the URL and forwards it to a renamed native handler HandleOpenURL. The exported C symbol and AppleEvent handler were renamed accordingly; documentation and changelog updated.

Changes

Cohort / File(s) Summary
AppDelegate — user activity handling
v2/internal/frontend/desktop/darwin/AppDelegate.m
Adds -application:continueUserActivity:restorationHandler: to detect NSUserActivityTypeBrowsingWeb, extract the URL and call HandleOpenURL; imports CustomProtocol.h.
CustomProtocol header updates
v2/internal/frontend/desktop/darwin/CustomProtocol.h
Renames exported function declaration to extern void HandleOpenURL(char*); and adds - (void)handleGetURLEvent:withReplyEvent: method declaration on CustomProtocolSchemeHandler.
CustomProtocol implementation
v2/internal/frontend/desktop/darwin/CustomProtocol.m
Replaces calls to HandleCustomProtocol(...) with HandleOpenURL(...) in the AppleEvent URL handler; URL extraction and UTF-8 conversion remain the same.
Go binding export rename
v2/internal/frontend/desktop/darwin/frontend.go
Updates the cgo export directive and Go function name from HandleCustomProtocol to HandleOpenURL, preserving internals that forward the URL to openUrlBuffer.
Docs & changelog
website/src/pages/changelog.mdx, website/docs/guides/custom-protocol-schemes.mdx
Adds "Add universal link support for macOS" to changelog and documents entitlements/Info.plist keys and apple-app-site-association guidance for macOS universal links.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant macOS
    participant AppDelegate
    participant ObjC as CustomProtocol
    participant Go as Frontend

    User->>macOS: Open universal link
    macOS->>AppDelegate: continueUserActivity(_:restorationHandler:)

    rect rgb(230,245,255)
    Note over AppDelegate: Check activity.type == BrowsingWeb
    AppDelegate->>AppDelegate: Extract NSURL, get absoluteString
    end

    alt BrowsingWeb
        AppDelegate->>ObjC: Call HandleOpenURL(c-string)
        ObjC->>Go: cgo exported HandleOpenURL -> openUrlBuffer
        Go-->>ObjC: ack/queued
        ObjC-->>AppDelegate: return YES
    else Other activity
        AppDelegate-->>macOS: return NO
    end

    AppDelegate-->>macOS: return result
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20–30 minutes

  • Pay attention to:
    • cgo export rename and symbol visibility across Objective-C/Go.
    • UTF-8 conversion and C string memory ownership between ObjC and Go.
    • Edge cases in AppDelegate continuation (nil URL, non-http(s) or malformed URLs).

Suggested labels

Enhancement, Documentation, MacOS, size:L, lgtm

Suggested reviewers

  • leaanthony

Poem

🐰 I hopped through code where links now gleam,
AppDelegate listens to the browsing stream,
A tiny hop from event to queue,
The frontend wakes and greets the new,
Hooray — links land home, and I nibble a dream. 🥕

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title 'V2 - Add universal link support for macOS' accurately and specifically summarizes the main change—adding universal link support for macOS.
Description check ✅ Passed The description adequately covers the change with motivation (Apple's universal links documentation), type of change (new feature), testing verification (macOS), and most checklist items completed.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 78c625f and 26e249c.

📒 Files selected for processing (1)
  • website/docs/guides/custom-protocol-schemes.mdx (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • website/docs/guides/custom-protocol-schemes.mdx
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
  • GitHub Check: Run Go Tests (ubuntu-24.04, 1.23)
  • GitHub Check: Run Go Tests (macos-latest, 1.23)
  • GitHub Check: Run Go Tests (ubuntu-22.04, 1.23)
  • GitHub Check: Run Go Tests (windows-latest, 1.23)
  • GitHub Check: semgrep-cloud-platform/scan

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@APshenkin APshenkin changed the title Add universal link support V2 - Add universal link support Nov 6, 2025
@APshenkin APshenkin changed the title V2 - Add universal link support V2 - Add universal link support for macOS Nov 6, 2025
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (1)
v2/internal/frontend/desktop/darwin/CustomProtocol.m (1)

5-9: Clean up redundant code.

Lines 5 and 7 contain unused code. Line 5 extracts the event parameter but discards the result, and line 7 stores the URL string in urlStr but line 9 duplicates the extraction instead of using the variable.

Apply this diff to simplify:

 + (void)handleGetURLEvent:(NSAppleEventDescriptor *)event withReplyEvent:(NSAppleEventDescriptor *)replyEvent {
-  [event paramDescriptorForKeyword:keyDirectObject];
-
-   NSString *urlStr = [[event paramDescriptorForKeyword:keyDirectObject] stringValue];
-
-   HandleOpenURL((char*)[[[event paramDescriptorForKeyword:keyDirectObject] stringValue] UTF8String]);
+   NSString *urlStr = [[event paramDescriptorForKeyword:keyDirectObject] stringValue];
+   HandleOpenURL((char*)[urlStr UTF8String]);
 }
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between fc1c90e and bfbffc5.

📒 Files selected for processing (4)
  • v2/internal/frontend/desktop/darwin/AppDelegate.m (2 hunks)
  • v2/internal/frontend/desktop/darwin/CustomProtocol.h (1 hunks)
  • v2/internal/frontend/desktop/darwin/CustomProtocol.m (1 hunks)
  • v2/internal/frontend/desktop/darwin/frontend.go (1 hunks)
🧰 Additional context used
🧠 Learnings (1)
📓 Common learnings
Learnt from: APshenkin
Repo: wailsapp/wails PR: 4484
File: v2/internal/frontend/utils/urlValidator.go:25-31
Timestamp: 2025-08-08T13:15:20.339Z
Learning: In Wails v2 (PR wailsapp/wails#4484), for BrowserOpenURL URL validation (v2/internal/frontend/utils/urlValidator.go), maintainers (APshenkin) prefer not to restrict schemes to an http/https allowlist because supported schemes may vary. The allowlist suggestion is declined; continue with the existing denylist approach and generic validation.
🧬 Code graph analysis (1)
v2/internal/frontend/desktop/darwin/CustomProtocol.h (1)
v2/internal/frontend/desktop/darwin/frontend.go (1)
  • HandleOpenURL (522-525)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
  • GitHub Check: Run Go Tests (ubuntu-24.04, 1.23)
  • GitHub Check: Run Go Tests (ubuntu-22.04, 1.23)
  • GitHub Check: Run Go Tests (windows-latest, 1.23)
  • GitHub Check: Run Go Tests (macos-latest, 1.23)
  • GitHub Check: semgrep-cloud-platform/scan
🔇 Additional comments (4)
v2/internal/frontend/desktop/darwin/AppDelegate.m (2)

12-12: LGTM!

The import of CustomProtocol.h is necessary to access the HandleOpenURL function and follows the existing pattern in this file.


23-32: LGTM! Correct implementation of universal links support.

The method correctly implements Apple's universal links pattern:

  • Checks for NSUserActivityTypeBrowsingWeb activity type
  • Extracts the URL from webpageURL property
  • Converts to absolute string and passes to the handler
  • Returns appropriate boolean values

The memory management and error handling follow the same safe pattern as the existing openFile: method.

v2/internal/frontend/desktop/darwin/CustomProtocol.h (1)

6-6: LGTM! Consistent rename across the codebase.

The function signature rename from HandleCustomProtocol to HandleOpenURL is consistent with the changes in frontend.go, CustomProtocol.m, and AppDelegate.m. The more generic name appropriately reflects that it now handles both custom protocol URLs and universal links.

v2/internal/frontend/desktop/darwin/frontend.go (1)

521-525: LGTM! Consistent rename with appropriate unified handling.

The function rename from HandleCustomProtocol to HandleOpenURL aligns with the changes in the Objective-C bridge. The implementation correctly maintains the same processing for both custom protocol URLs and universal links, forwarding them through openUrlBuffer to the Mac.OnUrlOpen callback.

@sonarqubecloud
Copy link

sonarqubecloud bot commented Nov 6, 2025

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant