简体   繁体   English

在核心数据中保留书签

[英]Persisting bookmark in core-data

I have an OSX application that is supposed to have a list of files from anywhere in the user's disk. 我有一个OSX应用程序,该应用程序应该具有用户磁盘中任何位置的文件列表。

The first version of the app saves the path to these files in a core-data model. 该应用程序的第一个版本将这些文件的路径保存在核心数据模型中。

However, if the file is moved or renamed, the tool loses its purpose and the app can crash. 但是,如果文件被移动或重命名,该工具将失去其用途,并且应用程序可能会崩溃。

So I decided to use bookmarks. 因此,我决定使用书签。 It seems to be working, but every time I try to recover the data, I get the old path of the files. 它似乎正在工作,但是每次我尝试恢复数据时,都会得到文件的旧路径。 Why is that? 这是为什么? What am I missing? 我想念什么?

My core-data entity uses a binary data field to persist the bookmark. 我的核心数据实体使用二进制数据字段来保留书签。

The bookmark itself is done like this: 书签本身是这样完成的:

NSData * bookmark = [filePath bookmarkDataWithOptions:NSURLBookmarkCreationMinimalBookmark
                       includingResourceValuesForKeys:NULL
                                        relativeToURL:NULL
                                                error:NULL];

And on loading the application, I have a loop to iterate all the table and recover the bookmark like this: 在加载应用程序时,我有一个循环来迭代所有表并像这样恢复书签:

while (object = [rowEnumerator nextObject]) {
    NSError * error = noErr;
    NSURL * bookmark = [NSURL URLByResolvingBookmarkData:[object fileBookmark]
                                                 options:NSURLBookmarkResolutionWithoutUI
                                           relativeToURL:NULL
                                     bookmarkDataIsStale:NO
                                                   error:&error];
    if (error != noErr)
        DDLogCError(@"%@", [error description]);

    DDLogCInfo(@"File Path: %@", [bookmark fileReferenceURL]);
}

If I rename the file, the path is null. 如果我重命名文件,则路径为空。 I see no difference between storing this NSData object and a string with the path. 我看到存储此NSData对象和带有路径的字符串之间没有区别。 So I am obviously missing something. 所以我很明显地缺少一些东西。

Edit: I also often get an error like this: CFURLSetTemporaryResourcePropertyForKey failed because it was passed this URL which has no scheme . 编辑:我也经常会收到这样的错误: CFURLSetTemporaryResourcePropertyForKey failed because it was passed this URL which has no scheme

I appreciate any help, thanks! 感谢您的帮助,谢谢!

I can't find any issues in my code, so I changed it. 我在代码中找不到任何问题,因此我进行了更改。

After looking for the reason of the "no scheme" message, I came to the conclusion some third-party application is required for this code to work, and that's undesirable. 在找到“ no scheme”消息的原因之后,我得出结论,该代码需要一些第三方应用程序才能工作,这是不可取的。

I am now using aliases. 我现在正在使用别名。 This is how I create them: 这是我创建它们的方式:

FSRef fsFile, fsOriginal;
AliasHandle aliasHandle;
NSString * fileOriginalPath = [[filePath absoluteString] stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
OSStatus status = FSPathMakeRef((unsigned char*)[fileOriginalPath cStringUsingEncoding: NSUTF8StringEncoding], &fsOriginal, NULL);
status = FSPathMakeRef((unsigned char*)[fileOriginalPath cStringUsingEncoding: NSUTF8StringEncoding], &fsFile, NULL);
OSErr err = FSNewAlias(&fsOriginal, &fsFile, &aliasHandle);
NSData * aliasData = [NSData dataWithBytes: *aliasHandle length: GetAliasSize(aliasHandle)];

And now I recover the path like this: 现在,我恢复了这样的路径:

while (object = [rowEnumerator nextObject]) {
    NSData * aliasData = [object fileBookmark];
    NSUInteger aliasLen = [aliasData length];
    if (aliasLen > 0) {
        FSRef fsFile, fsOriginal;
        AliasHandle aliasHandle;
        OSErr err = PtrToHand([aliasData bytes], (Handle*)&aliasHandle, aliasLen);
        Boolean changed;
        err = FSResolveAlias(&fsOriginal, aliasHandle, &fsFile, &changed);
        if (err == noErr) {
            char pathC[2*1024];
            OSStatus status = FSRefMakePath(&fsFile, (UInt8*) &pathC, sizeof(pathC));
            NSAssert(status == 0, @"FSRefMakePath failed");
            NSLog(@"%@", [NSString stringWithCString: pathC encoding: NSUTF8StringEncoding]);
        } else {
            NSLog(@"The file disappeared!");
        }
    } else {
        NSLog(@"CardCollectionUserDefault was zero length");
    }
}

However, I am still curious on why my previous code failed. 但是,我仍然对为什么以前的代码失败感到好奇。 I appreciate any thoughts on that. 我对此表示感谢。 Thanks! 谢谢!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM