Commit 26df96f5 authored by 井庆林's avatar 井庆林

添加CoreData

parent b4bfd878
...@@ -168,8 +168,8 @@ ...@@ -168,8 +168,8 @@
6003F59C195388D20070C39A /* GMAppDelegate.h */, 6003F59C195388D20070C39A /* GMAppDelegate.h */,
6003F59D195388D20070C39A /* GMAppDelegate.m */, 6003F59D195388D20070C39A /* GMAppDelegate.m */,
873B8AEA1B1F5CCA007FD442 /* Main.storyboard */, 873B8AEA1B1F5CCA007FD442 /* Main.storyboard */,
6003F5A6195388D20070C39A /* GMViewController.m */,
6003F5A5195388D20070C39A /* GMViewController.h */, 6003F5A5195388D20070C39A /* GMViewController.h */,
6003F5A6195388D20070C39A /* GMViewController.m */,
6003F5A8195388D20070C39A /* Images.xcassets */, 6003F5A8195388D20070C39A /* Images.xcassets */,
6003F594195388D20070C39A /* Supporting Files */, 6003F594195388D20070C39A /* Supporting Files */,
); );
...@@ -436,6 +436,7 @@ ...@@ -436,6 +436,7 @@
"${BUILT_PRODUCTS_DIR}/GMCache/GMCache.framework", "${BUILT_PRODUCTS_DIR}/GMCache/GMCache.framework",
"${BUILT_PRODUCTS_DIR}/GMPhobos/GMPhobos.framework", "${BUILT_PRODUCTS_DIR}/GMPhobos/GMPhobos.framework",
"${BUILT_PRODUCTS_DIR}/MJExtension/MJExtension.framework", "${BUILT_PRODUCTS_DIR}/MJExtension/MJExtension.framework",
"${BUILT_PRODUCTS_DIR}/MagicalRecord/MagicalRecord.framework",
"${BUILT_PRODUCTS_DIR}/TMCache/TMCache.framework", "${BUILT_PRODUCTS_DIR}/TMCache/TMCache.framework",
); );
name = "[CP] Embed Pods Frameworks"; name = "[CP] Embed Pods Frameworks";
...@@ -443,6 +444,7 @@ ...@@ -443,6 +444,7 @@
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/GMCache.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/GMCache.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/GMPhobos.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/GMPhobos.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/MJExtension.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/MJExtension.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/MagicalRecord.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/TMCache.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/TMCache.framework",
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
......
...@@ -33,9 +33,9 @@ NSString *const MockCityId = @"beijing"; ...@@ -33,9 +33,9 @@ NSString *const MockCityId = @"beijing";
#ifdef POD_CONFIGURATION_APP_STORE #ifdef POD_CONFIGURATION_APP_STORE
NSString *url = @"http://log.gmei.com/log/collect"; NSString *url = @"http://log.gmei.com/log/collect";
#else #else
NSString *url = @"http://log.test.gengmei.cc/log/collect"; NSString *url = @"http://log.test.igengmei.com/log/collect";
#endif #endif
[GMCache removeObjectAtDocumentPathWithkey:PhobosCacheKey]; // [[NSUserDefaults standardUserDefaults] setBool:YES forKey:PhobosGray];
Phobos *client = [Phobos clientWithAppName:MockAppName channelId:MockChannelId]; Phobos *client = [Phobos clientWithAppName:MockAppName channelId:MockChannelId];
[Phobos setSharedClient:client]; [Phobos setSharedClient:client];
Phobos.sharedClient.serverAPI = url; Phobos.sharedClient.serverAPI = url;
......
...@@ -84,6 +84,11 @@ ...@@ -84,6 +84,11 @@
"idiom" : "ipad", "idiom" : "ipad",
"size" : "83.5x83.5", "size" : "83.5x83.5",
"scale" : "2x" "scale" : "2x"
},
{
"idiom" : "ios-marketing",
"size" : "1024x1024",
"scale" : "1x"
} }
], ],
"info" : { "info" : {
......
...@@ -3,7 +3,11 @@ PODS: ...@@ -3,7 +3,11 @@ PODS:
- TMCache (= 2.1.0) - TMCache (= 2.1.0)
- GMPhobos (1.3.5): - GMPhobos (1.3.5):
- GMCache - GMCache
- MagicalRecord
- MJExtension - MJExtension
- MagicalRecord (2.3.2):
- MagicalRecord/Core (= 2.3.2)
- MagicalRecord/Core (2.3.2)
- MJExtension (3.2.1) - MJExtension (3.2.1)
- TMCache (2.1.0) - TMCache (2.1.0)
...@@ -13,7 +17,8 @@ DEPENDENCIES: ...@@ -13,7 +17,8 @@ DEPENDENCIES:
SPEC REPOS: SPEC REPOS:
"git@git.wanmeizhensuo.com:gengmeiios/GMSpecs.git": "git@git.wanmeizhensuo.com:gengmeiios/GMSpecs.git":
- GMCache - GMCache
https://github.com/cocoapods/specs.git: https://github.com/CocoaPods/Specs.git:
- MagicalRecord
- MJExtension - MJExtension
- TMCache - TMCache
...@@ -23,10 +28,11 @@ EXTERNAL SOURCES: ...@@ -23,10 +28,11 @@ EXTERNAL SOURCES:
SPEC CHECKSUMS: SPEC CHECKSUMS:
GMCache: b78d8e46db864405e91d226ce640cc80d966c611 GMCache: b78d8e46db864405e91d226ce640cc80d966c611
GMPhobos: 242bc118edb737fb496b49235b2f24d61c349d7b GMPhobos: 81a3a1171bab1499b1147eca51a5359dcfb660d0
MagicalRecord: 53bed74b4323b930992a725be713e53b37d19755
MJExtension: 635f2c663dcb1bf76fa4b715b2570a5710aec545 MJExtension: 635f2c663dcb1bf76fa4b715b2570a5710aec545
TMCache: 95ebcc9b3c7e90fb5fd8fc3036cba3aa781c9bed TMCache: 95ebcc9b3c7e90fb5fd8fc3036cba3aa781c9bed
PODFILE CHECKSUM: ea0fac2144ac80baf8f21576cde49526c19991ad PODFILE CHECKSUM: ea0fac2144ac80baf8f21576cde49526c19991ad
COCOAPODS: 1.7.4 COCOAPODS: 1.8.4
...@@ -26,6 +26,7 @@ Pod::Spec.new do |s| ...@@ -26,6 +26,7 @@ Pod::Spec.new do |s|
s.source_files = 'GMPhobos/Classes/*.{h,m}' s.source_files = 'GMPhobos/Classes/*.{h,m}'
s.dependency 'GMCache' s.dependency 'GMCache'
s.dependency 'MJExtension' s.dependency 'MJExtension'
s.dependency 'MagicalRecord'
s.library = 'z' s.library = 'z'
end end
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<model type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="15702" systemVersion="19C57" minimumToolsVersion="Automatic" sourceLanguage="Objective-C" userDefinedModelVersionIdentifier="">
<entity name="SendDataEntity" representedClassName="SendDataEntity" syncable="YES">
<attribute name="api" optional="YES" attributeType="String"/>
<attribute name="data" optional="YES" attributeType="Binary"/>
<attribute name="id" optional="YES" attributeType="String"/>
<attribute name="status" optional="YES" attributeType="Integer 16" defaultValueString="0" usesScalarValueType="YES"/>
</entity>
<elements>
<element name="SendDataEntity" positionX="-45" positionY="0" width="128" height="103"/>
</elements>
</model>
\ No newline at end of file
...@@ -169,28 +169,13 @@ NS_ASSUME_NONNULL_BEGIN ...@@ -169,28 +169,13 @@ NS_ASSUME_NONNULL_BEGIN
+ (NSInteger)normalPhobosCount; + (NSInteger)normalPhobosCount;
/** 获取所有非立即发送埋点数据 */ /** 获取所有非立即发送埋点数据 */
+ (NSDictionary *)normalPhobosData; + (NSArray *)normalPhobosData;
/** 获取url的非立即发送埋点数量 */ /** 获取所有立即发送埋点数量 */
+ (NSInteger)normalPhobosCountForURL:(NSString *)url; + (NSUInteger)immediatelyPhobosCount;
/** 获取serverAPI的非立即发送埋点数据 */
+ (NSArray *)normalPhobosDataForServerAPI;
/** 获取url的非立即发送埋点数据 */
+ (NSArray *)normalPhobosDataForURL:(NSString *)url;
/** 获取所有立即发送埋点数据 */ /** 获取所有立即发送埋点数据 */
+ (NSDictionary *)immediatelyPhobosData; + (NSArray *)immediatelyPhobosData;
/** 获取serverAPI的立即发送埋点数据 */
+ (NSArray *)immediatelyPhobosForServerAPI;
/** 获取url的立即发送埋点数据 */
+ (NSArray *)immediatelyPhobosDataForURL:(NSString *)url;
/** 获取url的立即发送埋点数量 */
+ (NSUInteger)immediatelyPhobosCountForURL:(NSString *)url;
/** 清除非立即发送埋点数据缓存 */ /** 清除非立即发送埋点数据缓存 */
...@@ -200,9 +185,5 @@ NS_ASSUME_NONNULL_BEGIN ...@@ -200,9 +185,5 @@ NS_ASSUME_NONNULL_BEGIN
+ (void)removeAllImmediatelyPhobosData; + (void)removeAllImmediatelyPhobosData;
/** 获取将要发送的数据 */
@property (nonatomic, copy) void (^phobosSendDataBlock)(NSArray *datas);
@end @end
NS_ASSUME_NONNULL_END NS_ASSUME_NONNULL_END
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
#import <GMCache/GMCache.h> #import <GMCache/GMCache.h>
#import <objc/runtime.h> #import <objc/runtime.h>
#import "PhobosDataManager.h" #import "PhobosDataManager.h"
#import "PhobosSendManager.h"
static NewPhobos *_sharedClient; static NewPhobos *_sharedClient;
static NSString *sdkVersion = @"1.4.0"; static NSString *sdkVersion = @"1.4.0";
...@@ -27,10 +28,6 @@ static NSString *sdkVersion = @"1.4.0"; ...@@ -27,10 +28,6 @@ static NSString *sdkVersion = @"1.4.0";
/* 每一条埋点数据的物理ID,自增,生命周期和sessionId相同。特别注意:在sessionOver的时候,要把他置为0 */ /* 每一条埋点数据的物理ID,自增,生命周期和sessionId相同。特别注意:在sessionOver的时候,要把他置为0 */
@property (assign, nonatomic) NSInteger serialId; @property (assign, nonatomic) NSInteger serialId;
//@property (nonatomic, weak) dispatch_semaphore_t immediatelySemaphore;// 保障需要立即发送的埋点数据安全
//@property (nonatomic, weak) dispatch_semaphore_t normalSemaphore;// 保障普通埋点数据安全
@property (nonatomic, assign) NSInteger normalCount;// 记录普通埋点数量
@end @end
@implementation NewPhobos @implementation NewPhobos
...@@ -55,9 +52,6 @@ static NSString *sdkVersion = @"1.4.0"; ...@@ -55,9 +52,6 @@ static NSString *sdkVersion = @"1.4.0";
_appVersion = [PhobosUtil getAppVersion]; _appVersion = [PhobosUtil getAppVersion];
_signingType = PhobosSigningTypeUndefined; _signingType = PhobosSigningTypeUndefined;
NSArray<PhobosSendModel *> *datas = [PhobosDataManager fetchDataModelsWithStatus:PhobosModelSendStatusNormal];
self.normalCount = datas.count;
[self setupNotification]; [self setupNotification];
[self handleSessionStart]; [self handleSessionStart];
} }
...@@ -177,7 +171,7 @@ static NSString *sdkVersion = @"1.4.0"; ...@@ -177,7 +171,7 @@ static NSString *sdkVersion = @"1.4.0";
phobosLog(@"handleAppInForeground"); phobosLog(@"handleAppInForeground");
[self handleSessionStart]; [self handleSessionStart];
[self handleEventDeviceOpened]; [self handleEventDeviceOpened];
[self trackPhobosWithSendAPI:nil data:nil immediate:YES]; [NewPhobos disposeSendDataWithImmediately:NO];
[self handlePVEventAppInForeground]; [self handlePVEventAppInForeground];
} }
...@@ -190,7 +184,7 @@ static NSString *sdkVersion = @"1.4.0"; ...@@ -190,7 +184,7 @@ static NSString *sdkVersion = @"1.4.0";
phobosLog(@"handleAppInBackgound"); phobosLog(@"handleAppInBackgound");
[self handlePVEventAppInBackgound]; [self handlePVEventAppInBackgound];
[self handleSessionOver]; [self handleSessionOver];
[self trackPhobosWithSendAPI:nil data:nil immediate:YES]; [NewPhobos disposeSendDataWithImmediately:NO];
} }
/** /**
...@@ -392,32 +386,38 @@ static NSString *sdkVersion = @"1.4.0"; ...@@ -392,32 +386,38 @@ static NSString *sdkVersion = @"1.4.0";
NSDictionary *dataDict = [_sharedClient prepareDictionaryForEvent:eventName attributes:attributes]; NSDictionary *dataDict = [_sharedClient prepareDictionaryForEvent:eventName attributes:attributes];
@try { @try {
NSData *JSON = [PhobosUtil encodeJSON:dataDict]; NSData *JSON = [PhobosUtil encodeJSON:dataDict];
[_sharedClient trackPhobosWithSendAPI:currentAPI data:dataDict immediate:sendNow]; [PhobosDataManager insertData:dataDict sendAPI:currentAPI immediately:sendNow completion:^(BOOL contextDidSave, NSError * _Nullable error) {
if (sendNow) {
[self disposeSendDataWithImmediately:YES];
} else {
NSArray<SendDataEntity *> *fetchArray = [PhobosDataManager fetchDataEntitiesWithImmediately:NO];
if (fetchArray.count > 50) {
[self disposeSendDataWithImmediately:NO];
}
}
}];
} @catch (NSException *exception) { } @catch (NSException *exception) {
NSAssert(NO, @"哎呀呀,VALUE不能为NSObject "); NSAssert(NO, @"哎呀呀,VALUE不能为NSObject ");
} }
} }
#pragma mark - 事件存储、发送
/** /**
* 普通埋点 * 处理发送数据
* @param url 接口url
* @param dataArray 埋点数据
* @param nowSend 是否需要发送当前缓存数据(app进入到后台、前台等情况)
*/ */
- (void)trackPhobosWithSendAPI:(NSString *)sendAPI data:(NSDictionary *)data immediate:(BOOL)immediate { + (void)disposeSendDataWithImmediately:(BOOL)immediately {
dispatch_async(dispatch_get_main_queue(), ^{ NSArray<SendDataEntity *> *entities = [PhobosDataManager fetchDataEntitiesWithImmediately:immediately];
[PhobosDataManager insertData:data sendAPI:sendAPI immediately:immediate]; if (entities.count > 0) {
if (!immediate) { [PhobosDataManager updateDataEntities:entities sendStatus:PhobosDataSendStatusSending completion:nil];
_normalCount++; [PhobosSendManager sendDataWithEntities:entities completion:^(NSArray<SendDataEntity *> * _Nonnull finishEntities, NSInteger code) {
if (code == 200) {
[PhobosDataManager updateDataEntities:finishEntities sendStatus:PhobosDataSendStatusFinish completion:^(BOOL contextDidSave, NSError * _Nullable error) {
[PhobosDataManager deleteDataEntities:finishEntities];
}];
} else { } else {
[PhobosDataManager sendData]; [PhobosDataManager updateDataEntities:finishEntities sendStatus:PhobosDataSendStatusError completion:nil];
} }
if ((immediate && sendAPI == nil) || self.normalCount >= 50) { // 数据超过一定数量 或 进入后台等逻辑,统一进行发送普通埋点数据 }];
[NewPhobos removeAllNormalPhobosData];
} }
});
} }
@end @end
...@@ -426,65 +426,36 @@ static NSString *sdkVersion = @"1.4.0"; ...@@ -426,65 +426,36 @@ static NSString *sdkVersion = @"1.4.0";
/** 获取所有非立即发送埋点数量 */ /** 获取所有非立即发送埋点数量 */
+ (NSInteger)normalPhobosCount { + (NSInteger)normalPhobosCount {
return NewPhobos.sharedClient.normalCount; NSPredicate *predicate = [NSPredicate predicateWithFormat:@"sendStatus = %d", PhobosDataSendStatusNormal];
return [PhobosDataManager fetchCountOfEntitiesWithPredicate:predicate];
} }
/** 获取所有非立即发送埋点数据 */ /** 获取所有非立即发送埋点数据 */
+ (NSDictionary *)normalPhobosData { + (NSArray *)normalPhobosData {
return [GMCache fetchObjectAtDocumentPathWithkey:PhobosNormalCacheKey]; return [PhobosDataManager fetchDataEntitiesWithImmediately:NO];
} }
/** 获取url的非立即发送埋点数量 */ /** 获取所有立即发送埋点数量 */
+ (NSUInteger)normalPhobosCountForURL:(NSString *)url { + (NSUInteger)immediatelyPhobosCount {
NSDictionary *dict = [GMCache fetchObjectAtDocumentPathWithkey:PhobosNormalCacheKey]; NSPredicate *predicate = [NSPredicate predicateWithFormat:@"sendStatus = %d or sendStatus = %d", PhobosDataSendStatusToBeSend, PhobosDataSendStatusError];
NSArray *urlData = dict[url]; return [PhobosDataManager fetchCountOfEntitiesWithPredicate:predicate];
return urlData ? urlData.count : 0;
}
+ (NSArray *)normalPhobosDataForServerAPI {
return [self normalPhobosDataForURL:NewPhobos.sharedClient.serverAPI];
}
/** 获取url的非立即发送埋点数据 */
+ (NSArray *)normalPhobosDataForURL:(NSString *)url {
NSDictionary *dict = [GMCache fetchObjectAtDocumentPathWithkey:PhobosNormalCacheKey];
return dict[url];
}
+ (NSArray *)immediatelyPhobosForServerAPI {
return [self immediatelyPhobosDataForURL:NewPhobos.sharedClient.serverAPI];
} }
/** 获取所有立即发送埋点数据 */ /** 获取所有立即发送埋点数据 */
+ (NSDictionary *)immediatelyPhobosData { + (NSArray *)immediatelyPhobosData {
return [GMCache fetchObjectAtDocumentPathWithkey:PhobosImmediatelyCacheKey]; return [PhobosDataManager fetchDataEntitiesWithImmediately:YES];
}
/** 获取url的立即发送埋点数据 */
+ (NSArray *)immediatelyPhobosDataForURL:(NSString *)url {
NSDictionary *dict = [GMCache fetchObjectAtDocumentPathWithkey:PhobosImmediatelyCacheKey];
return dict[url];
}
+ (NSUInteger)immediatelyPhobosCountForURL:(NSString *)url {
NSDictionary *dict = [GMCache fetchObjectAtDocumentPathWithkey:PhobosImmediatelyCacheKey];
NSArray *urlData = dict[url];
return urlData ? urlData.count : 0;
} }
/** 清除非立即发送埋点数据缓存 */ /** 清除非立即发送埋点数据缓存 */
+ (void)removeAllNormalPhobosData { + (void)removeAllNormalPhobosData {
NewPhobos.sharedClient.normalCount = 0; NSArray<SendDataEntity *> *fetchArray = [PhobosDataManager fetchDataEntitiesWithImmediately:NO];
dispatch_async(dispatch_get_main_queue(), ^{ [PhobosDataManager deleteDataEntities:fetchArray];
[PhobosDataManager removeAllDataWithImmediately:NO];
});
} }
/** 清除立即发送埋点数据缓存 */ /** 清除立即发送埋点数据缓存 */
+ (void)removeAllImmediatelyPhobosData { + (void)removeAllImmediatelyPhobosData {
dispatch_async(dispatch_get_main_queue(), ^{ NSArray<SendDataEntity *> *fetchArray = [PhobosDataManager fetchDataEntitiesWithImmediately:YES];
[PhobosDataManager removeAllDataWithImmediately:YES]; [PhobosDataManager deleteDataEntities:fetchArray];
});
} }
@end @end
...@@ -6,37 +6,27 @@ ...@@ -6,37 +6,27 @@
// //
#import <Foundation/Foundation.h> #import <Foundation/Foundation.h>
#import <MagicalRecord/MagicalRecord.h>
#import "SendDataEntity+CoreDataClass.h"
NS_ASSUME_NONNULL_BEGIN NS_ASSUME_NONNULL_BEGIN
typedef NS_ENUM(NSInteger, PhobosModelSendStatus) { typedef NS_ENUM(NSInteger, PhobosDataSendStatus) {
PhobosModelSendStatusNormal = 0, PhobosDataSendStatusNormal = 0, // 普通埋点数据
PhobosModelSendStatusToBeSend, PhobosDataSendStatusToBeSend = 1, // 待发送数据
PhobosModelSendStatusSending, PhobosDataSendStatusSending = 2, // 发送中数据
PhobosModelSendStatusFinish, PhobosDataSendStatusFinish = 3, // 发送完成数据
PhobosModelSendStatusError, PhobosDataSendStatusError = 4, // 发送失败数据
}; };
@interface PhobosSendModel : NSObject
@property (nonatomic, copy, readonly) NSString *sendId;
@property (nonatomic, strong) id data;
@property (nonatomic, copy) NSString *sendAPI;
@property (nonatomic, assign) PhobosModelSendStatus sendStatus;
- (instancetype)initWithData:(id)data sendAPI:(NSString *)api;
@end
@interface PhobosDataManager : NSObject @interface PhobosDataManager : NSObject
+ (void)insertData:(NSDictionary *)data sendAPI:(NSString *)v immediately:(BOOL)immediately; + (NSArray<SendDataEntity *> *)fetchDataEntitiesWithImmediately:(BOOL)immediately;
+ (void)updateDataModel:(PhobosSendModel *)model sendStatus:(PhobosModelSendStatus)sendStatus; + (NSArray<SendDataEntity *> *)fetchDataEntitiesWithPredicate:(NSPredicate *)searchFilter;
+ (void)deleteDataModel:(PhobosSendModel *)model; + (NSUInteger)fetchCountOfEntitiesWithPredicate:(NSPredicate *)searchFilter;
+ (void)removeAllDataWithImmediately:(BOOL)immediately; + (void)insertData:(NSDictionary *)data sendAPI:(NSString *)sendAPI immediately:(BOOL)immediately completion:(MRSaveCompletionHandler)completion;
+ (NSArray<PhobosSendModel *> *)fetchDataModelsWithStatus:(PhobosModelSendStatus)stauts; + (void)updateDataEntities:(NSArray<SendDataEntity *> *)entities sendStatus:(PhobosDataSendStatus)sendStatus completion:(MRSaveCompletionHandler)completion;
+ (void)deleteDataEntities:(NSArray<SendDataEntity *> *)entities;
+ (void)sendData;
@end @end
......
...@@ -6,177 +6,74 @@ ...@@ -6,177 +6,74 @@
// //
#import "PhobosDataManager.h" #import "PhobosDataManager.h"
#import <GMCache/GMCache.h> #import "PhobosSendManager.h"
#import "PhobosUtil.h"
#import "PhobosConfig.h" #import "PhobosConfig.h"
#import "PhobosUtil.h"
#import <MJExtension/MJExtension.h> #import <MJExtension/MJExtension.h>
#import "Phobos.h" #import "NSManagedObjectModel+MagicalRecord.h"
#import "NSPersistentStoreCoordinator+MagicalRecord.h"
#ifdef APPSTORE
#define GMExactExposureApi @"https://log.igengmei.com/log/precise_exposure"
#else
#define GMExactExposureApi @"http://log.test.igengmei.com/log/precise_exposure"
#endif
@implementation PhobosSendModel
- (instancetype)initWithData:(id)data sendAPI:(NSString *)sendAPI {
if (self = [super init]) {
_data = data;
_sendId = [PhobosUtil currentMMTime];
_sendAPI = sendAPI;
}
return self;
}
@end
@implementation PhobosDataManager @implementation PhobosDataManager
static NSManagedObjectContext *Phobos_defaultContext;
+ (void)initialize { + (void)initialize {
static dispatch_once_t onceToken; static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{ dispatch_once(&onceToken, ^{
NSMutableArray *dataArray = [GMCache fetchObjectAtDocumentPathWithkey:PhobosTempCacheKey]; NSBundle *bundle = [NSBundle bundleForClass:[self class]];
NSArray *array = [GMCache fetchObjectAtDocumentPathWithkey:PhobosCacheKey]; NSURL *modelURL = [bundle URLForResource:@"PhobosDatas" withExtension:@"momd"];//NewCodeDataModel.xcdatamodeld
if (dataArray) { NSManagedObjectModel *model = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
[dataArray addObjectsFromArray:array]; [NSManagedObjectModel MR_setDefaultManagedObjectModel:model];
} else{ [MagicalRecord setupAutoMigratingCoreDataStack];
dataArray = [NSMutableArray arrayWithArray:array];
}
if (dataArray.count > 0) {
[self utilSendDataArray:dataArray currentAPI:Phobos.sharedClient.apiHost success:^(NSInteger code) {
[GMCache removeObjectAtDocumentPathWithkey:PhobosCacheKey];
[GMCache removeObjectAtDocumentPathWithkey:PhobosTempCacheKey];
}];
}
NSString *exposureAPI = GMExactExposureApi;
NSArray *exposureArray = [GMCache fetchObjectAtDocumentPathWithkey:[PhobosUtil MD5String:exposureAPI]];
if (exposureArray.count > 0) {
[self utilSendDataArray:exposureArray currentAPI:exposureAPI success:^(NSInteger code) {
[GMCache removeObjectAtDocumentPathWithkey:[PhobosUtil MD5String:exposureAPI]];
}];
}
}); });
} }
+ (NSArray<PhobosSendModel *> *)fetchCache { + (NSArray<SendDataEntity *> *)fetchDataEntitiesWithImmediately:(BOOL)immediately {
NSArray *data = [GMCache fetchObjectAtDocumentPathWithkey:PhobosNewCacheKey]; NSPredicate *predicate;
NSArray<PhobosSendModel *> *sendModelArray = [PhobosSendModel mj_objectArrayWithKeyValuesArray:data]; if (immediately) {
return sendModelArray ?: [NSArray new]; predicate = [NSPredicate predicateWithFormat:@"sendStatus = %d or sendStatus = %d", PhobosDataSendStatusToBeSend, PhobosDataSendStatusError];
} } else {
predicate = [NSPredicate predicateWithFormat:@"sendStatus = %d", PhobosDataSendStatusNormal];
+ (void)storeCache:(NSArray<PhobosSendModel *> *)sendModelArray {
NSArray *data = [PhobosSendModel mj_keyValuesArrayWithObjectArray:sendModelArray];
[GMCache storeObjectAtDocumentPathWithkey:PhobosNewCacheKey object:data];
}
+ (void)insertData:(NSDictionary *)data sendAPI:(NSString *)sendAPI immediately:(BOOL)immediately {
NSMutableArray<PhobosSendModel *> *datas = [[self fetchCache] mutableCopy];
PhobosSendModel *model = [[PhobosSendModel alloc] initWithData:data sendAPI:sendAPI];
model.sendStatus = immediately ? PhobosModelSendStatusToBeSend: PhobosModelSendStatusNormal;
[datas addObject:model];
[self storeCache:datas];
}
+ (void)updateDataModel:(PhobosSendModel *)model sendStatus:(PhobosModelSendStatus)sendStatus {
NSMutableArray<PhobosSendModel *> *datas = [[self fetchCache] mutableCopy];
__block NSInteger updateIdx = -1;
[datas enumerateObjectsUsingBlock:^(PhobosSendModel * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
if ([model.sendId isEqualToString:obj.sendId]) {
updateIdx = idx;
model.sendStatus = sendStatus;
*stop = YES;
}
}];
if (updateIdx != -1) {
[datas replaceObjectAtIndex:updateIdx withObject:model];
} }
[self storeCache:datas]; return [self fetchDataEntitiesWithPredicate:predicate];
} }
+ (void)deleteDataModel:(PhobosSendModel *)model { + (NSArray<SendDataEntity *> *)fetchDataEntitiesWithPredicate:(NSPredicate *)searchFilter {
NSMutableArray<PhobosSendModel *> *datas = [[self fetchCache] mutableCopy]; return [SendDataEntity MR_findAllWithPredicate:searchFilter inContext:[NSManagedObjectContext MR_defaultContext]];
__block NSInteger updateIdx = -1;
[datas enumerateObjectsUsingBlock:^(PhobosSendModel * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
if ([model.sendId isEqualToString:obj.sendId]) {
updateIdx = idx;
*stop = YES;
}
}];
[datas removeObjectAtIndex:updateIdx];
[self storeCache:datas];
} }
+ (void)removeAllDataWithImmediately:(BOOL)immediately { + (NSUInteger)fetchCountOfEntitiesWithPredicate:(NSPredicate *)searchFilter {
NSArray<PhobosSendModel *> *datas = [self fetchCache]; return [SendDataEntity MR_numberOfEntitiesWithPredicate:searchFilter inContext:[NSManagedObjectContext MR_defaultContext]];
NSMutableArray<PhobosSendModel *> *temp = [datas mutableCopy];
[datas enumerateObjectsUsingBlock:^(PhobosSendModel * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
if (immediately) {
if (obj.sendStatus == PhobosModelSendStatusFinish) {
[temp removeObject:obj];
}
} else {
if (obj.sendStatus == PhobosModelSendStatusNormal) {
obj.sendStatus = PhobosModelSendStatusToBeSend;
[temp replaceObjectAtIndex:idx withObject:obj];
}
}
}];
[self storeCache:temp];
} }
+ (NSArray<PhobosSendModel *> *)fetchDataModelsWithStatus:(PhobosModelSendStatus)status { + (void)insertData:(NSDictionary *)data sendAPI:(NSString *)sendAPI immediately:(BOOL)immediately completion:(MRSaveCompletionHandler)completion {
NSArray<PhobosSendModel *> *data = [self fetchCache]; if (!sendAPI || [sendAPI isEqualToString:@""] || !data) {
NSMutableArray *temp = [NSMutableArray new]; return;
[data enumerateObjectsUsingBlock:^(PhobosSendModel * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
if (obj.sendStatus == status) {
[temp addObject:obj];
} }
}]; SendDataEntity *entity = [SendDataEntity MR_createEntity];
return temp; entity.data = [data mj_JSONData];
entity.api = sendAPI;
entity.status = immediately ? PhobosDataSendStatusToBeSend : PhobosDataSendStatusNormal;
entity.id = [PhobosUtil currentMMTime];
[[NSManagedObjectContext MR_defaultContext] MR_saveWithOptions:MRSaveSynchronously completion:completion];
} }
+ (void)sendData { + (void)updateDataEntities:(NSArray<SendDataEntity *> *)entities sendStatus:(PhobosDataSendStatus)sendStatus completion:(MRSaveCompletionHandler)completion {
NSMutableDictionary *sendDataMap = [NSMutableDictionary new]; if (entities.count > 0) {
NSArray<PhobosSendModel *> *needSendData = [self fetchCache]; [entities enumerateObjectsUsingBlock:^(SendDataEntity *obj, NSUInteger idx, BOOL * _Nonnull stop) {
[needSendData enumerateObjectsUsingBlock:^(PhobosSendModel * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { obj.status = sendStatus;
if (obj.sendStatus == PhobosModelSendStatusToBeSend || obj.sendStatus == PhobosModelSendStatusError) {
NSMutableArray *temp = sendDataMap[obj.sendAPI] ?: [NSMutableArray new];
[temp addObject:obj];
[sendDataMap setValue:temp forKey:obj.sendAPI];
}
}];
[sendDataMap enumerateKeysAndObjectsUsingBlock:^(NSString *api, NSArray<PhobosSendModel *> *data, BOOL * _Nonnull stop) {
NSMutableArray *temp = [NSMutableArray new];
[data enumerateObjectsUsingBlock:^(PhobosSendModel *obj, NSUInteger idx, BOOL * _Nonnull stop) {
[self updateDataModel:obj sendStatus:PhobosModelSendStatusSending];
[temp addObject:obj.data];
}]; }];
if (temp.count > 0) { [[NSManagedObjectContext MR_defaultContext] MR_saveWithOptions:MRSaveSynchronously completion:completion];
[self utilSendDataArray:temp currentAPI:api success:^(NSInteger code) {
[data enumerateObjectsUsingBlock:^(PhobosSendModel *obj, NSUInteger idx, BOOL * _Nonnull stop) {
dispatch_async(dispatch_get_main_queue(), ^{
if (code == 200) {
[self deleteDataModel:obj];
} else {
[self updateDataModel:obj sendStatus:PhobosModelSendStatusError];
} }
});
}];
}];
}
}];
} }
+ (void)utilSendDataArray:(NSArray *)dataArray currentAPI:(NSString *)currentAPI success:(SendDataSuccessBlock)success { + (void)deleteDataEntities:(NSArray<SendDataEntity *> *)entities {
NSData *JSON = [PhobosUtil encodeJSON:dataArray]; if (entities.count > 0) {
NSData *compressedData = [PhobosUtil compressData:JSON]; [entities enumerateObjectsUsingBlock:^(SendDataEntity *obj, NSUInteger idx, BOOL * _Nonnull stop) {
[PhobosUtil sendData:compressedData currentAPI:currentAPI success:^(NSInteger code) { [obj MR_deleteEntity];
if (success) {
success(code);
}
}]; }];
[[NSManagedObjectContext MR_defaultContext] MR_saveOnlySelfAndWait];
}
} }
@end @end
//
// PhobosSendManager.h
// GMPhobos
//
// Created by Locus on 2020/3/3.
//
#import <Foundation/Foundation.h>
#import "PhobosDataManager.h"
#import "PhobosUtil.h"
NS_ASSUME_NONNULL_BEGIN
@interface PhobosSendManager : NSObject
+ (void)sendDataWithEntities:(NSArray<SendDataEntity *> *)needSendData completion:(nullable void(^)(NSArray<SendDataEntity *> *finishEntities, NSInteger code))completion;
@end
NS_ASSUME_NONNULL_END
//
// PhobosSendManager.m
// GMPhobos
//
// Created by Locus on 2020/3/3.
//
#import "PhobosSendManager.h"
#import <GMCache/GMCache.h>
#import <MJExtension/MJExtension.h>
#import "PhobosConfig.h"
#import "Phobos.h"
#ifdef APPSTORE
#define GMExactExposureApi @"https://log.igengmei.com/log/precise_exposure"
#else
#define GMExactExposureApi @"http://log.test.igengmei.com/log/precise_exposure"
#endif
@implementation PhobosSendManager
+ (void)initialize {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
[self disposeOldData];
});
}
+ (void)disposeOldData {
NSMutableArray *total = [NSMutableArray new];
NSArray *normalDataArray = [GMCache fetchObjectAtDocumentPathWithkey:PhobosTempCacheKey];
NSArray *immiDataArray = [GMCache fetchObjectAtDocumentPathWithkey:PhobosCacheKey];
[total addObjectsFromArray:normalDataArray];
[total addObjectsFromArray:immiDataArray];
if (total.count > 0) {
[self sendDataArray:total currentAPI:Phobos.sharedClient.apiHost success:^(NSInteger code) {
if (code) {
[GMCache removeObjectAtDocumentPathWithkey:PhobosCacheKey];
[GMCache removeObjectAtDocumentPathWithkey:PhobosTempCacheKey];
}
}];
}
NSString *exposureAPI = GMExactExposureApi;
NSArray *exposureArray = [GMCache fetchObjectAtDocumentPathWithkey:[PhobosUtil MD5String:exposureAPI]];
if (exposureArray.count > 0) {
[self sendDataArray:exposureArray currentAPI:exposureAPI success:^(NSInteger code) {
if (code) {
[GMCache removeObjectAtDocumentPathWithkey:[PhobosUtil MD5String:exposureAPI]];
}
}];
}
}
+ (void)sendDataWithEntities:(NSArray<SendDataEntity *> *)sendDataEntities completion:(void (^)(NSArray<SendDataEntity *> * _Nonnull, NSInteger))completion {
if (sendDataEntities.count == 0) {
return;
}
NSMutableDictionary *sendDataMap = [NSMutableDictionary new];
[sendDataEntities enumerateObjectsUsingBlock:^(SendDataEntity *obj, NSUInteger idx, BOOL * _Nonnull stop) {
NSMutableArray *sendData = sendDataMap[obj.api] ?: [NSMutableArray new];
[sendData addObject:obj];
[sendDataMap setValue:sendData forKey:obj.api];
}];
[sendDataMap enumerateKeysAndObjectsUsingBlock:^(NSString *api, NSArray<SendDataEntity *> *entities, BOOL * _Nonnull stop) {
NSMutableArray *sendDatas = [NSMutableArray new];
[entities enumerateObjectsUsingBlock:^(SendDataEntity *obj, NSUInteger idx, BOOL * _Nonnull stop) {
[sendDatas addObject:[obj.data mj_JSONObject]];
}];
if (sendDatas.count > 0) {
[self sendDataArray:sendDatas currentAPI:api success:^(NSInteger code) {
if (completion) {
completion(entities, code);
}
}];
}
}];
}
+ (void)sendDataArray:(NSArray *)dataArray currentAPI:(NSString *)currentAPI success:(SendDataSuccessBlock)success {
NSData *JSON = [PhobosUtil encodeJSON:dataArray];
NSData *compressedData = [PhobosUtil compressData:JSON];
[PhobosUtil sendData:compressedData currentAPI:currentAPI success:^(NSInteger code) {
if (success) {
success(code);
}
}];
}
@end
//
// SendDataEntity+CoreDataClass.h
// GMPhobos
//
// Created by Locus on 2020/3/5.
//
//
#import <Foundation/Foundation.h>
#import <CoreData/CoreData.h>
NS_ASSUME_NONNULL_BEGIN
@interface SendDataEntity : NSManagedObject
@end
NS_ASSUME_NONNULL_END
#import "SendDataEntity+CoreDataProperties.h"
//
// SendDataEntity+CoreDataClass.m
// GMPhobos
//
// Created by Locus on 2020/3/5.
//
//
#import "SendDataEntity+CoreDataClass.h"
@implementation SendDataEntity
@end
//
// SendDataEntity+CoreDataProperties.h
// GMPhobos
//
// Created by Locus on 2020/3/5.
//
//
#import "SendDataEntity+CoreDataClass.h"
NS_ASSUME_NONNULL_BEGIN
@interface SendDataEntity (CoreDataProperties)
+ (NSFetchRequest<SendDataEntity *> *)fetchRequest;
@property (nullable, nonatomic, copy) NSString *id;
@property (nullable, nonatomic, retain) NSData *data;
@property (nullable, nonatomic, copy) NSString *api;
@property (nonatomic) int16_t status;
@end
NS_ASSUME_NONNULL_END
//
// SendDataEntity+CoreDataProperties.m
// GMPhobos
//
// Created by Locus on 2020/3/5.
//
//
#import "SendDataEntity+CoreDataProperties.h"
@implementation SendDataEntity (CoreDataProperties)
+ (NSFetchRequest<SendDataEntity *> *)fetchRequest {
return [NSFetchRequest fetchRequestWithEntityName:@"SendDataEntity"];
}
@dynamic id;
@dynamic data;
@dynamic api;
@dynamic status;
@end
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment