Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
GMPhobos
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
gengmeiios
GMPhobos
Commits
2d57d66e
Commit
2d57d66e
authored
Apr 28, 2020
by
井庆林
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
优化
parent
19039216
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
153 additions
and
101 deletions
+153
-101
GMViewController.m
Example/GMPhobos/GMViewController.m
+13
-9
NewPhobos.m
GMPhobos/Classes/NewPhobos.m
+19
-13
Phobos.m
GMPhobos/Classes/Phobos.m
+2
-2
PhobosDataManager.h
GMPhobos/Classes/PhobosDataManager.h
+10
-13
PhobosDataManager.m
GMPhobos/Classes/PhobosDataManager.m
+109
-64
No files found.
Example/GMPhobos/GMViewController.m
View file @
2d57d66e
...
...
@@ -66,15 +66,19 @@ NSString *const MockCityId = @"beijing";
// [Phobos track:@"page_view" attributes:dict];
// array = [GMCache fetchObjectAtDocumentPathWithkey:PhobosCacheKey];
for
(
int
i
=
0
;
i
<
200
;
i
++
)
{
[
Phobos
track
:[
NSString
stringWithFormat
:
@"tt-%d"
,
i
]
attributes
:
dict
sendNow
:
YES
];
[
Phobos
track
:[
NSString
stringWithFormat
:
@"pv-%d"
,
i
]
attributes
:
dict
sendNow
:
(
arc4random
()
%
2
==
0
)];
}
for
(
int
i
=
5
;
i
<
5
;
i
++
)
{
dispatch_async
(
dispatch_get_global_queue
(
0
,
0
),
^
{
[
Phobos
track
:[
NSString
stringWithFormat
:
@"ay-%d"
,
i
]
attributes
:
dict
sendNow
:
YES
];
});
}
// for (int i = 0; i < 200; i++) {
// [Phobos track:[NSString stringWithFormat:@"phobos>>>tt-%d", i] attributes:dict sendNow:YES];
// [Phobos track:[NSString stringWithFormat:@"phobos>>>pv-%d", i] attributes:dict sendNow:(arc4random() % 2 == 0)];
// NSUInteger count = [Phobos fetchToBeSendPhobosDataCount];
// NSLog(@"%lu", (unsigned long)count);
// }
// for (int i = 0; i < 200; i++) {
// dispatch_async(dispatch_get_global_queue(0, 0), ^{
// NSUInteger count = [Phobos fetchToBeSendPhobosDataCount];
// NSLog(@"%lu", (unsigned long)count);
// [Phobos track:[NSString stringWithFormat:@"phobos>>>ay-%d", i] attributes:dict sendNow:YES];
// });
// }
}
-
(
void
)
touchesBegan
:
(
NSSet
<
UITouch
*>
*
)
touches
withEvent
:
(
UIEvent
*
)
event
{
...
...
GMPhobos/Classes/NewPhobos.m
View file @
2d57d66e
...
...
@@ -32,8 +32,6 @@ static NewPhobos *_sharedClient;
@implementation
NewPhobos
static
dispatch_semaphore_t
_phobos_semaphore
;
+
(
NewPhobos
*
)
clientWithAppName
:(
NSString
*
)
appName
channelId
:(
NSString
*
)
channelId
{
NewPhobos
.
sharedClient
.
appName
=
appName
;
NewPhobos
.
sharedClient
.
channelId
=
channelId
;
...
...
@@ -42,7 +40,6 @@ static dispatch_semaphore_t _phobos_semaphore;
-
(
instancetype
)
init
{
if
(
self
=
[
super
init
])
{
_phobos_semaphore
=
dispatch_semaphore_create
(
1
);
_appName
=
@""
;
_channelId
=
@""
;
_logEnabled
=
NO
;
...
...
@@ -218,7 +215,7 @@ static dispatch_semaphore_t _phobos_semaphore;
@"uuid"
:
[
PhobosUtil
deviceId
],
@"build_version_release"
:
[[
UIDevice
currentDevice
]
systemVersion
],
};
[
NewPhobos
track
:
@"on_app_session_over"
a
ttributes
:
dict
];
[
NewPhobos
track
SessionOverWithA
ttributes
:
dict
];
[
GMCache
removeObjectAtDocumentPathWithkey
:
PhobosBeginTime
];
//当前session结束之后,把id置为0
_serialId
=
0
;
...
...
@@ -328,7 +325,6 @@ static dispatch_semaphore_t _phobos_semaphore;
[
deviceParams
setValue
:[
PhobosUtil
getIPAddress
:
YES
]
forKey
:
@"ip"
];
[
deviceParams
setValue
:
PhobosSafeString
(
_networkStatus
)
forKey
:
@"net_type"
];
[
deviceParams
setValue
:
PhobosSafeString
([
PhobosUtil
platform
])
forKey
:
@"model"
];
[
deviceParams
setValue
:
@
(
_isGray
)
forKey
:
@"isGray"
];
[
deviceParams
setValue
:
PhobosSafeString
([
UIDevice
currentDevice
].
systemVersion
)
forKey
:
@"sys_version"
];
NSMutableDictionary
*
appParams
=
[
NSMutableDictionary
new
];
...
...
@@ -337,6 +333,7 @@ static dispatch_semaphore_t _phobos_semaphore;
[
appParams
setValue
:
PhobosSafeString
(
_appVersion
)
forKey
:
@"version"
];
[
appParams
setValue
:
PhobosSafeString
(
_channelId
)
forKey
:
@"channel"
];
[
appParams
setValue
:
PhobosSafeString
(
_userType
)
forKey
:
@"user_type"
];
[
appParams
setValue
:
@
(
_isGray
)
forKey
:
@"is_gray"
];
[
appParams
setValue
:
PhobosSafeString
(
_currentCityId
)
forKey
:
@"current_city_id"
];
[
appParams
setValue
:
@
(
_serialId
++
)
forKey
:
@"serial_id"
];
...
...
@@ -381,11 +378,11 @@ static dispatch_semaphore_t _phobos_semaphore;
}
+
(
void
)
onClickButtonWithAttributes
:
(
NSDictionary
*
)
attributes
{
[
self
track
:
@"on_cick_button"
attributes
:
attributes
];
[
self
track
:
@"on_c
l
ick_button"
attributes
:
attributes
];
}
+
(
void
)
onClickButtonWithAttributes
:
(
NSDictionary
*
)
attributes
sendNow
:
(
BOOL
)
sendNow
{
[
self
track
:
@"on_cick_button"
attributes
:
attributes
sendNow
:
sendNow
];
[
self
track
:
@"on_c
l
ick_button"
attributes
:
attributes
sendNow
:
sendNow
];
}
+
(
void
)
track
:
(
NSString
*
)
eventName
{
...
...
@@ -412,25 +409,34 @@ static dispatch_semaphore_t _phobos_semaphore;
NSDictionary
*
dataDict
=
[
_sharedClient
prepareDictionaryForEvent
:
eventName
attributes
:
attributes
];
@try
{
NSData
*
JSON
=
[
PhobosUtil
encodeJSON
:
dataDict
];
[
PhobosDataManager
insertData
:
dataDict
sendAPI
:
currentAPI
];
[
PhobosDataManager
insertData
:
dataDict
sendAPI
:
currentAPI
completion
:^
(
BOOL
contextDidSave
,
NSError
*
_Nullable
error
)
{
[
self
disposeSendDataWithImmediately
:
sendNow
];
}];
}
@catch
(
NSException
*
exception
)
{
NSAssert
(
NO
,
@"哎呀呀,VALUE不能为NSObject "
);
}
}
/**
* 为app_session_over提供埋点发送
* 其他情况在写入数据库成功,异步回调后在发送数据
* 这样可以优化发送次数,并能保障数据安全,但因为completion是使用主线程回调的,但进入后台后,主线程会休眠,所以单独处理该埋点
*/
+
(
void
)
trackSessionOverWithAttributes
:
(
NSDictionary
*
)
attributes
{
NSDictionary
*
dataDict
=
[
_sharedClient
prepareDictionaryForEvent
:
@"on_app_session_over"
attributes
:
attributes
];
[
PhobosDataManager
insertData
:
dataDict
sendAPI
:
_sharedClient
.
serverAPI
completion
:
nil
];
[
self
disposeSendDataWithImmediately
:
YES
];
}
/**
* 处理发送数据
*/
+
(
void
)
disposeSendDataWithImmediately
:
(
BOOL
)
immediately
{
NSInteger
count
=
[
PhobosDataManager
fetchCountOfToBeSendEntities
];
if
(
immediately
||
count
>=
PhobosShardCount
)
{
dispatch_semaphore_wait
(
_phobos_semaphore
,
DISPATCH_TIME_FOREVER
);
NSArray
<
PhobosSendDataEntity
*>
*
entities
=
[
PhobosDataManager
fetchToBeSendDataEntities
];
[
PhobosDataManager
updateDataEntities
:
entities
sendStatus
:
PhobosDataSendStatusSending
];
dispatch_semaphore_signal
(
_phobos_semaphore
);
NSArray
<
PhobosSendDataEntity
*>
*
entities
=
[
PhobosDataManager
fetchToBeSendDataEntitiesAndUpdateWithSendStatus
:
PhobosDataSendStatusSending
];
[
PhobosSendManager
sendDataWithEntities
:
entities
completion
:
^
(
NSArray
<
PhobosSendDataEntity
*>
*
_Nonnull
finishEntities
,
NSInteger
code
)
{
[
PhobosDataManager
updateDataEntities
:
finishEntities
sendStatus
:(
code
==
200
?
PhobosDataSendStatusFinish
:
PhobosDataSendStatusError
)];
[
PhobosDataManager
updateDataEntities
:
finishEntities
sendStatus
:(
code
==
200
?
PhobosDataSendStatusFinish
:
PhobosDataSendStatusError
)
completion
:
nil
];
}];
}
}
...
...
GMPhobos/Classes/Phobos.m
View file @
2d57d66e
...
...
@@ -65,7 +65,7 @@ static BOOL isGray = NO;
if
(
isGray
)
{
[
NewPhobos
onClickButtonWithAttributes
:
attributes
];
}
else
{
[
self
track
:
@"on_cick_button"
attributes
:
attributes
];
[
self
track
:
@"on_c
l
ick_button"
attributes
:
attributes
];
}
}
...
...
@@ -73,7 +73,7 @@ static BOOL isGray = NO;
if
(
isGray
)
{
[
NewPhobos
onClickButtonWithAttributes
:
attributes
sendNow
:
sendNow
];
}
else
{
[
self
track
:
@"on_cick_button"
attributes
:
attributes
sendNow
:
sendNow
];
[
self
track
:
@"on_c
l
ick_button"
attributes
:
attributes
sendNow
:
sendNow
];
}
}
...
...
GMPhobos/Classes/PhobosDataManager.h
View file @
2d57d66e
...
...
@@ -20,23 +20,22 @@ typedef NS_ENUM(NSInteger, PhobosDataSendStatus) {
@interface
PhobosDataManager
:
NSObject
/** 获取待发送数据,包含待发送数据和发送失败数据 */
+
(
NSArray
<
PhobosSendDataEntity
*>
*
)
fetchToBeSendDataEntities
;
/**
*
通过 searchFilter 获取数据
*
获取待发送和发送失败的数据数量
*/
+
(
NS
Array
<
PhobosSendDataEntity
*>
*
)
fetchDataEntitiesWithPredicate
:(
NSPredicate
*
)
searchFilter
;
+
(
NS
UInteger
)
fetchCountOfToBeSendEntities
;
/**
* 获取待发送和发送失败的数据数量
* 获取待发送数据,包含待发送数据和发送失败数据
* predicate 通过谓词获取相应的数据
*/
+
(
NSUInteger
)
fetchCountOfToBeSendEntities
;
+
(
NSArray
<
PhobosSendDataEntity
*>
*
)
fetchToBeSendDataEntities
;
+
(
NSArray
<
PhobosSendDataEntity
*>
*
)
fetchDataEntitiesWithPredicate
:(
NSPredicate
*
)
predicate
;
/**
*
通过 searchFilter 获取数据数量
*
获取待发送数据,包含待发送数据和发送失败数据, 并修改状态为sendStatus
*/
+
(
NS
UInteger
)
fetchCountOfEntitiesWithPredicate
:(
NSPredicate
*
)
searchFilter
;
+
(
NS
Array
<
PhobosSendDataEntity
*>
*
)
fetchToBeSendDataEntitiesAndUpdateWithSendStatus
:(
PhobosDataSendStatus
)
sendStatus
;
/**
* 插入埋点数据
...
...
@@ -45,7 +44,6 @@ typedef NS_ENUM(NSInteger, PhobosDataSendStatus) {
* completion 插入数据库成功后的回调方法,在保存完成后调用的完成块。如果发生错误,块将以“BOOL”和“NSError”实例的形式传递成功状态。总是在主队列上调用。
* 该方法调用完成,fetch方法获取相应的数据就可获取到,不需要等completion回调。
*/
+
(
void
)
insertData
:(
NSDictionary
*
)
data
sendAPI
:(
NSString
*
)
sendAPI
;
+
(
void
)
insertData
:(
NSDictionary
*
)
data
sendAPI
:(
NSString
*
)
sendAPI
completion
:(
MRSaveCompletionHandler
)
completion
;
/**
...
...
@@ -55,13 +53,12 @@ typedef NS_ENUM(NSInteger, PhobosDataSendStatus) {
* completion 插入数据库成功后的回调方法,在保存完成后调用的完成块。如果发生错误,块将以“BOOL”和“NSError”实例的形式传递成功状态。总是在主队列上调用。
* 该方法调用完成,fetch方法获取相应的数据就可获取到,不需要等completion回调。
*/
+
(
void
)
updateDataEntities
:(
NSArray
<
PhobosSendDataEntity
*>
*
)
entities
sendStatus
:(
PhobosDataSendStatus
)
sendStatus
;
+
(
void
)
updateDataEntities
:(
NSArray
<
PhobosSendDataEntity
*>
*
)
entities
sendStatus
:(
PhobosDataSendStatus
)
sendStatus
completion
:(
MRSaveCompletionHandler
)
completion
;
/**
* 删除数据
* 删除所有数据
* 仅限单元测试使用
*/
+
(
void
)
deleteDataEntities
:(
NSArray
<
PhobosSendDataEntity
*>
*
)
entities
;
+
(
void
)
deleteAllEntities
;
@end
...
...
GMPhobos/Classes/PhobosDataManager.m
View file @
2d57d66e
...
...
@@ -15,13 +15,79 @@
@implementation
PhobosDataManager
static
NSManagedObjectContext
*
PhobosDefaultContext
;
static
dispatch_semaphore_t
phobos_semaphore_t
;
static
NSUInteger
PhobosToBeSendEntitiesCount
=
0
;
+
(
void
)
initialize
{
static
dispatch_once_t
onceToken
;
dispatch_once
(
&
onceToken
,
^
{
phobos_semaphore_t
=
dispatch_semaphore_create
(
1
);
[
self
setupSDK
];
[
self
resetData
];
});
}
+
(
NSUInteger
)
fetchCountOfToBeSendEntities
{
return
PhobosToBeSendEntitiesCount
;
}
+
(
NSArray
<
PhobosSendDataEntity
*>
*
)
fetchToBeSendDataEntities
{
NSPredicate
*
predicate
=
[
NSPredicate
predicateWithFormat
:
@"status = %d or status = %d"
,
PhobosDataSendStatusToBeSend
,
PhobosDataSendStatusError
];
return
[
self
fetchDataEntitiesWithPredicate
:
predicate
];
}
+
(
NSArray
<
PhobosSendDataEntity
*>
*
)
fetchDataEntitiesWithPredicate
:
(
NSPredicate
*
)
predicate
{
__block
NSArray
*
results
=
nil
;
[[
self
PhobosContext
]
performBlockAndWait
:
^
{
results
=
[
self
noWaitFetchDataEntitiesWithPredicate
:
predicate
];
}];
return
results
;
}
+
(
NSArray
<
PhobosSendDataEntity
*>
*
)
fetchToBeSendDataEntitiesAndUpdateWithSendStatus
:
(
PhobosDataSendStatus
)
sendStatus
{
__block
NSArray
*
results
=
nil
;
[[
self
PhobosContext
]
performBlockAndWait
:
^
{
NSPredicate
*
predicate
=
[
NSPredicate
predicateWithFormat
:
@"status = %d or status = %d"
,
PhobosDataSendStatusToBeSend
,
PhobosDataSendStatusError
];
results
=
[
self
noWaitFetchDataEntitiesWithPredicate
:
predicate
];
[
self
noWaitUpdateEntities
:
results
sendStatus
:
sendStatus
completion
:
nil
];
}];
return
results
;
}
+
(
void
)
insertData
:
(
NSDictionary
*
)
data
sendAPI
:
(
NSString
*
)
sendAPI
completion
:
(
MRSaveCompletionHandler
)
completion
{
if
(
!
sendAPI
||
[
sendAPI
isEqualToString
:
@""
]
||
!
data
)
{
return
;
}
[[
self
PhobosContext
]
performBlockAndWait
:
^
{
PhobosSendDataEntity
*
entity
=
[
PhobosSendDataEntity
MR_createEntityInContext
:[
self
PhobosContext
]];
entity
.
data
=
[
data
mj_JSONData
];
entity
.
api
=
sendAPI
;
entity
.
status
=
PhobosDataSendStatusToBeSend
;
entity
.
id
=
mach_absolute_time
();
PhobosToBeSendEntitiesCount
++
;
[
self
saveWithCompletion
:
completion
];
}];
}
+
(
void
)
updateDataEntities
:
(
NSArray
<
PhobosSendDataEntity
*>
*
)
entities
sendStatus
:
(
PhobosDataSendStatus
)
sendStatus
completion
:
(
MRSaveCompletionHandler
)
completion
{
if
(
entities
.
count
>
0
)
{
[[
self
PhobosContext
]
performBlockAndWait
:
^
{
[
self
noWaitUpdateEntities
:
entities
sendStatus
:
sendStatus
completion
:
completion
];
}];
}
}
+
(
void
)
deleteAllEntities
{
[[
self
PhobosContext
]
performBlockAndWait
:
^
{
PhobosToBeSendEntitiesCount
=
0
;
[
PhobosSendDataEntity
MR_truncateAllInContext
:[
self
PhobosContext
]];
[
self
saveWithCompletion
:
nil
];
}];
}
#pragma mark - private
/**
* 初始化sdk
*/
+
(
void
)
setupSDK
{
// 创建 NSManagedObjectContext,供埋点库访问CoreData库使用
PhobosDefaultContext
=
[[
NSManagedObjectContext
alloc
]
initWithConcurrencyType
:
NSPrivateQueueConcurrencyType
];
NSBundle
*
bundle
=
[
NSBundle
bundleForClass
:[
self
class
]];
...
...
@@ -39,94 +105,73 @@ static dispatch_semaphore_t phobos_semaphore_t;
[
coordinator
addPersistentStoreWithType
:
NSSQLiteStoreType
configuration
:
nil
URL
:
[
NSURL
fileURLWithPath
:
dataPath
]
options
:
nil
error
:
nil
];
// 设置storeCoordinator
PhobosDefaultContext
.
persistentStoreCoordinator
=
coordinator
;
[
self
PhobosContext
].
persistentStoreCoordinator
=
coordinator
;
}
/*
* 重置数据库中的数据和待发送数量
*/
+
(
void
)
resetData
{
[[
self
PhobosContext
]
performBlockAndWait
:
^
{
/** 将上次没有获取到发送结果的数据的状态修改为发送失败,待下次重新发送 */
NSPredicate
*
predicate
=
[
NSPredicate
predicateWithFormat
:
@"status = %d"
,
PhobosDataSendStatusSending
];
NSArray
<
PhobosSendDataEntity
*>
*
entities
=
[
self
f
etchDataEntitiesWithPredicate
:
predicate
];
[
self
updateDataEntities
:
entities
sendStatus
:
PhobosDataSendStatusError
];
NSArray
<
PhobosSendDataEntity
*>
*
entities
=
[
self
noWaitF
etchDataEntitiesWithPredicate
:
predicate
];
[
self
noWaitUpdateEntities
:
entities
sendStatus
:
PhobosDataSendStatusError
completion
:
nil
];
/** 将发送成功的数据删除 */
NSPredicate
*
finishPredicate
=
[
NSPredicate
predicateWithFormat
:
@"status = %d"
,
PhobosDataSendStatusFinish
];
NSArray
<
PhobosSendDataEntity
*>
*
finishEntities
=
[
self
fetchDataEntitiesWithPredicate
:
finishPredicate
];
[
self
deleteDataEntities
:
finishEntities
];
});
}
+
(
NSArray
<
PhobosSendDataEntity
*>
*
)
fetchToBeSendDataEntities
{
NSPredicate
*
predicate
=
[
NSPredicate
predicateWithFormat
:
@"status = %d or status = %d"
,
PhobosDataSendStatusToBeSend
,
PhobosDataSendStatusError
];
return
[
self
fetchDataEntitiesWithPredicate
:
predicate
];
}
+
(
NSArray
<
PhobosSendDataEntity
*>
*
)
fetchDataEntitiesWithPredicate
:
(
NSPredicate
*
)
searchFilter
{
return
[
PhobosSendDataEntity
MR_findAllWithPredicate
:
searchFilter
inContext
:
PhobosDefaultContext
];
}
+
(
NSUInteger
)
fetchCountOfToBeSendEntities
{
NSPredicate
*
predicate
=
[
NSPredicate
predicateWithFormat
:
@"status = %d or status = %d"
,
PhobosDataSendStatusToBeSend
,
PhobosDataSendStatusError
];
return
[
self
fetchCountOfEntitiesWithPredicate
:
predicate
];
}
+
(
NSUInteger
)
fetchCountOfEntitiesWithPredicate
:
(
NSPredicate
*
)
searchFilter
{
return
[[
PhobosSendDataEntity
MR_numberOfEntitiesWithPredicate
:
searchFilter
inContext
:
PhobosDefaultContext
]
integerValue
];
}
[
PhobosSendDataEntity
MR_deleteAllMatchingPredicate
:
finishPredicate
inContext
:[
self
PhobosContext
]];
[
self
saveWithCompletion
:
nil
];
+
(
void
)
insertData
:
(
NSDictionary
*
)
data
sendAPI
:
(
NSString
*
)
sendAPI
{
[
self
insertData
:
data
sendAPI
:
sendAPI
completion
:
nil
];
/** 设置未发送数据数量 */
NSPredicate
*
countPredicate
=
[
NSPredicate
predicateWithFormat
:
@"status = %d or status = %d"
,
PhobosDataSendStatusToBeSend
,
PhobosDataSendStatusError
];
PhobosToBeSendEntitiesCount
=
[[
PhobosSendDataEntity
MR_numberOfEntitiesWithPredicate
:
countPredicate
inContext
:[
self
PhobosContext
]]
integerValue
];
}];
}
+
(
void
)
insertData
:
(
NSDictionary
*
)
data
sendAPI
:
(
NSString
*
)
sendAPI
completion
:
(
MRSaveCompletionHandler
)
completion
{
if
(
!
sendAPI
||
[
sendAPI
isEqualToString
:
@""
]
||
!
data
)
{
return
;
/**
* 在批量修改和删除时维护PhobosToBeSendEntitiesCount字段
*/
+
(
void
)
updatePhobosCountOfToBeSendEntitiesWithStatus
:
(
PhobosDataSendStatus
)
sendStatus
changeCount
:
(
NSUInteger
)
changeCount
{
if
(
sendStatus
==
PhobosDataSendStatusSending
)
{
PhobosToBeSendEntitiesCount
-=
changeCount
;
}
else
if
(
sendStatus
==
PhobosDataSendStatusError
)
{
PhobosToBeSendEntitiesCount
+=
changeCount
;
}
dispatch_semaphore_wait
(
phobos_semaphore_t
,
DISPATCH_TIME_FOREVER
);
PhobosSendDataEntity
*
entity
=
[
PhobosSendDataEntity
MR_createEntityInContext
:
PhobosDefaultContext
];
entity
.
data
=
[
data
mj_JSONData
];
entity
.
api
=
sendAPI
;
entity
.
status
=
PhobosDataSendStatusToBeSend
;
entity
.
id
=
mach_absolute_time
();
dispatch_semaphore_signal
(
phobos_semaphore_t
);
[
self
saveWithCompletion
:
completion
];
}
+
(
void
)
updateDataEntities
:
(
NSArray
<
PhobosSendDataEntity
*>
*
)
entities
sendStatus
:
(
PhobosDataSendStatus
)
sendStatus
{
[
self
updateDataEntities
:
entities
sendStatus
:
sendStatus
completion
:
nil
];
/**
* 不使用同步线程安全方案[NSManagedObjectContext performBlockAndWait]获取谓词相应的数据
* 不对外使用,使用该方法时,需要保障线程同步
*/
+
(
NSArray
<
PhobosSendDataEntity
*>
*
)
noWaitFetchDataEntitiesWithPredicate
:
(
NSPredicate
*
)
predicate
{
NSFetchRequest
*
request
=
[
PhobosSendDataEntity
MR_createFetchRequestInContext
:[
self
PhobosContext
]];
[
request
setPredicate
:
predicate
];
NSError
*
error
=
nil
;
return
[[
self
PhobosContext
]
executeFetchRequest
:
request
error
:
&
error
];
}
+
(
void
)
updateDataEntities
:
(
NSArray
<
PhobosSendDataEntity
*>
*
)
entities
sendStatus
:
(
PhobosDataSendStatus
)
sendStatus
completion
:
(
MRSaveCompletionHandler
)
completion
{
if
(
entities
.
count
>
0
)
{
dispatch_semaphore_wait
(
phobos_semaphore_t
,
DISPATCH_TIME_FOREVER
);
/**
* 不使用同步线程安全方案[NSManagedObjectContext performBlockAndWait]去修改实体数据sendStatus
* 不对外使用,使用该方法时,需要保障线程同步
*/
+
(
void
)
noWaitUpdateEntities
:
(
NSArray
<
PhobosSendDataEntity
*>
*
)
entities
sendStatus
:
(
PhobosDataSendStatus
)
sendStatus
completion
:
(
MRSaveCompletionHandler
)
completion
{
[
self
updatePhobosCountOfToBeSendEntitiesWithStatus
:
sendStatus
changeCount
:
entities
.
count
];
[
entities
enumerateObjectsUsingBlock
:
^
(
PhobosSendDataEntity
*
obj
,
NSUInteger
idx
,
BOOL
*
_Nonnull
stop
)
{
obj
.
status
=
sendStatus
;
}];
dispatch_semaphore_signal
(
phobos_semaphore_t
);
[
self
saveWithCompletion
:
completion
];
}
}
+
(
void
)
deleteDataEntities
:
(
NSArray
<
PhobosSendDataEntity
*>
*
)
entities
{
if
(
entities
.
count
>
0
)
{
dispatch_semaphore_wait
(
phobos_semaphore_t
,
DISPATCH_TIME_FOREVER
);
[
entities
enumerateObjectsUsingBlock
:
^
(
PhobosSendDataEntity
*
obj
,
NSUInteger
idx
,
BOOL
*
_Nonnull
stop
)
{
[
obj
MR_deleteEntityInContext
:
PhobosDefaultContext
];
}];
dispatch_semaphore_signal
(
phobos_semaphore_t
);
[
self
saveWithCompletion
:
nil
];
}
}
+
(
void
)
deleteAllEntities
{
dispatch_semaphore_wait
(
phobos_semaphore_t
,
DISPATCH_TIME_FOREVER
);
[
PhobosSendDataEntity
MR_truncateAllInContext
:
PhobosDefaultContext
];
dispatch_semaphore_signal
(
phobos_semaphore_t
);
[
self
saveWithCompletion
:
nil
];
+
(
NSManagedObjectContext
*
)
PhobosContext
{
return
PhobosDefaultContext
?:
[
NSManagedObjectContext
MR_defaultContext
];
}
/**
* 在保存完成后调用的完成块。如果发生错误,块将以“BOOL”和“NSError”实例的形式传递成功状态。总是在主队列上调用。
*/
+
(
void
)
saveWithCompletion
:
(
MRSaveCompletionHandler
)
completion
{
[
PhobosDefaultContext
MR_saveOnlySelfWithCompletion
:
completion
];
[
[
self
PhobosContext
]
MR_saveOnlySelfWithCompletion
:
completion
];
}
@end
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment