// // KBStreamFetcher.h // CustomKeyboard // // 轻量网络流拉取器:支持纯文本分块与 SSE(text/event-stream) 两种形式的“边下边显”。 // - 增量解码:按 UTF-8 安全前缀逐步转成字符串,避免半个多字节字符导致阻塞/乱码 // - SSE 解析:按 \n\n 切事件,合并 data: 行,移除前缀,仅回传正文 // - 兼容后端“/t”作为分段标记:可自动替换为制表符“\t” // - 首段去首个“\t”:若首次正文以一个制表符起始(允许前导空白),可只移除“一个”\t // #import NS_ASSUME_NONNULL_BEGIN typedef void (^KBStreamFetcherChunkHandler)(NSString *chunk); typedef void (^KBStreamFetcherFinishHandler)(NSError *_Nullable error); @interface KBStreamFetcher : NSObject // 便利构造 + (instancetype)fetcherWithURL:(NSURL *)url; // 必填:请求地址 @property (nonatomic, strong) NSURL *url; // 可选 Header @property (nonatomic, copy, nullable) NSDictionary *extraHeaders; // 配置项(默认值见注释) @property (nonatomic, assign) BOOL acceptEventStream; // 默认 NO;置 YES 时发送 Accept: text/event-stream @property (nonatomic, assign) BOOL disableCompression; // 默认 YES;发送 Accept-Encoding: identity @property (nonatomic, assign) BOOL treatSlashTAsTab; // 默认 YES;将“/t”替换为“\t” @property (nonatomic, assign) BOOL trimLeadingTabOnce; // 默认 YES;首次正文起始的“\t”删一个(忽略前导空白) @property (nonatomic, assign) NSTimeInterval requestTimeout; // 默认 30s /// UI 刷新节奏:当一次回调内解析出多段(如多条 SSE 事件)时,按该间隔逐条回调(默认 0.10s)。 @property (nonatomic, assign) NSTimeInterval flushInterval; /// 非 SSE 且一次性拿到大段文本时,是否按空格切词逐条回调(模拟“逐词流式”),默认 YES。 @property (nonatomic, assign) BOOL splitLargeDeltasOnWhitespace; // 回调(统一在主线程触发) @property (nonatomic, copy, nullable) KBStreamFetcherChunkHandler onChunk; @property (nonatomic, copy, nullable) KBStreamFetcherFinishHandler onFinish; // 控制 - (void)start; - (void)cancel; @end NS_ASSUME_NONNULL_END