TwitterKit 过滤时间线但反之?

TwitterKit filter timeline but inversely?

我通过 Fabric TwitterKit 在我的应用程序中显示 Twitter 时间线。

我想通过仅显示@特定用户的推文来过滤时间线。我已阅读 here 中有关如何在时间轴中过滤推文的文档。对我来说不幸的是,他们提供的功能将排除时间轴中包含指定 keyword/s 的任何推文。

我正在寻找的行为将仅包含时间轴中包含指定 keyword/s 的推文。

这可能与 TwitterKit 相关吗?我一直在为此寻找反向过滤器,但似乎有 none.

首先不清楚你的源时间线是什么。您是否考虑过使用 TWTRSearchTimelineDataSource and configuring Search API query?搜索 API 支持具有某些逻辑函数的复合查询,因此您可以创建一个满足您所有需求的查询。

注意:鉴于您在问题中提供的link,我假设您的目标平台是iOS。您可以为 Android.

应用类似的解决方案

如果搜索 API 对您来说不够强大,您的另一个选择是进行一些客户端过滤。我找不到 iOS 源代码,但找到了 Twitter Kit for Android is available at GitHub. If you look at BasicTimelineFilter 的某些版本和 FilterTimelineDelegate, you can see that in Android filtering is actually performed on the client side. So you can do the same with any custom filtering in your iOS application. All you need is create a wrapper class that will implement TWTRTimelineDataSource 协议并进行自定义过滤。这是 Objective-C 中代码的一些草图(当然,您可以在 Swift 中执行相同的操作):

注:注意bug,我连这段代码都没有编译

.h 文件

typedef BOOL (^SOTweetFilter)(TWTRTweet * tweet);

@interface SOFilteredTimelineDataSourceWrapper : NSObject<TWTRTimelineDataSource>

- (instancetype)initWithDataSource:(id<TWTRTimelineDataSource>)dataSource filter:(SOTweetFilter)filter;

@end

.m 文件

@implementation SOFilteredTimelineDataSourceWrapper
@property (nonatomic, strong, readwrite) id<TWTRTimelineDataSource> wrapped;
@property (nonatomic, copy) SOTweetFilter filter;

- (instancetype)initWithDataSource:(id<TWTRTimelineDataSource>)dataSource filter:(SOTweetFilter)filter {
    if(!(self = [super init])) return self;

    self.wrapped = dataSource;
    self.filter = filter;

    return self;
}

- (void)loadPreviousTweetsBeforePosition:(nullable NSString *)position completion:(TWTRLoadTimelineCompletion)completion {
    // typedef void (^TWTRLoadTimelineCompletion)(NSArray<TWTRTweet *> * _Nullable tweets, TWTRTimelineCursor * _Nullable cursor, NSError * _Nullable error);
    [wrapped loadPreviousTweetsBeforePosition:position completion:^(NSArray<TWTRTweet *> * _Nullable tweets, TWTRTimelineCursor * _Nullable cursor, NSError * _Nullable error) {
            if(error) {
                // forward error
                completion(tweets, cursor, error);
            }
            else {
                // filter results
                NSArray* filtered = [tweets filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:(id evaluatedObject, NSDictionary<NSString *,id> *bindings) {
                    return self.filter(evaluatedObject);
                }]];
                completion(filtered, cursor, error);
            }
    }];
}


// delegate all properties to the wrapped

- (TWTRTimelineType)timelineType {
    return wrapped.timelineType;
}

-(TWTRTimelineFilter *)timelineFilter {
    return wrapped.timelineFilter;
}

-(void)setTimelineFilter:(TWTRTimelineFilter *)timelineFilter {
    wrapped.timelineFilter = timelineFilter;
}

- (TWTRAPIClient *)APIClient{ 
    return wrapped.APIClient;
}

- (void)setAPIClient:(TWTRAPIClient *)APIClient{ 
    wrapped.APIClient = APIClient;
}

@end

主要思想是拦截 loadPreviousTweetsBeforePosition:completion: 调用并在调用原始 completion 回调之前添加额外的处理。使用这样的 SOFilteredTimelineDataSourceWrapper 你可以包装任何其他 TWTRTimelineDataSource 并进行任何你想分析的过滤 TWTRTweet.text. For mentions (i.e. handle-based) filtering you might want to take a look at Android implementation of normalizeHandle.