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

macOS Objective-C:重启后重新加载用户选择的NSImage问题

macOS沙盒下安全范围书签恢复图片加载的正确方案

你的代码存在两个核心问题,导致无法正常加载图片:

  1. 路径格式错误:url.absoluteString返回的是带file://前缀的URL字符串,而NSImage initWithContentsOfFile:需要的是本地文件路径(不带协议前缀),应该使用url.path。
  2. 未启动安全范围资源访问:沙盒下使用安全范围书签解析出URL后,必须调用startAccessingSecurityScopedResource获取临时访问权限,否则无法读取文件;访问完成后要调用stopAccessingSecurityScopedResource释放权限。

修正后的AwakeFromNib加载代码

NSData *bookmark = [preferences objectForKey:@"bookmark"];
if (!bookmark) {
    return; // 无书签数据直接返回
}

NSError *error = nil;
BOOL isStale;
NSURL *url = [NSURL URLByResolvingBookmarkData:bookmark
                                         options:NSURLBookmarkResolutionWithSecurityScope
                                   relativeToURL:nil
                             bookmarkDataIsStale:&isStale
                                           error:&error];

if (error) {
    NSLog(@"解析书签失败:%@", error);
    return;
}

// 检查书签是否过期,过期则需要重新获取用户授权并创建新书签
if (isStale) {
    NSLog(@"书签已过期,请重新选择图片");
    // 这里可触发重新选择图片的逻辑,重新生成书签
    return;
}

// 启动安全范围资源访问
if ([url startAccessingSecurityScopedResource]) {
    NSString *path = url.path; // 使用正确的本地路径
    NSImage *imgC = [[NSImage alloc] initWithContentsOfFile:path];
    imageView2.image = imgC;
    
    // 完成访问后停止权限
    [url stopAccessingSecurityScopedResource];
} else {
    NSLog(@"无法获取安全范围资源访问权限");
}

书签创建代码的优化建议

你的创建代码基本正确,但建议添加userDefaults同步操作,确保书签数据立即写入磁盘:

NSData *bookmark = nil;
NSError *error = nil;
bookmark = [url bookmarkDataWithOptions:NSURLBookmarkCreationWithSecurityScope
                 includingResourceValuesForKeys:nil
                                  relativeToURL:nil
                                          error:&error];

if (error) {
    NSLog(@"创建书签失败:%@", error);
    [NSApp presentError:error];
    return;
}

NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
[userDefaults setObject:bookmark forKey:@"bookmark"];
[userDefaults synchronize]; // 确保数据立即写入磁盘

额外注意事项

  • 确保你的App已开启沙盒的用户选定文件权限(在Xcode的项目设置>Signing & Capabilities>App Sandbox>File Access中勾选)。
  • 如果书签过期(isStale为YES),需要引导用户重新选择图片并生成新书签,因为旧书签已经失效。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.23 09:39:25