已创建Mac沙箱,但没有NSUserDefaults plist

时间:2014-03-07 05:17:28

标签: macos cocoa nsuserdefaults sandbox

我正在尝试追踪沙盒创建过程中出现的一些问题。在多种情况下,似乎未在Data / Library / Preferences中创建NSUserDefaults .plist文件。我在调试器中以及从Applications目录启动应用程序时已经看到了这一点。我没有尝试存档,签署应用程序然后启动。这需要吗?

创建以.LSSharedFileList.plist结尾的别名文件,但它指向自身,因此不存在。

我不知道它是否相关,但控制台报告:

appleeventsd[72]: <rdar://problem/11489077> A sandboxed application with pid ... checked in with appleeventsd, but its code signature could not be validated ( either because it was corrupt, or could not be read by appleeventsd ) and so it cannot receive AppleEvents targeted by name, bundle id, or signature. Error=ERROR: #100013  { "NSDescription"="SecCodeCopySigningInformation() returned 100013, -." }  (handleMessage()/appleEventsD.cp #2072) client-reqs-q

感谢。

5 个答案:

答案 0 :(得分:17)

这可能与NSUserDefaults的缓存有关吗?

在最近的OS X版本中,默认值不会立即写入磁盘,因此您可能无法立即看到它们。您可能想尝试手动同步prefs - 来自NSUserDefaults Class Reference

  

在运行时,您使用NSUserDefaults对象来读取默认值   您的应用程序使用用户的默认数据库。 NSUserDefaults的   缓存信息以避免必须打开用户的默认值   数据库每次需要默认值时。同步方法,   它会定期自动调用,保持   内存缓存与用户的默认数据库同步。

虽然我相信即使这样也不会立即将默认值写入10.9中的磁盘,因为现在还涉及缓存用户默认值的守护进程。

检查

Reading NSUserDefaults from helper app in the sandbox

Objective-C NSUserDefaults caching prevents another app from accurately reading changes

When (not) to abuse NSUserDefaults

答案 1 :(得分:7)

只需将其转换为完整答案,这样就不会错过。我只是在尝试其他解决方案后才阅读它,只需点击几下即可解决此问题。

@greg和@mehals在评论部分回答第一个解决方案为我解决了这个问题而无需更改我的任何代码

  

杀死cfprefsd完成了活动经理的伎俩。

答案 2 :(得分:2)

花了很多时间后发现了一个简单的解决方案:

- (void)fixDefaultsIfNeeded{
    NSArray *domains = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory,NSUserDomainMask,YES);
    //File should be in library
    NSString *libraryPath = [domains firstObject];
    if (libraryPath) {
        NSString *preferensesPath = [libraryPath stringByAppendingPathComponent:@"Preferences"];

        //Defaults file name similar to bundle identifier
        NSString *bundleIdentifier = [[NSBundle mainBundle] bundleIdentifier];

        //Add correct extension
        NSString *defaultsName = [bundleIdentifier stringByAppendingString:@".plist"];

        NSString *defaultsPath = [preferensesPath stringByAppendingPathComponent:defaultsName];

        NSFileManager *manager = [NSFileManager defaultManager];

        if (![manager fileExistsAtPath:defaultsPath]) {
            //Create to fix issues
            [manager createFileAtPath:defaultsPath contents:nil attributes:nil];

            //And restart defaults at the end
            [NSUserDefaults resetStandardUserDefaults];
            [[NSUserDefaults standardUserDefaults] synchronize];
        }
    }
}

答案 3 :(得分:2)

当我在我的应用程序的容器目录中删除但是没有清空垃圾箱时,我在10.10遇到了这个。

在10.10上,如果容器目录仍然在垃圾箱中,并且如果垃圾箱为空则可以成功创建,我可以不断创建应用程序的属性列表文件。

因此,解决方案(至少对我的问题而言)是在测试时删除沙盒应用程序的容器目录后始终清空垃圾箱。

答案 4 :(得分:1)

Swift 2解决方案

let settingsDefaults = NSUserDefaults.standardUserDefaults();    

func registerSettingsPlist() {
        let sourcePath = NSBundle.mainBundle().pathForResource("Settings", ofType: "plist");
        let appDocsDirURL = self.applicationDocumentsDirectory;
        let destinationPath = appDocsDirURL.path?.stringByAppendingString("/Settings.plist");
        if (!NSFileManager.defaultManager().fileExistsAtPath(destinationPath!)) {
            do {
                try NSFileManager.defaultManager().createDirectoryAtPath(appDocsDirURL.path!, withIntermediateDirectories: true, attributes: nil);
                try NSFileManager.defaultManager().copyItemAtPath(sourcePath!, toPath: destinationPath!);
            } catch let error as NSError {
                print ("Error: \(error.domain)")
            }
        }
        let settingsDic = NSDictionary(contentsOfFile: destinationPath!);
        NSUserDefaults.standardUserDefaults().registerDefaults(settingsDic as! [String : AnyObject]);
        self.settingsDefaults.synchronize();
    }


lazy var applicationDocumentsDirectory: NSURL = {
            let urls = NSFileManager.defaultManager().URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask);
            return urls[urls.count-1];
}();