Mac Catalyst 是不是支持 UIActivityViewController?

Posted

技术标签:

【中文标题】Mac Catalyst 是不是支持 UIActivityViewController?【英文标题】:Does Mac Catalyst supports UIActivityViewController?Mac Catalyst 是否支持 UIActivityViewController? 【发布时间】:2019-10-08 16:03:31 【问题描述】:

我正在尝试将我们的应用程序移植到 Mac。但似乎适用于 ios/iPadOS 的东西并没有出现在 Mac 应用程序上。根本没有弹出窗口。

let activityController = UIActivityViewController(activityItems:items, applicationActivities:nil)

activityController.setValue(NSLocalizedString("App Name", comment:""), forKey:"subject")
activityController.modalPresentationStyle = .popover

let popoverController = activityController.popoverPresentationController

if popoverController != nil 
      popoverController!.barButtonItem = sender
      popoverController!.permittedArrowDirections = .down


self.present(activityController, animated:true, completion:nil)

看到一条可能相关的错误消息:

setting preferences outside an application's container requires user-preference-write or file-write-data sandbox access

我在沙盒中尝试了各种设置,但效果不佳。

PS:删除此行后它可以工作:activityController.setValue(NSLocalizedString("App Name", comment:""), forKey:"subject")

显示的选项也取决于。例如,如果项目中有字符串和图像,则不会显示“保存到照片”。

【问题讨论】:

UIActivityViewController 在 Mac 上为我显示。尝试取消对允许箭头方向的限制。 您好,感谢您的帮助。这不起作用,但我看到一条消息“内容需要刷新:是):在应用程序容器之外设置首选项需要用户首选项写入或文件写入数据沙箱访问权限” - 我已将图片文件夹设置为读/写,还有什么我需要在 Sandbox 中设置的吗? @rmaddy 你能显示你的代码吗?当我显示 UIActivityViewController 时,我只得到一个带有“更多”文本的“按钮”。 @sabiland 你真的有一个窗口出现?我的什么都没有显示。你有没有在 Xcode 中设置任何东西来显示? 我只得到一个带有“更多”按钮的迷你小弹出窗口,它可以打开系统设置:S :) 【参考方案1】:

嗯,我似乎有一个有趣的类似问题。我还得到一个“更多”的迷你弹出窗口。但是,如果我使用 UIButton 而不是 UIView 作为目标,它就可以工作。

使用 UIButton 调用此代码有效:

func shareImage(_ image: UIImage, from fromView: UIView) 
    let activityViewController = UIActivityViewController(activityItems: [image], applicationActivities: nil)
    activityViewController.popoverPresentationController?.sourceView = fromView
    activityViewController.popoverPresentationController?.sourceRect = fromView.bounds
    self.present(activityViewController, animated: true, completion: nil)

可能是 macOS/Catalyst 中的错误?

这似乎还取决于共享的项目类型。与 PDF 数据相同的代码不会在 macOS 上共享。但是 UIImage 工作得很好:/

【讨论】:

删除此行后我让它工作了:activityController.setValue(NSLocalizedString("App Name", comment:""), forKey:"subject") 我还检查了图像可以发送到照片应用程序,通过电子邮件发送......但不是 AirDrop。 我复制/粘贴了您的代码(使用我的 UIButton),但我仍然收到“更多”弹出窗口 :) 耶稣:) 我找到了我遇到的问题。我正在向 UIActivityViewController 发送 PNG。这就是问题所在。当我发送普通 UIImage 时,一切正常 :) 当我选择添加到照片时,我得到了这个异常: [xpc.exceptions] connection to service on pid 17561 named com.apple.share.System.add-to-iphoto.apple -extension-service:在解码接收到的选择器 _completeRequestReturningItems:forExtensionContextWithUUID:completion: 时捕获异常,丢弃传入消息。异常:解码参数 0 时出现异常(调用#2):异常:键“NS.objects”的值属于意外类“NSURL”。允许的类是 '( NSDate, NSNumber, NSData, NSDictionary, NSArray, NSString )'。【参考方案2】:
    let documentURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]

    let document = documentURL.appendingPathComponent("myFile.mp3")

    let activityController = UIActivityViewController(activityItems: [document], applicationActivities: nil)

    DispatchQueue.main.async 
                    
        activityController.modalPresentationStyle = .popover
        
        let popoverController = activityController.popoverPresentationController
        
        if popoverController != nil 
            
            popoverController!.sourceView = self.myUIButton
            popoverController!.sourceRect = self.myUIButton.bounds
            popoverController!.permittedArrowDirections = .any

        
        
        self.present(activityController, animated: true) 
            
            print("UIActivityViewController was presented")
            
        
        
    

【讨论】:

【参考方案3】:
#if _MAC_CATALYST_
//fix mac catalyst bug: UIActivityViewController add image to photo
@interface NSObject (FixCatalystBug)

@end

@implementation NSObject  (FixCatalystBug)

+ (void)load
    Class cls = NSClassFromString(@"NSXPCDecoder");
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^

        SEL selectors[] = 
            #pragma clang diagnostic push
            #pragma clang diagnostic ignored "-Wundeclared-selector"
            @selector(_validateAllowedClass:forKey:allowingInvocations:)
            #pragma clang diagnostic pop
        ;

        for (NSUInteger index = 0; index < sizeof(selectors) / sizeof(SEL); ++index) 
            SEL originalSel = selectors[index];
            SEL swizzledSel = NSSelectorFromString([@"fs_swizzled_" stringByAppendingString:NSStringFromSelector(originalSel)]);
            [cls fs_exchangeImpWithOriginalSel:originalSel swizzledSel:swizzledSel];
        
    );


- (BOOL)fs_swizzled__validateAllowedClass:(Class)cls forKey:(id)key allowingInvocations:(id)allowingInvocations
    BOOL _validate = NO;
    @try 
        _validate = [self fs_swizzled__validateAllowedClass:cls forKey:key allowingInvocations:allowingInvocations];
     @catch (NSException *exception) 
        if ([key isEqualToString:@"NS.objects"] && [cls isKindOfClass:[NSURL class]]) 
            _validate = YES;
        
    
    return _validate;


@end
#endif

【讨论】:

虽然此代码可能会回答问题,但提供有关它如何和/或为什么解决问题的额外上下文将提高​​答案的长期价值。

以上是关于Mac Catalyst 是不是支持 UIActivityViewController?的主要内容,如果未能解决你的问题,请参考以下文章

关于Cisco Catalyst 2960-S Series SI 交换机支持IP和MAC地址绑定功能吗?

如何修复“读写数据沙箱:使用 Mac Catalyst 时出错”

关于Cisco Catalyst 2960-S Series SI 交换机支持IP和MAC地址绑定功能吗?

Mac Catalyst ITMS-4241 错误上传二进制文件

为 Mac Catalyst 构建 Realm 失败:未找到 Realm.h

如何在 Mac 上的 Mac Catalyst 应用程序中使用钥匙串?