通讯录排序

2017-02-07 16_33_47.gif

通讯录是现在开发一个app必不可少的功能了,因为每个老板都想囤积用户,所以都想搞IM,虽然这块肉不是人人都能吃,但明显很多人都想分一杯羹,我们作为开发,吃肉喝汤当然轮不到我们o(╯□╰)o,可是分下来的任务必须完成。

既然有通讯录,当然离不开排序

  • 排序标记
    @protocol SortProtocol <NSObject>

    /// 排序标记
    - (NSString *)sortPreferredFlag;

    @end
  • 外部调用接口

      /**
       分组排序
      
       @param objects 排序对象
       @param completion 排序结果
       @param empty 是否允许空数组
       @param queue 排序线程
       */
      + (void)sortObjects:(nullable NSArray<SortProtocol> *)objects
           withCompletion:(void(^)(NSDictionary * _Nullable sortedResult, NSArray * _Nullable sectionTitles))completion
              withEmptySections:(BOOL)empty withQueue:(nullable dispatch_queue_t)queue;
    
  • 内部实现

    • 创建一个SortPresenter类
+ (void)sortObjects:(NSArray<SortProtocol> *)objects withCompletion:(void (^)(NSDictionary * _Nullable, NSArray * _Nullable))completion withEmptySections:(BOOL)empty withQueue:(dispatch_queue_t)queue {
    if (!objects || objects.count == 0) {  // 没有可执行排序数据
        dispatch_async(dispatch_get_main_queue(), ^{
            completion(nil,nil);
        });
    } else {
        dispatch_queue_t currentQueue = queue ? queue : dispatch_queue_create("sortPresenter.queue", 0);
        dispatch_async(currentQueue, ^{
            [self invokeSortObjects:objects withEmptySections:empty withCompletion:completion];
        });
    }
}
+ (void)invokeSortObjects:(NSArray<SortProtocol> *)objects withEmptySections:(BOOL)empty withCompletion:(void (^)(NSDictionary * _Nullable,NSArray * _Nullable))completion {
    
    UILocalizedIndexedCollation *collation = [UILocalizedIndexedCollation currentCollation];
    
    NSInteger sectionTitlesCount = [[collation sectionTitles] count];
    NSMutableArray *sectionArray = [[NSMutableArray alloc] initWithCapacity:sectionTitlesCount];
    
    for (NSInteger index = 0; index < sectionTitlesCount; index ++) {
        NSMutableArray *section = [[NSMutableArray alloc] init];
        [sectionArray addObject:section];
    }
    
    for (id<SortProtocol> obj in objects) {
        NSInteger sectionIndex = [collation sectionForObject:obj collationStringSelector:@selector(sortPreferredFlag)];
        NSMutableArray *section = sectionArray[sectionIndex];
        [section addObject:obj];
    }
    
    
    NSMutableDictionary *resultDictionary = [NSMutableDictionary dictionaryWithCapacity:10];
    for (NSInteger index = 0; index < sectionArray.count; index ++) {
        NSMutableArray *section = sectionArray[index];
        NSArray *sortedSection = [collation sortedArrayFromArray:section collationStringSelector:@selector(sortPreferredFlag)];
        sectionArray[index] = sortedSection;
    }

    if (empty) {
        for (int index = 0; index < sectionArray.count && collation.sectionTitles.count; index ++) {
            [resultDictionary setObject:sectionArray[index] forKey:collation.sectionTitles[index]];
        }
        dispatch_async(dispatch_get_main_queue(), ^{
            completion(resultDictionary, collation.sectionTitles);
        });
        
    } else {
        NSMutableArray *fitterSectionArray = [NSMutableArray arrayWithCapacity:0];
        NSMutableArray *fitterSectionTitles = [NSMutableArray arrayWithCapacity:0];
        for (int index = 0; index < sectionArray.count  && collation.sectionTitles.count; index ++) {
            if ([sectionArray[index] count] != 0) {
                [fitterSectionArray addObject:sectionArray[index]];
                [resultDictionary setObject:sectionArray[index] forKey:collation.sectionTitles[index]];
                [fitterSectionTitles addObject:collation.sectionTitles[index]];
            }
        }
        dispatch_async(dispatch_get_main_queue(), ^{
            completion(resultDictionary, fitterSectionTitles);
        });
    }    
}

调用只需要一句代码:

[SortPresenter sortObjects:contacts
                withCompletion:^(NSDictionary * _Nullable sortedResult, NSArray * _Nullable sectionTitles) {
                    self.dataSource = sortedResult.mutableCopy;
                    self.sectionTitles = sectionTitles.mutableCopy;
                    [self.tableView reloadData];    
    } withEmptySections:NO withQueue:nil];

看看控制台打印:

sortResult->>>>>>{
    A =     (
        "<Contact: 0x60800003b840>"
    );
    B =     (
        "<Contact: 0x60800003b860>"
    );
    C =     (
        "<Contact: 0x608000227880>"
    );
    H =     (
        "<Contact: 0x60800003b580>",
        "<Contact: 0x60800003b620>"
    );
    K =     (
        "<Contact: 0x60800003b600>"
    );
    L =     (
        "<Contact: 0x60800003b640>",
        "<Contact: 0x60800003b540>"
    );
    M =     (
        "<Contact: 0x608000229980>"
    );
    X =     (
        "<Contact: 0x60800003b520>",
        "<Contact: 0x60800003b4a0>",
        "<Contact: 0x60800003b5a0>"
    );
    Z =     (
        "<Contact: 0x60800003b560>"
    );
}

喜欢这个排序后的格式,条理清晰,又不会有太多冗余。
这个排序还是比较简单,没有做多音字同音字处理,以后会完善。

推荐阅读更多精彩内容