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

添加CoreData

parent b4bfd878
......@@ -168,8 +168,8 @@
6003F59C195388D20070C39A /* GMAppDelegate.h */,
6003F59D195388D20070C39A /* GMAppDelegate.m */,
873B8AEA1B1F5CCA007FD442 /* Main.storyboard */,
6003F5A6195388D20070C39A /* GMViewController.m */,
6003F5A5195388D20070C39A /* GMViewController.h */,
6003F5A6195388D20070C39A /* GMViewController.m */,
6003F5A8195388D20070C39A /* Images.xcassets */,
6003F594195388D20070C39A /* Supporting Files */,
);
......@@ -436,6 +436,7 @@
"${BUILT_PRODUCTS_DIR}/GMCache/GMCache.framework",
"${BUILT_PRODUCTS_DIR}/GMPhobos/GMPhobos.framework",
"${BUILT_PRODUCTS_DIR}/MJExtension/MJExtension.framework",
"${BUILT_PRODUCTS_DIR}/MagicalRecord/MagicalRecord.framework",
"${BUILT_PRODUCTS_DIR}/TMCache/TMCache.framework",
);
name = "[CP] Embed Pods Frameworks";
......@@ -443,6 +444,7 @@
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/GMCache.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/GMPhobos.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",
);
runOnlyForDeploymentPostprocessing = 0;
......
......@@ -33,9 +33,9 @@ NSString *const MockCityId = @"beijing";
#ifdef POD_CONFIGURATION_APP_STORE
NSString *url = @"http://log.gmei.com/log/collect";
#else
NSString *url = @"http://log.test.gengmei.cc/log/collect";
NSString *url = @"http://log.test.igengmei.com/log/collect";
#endif
[GMCache removeObjectAtDocumentPathWithkey:PhobosCacheKey];
// [[NSUserDefaults standardUserDefaults] setBool:YES forKey:PhobosGray];
Phobos *client = [Phobos clientWithAppName:MockAppName channelId:MockChannelId];
[Phobos setSharedClient:client];
Phobos.sharedClient.serverAPI = url;
......
......@@ -84,6 +84,11 @@
"idiom" : "ipad",
"size" : "83.5x83.5",
"scale" : "2x"
},
{
"idiom" : "ios-marketing",
"size" : "1024x1024",
"scale" : "1x"
}
],
"info" : {
......
......@@ -3,7 +3,11 @@ PODS:
- TMCache (= 2.1.0)
- GMPhobos (1.3.5):
- GMCache
- MagicalRecord
- MJExtension
- MagicalRecord (2.3.2):
- MagicalRecord/Core (= 2.3.2)
- MagicalRecord/Core (2.3.2)
- MJExtension (3.2.1)
- TMCache (2.1.0)
......@@ -13,7 +17,8 @@ DEPENDENCIES:
SPEC REPOS:
"git@git.wanmeizhensuo.com:gengmeiios/GMSpecs.git":
- GMCache
https://github.com/cocoapods/specs.git:
https://github.com/CocoaPods/Specs.git:
- MagicalRecord
- MJExtension
- TMCache
......@@ -23,10 +28,11 @@ EXTERNAL SOURCES:
SPEC CHECKSUMS:
GMCache: b78d8e46db864405e91d226ce640cc80d966c611
GMPhobos: 242bc118edb737fb496b49235b2f24d61c349d7b
GMPhobos: 81a3a1171bab1499b1147eca51a5359dcfb660d0
MagicalRecord: 53bed74b4323b930992a725be713e53b37d19755
MJExtension: 635f2c663dcb1bf76fa4b715b2570a5710aec545
TMCache: 95ebcc9b3c7e90fb5fd8fc3036cba3aa781c9bed
PODFILE CHECKSUM: ea0fac2144ac80baf8f21576cde49526c19991ad
COCOAPODS: 1.7.4
COCOAPODS: 1.8.4
......@@ -26,6 +26,7 @@ Pod::Spec.new do |s|
s.source_files = 'GMPhobos/Classes/*.{h,m}'
s.dependency 'GMCache'
s.dependency 'MJExtension'
s.dependency 'MagicalRecord'
s.library = 'z'
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
+ (NSInteger)normalPhobosCount;
/** 获取所有非立即发送埋点数据 */
+ (NSDictionary *)normalPhobosData;
+ (NSArray *)normalPhobosData;
/** 获取url的非立即发送埋点数量 */
+ (NSInteger)normalPhobosCountForURL:(NSString *)url;
/** 获取serverAPI的非立即发送埋点数据 */
+ (NSArray *)normalPhobosDataForServerAPI;
/** 获取url的非立即发送埋点数据 */
+ (NSArray *)normalPhobosDataForURL:(NSString *)url;
/** 获取所有立即发送埋点数量 */
+ (NSUInteger)immediatelyPhobosCount;
/** 获取所有立即发送埋点数据 */
+ (NSDictionary *)immediatelyPhobosData;
/** 获取serverAPI的立即发送埋点数据 */
+ (NSArray *)immediatelyPhobosForServerAPI;
/** 获取url的立即发送埋点数据 */
+ (NSArray *)immediatelyPhobosDataForURL:(NSString *)url;
/** 获取url的立即发送埋点数量 */
+ (NSUInteger)immediatelyPhobosCountForURL:(NSString *)url;
+ (NSArray *)immediatelyPhobosData;
/** 清除非立即发送埋点数据缓存 */
......@@ -200,9 +185,5 @@ NS_ASSUME_NONNULL_BEGIN
+ (void)removeAllImmediatelyPhobosData;
/** 获取将要发送的数据 */
@property (nonatomic, copy) void (^phobosSendDataBlock)(NSArray *datas);
@end
NS_ASSUME_NONNULL_END
......@@ -14,6 +14,7 @@
#import <GMCache/GMCache.h>
#import <objc/runtime.h>
#import "PhobosDataManager.h"
#import "PhobosSendManager.h"
static NewPhobos *_sharedClient;
static NSString *sdkVersion = @"1.4.0";
......@@ -27,10 +28,6 @@ static NSString *sdkVersion = @"1.4.0";
/* 每一条埋点数据的物理ID,自增,生命周期和sessionId相同。特别注意:在sessionOver的时候,要把他置为0 */
@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
@implementation NewPhobos
......@@ -55,9 +52,6 @@ static NSString *sdkVersion = @"1.4.0";
_appVersion = [PhobosUtil getAppVersion];
_signingType = PhobosSigningTypeUndefined;
NSArray<PhobosSendModel *> *datas = [PhobosDataManager fetchDataModelsWithStatus:PhobosModelSendStatusNormal];
self.normalCount = datas.count;
[self setupNotification];
[self handleSessionStart];
}
......@@ -177,7 +171,7 @@ static NSString *sdkVersion = @"1.4.0";
phobosLog(@"handleAppInForeground");
[self handleSessionStart];
[self handleEventDeviceOpened];
[self trackPhobosWithSendAPI:nil data:nil immediate:YES];
[NewPhobos disposeSendDataWithImmediately:NO];
[self handlePVEventAppInForeground];
}
......@@ -190,7 +184,7 @@ static NSString *sdkVersion = @"1.4.0";
phobosLog(@"handleAppInBackgound");
[self handlePVEventAppInBackgound];
[self handleSessionOver];
[self trackPhobosWithSendAPI:nil data:nil immediate:YES];
[NewPhobos disposeSendDataWithImmediately:NO];
}
/**
......@@ -392,32 +386,38 @@ static NSString *sdkVersion = @"1.4.0";
NSDictionary *dataDict = [_sharedClient prepareDictionaryForEvent:eventName attributes:attributes];
@try {
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) {
NSAssert(NO, @"哎呀呀,VALUE不能为NSObject ");
}
}
#pragma mark - 事件存储、发送
/**
* 普通埋点
* @param url 接口url
* @param dataArray 埋点数据
* @param nowSend 是否需要发送当前缓存数据(app进入到后台、前台等情况)
* 处理发送数据
*/
- (void)trackPhobosWithSendAPI:(NSString *)sendAPI data:(NSDictionary *)data immediate:(BOOL)immediate {
dispatch_async(dispatch_get_main_queue(), ^{
[PhobosDataManager insertData:data sendAPI:sendAPI immediately:immediate];
if (!immediate) {
_normalCount++;
} else {
[PhobosDataManager sendData];
}
if ((immediate && sendAPI == nil) || self.normalCount >= 50) { // 数据超过一定数量 或 进入后台等逻辑,统一进行发送普通埋点数据
[NewPhobos removeAllNormalPhobosData];
}
});
+ (void)disposeSendDataWithImmediately:(BOOL)immediately {
NSArray<SendDataEntity *> *entities = [PhobosDataManager fetchDataEntitiesWithImmediately:immediately];
if (entities.count > 0) {
[PhobosDataManager updateDataEntities:entities sendStatus:PhobosDataSendStatusSending completion:nil];
[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 {
[PhobosDataManager updateDataEntities:finishEntities sendStatus:PhobosDataSendStatusError completion:nil];
}
}];
}
}
@end
......@@ -426,65 +426,36 @@ static NSString *sdkVersion = @"1.4.0";
/** 获取所有非立即发送埋点数量 */
+ (NSInteger)normalPhobosCount {
return NewPhobos.sharedClient.normalCount;
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"sendStatus = %d", PhobosDataSendStatusNormal];
return [PhobosDataManager fetchCountOfEntitiesWithPredicate:predicate];
}
/** 获取所有非立即发送埋点数据 */
+ (NSDictionary *)normalPhobosData {
return [GMCache fetchObjectAtDocumentPathWithkey:PhobosNormalCacheKey];
+ (NSArray *)normalPhobosData {
return [PhobosDataManager fetchDataEntitiesWithImmediately:NO];
}
/** 获取url的非立即发送埋点数量 */
+ (NSUInteger)normalPhobosCountForURL:(NSString *)url {
NSDictionary *dict = [GMCache fetchObjectAtDocumentPathWithkey:PhobosNormalCacheKey];
NSArray *urlData = dict[url];
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];
/** 获取所有立即发送埋点数量 */
+ (NSUInteger)immediatelyPhobosCount {
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"sendStatus = %d or sendStatus = %d", PhobosDataSendStatusToBeSend, PhobosDataSendStatusError];
return [PhobosDataManager fetchCountOfEntitiesWithPredicate:predicate];
}
/** 获取所有立即发送埋点数据 */
+ (NSDictionary *)immediatelyPhobosData {
return [GMCache fetchObjectAtDocumentPathWithkey:PhobosImmediatelyCacheKey];
}
/** 获取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;
+ (NSArray *)immediatelyPhobosData {
return [PhobosDataManager fetchDataEntitiesWithImmediately:YES];
}
/** 清除非立即发送埋点数据缓存 */
+ (void)removeAllNormalPhobosData {
NewPhobos.sharedClient.normalCount = 0;
dispatch_async(dispatch_get_main_queue(), ^{
[PhobosDataManager removeAllDataWithImmediately:NO];
});
NSArray<SendDataEntity *> *fetchArray = [PhobosDataManager fetchDataEntitiesWithImmediately:NO];
[PhobosDataManager deleteDataEntities:fetchArray];
}
/** 清除立即发送埋点数据缓存 */
+ (void)removeAllImmediatelyPhobosData {
dispatch_async(dispatch_get_main_queue(), ^{
[PhobosDataManager removeAllDataWithImmediately:YES];
});
NSArray<SendDataEntity *> *fetchArray = [PhobosDataManager fetchDataEntitiesWithImmediately:YES];
[PhobosDataManager deleteDataEntities:fetchArray];
}
@end
......@@ -6,37 +6,27 @@
//
#import <Foundation/Foundation.h>
#import <MagicalRecord/MagicalRecord.h>
#import "SendDataEntity+CoreDataClass.h"
NS_ASSUME_NONNULL_BEGIN
typedef NS_ENUM(NSInteger, PhobosModelSendStatus) {
PhobosModelSendStatusNormal = 0,
PhobosModelSendStatusToBeSend,
PhobosModelSendStatusSending,
PhobosModelSendStatusFinish,
PhobosModelSendStatusError,
typedef NS_ENUM(NSInteger, PhobosDataSendStatus) {
PhobosDataSendStatusNormal = 0, // 普通埋点数据
PhobosDataSendStatusToBeSend = 1, // 待发送数据
PhobosDataSendStatusSending = 2, // 发送中数据
PhobosDataSendStatusFinish = 3, // 发送完成数据
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
+ (void)insertData:(NSDictionary *)data sendAPI:(NSString *)v immediately:(BOOL)immediately;
+ (void)updateDataModel:(PhobosSendModel *)model sendStatus:(PhobosModelSendStatus)sendStatus;
+ (void)deleteDataModel:(PhobosSendModel *)model;
+ (void)removeAllDataWithImmediately:(BOOL)immediately;
+ (NSArray<PhobosSendModel *> *)fetchDataModelsWithStatus:(PhobosModelSendStatus)stauts;
+ (void)sendData;
+ (NSArray<SendDataEntity *> *)fetchDataEntitiesWithImmediately:(BOOL)immediately;
+ (NSArray<SendDataEntity *> *)fetchDataEntitiesWithPredicate:(NSPredicate *)searchFilter;
+ (NSUInteger)fetchCountOfEntitiesWithPredicate:(NSPredicate *)searchFilter;
+ (void)insertData:(NSDictionary *)data sendAPI:(NSString *)sendAPI immediately:(BOOL)immediately completion:(MRSaveCompletionHandler)completion;
+ (void)updateDataEntities:(NSArray<SendDataEntity *> *)entities sendStatus:(PhobosDataSendStatus)sendStatus completion:(MRSaveCompletionHandler)completion;
+ (void)deleteDataEntities:(NSArray<SendDataEntity *> *)entities;
@end
......
......@@ -6,177 +6,74 @@
//
#import "PhobosDataManager.h"
#import <GMCache/GMCache.h>
#import "PhobosUtil.h"
#import "PhobosSendManager.h"
#import "PhobosConfig.h"
#import "PhobosUtil.h"
#import <MJExtension/MJExtension.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 PhobosSendModel
- (instancetype)initWithData:(id)data sendAPI:(NSString *)sendAPI {
if (self = [super init]) {
_data = data;
_sendId = [PhobosUtil currentMMTime];
_sendAPI = sendAPI;
}
return self;
}
@end
#import "NSManagedObjectModel+MagicalRecord.h"
#import "NSPersistentStoreCoordinator+MagicalRecord.h"
@implementation PhobosDataManager
static NSManagedObjectContext *Phobos_defaultContext;
+ (void)initialize {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
NSMutableArray *dataArray = [GMCache fetchObjectAtDocumentPathWithkey:PhobosTempCacheKey];
NSArray *array = [GMCache fetchObjectAtDocumentPathWithkey:PhobosCacheKey];
if (dataArray) {
[dataArray addObjectsFromArray:array];
} else{
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]];
}];
}
NSBundle *bundle = [NSBundle bundleForClass:[self class]];
NSURL *modelURL = [bundle URLForResource:@"PhobosDatas" withExtension:@"momd"];//NewCodeDataModel.xcdatamodeld
NSManagedObjectModel *model = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
[NSManagedObjectModel MR_setDefaultManagedObjectModel:model];
[MagicalRecord setupAutoMigratingCoreDataStack];
});
}
+ (NSArray<PhobosSendModel *> *)fetchCache {
NSArray *data = [GMCache fetchObjectAtDocumentPathWithkey:PhobosNewCacheKey];
NSArray<PhobosSendModel *> *sendModelArray = [PhobosSendModel mj_objectArrayWithKeyValuesArray:data];
return sendModelArray ?: [NSArray new];
}
+ (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];
+ (NSArray<SendDataEntity *> *)fetchDataEntitiesWithImmediately:(BOOL)immediately {
NSPredicate *predicate;
if (immediately) {
predicate = [NSPredicate predicateWithFormat:@"sendStatus = %d or sendStatus = %d", PhobosDataSendStatusToBeSend, PhobosDataSendStatusError];
} else {
predicate = [NSPredicate predicateWithFormat:@"sendStatus = %d", PhobosDataSendStatusNormal];
}
[self storeCache:datas];
return [self fetchDataEntitiesWithPredicate:predicate];
}
+ (void)deleteDataModel:(PhobosSendModel *)model {
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;
*stop = YES;
}
}];
[datas removeObjectAtIndex:updateIdx];
[self storeCache:datas];
+ (NSArray<SendDataEntity *> *)fetchDataEntitiesWithPredicate:(NSPredicate *)searchFilter {
return [SendDataEntity MR_findAllWithPredicate:searchFilter inContext:[NSManagedObjectContext MR_defaultContext]];
}
+ (void)removeAllDataWithImmediately:(BOOL)immediately {
NSArray<PhobosSendModel *> *datas = [self fetchCache];
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];
+ (NSUInteger)fetchCountOfEntitiesWithPredicate:(NSPredicate *)searchFilter {
return [SendDataEntity MR_numberOfEntitiesWithPredicate:searchFilter inContext:[NSManagedObjectContext MR_defaultContext]];
}
+ (NSArray<PhobosSendModel *> *)fetchDataModelsWithStatus:(PhobosModelSendStatus)status {
NSArray<PhobosSendModel *> *data = [self fetchCache];
NSMutableArray *temp = [NSMutableArray new];
[data enumerateObjectsUsingBlock:^(PhobosSendModel * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
if (obj.sendStatus == status) {
[temp addObject:obj];
}
}];
return temp;
+ (void)insertData:(NSDictionary *)data sendAPI:(NSString *)sendAPI immediately:(BOOL)immediately completion:(MRSaveCompletionHandler)completion {
if (!sendAPI || [sendAPI isEqualToString:@""] || !data) {
return;
}
SendDataEntity *entity = [SendDataEntity MR_createEntity];
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 {
NSMutableDictionary *sendDataMap = [NSMutableDictionary new];
NSArray<PhobosSendModel *> *needSendData = [self fetchCache];
[needSendData enumerateObjectsUsingBlock:^(PhobosSendModel * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
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];
+ (void)updateDataEntities:(NSArray<SendDataEntity *> *)entities sendStatus:(PhobosDataSendStatus)sendStatus completion:(MRSaveCompletionHandler)completion {
if (entities.count > 0) {
[entities enumerateObjectsUsingBlock:^(SendDataEntity *obj, NSUInteger idx, BOOL * _Nonnull stop) {
obj.status = sendStatus;
}];
if (temp.count > 0) {
[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];
}
});
}];
}];
}
}];
[[NSManagedObjectContext MR_defaultContext] MR_saveWithOptions:MRSaveSynchronously completion:completion];
}
}
+ (void)utilSendDataArray:(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);
}
}];
+ (void)deleteDataEntities:(NSArray<SendDataEntity *> *)entities {
if (entities.count > 0) {
[entities enumerateObjectsUsingBlock:^(SendDataEntity *obj, NSUInteger idx, BOOL * _Nonnull stop) {
[obj MR_deleteEntity];
}];
[[NSManagedObjectContext MR_defaultContext] MR_saveOnlySelfAndWait];
}
}
@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