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

UIActivityViewController如何筛选分享目标应用?含Garmin Drive适配问题

UIActivityViewController 筛选分享应用机制及Garmin Drive适配方案

核心筛选机制

UIActivityViewController 筛选分享目标应用的流程分为两步:

  1. 初始候选池筛选:系统会收集所有 Activity Item 的**占位符(Placeholder)**对应的UTI集合,然后匹配系统中支持这些UTI的应用。只有能处理至少一个UTI的应用才会进入候选列表。
  2. 应用兼容性验证:针对每个候选应用,系统会逐一检查该应用是否能处理每个 Activity Item 针对它返回的UTI(通过UIActivityItemSource的dataTypeIdentifierForActivityType:方法获取)。如果有任意一个Item的UTI不被应用支持,该应用会被从列表中移除。

你的问题根因

你用UIActivityItemSource后Garmin Drive消失,大概率是两个原因:

  • 占位符返回的是字符串而非GPX文件URL,导致初始筛选阶段系统识别不到com.topografix.gpx这个UTI,Garmin Drive直接被排除在候选池外。
  • 即使你在dataTypeIdentifierForActivityType:中返回了正确UTI,但如果占位符的UTI不匹配,系统不会触发后续针对Garmin Drive的兼容性验证。

解决方案

实现UIActivityItemSource时,必须保证占位符、返回内容、UTI三者对应匹配,针对不同应用返回不同数据:

代码实现示例

@interface GPXShareItemSource : NSObject <UIActivityItemSource>
@property (nonatomic, strong) NSURL *localGPXURL; // 本地GPX文件的file:// URL
@property (nonatomic, copy) NSString *shareText;
@end

@implementation GPXShareItemSource

// 占位符必须返回GPX URL,让系统初始筛选时识别到com.topografix.gpx UTI
- (id)activityViewControllerPlaceholderItem:(UIActivityViewController *)activityViewController {
    return self.localGPXURL;
}

// 针对不同应用返回对应数据
- (id)activityViewController:(UIActivityViewController *)activityViewController itemForActivityType:(UIActivityType *)activityType {
    if ([self isGarminDriveActivity:activityType]) {
        return self.localGPXURL;
    } else {
        return self.shareText;
    }
}

// 针对不同应用返回对应UTI
- (NSString *)activityViewController:(UIActivityViewController *)activityViewController dataTypeIdentifierForActivityType:(UIActivityType *)activityType {
    if ([self isGarminDriveActivity:activityType]) {
        return @"com.topografix.gpx";
    } else {
        return @"public.plain-text";
    }
}

// 判断是否为Garmin Drive应用
- (BOOL)isGarminDriveActivity:(UIActivityType)activityType {
    // 方式1:通过自定义ActivityType判断(如果Garmin Drive注册了)
    if ([activityType isEqualToString:@"com.garmin.drive.share"]) {
        return YES;
    }
    // 方式2:通过OpenIn类应用的URL Scheme判断(需在Info.plist配置LSApplicationQueriesSchemes)
    NSURL *garminSchemeURL = [NSURL URLWithString:@"garmin-drive://"];
    return [[UIApplication sharedApplication] canOpenURL:garminSchemeURL];
}

@end

使用方式

GPXShareItemSource *itemSource = [[GPXShareItemSource alloc] init];
itemSource.localGPXURL = [NSURL fileURLWithPath:@"/path/to/your.gpx"];
itemSource.shareText = @"分享的位置信息文本";

UIActivityViewController *activityVC = [[UIActivityViewController alloc] initWithActivityItems:@[itemSource] applicationActivities:nil];
[self presentViewController:activityVC animated:YES completion:nil];

关键注意事项

  • 必须使用本地文件URL(file://开头),Garmin Drive通常不支持远程URL分享。
  • 占位符的类型要和实际返回的Item类型一致:如果给Garmin Drive返回URL,占位符也必须是URL,否则系统无法识别对应的UTI。
  • 若使用UIActivityItemsConfiguration,逻辑和UIActivityItemSource一致,只需在activityItemsConfiguration:dataTypeIdentifiersForActivityType:中返回对应UTI即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 04:30:35