1
This commit is contained in:
70
CustomKeyboard/Network/WJXEventSource/WJXEventSource.h
Normal file
70
CustomKeyboard/Network/WJXEventSource/WJXEventSource.h
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
//
|
||||||
|
// WJXEventSource.h
|
||||||
|
// WJXEventSource
|
||||||
|
//
|
||||||
|
// Created by JiuxingWang on 2025/2/9.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import <Foundation/Foundation.h>
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
#define WJX_EXTERN extern "C" __attribute__((visibility ("default")))
|
||||||
|
#else
|
||||||
|
#define WJX_EXTERN extern __attribute__((visibility ("default")))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/// 消息事件
|
||||||
|
typedef NSString *WJXEventName NS_TYPED_EXTENSIBLE_ENUM;
|
||||||
|
|
||||||
|
/// 消息事件
|
||||||
|
WJX_EXTERN WJXEventName const WJXEventNameMessage;
|
||||||
|
|
||||||
|
/// readyState 变化事件
|
||||||
|
WJX_EXTERN WJXEventName const WJXEventNameReadyState;
|
||||||
|
|
||||||
|
/// open 事件
|
||||||
|
WJX_EXTERN WJXEventName const WJXEventNameOpen;
|
||||||
|
|
||||||
|
/// error 事件
|
||||||
|
WJX_EXTERN WJXEventName const WJXEventNameError;
|
||||||
|
|
||||||
|
typedef NS_ENUM(NSUInteger, WJXEventState) {
|
||||||
|
WJXEventStateConnecting = 0,
|
||||||
|
WJXEventStateOpen,
|
||||||
|
WJXEventStateClosed,
|
||||||
|
};
|
||||||
|
|
||||||
|
@interface WJXEvent : NSObject
|
||||||
|
|
||||||
|
@property (nonatomic, strong, nullable) id eventId;
|
||||||
|
|
||||||
|
@property (nonatomic, copy, nullable) NSString *event;
|
||||||
|
@property (nonatomic, copy, nullable) NSString *data;
|
||||||
|
|
||||||
|
@property (nonatomic, assign) WJXEventState readyState;
|
||||||
|
@property (nonatomic, strong, nullable) NSError *error;
|
||||||
|
|
||||||
|
- (instancetype)initWithReadyState:(WJXEventState)readyState;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
typedef void(^WJXEventSourceEventHandler)(WJXEvent *event);
|
||||||
|
|
||||||
|
@interface WJXEventSource : NSObject
|
||||||
|
|
||||||
|
@property (nonatomic, assign) BOOL ignoreRetryAction;
|
||||||
|
|
||||||
|
- (instancetype)initWithRquest:(NSURLRequest *)request;
|
||||||
|
|
||||||
|
- (void)addListener:(WJXEventSourceEventHandler)listener
|
||||||
|
forEvent:(WJXEventName)eventName
|
||||||
|
queue:(nullable NSOperationQueue *)queue;
|
||||||
|
|
||||||
|
- (void)open;
|
||||||
|
- (void)close;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_END
|
||||||
287
CustomKeyboard/Network/WJXEventSource/WJXEventSource.m
Normal file
287
CustomKeyboard/Network/WJXEventSource/WJXEventSource.m
Normal file
@@ -0,0 +1,287 @@
|
|||||||
|
//
|
||||||
|
// WJXEventSource.m
|
||||||
|
// WJXEventSource
|
||||||
|
//
|
||||||
|
// Created by JiuxingWang on 2025/2/9.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import "WJXEventSource.h"
|
||||||
|
|
||||||
|
/// 消息事件
|
||||||
|
WJXEventName const WJXEventNameMessage = @"message";
|
||||||
|
|
||||||
|
/// readyState 变化事件
|
||||||
|
WJXEventName const WJXEventNameReadyState = @"readyState";
|
||||||
|
|
||||||
|
/// open 事件
|
||||||
|
WJXEventName const WJXEventNameOpen = @"open";
|
||||||
|
|
||||||
|
/// error 事件
|
||||||
|
WJXEventName const WJXEventNameError = @"error";
|
||||||
|
|
||||||
|
#pragma mark -
|
||||||
|
#pragma mark WJXEvent
|
||||||
|
|
||||||
|
@implementation WJXEvent
|
||||||
|
|
||||||
|
- (instancetype)initWithReadyState:(WJXEventState)readyState;
|
||||||
|
{
|
||||||
|
if (self = [super init]) {
|
||||||
|
self.readyState = readyState;
|
||||||
|
}
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSString *)description
|
||||||
|
{
|
||||||
|
NSString *state = nil;
|
||||||
|
switch (_readyState) {
|
||||||
|
case WJXEventStateConnecting: {
|
||||||
|
state = @"CONNECTING";
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case WJXEventStateOpen: {
|
||||||
|
state = @"OPEN";
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case WJXEventStateClosed: {
|
||||||
|
state = @"CLOSED";
|
||||||
|
} break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return [NSString stringWithFormat:@"<%@: readyState: %@, id: %@; event: %@; data: %@>", [self class], state, _eventId, _event, _data];
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
|
||||||
|
#pragma mark -
|
||||||
|
#pragma mark WJXEventHandler
|
||||||
|
|
||||||
|
@interface WJXEventHandler : NSObject
|
||||||
|
|
||||||
|
@property (nonatomic, copy, nonnull) WJXEventSourceEventHandler handler;
|
||||||
|
@property (nonatomic, strong, nullable) NSOperationQueue *queue;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
@implementation WJXEventHandler
|
||||||
|
|
||||||
|
- (instancetype)initWithHandler:(WJXEventSourceEventHandler)handler queue:(NSOperationQueue *)queue
|
||||||
|
{
|
||||||
|
if (self = [super init]) {
|
||||||
|
self.handler = handler;
|
||||||
|
self.queue = queue;
|
||||||
|
}
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
|
||||||
|
#pragma mark -
|
||||||
|
#pragma mark WJXEventSource
|
||||||
|
|
||||||
|
@interface WJXEventSource () <NSURLSessionDataDelegate>
|
||||||
|
|
||||||
|
@property (nonatomic, strong) NSMutableURLRequest *request;
|
||||||
|
@property (nonatomic, strong) NSMutableDictionary<WJXEventName, NSMutableArray<WJXEventHandler *> *> *listeners;
|
||||||
|
|
||||||
|
@property (nonatomic, strong) NSURLSession *session;
|
||||||
|
@property (nonatomic, strong) NSURLSessionDataTask *dataTask;
|
||||||
|
@property (nonatomic, copy) NSString *lastEventId;
|
||||||
|
@property (nonatomic, assign) NSTimeInterval retryInterval;
|
||||||
|
|
||||||
|
@property (nonatomic, assign) BOOL closedByUser;
|
||||||
|
@property (nonatomic, strong) NSMutableData *buffer;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
@implementation WJXEventSource
|
||||||
|
|
||||||
|
- (instancetype)initWithRquest:(NSURLRequest *)request;
|
||||||
|
{
|
||||||
|
if (self = [super init]) {
|
||||||
|
self.request = [request mutableCopy];
|
||||||
|
self.listeners = [NSMutableDictionary dictionary];
|
||||||
|
self.session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration ephemeralSessionConfiguration] delegate:self delegateQueue:NSOperationQueue.mainQueue];
|
||||||
|
self.buffer = [NSMutableData data];
|
||||||
|
}
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)dealloc
|
||||||
|
{
|
||||||
|
[_session finishTasksAndInvalidate];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)addListener:(WJXEventSourceEventHandler)listener
|
||||||
|
forEvent:(WJXEventName)eventName
|
||||||
|
queue:(nullable NSOperationQueue *)queue;
|
||||||
|
{
|
||||||
|
if (nil == listener) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
NSMutableArray *listeners = self.listeners[eventName];
|
||||||
|
if (nil == listeners) {
|
||||||
|
self.listeners[eventName] = listeners = [NSMutableArray array];
|
||||||
|
}
|
||||||
|
[listeners addObject:[[WJXEventHandler alloc] initWithHandler:listener queue:queue]];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)open;
|
||||||
|
{
|
||||||
|
if (_lastEventId.length) {
|
||||||
|
[_request setValue:_lastEventId forHTTPHeaderField:@"Last-Event-ID"];
|
||||||
|
}
|
||||||
|
|
||||||
|
self.dataTask = [_session dataTaskWithRequest:_request];
|
||||||
|
[_dataTask resume];
|
||||||
|
|
||||||
|
WJXEvent *event = [[WJXEvent alloc] initWithReadyState:WJXEventStateConnecting];
|
||||||
|
[self _dispatchEvent:event forName:WJXEventNameReadyState];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)close;
|
||||||
|
{
|
||||||
|
self.closedByUser = YES;
|
||||||
|
[_dataTask cancel];
|
||||||
|
[_session finishTasksAndInvalidate];
|
||||||
|
_buffer = [NSMutableData data];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#pragma mark -
|
||||||
|
#pragma mark NSURLSessionDataDelegate
|
||||||
|
|
||||||
|
- (void)URLSession:(NSURLSession *)session
|
||||||
|
dataTask:(NSURLSessionDataTask *)dataTask
|
||||||
|
didReceiveResponse:(NSURLResponse *)response
|
||||||
|
completionHandler:(void (^)(NSURLSessionResponseDisposition disposition))completionHandler;
|
||||||
|
{
|
||||||
|
NSHTTPURLResponse *HTTPResponse = (NSHTTPURLResponse *)response;
|
||||||
|
if (200 == HTTPResponse.statusCode) {
|
||||||
|
WJXEvent *event = [[WJXEvent alloc] initWithReadyState:WJXEventStateOpen];
|
||||||
|
[self _dispatchEvent:event forName:WJXEventNameReadyState];
|
||||||
|
[self _dispatchEvent:event forName:WJXEventNameOpen];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nil != completionHandler) {
|
||||||
|
completionHandler(NSURLSessionResponseAllow);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)URLSession:(NSURLSession *)session
|
||||||
|
dataTask:(NSURLSessionDataTask *)dataTask
|
||||||
|
didReceiveData:(NSData *)data;
|
||||||
|
{
|
||||||
|
[_buffer appendData:data];
|
||||||
|
[self _processBuffer];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)URLSession:(NSURLSession *)session
|
||||||
|
task:(NSURLSessionTask *)task
|
||||||
|
didCompleteWithError:(nullable NSError *)error;
|
||||||
|
{
|
||||||
|
if (_closedByUser) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
WJXEvent *event = [[WJXEvent alloc] initWithReadyState:WJXEventStateClosed];
|
||||||
|
if (nil == (event.error = error)) {
|
||||||
|
event.error = [NSError errorWithDomain:@"WJXEventSource" code:event.readyState userInfo:@{
|
||||||
|
NSLocalizedDescriptionKey: @"Connection with the event source was closed without error",
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
[self _dispatchEvent:event forName:WJXEventNameReadyState];
|
||||||
|
|
||||||
|
if (nil != error) {
|
||||||
|
[self _dispatchEvent:event forName:WJXEventNameError];
|
||||||
|
if (!_ignoreRetryAction) {
|
||||||
|
[self performSelector:@selector(open) withObject:nil afterDelay:_retryInterval];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#pragma mark -
|
||||||
|
#pragma mark Private
|
||||||
|
|
||||||
|
- (void)_processBuffer
|
||||||
|
{
|
||||||
|
NSData *separatorLFLFData = [NSData dataWithBytes:"\n\n" length:2];
|
||||||
|
|
||||||
|
NSRange range = [_buffer rangeOfData:separatorLFLFData options:kNilOptions range:(NSRange) {
|
||||||
|
.length = _buffer.length
|
||||||
|
}];
|
||||||
|
|
||||||
|
while (NSNotFound != range.location) {
|
||||||
|
// Extract event data
|
||||||
|
NSData *eventData = [_buffer subdataWithRange:(NSRange) {
|
||||||
|
.length = range.location
|
||||||
|
}];
|
||||||
|
[_buffer replaceBytesInRange:(NSRange) {
|
||||||
|
.length = range.location + 2
|
||||||
|
} withBytes:NULL length:0];
|
||||||
|
|
||||||
|
[self _parseEventData:eventData];
|
||||||
|
|
||||||
|
// Look for next event
|
||||||
|
range = [_buffer rangeOfData:separatorLFLFData options:kNilOptions range:(NSRange) {
|
||||||
|
.length = _buffer.length
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)_parseEventData:(NSData *)data
|
||||||
|
{
|
||||||
|
WJXEvent *event = [[WJXEvent alloc] initWithReadyState:WJXEventStateOpen];
|
||||||
|
|
||||||
|
NSString *eventString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
|
||||||
|
NSArray *lines = [eventString componentsSeparatedByCharactersInSet:NSCharacterSet.newlineCharacterSet];
|
||||||
|
for (NSString *line in lines) {
|
||||||
|
if ([line hasPrefix:@"id:"]) {
|
||||||
|
event.eventId = [[line substringFromIndex:3] stringByTrimmingCharactersInSet:NSCharacterSet.whitespaceCharacterSet];
|
||||||
|
} else if ([line hasPrefix:@"event:"]) {
|
||||||
|
event.event = [[line substringFromIndex:6] stringByTrimmingCharactersInSet:NSCharacterSet.whitespaceCharacterSet];
|
||||||
|
} else if ([line hasPrefix:@"data:"]) {
|
||||||
|
NSString *data = [[line substringFromIndex:5] stringByTrimmingCharactersInSet:NSCharacterSet.whitespaceCharacterSet];
|
||||||
|
event.data = event.data ? [event.data stringByAppendingFormat:@"\n%@", data] : data;
|
||||||
|
} else if ([line hasPrefix:@"retry:"]) {
|
||||||
|
NSString *retryString = [[line substringFromIndex:6] stringByTrimmingCharactersInSet:NSCharacterSet.whitespaceCharacterSet];
|
||||||
|
self.retryInterval = [retryString doubleValue] / 1000;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (event.eventId) {
|
||||||
|
self.lastEventId = event.eventId;
|
||||||
|
}
|
||||||
|
|
||||||
|
[self _dispatchEvent:event forName:WJXEventNameMessage];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)_dispatchEvent:(WJXEvent *)event forName:(WJXEventName)name
|
||||||
|
{
|
||||||
|
NSMutableArray<WJXEventHandler *> *listeners = self.listeners[name];
|
||||||
|
[listeners enumerateObjectsUsingBlock:^(WJXEventHandler * _Nonnull handler, NSUInteger idx, BOOL * _Nonnull stop) {
|
||||||
|
NSOperationQueue *queue = handler.queue ?: NSOperationQueue.mainQueue;
|
||||||
|
[queue addOperationWithBlock:^{
|
||||||
|
handler.handler(event);
|
||||||
|
}];
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#pragma mark -
|
||||||
|
#pragma mark Setters
|
||||||
|
|
||||||
|
- (void)setDataTask:(NSURLSessionDataTask *)dataTask
|
||||||
|
{
|
||||||
|
self.closedByUser = YES; {
|
||||||
|
[_dataTask cancel];
|
||||||
|
_dataTask = dataTask;
|
||||||
|
} self.closedByUser = NO;
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
@@ -115,6 +115,7 @@
|
|||||||
0498BD8C2EE69E15006CC1D5 /* KBTagItemModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 0498BD8A2EE69E15006CC1D5 /* KBTagItemModel.m */; };
|
0498BD8C2EE69E15006CC1D5 /* KBTagItemModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 0498BD8A2EE69E15006CC1D5 /* KBTagItemModel.m */; };
|
||||||
0498BD8F2EE6A3BD006CC1D5 /* KBMyMainModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 0498BD8E2EE6A3BD006CC1D5 /* KBMyMainModel.m */; };
|
0498BD8F2EE6A3BD006CC1D5 /* KBMyMainModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 0498BD8E2EE6A3BD006CC1D5 /* KBMyMainModel.m */; };
|
||||||
0498BD902EE6A3BD006CC1D5 /* KBMyMainModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 0498BD8E2EE6A3BD006CC1D5 /* KBMyMainModel.m */; };
|
0498BD902EE6A3BD006CC1D5 /* KBMyMainModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 0498BD8E2EE6A3BD006CC1D5 /* KBMyMainModel.m */; };
|
||||||
|
0498BDDA2EE7ECEA006CC1D5 /* WJXEventSource.m in Sources */ = {isa = PBXBuildFile; fileRef = 0498BDD82EE7ECEA006CC1D5 /* WJXEventSource.m */; };
|
||||||
049FB20B2EC1C13800FAB05D /* KBSkinBottomActionView.m in Sources */ = {isa = PBXBuildFile; fileRef = 049FB20A2EC1C13800FAB05D /* KBSkinBottomActionView.m */; };
|
049FB20B2EC1C13800FAB05D /* KBSkinBottomActionView.m in Sources */ = {isa = PBXBuildFile; fileRef = 049FB20A2EC1C13800FAB05D /* KBSkinBottomActionView.m */; };
|
||||||
049FB20E2EC1CD2800FAB05D /* KBAlert.m in Sources */ = {isa = PBXBuildFile; fileRef = 049FB20D2EC1CD2800FAB05D /* KBAlert.m */; };
|
049FB20E2EC1CD2800FAB05D /* KBAlert.m in Sources */ = {isa = PBXBuildFile; fileRef = 049FB20D2EC1CD2800FAB05D /* KBAlert.m */; };
|
||||||
049FB2112EC1F72F00FAB05D /* KBMyListCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 049FB2102EC1F72F00FAB05D /* KBMyListCell.m */; };
|
049FB2112EC1F72F00FAB05D /* KBMyListCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 049FB2102EC1F72F00FAB05D /* KBMyListCell.m */; };
|
||||||
@@ -405,6 +406,8 @@
|
|||||||
0498BD8A2EE69E15006CC1D5 /* KBTagItemModel.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KBTagItemModel.m; sourceTree = "<group>"; };
|
0498BD8A2EE69E15006CC1D5 /* KBTagItemModel.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KBTagItemModel.m; sourceTree = "<group>"; };
|
||||||
0498BD8D2EE6A3BD006CC1D5 /* KBMyMainModel.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KBMyMainModel.h; sourceTree = "<group>"; };
|
0498BD8D2EE6A3BD006CC1D5 /* KBMyMainModel.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KBMyMainModel.h; sourceTree = "<group>"; };
|
||||||
0498BD8E2EE6A3BD006CC1D5 /* KBMyMainModel.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KBMyMainModel.m; sourceTree = "<group>"; };
|
0498BD8E2EE6A3BD006CC1D5 /* KBMyMainModel.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KBMyMainModel.m; sourceTree = "<group>"; };
|
||||||
|
0498BDD72EE7ECEA006CC1D5 /* WJXEventSource.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WJXEventSource.h; sourceTree = "<group>"; };
|
||||||
|
0498BDD82EE7ECEA006CC1D5 /* WJXEventSource.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = WJXEventSource.m; sourceTree = "<group>"; };
|
||||||
049FB2092EC1C13800FAB05D /* KBSkinBottomActionView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KBSkinBottomActionView.h; sourceTree = "<group>"; };
|
049FB2092EC1C13800FAB05D /* KBSkinBottomActionView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KBSkinBottomActionView.h; sourceTree = "<group>"; };
|
||||||
049FB20A2EC1C13800FAB05D /* KBSkinBottomActionView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KBSkinBottomActionView.m; sourceTree = "<group>"; };
|
049FB20A2EC1C13800FAB05D /* KBSkinBottomActionView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KBSkinBottomActionView.m; sourceTree = "<group>"; };
|
||||||
049FB20C2EC1CD2800FAB05D /* KBAlert.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KBAlert.h; sourceTree = "<group>"; };
|
049FB20C2EC1CD2800FAB05D /* KBAlert.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KBAlert.h; sourceTree = "<group>"; };
|
||||||
@@ -909,6 +912,15 @@
|
|||||||
path = VM;
|
path = VM;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
|
0498BDD92EE7ECEA006CC1D5 /* WJXEventSource */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
0498BDD72EE7ECEA006CC1D5 /* WJXEventSource.h */,
|
||||||
|
0498BDD82EE7ECEA006CC1D5 /* WJXEventSource.m */,
|
||||||
|
);
|
||||||
|
path = WJXEventSource;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
049FB2162EC20A6600FAB05D /* BMLongPressDragCellCollectionView */ = {
|
049FB2162EC20A6600FAB05D /* BMLongPressDragCellCollectionView */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
@@ -1490,6 +1502,7 @@
|
|||||||
A1B2C3E52EB0C0A100000001 /* Network */ = {
|
A1B2C3E52EB0C0A100000001 /* Network */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
0498BDD92EE7ECEA006CC1D5 /* WJXEventSource */,
|
||||||
A1B2C3E02EB0C0A100000001 /* KBNetworkManager.h */,
|
A1B2C3E02EB0C0A100000001 /* KBNetworkManager.h */,
|
||||||
A1B2C3E12EB0C0A100000001 /* KBNetworkManager.m */,
|
A1B2C3E12EB0C0A100000001 /* KBNetworkManager.m */,
|
||||||
049FB2302EC45A0000FAB05D /* KBStreamFetcher.h */,
|
049FB2302EC45A0000FAB05D /* KBStreamFetcher.h */,
|
||||||
@@ -1716,6 +1729,7 @@
|
|||||||
04FC95672EB0546C007BD342 /* KBKey.m in Sources */,
|
04FC95672EB0546C007BD342 /* KBKey.m in Sources */,
|
||||||
A1B2C3F42EB35A9900000001 /* KBFullAccessGuideView.m in Sources */,
|
A1B2C3F42EB35A9900000001 /* KBFullAccessGuideView.m in Sources */,
|
||||||
0498BD8F2EE6A3BD006CC1D5 /* KBMyMainModel.m in Sources */,
|
0498BD8F2EE6A3BD006CC1D5 /* KBMyMainModel.m in Sources */,
|
||||||
|
0498BDDA2EE7ECEA006CC1D5 /* WJXEventSource.m in Sources */,
|
||||||
04D1F6B22EDFF10A00B12345 /* KBSkinInstallBridge.m in Sources */,
|
04D1F6B22EDFF10A00B12345 /* KBSkinInstallBridge.m in Sources */,
|
||||||
A1B2C4002EB4A0A100000003 /* KBAuthManager.m in Sources */,
|
A1B2C4002EB4A0A100000003 /* KBAuthManager.m in Sources */,
|
||||||
04A9FE132EB4D0D20020DB6D /* KBFullAccessManager.m in Sources */,
|
04A9FE132EB4D0D20020DB6D /* KBFullAccessManager.m in Sources */,
|
||||||
|
|||||||
Reference in New Issue
Block a user