使用 LSSharedFileListInsertItemURL 在 ObjC 中重新排序 Finder 最喜欢的项目抛出异常

Reorder Finder favourite items in ObjC using LSSharedFileListInsertItemURL throws exception

当我调用 LSSharedFileListInsertItemURL() 时,我得到了这个异常。

[FinderFavorites][FinderFavorites] EXIT: findItemWithId: FOUND: id=2182102545; name=shark;
[FinderFavorites][FinderFavorites] EXIT: findItemWithId: FOUND: id=3643821739; name=inspection-bgs;
2018-07-12 12:51:03.719771+0200 NC_FULL_OSX[31119:7191287] -[SFLItem insertItem:afterItem:error:]: unrecognized selector sent to instance 0x600000628ce0
2018-07-12 12:51:03.720469+0200 NC_FULL_OSX[31119:7191287] [General] -[SFLItem insertItem:afterItem:error:]: unrecognized selector sent to instance 0x600000628ce0
2018-07-12 12:51:03.723781+0200 NC_FULL_OSX[31119:7191287] [General] (
    0   CoreFoundation                      0x00007fff5654e32b __exceptionPreprocess + 171
    1   libobjc.A.dylib                     0x00007fff7d6bcc76 objc_exception_throw + 48
    2   CoreFoundation                      0x00007fff565e6e04 -[NSObject(NSObject) doesNotRecognizeSelector:] + 132
    3   CoreFoundation                      0x00007fff564c4870 ___forwarding___ + 1456
    4   CoreFoundation                      0x00007fff564c4238 _CF_forwarding_prep_0 + 120
    5   SharedFileList                      0x00007fff57c93b19 +[SFLList(LSSharedFileListSupport) itemByInsertingAfterItem:name:URL:propertiesToSet:propertiesToClear:list:] + 994
    6   SharedFileList                      0x00007fff57c98695 LSSharedFileListInsertItemURL + 257
    7   NC_FULL_OSX                         0x000000010003c0f4 -[FinderFavorites reorderItem:toItem:] + 1172

前两行日志显示正确找到了 from_refto_ref。我查看了许多示例,代码几乎完全相同。如果我测试 from_ref/to_ref,那么两者都是 SFLItem 的实例。这个 class 应该实现 insertItem:afterItem:error: 吗?有什么线索吗?

下面是我的完整源代码。

- (BOOL) reorderItem:(NSString*)fromId toItem:(NSString*)toId;
{
    SDEBUG(LEVEL_ERROR, LOG_TOPIC, @"ENTER: reorderItem(fromId=%@; toId=%@);", fromId, toId);

    LSSharedFileListRef sflRef = LSSharedFileListCreate(kCFAllocatorDefault, kLSSharedFileListFavoriteItems, NULL);
    if (!sflRef) {
        SDEBUG(LEVEL_ERROR, LOG_TOPIC, @"QUIT: reorderItem: Unable to create list, LSSharedFileListCreate() fails.", @"");
        return NO;
    }
    UInt32 seed;
    NSArray *list = CFBridgingRelease(LSSharedFileListCopySnapshot(sflRef, &seed));

    LSSharedFileListItemRef from_ref = [self findItemWithId:fromId inList:list];
    LSSharedFileListItemRef to_ref = [self findItemWithId:toId inList:list];

    CFStringRef nameRef = LSSharedFileListItemCopyDisplayName(to_ref);
    CFURLRef urlRef = NULL;
    LSSharedFileListItemResolve(to_ref, kLSSharedFileListNoUserInteraction | kLSSharedFileListDoNotMountVolumes, &urlRef, NULL);

    // <C> Inserts item into shared list at specified location. If the item already exists in the list it will be moved and its icon, display name and properties will be updated.
    LSSharedFileListInsertItemURL(from_ref, to_ref, NULL, NULL, NULL, NULL, NULL);
    CFRelease(sflRef);
    return YES;
}

- (LSSharedFileListItemRef) findItemWithId:(NSString*)identifier inList:(NSArray*)list;
{
    NSInteger identifier_int = identifier.integerValue;

    for (NSObject *obj in list)  {
        LSSharedFileListItemRef sflItemRef = (__bridge LSSharedFileListItemRef)obj;
        UInt32 id_int = LSSharedFileListItemGetID(sflItemRef);
        if (id_int == identifier_int) {
            CFStringRef nameRef = LSSharedFileListItemCopyDisplayName(sflItemRef);
            SDEBUG(LEVEL_DEBUG, LOG_TOPIC, @"EXIT: findItemWithId: FOUND: id=%@; name=%@;", identifier, nameRef);
            return sflItemRef;
        }
    }

    SDEBUG(LEVEL_ERROR, LOG_TOPIC, @"QUIT: findItemWithId: NOT found: id=%@;", identifier);
    return nil;
}

LSSharedFileListInsertItemURL的第一个参数是LSSharedFileListRef,不是LSSharedFileListItemRef