Skip to content

Commit

Permalink
fix: deep and universal links when app is running (#140)
Browse files Browse the repository at this point in the history
Co-authored-by: Thiago Brezinski <thiagobrez@gmail.com>
  • Loading branch information
okwasniewski and thiagobrez committed Aug 26, 2024
1 parent 0b9bfeb commit ab610a7
Show file tree
Hide file tree
Showing 5 changed files with 44 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,6 @@
continueUserActivity:(nonnull NSUserActivity *)userActivity
restorationHandler:(nonnull void (^)(NSArray<id<UIUserActivityRestoring>> *_Nullable))restorationHandler;

+ (void)onOpenURL:(nonnull NSURL *)url NS_SWIFT_NAME(onOpenURL(url:));

@end
14 changes: 14 additions & 0 deletions packages/react-native/Libraries/LinkingIOS/RCTLinkingManager.mm
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#import "RCTLinkingPlugins.h"

static NSString *const kOpenURLNotification = @"RCTOpenURLNotification";
static NSURL *initialURL = nil;

static void postNotificationWithURL(NSURL *URL, id sender)
{
Expand Down Expand Up @@ -81,6 +82,16 @@ + (BOOL)application:(UIApplication *)application
return YES;
}


+ (void)onOpenURL:(NSURL *)url
{
if (initialURL == nil) {
initialURL = url;
} else {
postNotificationWithURL(url, self);
}
}

- (void)handleOpenURLNotification:(NSNotification *)notification
{
[self sendEventWithName:@"url" body:notification.userInfo];
Expand Down Expand Up @@ -153,6 +164,7 @@ - (void)handleOpenURLNotification:(NSNotification *)notification

RCT_EXPORT_METHOD(getInitialURL : (RCTPromiseResolveBlock)resolve reject : (__unused RCTPromiseRejectBlock)reject)
{
#if !TARGET_OS_VISION
NSURL *initialURL = nil;
if (self.bridge.launchOptions[UIApplicationLaunchOptionsURLKey]) {
initialURL = self.bridge.launchOptions[UIApplicationLaunchOptionsURLKey];
Expand All @@ -163,6 +175,8 @@ - (void)handleOpenURLNotification:(NSNotification *)notification
initialURL = ((NSUserActivity *)userActivityDictionary[@"UIApplicationLaunchOptionsUserActivityKey"]).webpageURL;
}
}
#endif
// React Native visionOS uses static property to retrieve initialURL.
resolve(RCTNullIfNil(initialURL.absoluteString));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import SwiftUI
public struct RCTMainWindow: Scene {
var moduleName: String
var initialProps: RCTRootViewRepresentable.InitialPropsType
var onOpenURLCallback: ((URL) -> ())?

public init(moduleName: String, initialProps: RCTRootViewRepresentable.InitialPropsType = nil) {
self.moduleName = moduleName
Expand All @@ -30,10 +31,21 @@ public struct RCTMainWindow: Scene {
WindowGroup {
RCTRootViewRepresentable(moduleName: moduleName, initialProps: initialProps)
.modifier(WindowHandlingModifier())
.onOpenURL(perform: { url in
onOpenURLCallback?(url)
})
}
}
}

extension RCTMainWindow {
public func onOpenURL(perform action: @escaping (URL) -> ()) -> some Scene {
var scene = self
scene.onOpenURLCallback = action
return scene
}
}

/**
Handles data sharing between React Native and SwiftUI views.
*/
Expand Down
3 changes: 3 additions & 0 deletions packages/rn-tester/RNTester-visionOS/App.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ struct RNTesterApp: App {

var body: some Scene {
RCTMainWindow(moduleName: "RNTesterApp")
.onOpenURL(perform: { url in
RCTLinkingManager.onOpenURL(url: url)
})

RCTWindow(id: "SecondWindow", sceneData: reactContext.getSceneData(id: "SecondWindow"))
.defaultSize(CGSize(width: 400, height: 700))
Expand Down
13 changes: 13 additions & 0 deletions packages/rn-tester/RNTester-visionOS/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,19 @@
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleTypeRole</key>
<string>Editor</string>
<key>CFBundleURLName</key>
<string>com.reactjs.ios</string>
<key>CFBundleURLSchemes</key>
<array>
<string>rntester</string>
</array>
</dict>
</array>
<key>UIApplicationSceneManifest</key>
<dict>
<key>UIApplicationPreferredDefaultSceneSessionRole</key>
Expand Down

0 comments on commit ab610a7

Please sign in to comment.