2014-06-09 136 views
0

我有一個OSX應用程序應該有用戶磁盤中任何位置的文件列表。核心數據中的持久書籤

應用程序的第一個版本將這些文件的路徑保存在覈心數據模型中。

但是,如果文件被移動或重命名,該工具會失去其用途,應用程序可能會崩潰。

所以我決定使用書籤。它似乎在工作,但每次我嘗試恢復數據時,都會得到文件的舊路徑。這是爲什麼?我錯過了什麼?

我的核心數據實體使用二進制數據字段來保存書籤。

書籤本身就像下面這樣:

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

而且在加載應用程序,我有一個循環遍歷所有的表,恢復這樣的書籤:

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]); 
} 

如果我重命名文件,路徑爲空。我看到存儲此NSData對象和一個字符串與路徑之間沒有區別。所以我顯然缺少一些東西。

編輯: 我也經常得到這樣的錯誤:CFURLSetTemporaryResourcePropertyForKey failed because it was passed this URL which has no scheme

我感謝任何幫助,謝謝!

回答

0

我在我的代碼中找不到任何問題,所以我改變了它。

在查找「無方案」消息的原因後,我得出結論需要一些第三方應用程序才能使此代碼正常工作,這是不可取的。

我現在正在使用別名。這是我如何創建它們:

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)]; 

現在我恢復這樣的路徑:

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"); 
    } 
} 

不過,我爲什麼我以前的代碼的失敗仍然好奇。我很欣賞這方面的任何想法。謝謝!