首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用相关项在沙箱应用程序中创建备份文件的尝试失败

使用相关项在沙箱应用程序中创建备份文件的尝试失败
EN

Stack Overflow用户
提问于 2018-07-01 09:15:54
回答 1查看 211关注 0票数 1

应用程序沙箱设计指南说:

App的相关项功能允许您的应用程序访问与用户选择的文件相同的文件,但扩展名不同。这个特性由两个部分组成:应用程序的Info.plist文件中的相关扩展列表和告诉沙箱您正在做什么的代码。

我的Info.plist为.pnd文件(用户选择的文件)定义了文档类型,为.bak文件定义了文档类型。.bak文件的条目除其他属性外,还具有属性NSIsRelatedItemType = YES

当用户写入新版本的.pnd文件时,我试图使用相关项将现有文件移动到备份文件(将.pnd后缀更改为.bak后缀)。应用程序是沙箱。我不精通太极拳。

我使用PasteurOrgManager作为原始和备份文件的NSFilePresenter类:

代码语言:javascript
复制
@interface PasteurOrgData : NSObject <NSFilePresenter>
. . . .
@property (readonly, copy) NSURL *primaryPresentedItemURL;
@property (readonly, copy) NSURL *presentedItemURL;
@property (readwrite) NSOperationQueue *presentedItemOperationQueue;
@property (readwrite) NSFileCoordinator *fileCoordinator;
. . . .
- (void) doBackupOf: (NSString*) path;
. . . .
@end

doBackupOf:方法如下所示。注意,它还设置了NSFilePresenter属性:

代码语言:javascript
复制
- (void) doBackupOf: (NSString*) path
{
    NSError *error = nil;
    NSString *appSuffix = @".pnd";

    NSURL *const pathAsURL = [NSURL URLWithString: [NSString stringWithFormat: @"file://%@", path]];
    NSString *const baseName = [pathAsURL lastPathComponent];
    NSString *const prefixToBasename = [path substringToIndex: [path length] - [baseName length] - 1];
    NSString *const baseNameWithoutExtension = [baseName substringToIndex: [baseName length] - [appSuffix length]];
    NSString *backupPath = [NSString stringWithFormat: @"%@/%@.bak", prefixToBasename, baseNameWithoutExtension];
    NSURL *const backupURL = [NSURL URLWithString: [NSString stringWithFormat: @"file://%@", backupPath]];

    // Move backup to trash — I am sure this will be my next challenge
    // (it's a no-op now because there is no pre-existing .bak file)
    [[NSFileManager defaultManager] trashItemAtURL: backupURL
                                  resultingItemURL: nil
                                             error: &error];

    // Move file to backup
    primaryPresentedItemURL = pathAsURL;
    presentedItemURL = backupURL;
    presentedItemOperationQueue = [NSOperationQueue mainQueue];

    [NSFileCoordinator addFilePresenter: self];
    fileCoordinator = [[NSFileCoordinator alloc] initWithFilePresenter: self];   // error here
    [self backupItemWithCoordinationFrom: pathAsURL
                                      to: backupURL];
    [NSFileCoordinator removeFilePresenter: self];
    fileCoordinator = nil;
}

backupItemWithCoordinationFrom:方法主要是做繁重的工作:

代码语言:javascript
复制
[fileCoordinator coordinateWritingItemAtURL: from
                                    options: NSFileCoordinatorWritingForMoving
                                      error: &error
                                 byAccessor: ^(NSURL *oldURL) {
                                     [self.fileCoordinator itemAtURL: oldURL willMoveToURL: to];
                                     [[NSFileManager defaultManager] moveItemAtURL: oldURL
                                                                             toURL: to
                                                                             error: &error];
                                     [self.fileCoordinator itemAtURL: oldURL didMoveToURL: to];
                                 }

但代码没那么远。我已经跟踪了代码,URL变量和我所期望的一样,并且是合理的。在上面代码中的"error here“(我分配了文件演示者)的点上,我得到:

代码语言:javascript
复制
NSFileSandboxingRequestRelatedItemExtension: an error was received from pboxd instead of a token. Domain: NSPOSIXErrorDomain, code: 1
[presenter] +[NSFileCoordinator addFilePresenter:] could not get a sandbox extension. primaryPresentedItemURL: file:///Users/cope/Me.pnd, presentedItemURL: file:///Users/cope/Me.bak

任何帮助都是非常感谢的。

(我读过Where can a sandboxed Mac app save files?Why do NSFilePresenter protocol methods never get called?的相关帖子。我注意到了其他几个与沙箱有关的帖子,这些帖子似乎与这个问题无关。)

MacBook Pro,MacOS 10.13.5,XCode版本9.3 (9E145)

EN

回答 1

Stack Overflow用户

发布于 2021-06-06 19:09:39

不要读太多关于避免沙箱的文章。大多数解释离最明显的问题太远了。他们没有解释正确触发沙箱的陷阱,而是解释了如何完全避免沙箱。这不是一个解决方案--它是一根线!

因此,最明显的问题是,在转换到NSURL**.**之前,仍然需要在字符串中正确转义字符的pasteboard公开

因此,以file://“开头的NSString应该使用类似..。

代码语言:javascript
复制
NSString *encodeStringForURL = [yourstring stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];

在转换为NSURL之前,

代码语言:javascript
复制
NSURL *fileurl = [NSURL URLWithString:encodeStringForURL];
NString *output = fileurl.absoluteString;
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51121960

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档