Search code examples
objective-cxcodecore-foundationfinder

Reorder Finder favourite items in ObjC using LSSharedFileListInsertItemURL throws exception


When I call LSSharedFileListInsertItemURL() then I get this exception.

[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

The first two log lines show that from_ref and to_ref is correctly found. I reviewed many examples and the code is more-less identical. If I test the from_ref/to_ref then both are instances of SFLItem. Should this class implement insertItem:afterItem:error:? Any clues what is wrong?

Bellow is my full source code.

- (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;
}

Solution

  • The first parameter of LSSharedFileListInsertItemURL is a LSSharedFileListRef, not a LSSharedFileListItemRef.