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

Flutter使用share_plus分享URL时iOS选择器未显示Safari求解决方案

解决方案

问题原因

share_plus 默认将URL作为纯文本字符串传递给iOS的UIActivityViewController,而iOS仅当分享项为NSURL类型时,才会在分享选择器中显示Safari等可处理URL的应用选项。

方案一:自定义原生iOS分享逻辑(推荐)

通过Flutter的MethodChannel调用iOS原生代码,直接构造包含NSURL的分享控制器,确保Safari出现在选项中。

Flutter端代码

import 'package:flutter/services.dart';

// 定义MethodChannel
const _shareChannel = MethodChannel('your.app.bundle/share_url');

/// 分享URL并确保Safari出现在选择器中
Future<void> shareUrlWithSafari(String url) async {
  try {
    await _shareChannel.invokeMethod('shareUrl', {'url': url});
  } on PlatformException catch (e) {
    print('分享失败: ${e.message}');
  }
}

// 调用示例
shareUrlWithSafari('https://www.google.com');

iOS端原生代码

在AppDelegate.m(或RunnerViewController.m)中注册通道并实现分享逻辑:

#import <Flutter/Flutter.h>
#import <UIKit/UIKit.h>

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
  FlutterViewController *flutterVC = (FlutterViewController *)self.window.rootViewController;
  
  FlutterMethodChannel *channel = [FlutterMethodChannel methodChannelWithName:@"your.app.bundle/share_url"
                                                          binaryMessenger:flutterVC.binaryMessenger];
  
  [channel setMethodCallHandler:^(FlutterMethodCall *call, FlutterResult result) {
    if ([call.method isEqualToString:@"shareUrl"]) {
      NSString *urlStr = call.arguments[@"url"];
      NSURL *url = [NSURL URLWithString:urlStr];
      
      if (!url) {
        result([FlutterError errorWithCode:@"INVALID_URL"
                                   message:@"无效的URL"
                                   details:nil]);
        return;
      }
      
      // 构造包含NSURL的分享控制器
      UIActivityViewController *activityVC = [[UIActivityViewController alloc] initWithActivityItems:@[url]
                                                                                 applicationActivities:nil];
      
      // 适配iPad的弹出位置
      if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
        activityVC.popoverPresentationController.sourceView = flutterVC.view;
        activityVC.popoverPresentationController.sourceRect = CGRectMake(flutterVC.view.bounds.size.width/2, flutterVC.view.bounds.size.height/2, 0, 0);
      }
      
      [flutterVC presentViewController:activityVC animated:YES completion:nil];
      result(nil);
    } else {
      result(FlutterMethodNotImplemented);
    }
  }];
  
  return [super application:application didFinishLaunchingWithOptions:launchOptions];
}

@end

方案二:尝试调整share_plus的调用参数

部分场景下,通过指定subject或确保URL格式严格,可让share_plus的iOS端识别为URL类型(但兼容性不如原生方案):

Share.share('https://www.google.com', 
  subject: '打开链接',
  sharePositionOrigin: Rect.fromLTWH(0, 0, MediaQuery.of(context).size.width, MediaQuery.of(context).size.height)
);

注:此方案依赖share_plus的内部实现,不同版本可能存在差异,稳定性不如原生自定义方案。

内容的提问来源于stack exchange,提问作者Sina Hamedi

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 11:02:00