You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React Native iOS动作扩展:如何从Objective-C传递输入Props?

How to Pass Safari URL from Objective-C Action Extension to React Native View

Got it, let's fix this issue of passing the Safari URL from your Objective-C action extension to your React Native view. I've dealt with this exact scenario before, so here's a step-by-step solution that should work for you:

Step 1: Correctly Retrieve the Safari URL in Your Extension ViewController

The common mistake here is trying to use inputItems directly without handling the attachments where the actual URL is stored. Safari passes the URL as an NSItemProvider with the type identifier public.url. Here's how to fetch it properly:

- (void)viewDidLoad {
    [super viewDidLoad];
    
    __weak typeof(self) weakSelf = self;
    for (NSExtensionItem *item in self.extensionContext.inputItems) {
        for (NSItemProvider *provider in item.attachments) {
            if ([provider hasItemConformingToTypeIdentifier:@"public.url"]) {
                [provider loadItemForTypeIdentifier:@"public.url" options:nil completionHandler:^(id<NSSecureCoding> _Nullable item, NSError * _Nullable error) {
                    if (!error && [item isKindOfClass:[NSURL class]]) {
                        NSString *urlString = [(NSURL *)item absoluteString];
                        // Always update UI on the main thread
                        dispatch_async(dispatch_get_main_queue(), ^{
                            [weakSelf setupReactNativeViewWithURL:urlString];
                        });
                    }
                }];
                break;
            }
        }
        if (weakSelf.view.subviews.count > 0) break; // Exit once we've loaded the RN view
    }
}

Step 2: Pass the URL as Initial Props to React Native

Once you have the URL string, initialize your RCTRootView with the initialProperties parameter—this is the standard way to pass data from Objective-C to React Native on launch:

- (void)setupReactNativeViewWithURL:(NSString *)url {
    // Adjust the bundle URL based on your environment:
    // For debug mode, use the RCTBundleURLProvider
    NSURL *jsCodeLocation = [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index" fallbackResource:nil];
    // For release mode, use the local bundled file (uncomment below)
    // NSURL *jsCodeLocation = [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"];
    
    RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation
                                                        moduleName:@"YourExtensionModuleName" // Match this to your RN AppRegistry name
                                                 initialProperties:@{@"inputURL": url} // This is your passed prop
                                                     launchOptions:nil];
    
    self.view = rootView;
}

Step 3: Receive the Prop in Your React Native Component

In your React Native extension component, access the inputURL prop like any standard React prop:

import React from 'react';
import { View, Text, StyleSheet } from 'react-native';
import { AppRegistry } from 'react-native';

const ExtensionScreen = ({ inputURL }) => {
    return (
        <View style={styles.container}>
            <Text style={styles.text}>Received URL:</Text>
            <Text style={styles.urlText}>{inputURL}</Text>
        </View>
    );
};

const styles = StyleSheet.create({
    container: {
        flex: 1,
        justifyContent: 'center',
        alignItems: 'center',
        padding: 20,
    },
    text: {
        fontSize: 18,
        marginBottom: 10,
    },
    urlText: {
        fontSize: 16,
        color: '#0066cc',
        textAlign: 'center',
    },
});

// Ensure this matches the moduleName in your Objective-C code
AppRegistry.registerComponent('YourExtensionModuleName', () => ExtensionScreen);

Critical Checks to Avoid Common Issues

  • Main Thread Requirement: The loadItemForTypeIdentifier callback runs on a background thread—always dispatch to the main thread when initializing the React Native view, otherwise you'll get crashes or rendering glitches.
  • Module Name Match: Double-check that the moduleName in RCTRootView exactly matches the name you use in AppRegistry.registerComponent in React Native.
  • Extension Activation Rule: Verify your extension's Info.plist has the correct rule to accept URLs from Safari:
    <key>NSExtension</key>
    <dict>
        <key>NSExtensionAttributes</key>
        <dict>
            <key>NSExtensionActivationRule</key>
            <dict>
                <key>NSExtensionActivationSupportsWebURLWithMaxCount</key>
                <integer>1</integer>
            </dict>
        </dict>
        <!-- Other extension configuration -->
    </dict>
    

This should resolve your issue—you'll now see the Safari URL displayed in your React Native action extension view.

内容的提问来源于stack exchange,提问作者Alex Gurr

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 07:39:43