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
e58799c9
Commit
e58799c9
authored
Aug 01, 2019
by
乔金柱
1
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'jql/newPhobos' into 'master'
埋点库重构 See merge request
!39
parents
2e1dbac1
2814756f
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
414 additions
and
388 deletions
+414
-388
GMViewController.m
Example/GMPhobos/GMViewController.m
+1
-1
GMPhobosUtilTest.m
Example/Tests/GMPhobosUtilTest.m
+4
-3
GMPhotoTest.m
Example/Tests/GMPhotoTest.m
+45
-68
Phobos.h
GMPhobos/Classes/Phobos.h
+49
-11
Phobos.m
GMPhobos/Classes/Phobos.m
+310
-297
PhobosConfig.h
GMPhobos/Classes/PhobosConfig.h
+2
-2
PhobosUtil.h
GMPhobos/Classes/PhobosUtil.h
+1
-1
PhobosUtil.m
GMPhobos/Classes/PhobosUtil.m
+2
-5
No files found.
Example/GMPhobos/GMViewController.m
View file @
e58799c9
...
...
@@ -41,7 +41,7 @@ NSString *const MockCityId = @"beijing";
[
phobos
setLogEnabled
:
NO
];
// 调试打Log模式,看情况开启
phobos
.
signingType
=
PhobosSigningTypeDebug
;
phobos
.
userId
=
@""
;
[
Phobos
setSharedClient
:
phobos
];
//
[Phobos setSharedClient:phobos];
NSString
*
inDate
=
[
PhobosUtil
currentTime
];
NSMutableDictionary
*
dict
=
[[
NSMutableDictionary
alloc
]
init
];
...
...
Example/Tests/GMPhobosUtilTest.m
View file @
e58799c9
...
...
@@ -19,7 +19,8 @@
-
(
void
)
setUp
{
[
super
setUp
];
NSString
*
url
=
@"http://log.test.gengmei.cc/log/collect"
;
[
Phobos
setSharedClient
:[
Phobos
clientWithAppName
:
@"gengmei_test"
channelId
:
@"AppStore"
]];
[
Phobos
clientWithAppName
:
@"gengmei_test"
channelId
:
@"AppStore"
];
// [Phobos setSharedClient:[Phobos clientWithAppName:@"gengmei_test" channelId:@"AppStore"]];
[
Phobos
sharedClient
].
serverAPI
=
url
;
_mockArray
=
[[
NSMutableArray
alloc
]
init
];
for
(
int
i
=
0
;
i
<
50
;
i
++
)
{
...
...
@@ -63,9 +64,9 @@
XCTestExpectation
*
expectation
=
[
self
expectationWithDescription
:
@"Testing Async Method Works!"
];
NSData
*
mockData
=
[
self
encodeAndCompressArray
:
_mockArray
];
[
PhobosUtil
sendData
:
mockData
success
:
^
(
NSInteger
code
)
{
[
PhobosUtil
sendData
:
mockData
success
:
^
(
BOOL
success
)
{
[
expectation
fulfill
];
XCTAssertEqual
(
code
,
200
);
XCTAssertEqual
(
success
,
YES
);
}];
//如果超时,则认为发送失败
...
...
Example/Tests/GMPhotoTest.m
View file @
e58799c9
...
...
@@ -9,8 +9,6 @@
#import <XCTest/XCTest.h>
#import <GMPhobos/Phobos.h>
#import "GMPhobosController.h"
#define PhobosCacheKey @"PhobosCacheKey"
@import
GMCache
;
NSString
*
const
MockAppName
=
@"gengmei_test"
;
NSString
*
const
MockChannelId
=
@"AppStore"
;
...
...
@@ -31,14 +29,14 @@ NSString *const MockCityId = @"beijing";
[
_client
setLogEnabled
:
NO
];
// 调试打Log模式,看情况开启
_client
.
signingType
=
PhobosSigningTypeDebug
;
_client
.
userId
=
@""
;
[
Phobos
setSharedClient
:
_client
];
//
[Phobos setSharedClient:_client];
}
-
(
void
)
tearDown
{
// Put teardown code here. This method is called after the invocation of each test method in the class.
[
super
tearDown
];
[
GMCache
removeObjectAtDocumentPathWithkey
:
PhobosCacheKey
];
[
GMCache
removeObjectAtDocumentPathWithkey
:
PhobosTempCacheKey
];
[
Phobos
removeAllNormalPhobosData
];
[
Phobos
removeAllImmediatelyPhobosData
];
}
/**
...
...
@@ -50,7 +48,7 @@ NSString *const MockCityId = @"beijing";
[
_client
setUserId
:
MockUserId
];
[
_client
setCurrentCityId
:
MockCityId
];
[
Phobos
track
:
MockEventId
];
NSArray
*
array
=
[
GMCache
fetchObjectAtDocumentPathWithkey
:
PhobosCacheKey
];
NSArray
*
array
=
[
Phobos
normalPhobosDataForURL
:
_client
.
serverAPI
];
//[
GMCache fetchObjectAtDocumentPathWithkey:PhobosCacheKey];
XCTAssertTrue
(
array
.
count
==
1
,
@"array is empty"
);
NSDictionary
*
dict
=
[
array
objectAtIndex
:
0
];
[
self
verfiyDict
:
dict
];
...
...
@@ -64,7 +62,7 @@ NSString *const MockCityId = @"beijing";
*/
-
(
void
)
testTrackEventWithoutAttr
{
[
Phobos
track
:
MockEventId
];
NSArray
*
array
=
[
GMCache
fetchObjectAtDocumentPathWithkey
:
PhobosCacheKey
];
NSArray
*
array
=
[
Phobos
normalPhobosDataForURL
:
_client
.
serverAPI
];
XCTAssertTrue
(
array
.
count
==
1
,
@"array is empty"
);
NSDictionary
*
dict
=
[
array
objectAtIndex
:
0
];
[
self
verfiyDict
:
dict
];
...
...
@@ -79,7 +77,7 @@ NSString *const MockCityId = @"beijing";
-
(
void
)
testTrackEventWithAttr
{
NSDictionary
*
attr
=
@{
@"attr"
:
@"track_attr"
};
[
Phobos
track
:
MockEventId
attributes
:
attr
];
NSArray
*
array
=
[
GMCache
fetchObjectAtDocumentPathWithkey
:
PhobosCacheKey
];
NSArray
*
array
=
[
Phobos
normalPhobosDataForURL
:
_client
.
serverAPI
];
XCTAssertTrue
(
array
.
count
==
1
,
@"array is empty"
);
NSDictionary
*
dict
=
[
array
objectAtIndex
:
0
];
[
self
verfiyDict
:
dict
];
...
...
@@ -100,8 +98,7 @@ NSString *const MockCityId = @"beijing";
// When
[
Phobos
track
:
MockEventId
attributes
:
attr
sendNow
:
YES
];
// Then
NSArray
*
array
=
[
GMCache
fetchObjectAtDocumentPathWithkey
:
PhobosCacheKey
];
XCTAssertTrue
(
array
.
count
==
0
,
@"array should be empty"
);
XCTAssertTrue
([
Phobos
normalPhobosCountForURL
:
_client
.
serverAPI
]
==
0
,
@"phobos datas should be empty"
);
}
/**
...
...
@@ -118,8 +115,7 @@ NSString *const MockCityId = @"beijing";
// When
[
Phobos
track
:
MockEventId
attributes
:
sendNowAttr
sendNow
:
YES
];
NSArray
*
array
=
[
GMCache
fetchObjectAtDocumentPathWithkey
:
PhobosCacheKey
];
XCTAssertTrue
(
array
.
count
!=
0
,
@"array shouldn't be empty"
);
XCTAssertTrue
([
Phobos
normalPhobosCountForURL
:
_client
.
serverAPI
]
!=
0
,
@"phobos datas shouldn't be empty"
);
}
/**
...
...
@@ -133,16 +129,13 @@ NSString *const MockCityId = @"beijing";
// 因为实时埋点是异步删除,所以这个位置暂时延时取数据,待优化 TODO
dispatch_after
(
dispatch_time
(
DISPATCH_TIME_NOW
,
(
int64_t
)(
0
.
25
*
NSEC_PER_SEC
)),
dispatch_get_main_queue
(),
^
{
NSArray
*
array
=
[
GMCache
fetchObjectAtDocumentPathWithkey
:
PhobosTempCacheKey
];
XCTAssertTrue
(
array
.
count
==
0
,
@"array shouldn't be empty"
);
XCTAssertTrue
([
Phobos
immediatelyPhobosCountForURL
:
_client
.
serverAPI
]
==
0
,
@"phobos datas should be empty"
);
[
Phobos
track
:
MockEventId
attributes
:
attr
sendNow
:
YES
];
dispatch_after
(
dispatch_time
(
DISPATCH_TIME_NOW
,
(
int64_t
)(
0
.
25
*
NSEC_PER_SEC
)),
dispatch_get_main_queue
(),
^
{
NSArray
*
array
=
[
GMCache
fetchObjectAtDocumentPathWithkey
:
PhobosTempCacheKey
];
XCTAssertTrue
(
array
.
count
==
0
,
@"array shouldn't be empty"
);
XCTAssertTrue
([
Phobos
immediatelyPhobosCountForURL
:
_client
.
serverAPI
]
==
0
,
@"phobos datas should be empty"
);
[
Phobos
track
:
MockEventId
attributes
:
attr
sendNow
:
YES
];
array
=
[
GMCache
fetchObjectAtDocumentPathWithkey
:
PhobosCacheKey
];
XCTAssertTrue
(
array
.
count
==
0
,
@"array shouldn't be empty"
);
XCTAssertTrue
([
Phobos
normalPhobosCountForURL
:
_client
.
serverAPI
]
==
0
,
@"phobos datas should be empty"
);
});
});
}
...
...
@@ -153,23 +146,23 @@ NSString *const MockCityId = @"beijing";
* @since 1.1.4
*/
-
(
void
)
testTrackEventWithDoubleAttrAndNoSendNow
{
[
Phobos
removeAllNormalPhobosData
];
[
Phobos
removeAllImmediatelyPhobosData
];
NSDictionary
*
attr
=
@{
@"attr"
:
@"track_attr"
};
//
[
Phobos
track
:
MockEventId
attributes
:
attr
];
NSArray
*
array
=
[
GMCache
fetchObjectAtDocumentPathWithkey
:
PhobosCacheKey
];
XCTAssertTrue
(
array
.
count
==
1
,
@"array shouldn't be empty"
);
XCTAssertTrue
([
Phobos
normalPhobosCountForURL
:
_client
.
serverAPI
]
==
1
,
@"There should be one data in the phobos datas"
);
// PhobosCacheKey超过50条数据会自动上报,模拟此情况
for
(
int
i
=
0
;
i
<
50
;
i
++
)
{
[
Phobos
track
:
MockEventId
attributes
:
attr
];
}
array
=
[
GMCache
fetchObjectAtDocumentPathWithkey
:
PhobosCacheKey
]
;
XCTAssertTrue
(
array
.
count
==
0
,
@"array shouldn't be empty"
);
XCTAssertTrue
([
Phobos
normalPhobosCountForURL
:
_client
.
serverAPI
]
==
1
,
@"There should be one data in the phobos datas"
)
;
[
Phobos
track
:
MockEventId
attributes
:
attr
];
array
=
[
GMCache
fetchObjectAtDocumentPathWithkey
:
PhobosCacheKey
];
XCTAssertTrue
(
array
.
count
==
1
,
@"array shouldn't be empty"
);
XCTAssertTrue
([
Phobos
normalPhobosCountForURL
:
_client
.
serverAPI
]
==
2
,
@"There should be two data in the phobos datas"
);
}
/**
...
...
@@ -184,29 +177,23 @@ NSString *const MockCityId = @"beijing";
for
(
int
i
=
0
;
i
<
30
;
i
++
)
{
[
Phobos
track
:
MockEventId
attributes
:
attr
];
}
NSArray
*
array
=
[
GMCache
fetchObjectAtDocumentPathWithkey
:
PhobosCacheKey
];
XCTAssertTrue
(
array
.
count
==
30
,
@"array shouldn't be empty"
);
XCTAssertTrue
([
Phobos
normalPhobosCountForURL
:
_client
.
serverAPI
]
==
30
,
@"There should be 30 data in the phobos datas"
);
// PhobosCacheKey超过50条数据会自动上报,模拟此情况
[
Phobos
track
:
MockEventId
attributes
:
sendNowAttr
sendNow
:
YES
];
array
=
[
GMCache
fetchObjectAtDocumentPathWithkey
:
PhobosCacheKey
];
XCTAssertTrue
(
array
.
count
==
30
,
@"array shouldn't be empty"
);
XCTAssertTrue
([
Phobos
normalPhobosCountForURL
:
_client
.
serverAPI
]
==
30
,
@"There should be 30 data in the phobos datas"
);
[
Phobos
track
:
MockEventId
attributes
:
sendNowAttr
sendNow
:
YES
];
array
=
[
GMCache
fetchObjectAtDocumentPathWithkey
:
PhobosCacheKey
];
XCTAssertTrue
(
array
.
count
==
30
,
@"array shouldn't be empty"
);
XCTAssertTrue
([
Phobos
normalPhobosCountForURL
:
_client
.
serverAPI
]
==
30
,
@"There should be 30 data in the phobos datas"
);
[
Phobos
track
:
MockEventId
attributes
:
sendNowAttr
sendNow
:
YES
];
array
=
[
GMCache
fetchObjectAtDocumentPathWithkey
:
PhobosCacheKey
];
XCTAssertTrue
(
array
.
count
==
30
,
@"array shouldn't be empty"
);
XCTAssertTrue
([
Phobos
normalPhobosCountForURL
:
_client
.
serverAPI
]
==
30
,
@"There should be 30 data in the phobos datas"
);
[
Phobos
track
:
MockEventId
attributes
:
attr
];
array
=
[
GMCache
fetchObjectAtDocumentPathWithkey
:
PhobosCacheKey
];
XCTAssertTrue
(
array
.
count
==
31
,
@"array shouldn't be empty"
);
XCTAssertTrue
([
Phobos
normalPhobosCountForURL
:
_client
.
serverAPI
]
==
31
,
@"There should be 31 data in the phobos datas"
);
}
/**
...
...
@@ -219,29 +206,23 @@ NSString *const MockCityId = @"beijing";
NSDictionary
*
sendNowAttr
=
@{
@"attr"
:
@"track_attr_send_now"
};
[
Phobos
track
:
MockEventId
attributes
:
sendNowAttr
sendNow
:
YES
];
NSArray
*
array
=
[
GMCache
fetchObjectAtDocumentPathWithkey
:
PhobosCacheKey
];
XCTAssertTrue
(
array
.
count
==
0
,
@"array shouldn't be empty"
);
XCTAssertTrue
([
Phobos
normalPhobosCountForURL
:
_client
.
serverAPI
]
==
0
,
@"phobos datas should be empty"
);
[
Phobos
track
:
MockEventId
attributes
:
attr
];
array
=
[
GMCache
fetchObjectAtDocumentPathWithkey
:
PhobosCacheKey
];
XCTAssertTrue
(
array
.
count
==
1
,
@"array shouldn't be empty"
);
XCTAssertTrue
([
Phobos
normalPhobosCountForURL
:
_client
.
serverAPI
]
==
1
,
@"There should be one data in the phobos datas"
);
[
Phobos
track
:
MockEventId
attributes
:
attr
];
[
Phobos
track
:
MockEventId
attributes
:
sendNowAttr
sendNow
:
YES
];
array
=
[
GMCache
fetchObjectAtDocumentPathWithkey
:
PhobosCacheKey
];
XCTAssertTrue
(
array
.
count
==
2
,
@"array shouldn't be empty"
);
XCTAssertTrue
([
Phobos
normalPhobosCountForURL
:
_client
.
serverAPI
]
==
2
,
@"There should be two data in the phobos datas"
);
[
Phobos
track
:
MockEventId
attributes
:
sendNowAttr
sendNow
:
YES
];
array
=
[
GMCache
fetchObjectAtDocumentPathWithkey
:
PhobosCacheKey
];
XCTAssertTrue
(
array
.
count
==
2
,
@"array shouldn't be empty"
);
XCTAssertTrue
([
Phobos
normalPhobosCountForURL
:
_client
.
serverAPI
]
==
2
,
@"There should be two data in the phobos datas"
);
[
Phobos
track
:
MockEventId
attributes
:
attr
];
array
=
[
GMCache
fetchObjectAtDocumentPathWithkey
:
PhobosCacheKey
];
XCTAssertTrue
(
array
.
count
==
3
,
@"array shouldn't be empty"
);
XCTAssertTrue
([
Phobos
normalPhobosCountForURL
:
_client
.
serverAPI
]
==
3
,
@"There should be three data in the phobos datas"
);
}
/**
...
...
@@ -250,23 +231,22 @@ NSString *const MockCityId = @"beijing";
* @since 1.1.4
*/
-
(
void
)
testTrackEventWithSendNowAndNoSendNowThree
{
[
Phobos
removeAllNormalPhobosData
];
[
Phobos
removeAllImmediatelyPhobosData
];
NSDictionary
*
attr
=
@{
@"attr"
:
@"track_attr"
};
//
[
Phobos
track
:
MockEventId
attributes
:
attr
];
NSArray
*
array
=
[
GMCache
fetchObjectAtDocumentPathWithkey
:
PhobosCacheKey
];
XCTAssertTrue
(
array
.
count
==
1
,
@"array shouldn't be empty"
);
XCTAssertTrue
([
Phobos
normalPhobosCountForURL
:
_client
.
serverAPI
]
==
1
,
@"There should be one data in the phobos datas"
);
// PhobosCacheKey超过50条数据会自动上报,模拟此情况
for
(
int
i
=
0
;
i
<
50
;
i
++
)
{
[
Phobos
track
:
MockEventId
attributes
:
attr
];
NSLog
(
@"%s------%d--%d"
,
__func__
,
[
Phobos
normalPhobosCountForURL
:
_client
.
serverAPI
],
[
Phobos
normalPhobosCount
]);
}
array
=
[
GMCache
fetchObjectAtDocumentPathWithkey
:
PhobosCacheKey
];
XCTAssertTrue
(
array
.
count
==
0
,
@"array shouldn't be empty"
);
[
Phobos
track
:
MockEventId
attributes
:
attr
];
XCTAssertTrue
([
Phobos
normalPhobosCountForURL
:
_client
.
serverAPI
]
==
1
,
@"There should be one data in the phobos datas"
);
array
=
[
GMCache
fetchObjectAtDocumentPathWithkey
:
PhobosCacheKey
];
XCTAssertTrue
(
array
.
count
==
1
,
@"array shouldn't be empty
"
);
[
Phobos
track
:
MockEventId
attributes
:
attr
];
XCTAssertTrue
(
[
Phobos
normalPhobosCountForURL
:
_client
.
serverAPI
]
==
2
,
@"There should be two data in the phobos datas
"
);
}
-
(
void
)
verfiyDict
:
(
NSDictionary
*
)
dict
{
...
...
@@ -309,7 +289,7 @@ NSString *const MockCityId = @"beijing";
[
controller
viewWillAppear
:
true
];
[
controller
viewWillDisappear
:
true
];
[
self
paramUnNilCheck
];
NSArray
*
array
=
[
GMCache
fetchObjectAtDocumentPathWithkey
:
PhobosCacheKey
];
NSArray
*
array
=
[
Phobos
normalPhobosDataForURL
:
_client
.
serverAPI
];
XCTAssertTrue
(
array
.
count
!=
0
,
@"PhobosCacheKey 下面应该有数据"
);
NSDictionary
*
dic
=
array
[
0
][
@"params"
];
...
...
@@ -323,7 +303,7 @@ NSString *const MockCityId = @"beijing";
}
-
(
void
)
paramUnNilCheck
{
NSArray
*
array
=
[
GMCache
fetchObjectAtDocumentPathWithkey
:
PhobosCacheKey
];
NSArray
*
array
=
[
Phobos
normalPhobosDataForURL
:
_client
.
serverAPI
];
XCTAssertTrue
(
array
.
count
!=
0
,
@"PhobosCacheKey 下面应该有数据"
);
NSDictionary
*
dic
=
array
[
0
][
@"params"
];
...
...
@@ -341,8 +321,10 @@ NSString *const MockCityId = @"beijing";
XCTAssertFalse
(
controller
.
needLogPV
,
@"needLogPV赋值为NO时应该NO"
);
}
/** 校验PV事件,相差时间较短不应该发送,暂时废弃,现在还是正常插入 *//*
- (void)testCheckPVPhobos {
[
GMCache
removeObjectAtDocumentPathWithkey
:
PhobosCacheKey
];
NSString *inDate = [PhobosUtil currentTime];
[NSThread sleepForTimeInterval:1];//模拟浏览页面,让out和in时间相差1s
...
...
@@ -358,12 +340,10 @@ NSString *const MockCityId = @"beijing";
[dict setObject:@"" forKey:@"referrer_tab_name"];
[dict setObject:@(0) forKey:@"is_push"];
[Phobos track:@"page_view" attributes:dict];
NSArray
*
array
=
[
GMCache
fetchObjectAtDocumentPathWithkey
:
PhobosCacheKey
];
XCTAssertTrue
(
array
.
count
==
1
,
@"PhobosCacheKey 下面应该有数据"
);
XCTAssertTrue([Phobos normalPhobosCountForURL:_client.serverAPI] == 1, @"There should be one data in the phobos datas");
[Phobos track:@"page_view" attributes:dict];
array
=
[
GMCache
fetchObjectAtDocumentPathWithkey
:
PhobosCacheKey
];
XCTAssertTrue
(
array
.
count
==
1
,
@"PhobosCacheKey 上条数据不应该发送"
);
XCTAssertTrue([Phobos normalPhobosCountForURL:_client.serverAPI] == 1, @"PhobosCacheKey 上条数据不应该发送");
[NSThread sleepForTimeInterval:2];//模拟浏览页面,让第二次浏览和上一次时间相差2s
...
...
@@ -371,15 +351,12 @@ NSString *const MockCityId = @"beijing";
[NSThread sleepForTimeInterval:1];//模拟浏览页面,让out和in时间相差1s
[dict setObject:[PhobosUtil currentTime] forKey:@"out"];
[Phobos track:@"page_view" attributes:dict];
array
=
[
GMCache
fetchObjectAtDocumentPathWithkey
:
PhobosCacheKey
];
XCTAssertTrue
(
array
.
count
==
2
,
@"PhobosCacheKey 上条数据应该发送"
);
XCTAssertTrue([Phobos normalPhobosCountForURL:_client.serverAPI] == 2, @"PhobosCacheKey 上条数据应该发送");
[Phobos track:@"page_view" attributes:dict];
array
=
[
GMCache
fetchObjectAtDocumentPathWithkey
:
PhobosCacheKey
];
XCTAssertTrue
(
array
.
count
==
2
,
@"PhobosCacheKey 上条数据不应该发送"
);
XCTAssertTrue([Phobos normalPhobosCountForURL:_client.serverAPI] == 2, @"PhobosCacheKey 上条数据不应该发送");
[Phobos track:@"test" attributes:dict];
array
=
[
GMCache
fetchObjectAtDocumentPathWithkey
:
PhobosCacheKey
];
XCTAssertTrue
(
array
.
count
==
3
,
@"PhobosCacheKey 上条数据应该发送"
);
}
XCTAssertTrue([Phobos normalPhobosCountForURL:_client.serverAPI] == 3, @"PhobosCacheKey 上条数据应该发送s");
}*/
#pragma mark - 其它方法test
...
...
GMPhobos/Classes/Phobos.h
View file @
e58799c9
...
...
@@ -31,13 +31,14 @@ typedef NS_ENUM (NSInteger, PhobosSigningType) {
*/
+
(
Phobos
*
)
clientWithAppName
:(
NSString
*
)
appName
channelId
:(
NSString
*
)
channelId
;
+
(
instancetype
)
sharedClient
;
+
(
void
)
setSharedClient
:(
Phobos
*
)
client
;
+
(
instancetype
)
alloc
__attribute__
((
deprecated
));
-
(
instancetype
)
init
__attribute__
((
deprecated
));
+
(
instancetype
)
new
__attribute__
((
deprecated
));
#pragma mark - SDK配置
@property
(
class
,
readonly
,
strong
)
Phobos
*
sharedClient
;
// Phobos在处理业务端传递来的参数时会检查是否某个value为空,如果为空会调用这个block以通知业务层,业务层可以上报这个异常,以助解决问题
@property
(
nonatomic
,
copy
)
void
(
^
captureNullExpection
)
(
NSString
*
eventId
,
NSDictionary
*
info
);
...
...
@@ -131,12 +132,12 @@ typedef NS_ENUM (NSInteger, PhobosSigningType) {
*
* @since 0.0.1
*/
+
(
void
)
track
:(
NSString
*
)
event
Id
attributes
:(
NSDictionary
*
)
attributes
;
+
(
void
)
track
:(
NSString
*
)
event
Id
attributes
:(
NSDictionary
*
)
attributes
sendNow
:(
BOOL
)
sendNow
;
+
(
void
)
track
:(
NSString
*
)
event
Id
;
+
(
void
)
track
:(
NSString
*
)
event
Name
attributes
:(
NSDictionary
*
)
attributes
;
+
(
void
)
track
:(
NSString
*
)
event
Name
attributes
:(
NSDictionary
*
)
attributes
sendNow
:(
BOOL
)
sendNow
;
+
(
void
)
track
:(
NSString
*
)
event
Name
;
/**
* @brief 自定义事件,数量统计 7730 精准曝光.
* @brief 自定义事件,数量统计 7730 精准曝光
/数据链路
.
*
* @param eventId 事件Id
* @attributes 参数
...
...
@@ -144,9 +145,9 @@ typedef NS_ENUM (NSInteger, PhobosSigningType) {
* @currentAPI 当前传过来的API
* @
*/
+
(
void
)
track
:(
NSString
*
)
event
Id
attributes
:(
NSDictionary
*
)
attributes
currentAPI
:(
NSString
*
)
currentAPI
;
+
(
void
)
track
:(
NSString
*
)
event
Id
attributes
:(
NSDictionary
*
)
attributes
sendNow
:(
BOOL
)
sendNow
currentAPI
:(
NSString
*
)
currentAPI
;
+
(
void
)
track
:(
NSString
*
)
event
Id
currentAPI
:(
NSString
*
)
currentAPI
;
+
(
void
)
track
:(
NSString
*
)
event
Name
attributes
:(
NSDictionary
*
)
attributes
currentAPI
:(
NSString
*
)
currentAPI
;
+
(
void
)
track
:(
NSString
*
)
event
Name
attributes
:(
NSDictionary
*
)
attributes
sendNow
:(
BOOL
)
sendNow
currentAPI
:(
NSString
*
)
currentAPI
;
+
(
void
)
track
:(
NSString
*
)
event
Name
currentAPI
:(
NSString
*
)
currentAPI
;
/**
* @author 翟国钧, 16-02-03 16:02:30
...
...
@@ -181,4 +182,41 @@ typedef NS_ENUM (NSInteger, PhobosSigningType) {
*/
-
(
void
)
simulativePV
:(
NSString
*
)
pageName
businessId
:(
NSString
*
)
bid
referer
:(
NSString
*
)
referer
;
@end
@interface
Phobos
(
UtilTest
)
/** 获取所有非立即发送埋点数量 */
+
(
NSInteger
)
normalPhobosCount
;
/** 获取所有非立即发送埋点数据 */
+
(
NSDictionary
*
)
normalPhobosData
;
/** 获取url的非立即发送埋点数量 */
+
(
NSInteger
)
normalPhobosCountForURL
:(
NSString
*
)
url
;
/** 获取url的非立即发送埋点数据 */
+
(
NSArray
*
)
normalPhobosDataForURL
:(
NSString
*
)
url
;
/** 获取所有立即发送埋点数据 */
+
(
NSDictionary
*
)
immediatelyPhobosData
;
/** 获取url的立即发送埋点数据 */
+
(
NSArray
*
)
immediatelyPhobosDataForURL
:(
NSString
*
)
url
;
/** 获取url的立即发送埋点数量 */
+
(
NSUInteger
)
immediatelyPhobosCountForURL
:(
NSString
*
)
url
;
/** 清除非立即发送埋点数据缓存 */
+
(
void
)
removeAllNormalPhobosData
;
/** 清除立即发送埋点数据缓存 */
+
(
void
)
removeAllImmediatelyPhobosData
;
/** 获取将要发送的数据 */
@property
(
nonatomic
,
copy
)
void
(
^
phobosSendDataBlock
)(
NSArray
*
datas
);
@end
GMPhobos/Classes/Phobos.m
View file @
e58799c9
...
...
@@ -15,8 +15,9 @@
#import "PhobosCustomVisibleController.h"
#import "UIDevice+Resolutions.h"
#import <GMCache/GMCache.h>
static
Phobos
*
sharedClient
=
nil
;
static
NSString
*
sdkVersion
=
@"110"
;
#import <objc/runtime.h>
static
Phobos
*
_sharedClient
;
static
NSString
*
sdkVersion
=
@"1.3.0"
;
@interface
Phobos
()
@property
(
strong
,
nonatomic
)
UIViewController
*
visibleController
;
...
...
@@ -28,48 +29,80 @@ static NSString *sdkVersion = @"110";
/* 每一条埋点数据的物理ID,自增,生命周期和sessionId相同。特别注意:在sessionOver的时候,要把他置为0 */
@property
(
assign
,
nonatomic
)
NSInteger
serialId
;
// 用来记录除serverAPI以外的API
@property
(
strong
,
nonatomic
)
NSMutableArray
*
APIArray
;
//@property (nonatomic, weak) dispatch_semaphore_t immediatelySemaphore;// 保障需要立即发送的埋点数据安全
//@property (nonatomic, weak) dispatch_semaphore_t normalSemaphore;// 保障普通埋点数据安全
@property
(
nonatomic
,
assign
)
NSInteger
normalCount
;
// 记录普通埋点数量
@end
@implementation
Phobos
+
(
Phobos
*
)
clientWithAppName
:(
NSString
*
)
appName
channelId
:(
NSString
*
)
channelId
{
return
[[
self
alloc
]
initWithAppName
:
appName
channelId
:
channelId
];
}
static
dispatch_semaphore_t
_immediatelySemaphore
;
static
dispatch_semaphore_t
_normalSemaphore
;
+
(
Phobos
*
)
sharedClient
{
return
sharedClient
;
+
(
Phobos
*
)
clientWithAppName
:(
NSString
*
)
appName
channelId
:(
NSString
*
)
channelId
{
Phobos
.
sharedClient
.
appName
=
appName
;
Phobos
.
sharedClient
.
channelId
=
channelId
;
return
Phobos
.
sharedClient
;
}
+
(
void
)
setSharedClient
:
(
Phobos
*
)
client
{
sharedClient
=
client
;
+
(
void
)
initialize
{
static
dispatch_once_t
onceToken
;
dispatch_once
(
&
onceToken
,
^
{
_immediatelySemaphore
=
dispatch_semaphore_create
(
1
);
_normalSemaphore
=
dispatch_semaphore_create
(
1
);
});
}
-
(
instancetype
)
initWithAppName
:
(
NSString
*
)
appName
channelId
:
(
NSString
*
)
channelId
{
self
=
[
super
init
];
if
(
self
)
{
_appName
=
appName
;
_channelId
=
channelId
;
_logEnabled
=
NO
;
_userId
=
@""
;
_netStatus
=
@""
;
_currentCityId
=
@""
;
_serverAPI
=
@""
;
_greyType
=
@""
;
_userType
=
[[
NSMutableDictionary
alloc
]
initWithCapacity
:
0
];
_appVersion
=
[
PhobosUtil
getAppVersion
];
_APIArray
=
[
NSMutableArray
array
];
_signingType
=
PhobosSigningTypeUndefined
;
-
(
instancetype
)
init
{
if
(
self
=
[
super
init
])
{
self
.
appName
=
@""
;
self
.
channelId
=
@""
;
self
.
logEnabled
=
NO
;
self
.
userId
=
@""
;
self
.
netStatus
=
@""
;
self
.
currentCityId
=
@""
;
self
.
serverAPI
=
@""
;
self
.
greyType
=
@""
;
self
.
userType
=
[[
NSMutableDictionary
alloc
]
initWithCapacity
:
0
];
self
.
appVersion
=
[
PhobosUtil
getAppVersion
];
self
.
signingType
=
PhobosSigningTypeUndefined
;
// self.immediatelySemaphore = dispatch_semaphore_create(1);
// self.normalSemaphore = dispatch_semaphore_create(1);
NSMutableDictionary
*
dataDict
=
[[
GMCache
fetchObjectAtDocumentPathWithkey
:
PhobosNormalCacheKey
]
mutableCopy
];
for
(
NSArray
*
data
in
dataDict
.
allValues
)
{
self
.
normalCount
+=
data
.
count
;
}
[
self
setupNotification
];
[
self
handleSessionStart
];
[
self
synchronizePhobosKey
];
phobosLog
(
@"starts to orbit"
);
}
return
self
;
}
+
(
id
)
allocWithZone
:
(
struct
_NSZone
*
)
zone
{
return
Phobos
.
sharedClient
;
}
-
(
id
)
copyWithZone
:
(
struct
_NSZone
*
)
zone
{
return
Phobos
.
sharedClient
;
}
+
(
Phobos
*
)
sharedClient
{
// 使用单例设计模式,保证Phobos只有一个实例,并提供了全局访问点
static
dispatch_once_t
onceToken
;
dispatch_once
(
&
onceToken
,
^
{
_sharedClient
=
[[
super
allocWithZone
:
NULL
]
init
];
});
return
_sharedClient
;
}
-
(
void
)
setAppName
:
(
NSString
*
)
appName
channelId
:
(
NSString
*
)
channelId
{
self
.
appName
=
appName
;
self
.
channelId
=
channelId
;
}
/**
* disk下的PhobosHaveOpenApp只要存在,就把他取出来放到document下(注:当不支持7.6.16版本的时候,干掉这个方法)
*/
...
...
@@ -188,7 +221,7 @@ static NSString *sdkVersion = @"110";
phobosLog
(
@"handleAppInForeground"
);
[
self
handleSessionStart
];
[
self
handleEventDeviceOpened
];
[
self
fetchDataAndSend
];
[
self
sendImmediatelyNormalData
];
[
self
handlePVEventAppInForeground
];
}
...
...
@@ -201,7 +234,7 @@ static NSString *sdkVersion = @"110";
phobosLog
(
@"handleAppInBackgound"
);
[
self
handlePVEventAppInBackgound
];
[
self
handleSessionOver
];
[
self
fetchDataAndSend
];
[
self
sendImmediatelyNormalData
];
}
/**
...
...
@@ -256,78 +289,6 @@ static NSString *sdkVersion = @"110";
}
}
#pragma mark - track event handler
+
(
void
)
track
:
(
NSString
*
)
eventId
{
[
Phobos
track
:
eventId
attributes
:@{}];
}
+
(
void
)
track
:
(
NSString
*
)
eventId
attributes
:
(
NSDictionary
*
)
attributes
{
[
self
track
:
eventId
attributes
:
attributes
sendNow
:
NO
];
NSArray
*
array
=
[
GMCache
fetchObjectAtDocumentPathWithkey
:
PhobosCacheKey
];
//超过一定数量的话,统一发送一次
if
(
array
.
count
>
PhobosShardCount
)
{
[
sharedClient
sendArray
:
array
cleanCacheRightNow
:
YES
];
}
}
+
(
void
)
track
:
(
NSString
*
)
eventId
attributes
:
(
NSDictionary
*
)
attributes
sendNow
:
(
BOOL
)
sendNow
{
NSDictionary
*
dict
=
[
sharedClient
prepareDictionaryForEvent
:
eventId
attributes
:
attributes
];
if
(
sendNow
)
{
NSArray
*
array
=
@[
dict
];
// 实时发送的埋点,不能立即清楚缓存
[
sharedClient
sendArray
:
array
cleanCacheRightNow
:
NO
];
}
else
{
[
sharedClient
save
:
dict
];
}
}
+
(
void
)
track
:
(
NSString
*
)
eventId
attributes
:
(
NSDictionary
*
)
attributes
currentAPI
:
(
NSString
*
)
currentAPI
{
[
self
track
:
eventId
attributes
:
attributes
sendNow
:
NO
currentAPI
:
currentAPI
];
NSArray
*
array
=
[
GMCache
fetchObjectAtDocumentPathWithkey
:[
PhobosUtil
MD5String
:
currentAPI
]];
//超过一定数量的话,统一发送一次
if
(
array
.
count
>
PhobosShardCount
)
{
[
sharedClient
sendArray
:
array
currentAPI
:
currentAPI
cleanCacheRightNow
:
YES
];
}
}
+
(
void
)
track
:
(
NSString
*
)
eventId
attributes
:
(
NSDictionary
*
)
attributes
sendNow
:
(
BOOL
)
sendNow
currentAPI
:
(
NSString
*
)
currentAPI
{
[
sharedClient
addNewApi
:
currentAPI
];
// 记录新的API
NSDictionary
*
dict
=
[
sharedClient
prepareDictionaryForEvent
:
eventId
attributes
:
attributes
];
if
(
sendNow
)
{
NSArray
*
array
=
@[
dict
];
// 实时发送的埋点,不能立即清楚缓存
[
sharedClient
sendArray
:
array
currentAPI
:
currentAPI
cleanCacheRightNow
:
NO
];
}
else
{
[
sharedClient
save
:
dict
currentAPI
:
currentAPI
];
}
}
+
(
void
)
track
:
(
NSString
*
)
eventId
currentAPI
:
(
NSString
*
)
currentAPI
{
[
Phobos
track
:
eventId
attributes
:@{}
currentAPI
:
currentAPI
];
}
+
(
void
)
trackJsEvent
:
(
NSString
*
)
jsonString
{
@try
{
NSData
*
data
=
[
jsonString
dataUsingEncoding
:
NSUnicodeStringEncoding
];
NSMutableDictionary
*
dict
=
[
NSJSONSerialization
JSONObjectWithData
:
data
options
:
NSJSONReadingAllowFragments
error
:
nil
];
id
pa
=
dict
[
@"params"
];
NSDictionary
*
json
;
if
([
pa
isKindOfClass
:[
NSString
class
]])
{
NSError
*
jsonError
;
NSData
*
objectData
=
[
pa
dataUsingEncoding
:
NSUTF8StringEncoding
];
json
=
[
NSJSONSerialization
JSONObjectWithData
:
objectData
options
:
NSJSONReadingMutableContainers
error
:&
jsonError
];
[
Phobos
track
:
dict
[
@"type"
]
attributes
:
json
];
}
else
{
[
Phobos
track
:
dict
[
@"type"
]];
}
}
@catch
(
NSException
*
exception
)
{
phobosLog
(
exception
);
}
}
#pragma mark - PV
-
(
void
)
onPVStart
:
(
UIResponder
<
PhobosPVProtocol
>
*
)
page
{
// 必须在此处调用一下referer,因为onControllerStart
...
...
@@ -341,7 +302,7 @@ static NSString *sdkVersion = @"110";
if
(
!
[
PhobosUtil
isNonEmpty
:
page
.
pageName
]
||
!
page
.
needLogPV
)
{
return
;
}
NSMutableDictionary
*
dict
=
[[
NSMutableDictionary
alloc
]
init
];
@try
{
[
dict
setObject
:[
PhobosUtil
currentTime
]
forKey
:
@"out"
];
...
...
@@ -382,45 +343,44 @@ static NSString *sdkVersion = @"110";
}
}
#pragma mark - 事件存储、发送
/**
* @brief 将埋点时间封装成词典数据
*
* @since 0.0.1
*/
-
(
NSDictionary
*
)
prepareDictionaryForEvent
:
(
NSString
*
)
event
Id
attributes
:
(
NSDictionary
*
)
attributes
{
[
self
catchNullForEvent
:
event
Id
attributes
:
attributes
];
-
(
NSDictionary
*
)
prepareDictionaryForEvent
:
(
NSString
*
)
event
Name
attributes
:
(
NSDictionary
*
)
attributes
{
[
self
catchNullForEvent
:
event
Name
attributes
:
attributes
];
NSMutableDictionary
*
dict
=
[[
NSMutableDictionary
alloc
]
init
];
@try
{
NSString
*
currentTime
=
[
PhobosUtil
currentTime
];
NSMutableDictionary
*
deviceParams
=
[
NSMutableDictionary
dictionaryWithObjectsAndKeys
:
[[[
ASIdentifierManager
sharedManager
]
advertisingIdentifier
]
UUIDString
],
@"idfa"
,
[[[
UIDevice
currentDevice
]
identifierForVendor
]
UUIDString
],
@"idfv"
,
[
PhobosUtil
deviceId
],
@"device_id"
,
@"ios"
,
@"device_type"
,
@"Apple"
,
@"manufacturer"
,
@
(
self
.
gps
.
coordinate
.
latitude
),
@"lat"
,
@
(
self
.
gps
.
coordinate
.
longitude
),
@"lng"
,
_netStatus
,
@"is_WiFi"
,
[
PhobosUtil
getIPAddress
:
YES
],
@"ip"
,
nil
];
NSMutableDictionary
*
deviceParams
=
[
NSMutableDictionary
new
];
[
deviceParams
setValue
:[[[
ASIdentifierManager
sharedManager
]
advertisingIdentifier
]
UUIDString
]
forKey
:
@"idfa"
];
[
deviceParams
setValue
:[[[
UIDevice
currentDevice
]
identifierForVendor
]
UUIDString
]
forKey
:
@"idfv"
];
[
deviceParams
setValue
:[
PhobosUtil
deviceId
]
forKey
:
@"device_id"
];
[
deviceParams
setValue
:
@"ios"
forKey
:
@"device_type"
];
[
deviceParams
setValue
:
@"Apple"
forKey
:
@"manufacturer"
];
[
deviceParams
setValue
:
@
(
self
.
gps
.
coordinate
.
latitude
)
forKey
:
@"lat"
];
[
deviceParams
setValue
:
@
(
self
.
gps
.
coordinate
.
longitude
)
forKey
:
@"lng"
];
[
deviceParams
setValue
:
_netStatus
forKey
:
@"is_WiFi"
];
[
deviceParams
setValue
:[
PhobosUtil
getIPAddress
:
YES
]
forKey
:
@"ip"
];
[
deviceParams
setValue
:
_networkStatus
forKey
:
@"net_type"
];
[
deviceParams
setValue
:[
UIDevice
platform
]
forKey
:
@"model"
];
[
deviceParams
setValue
:[
UIDevice
currentDevice
].
systemVersion
forKey
:
@"sys_version"
];
NSMutableDictionary
*
appParams
=
[
NSMutableDictionary
dictionaryWithObjectsAndKeys
:
_greyType
,
@"grey_type"
,
self
.
appName
,
@"name"
,
self
.
appVersion
,
@"version"
,
self
.
channelId
,
@"channel"
,
_userType
,
@"user_type"
,
self
.
currentCityId
,
@"current_city_id"
,
@
(
_serialId
++
),
@"serial_id"
,
nil
];
NSMutableDictionary
*
appParams
=
[
NSMutableDictionary
new
];
[
appParams
setValue
:
_greyType
forKey
:
@"grey_type"
];
[
appParams
setValue
:
_appName
forKey
:
@"name"
];
[
appParams
setValue
:
_appVersion
forKey
:
@"version"
];
[
appParams
setValue
:
_channelId
forKey
:
@"channel"
];
[
appParams
setValue
:
_userType
forKey
:
@"net_type"
];
[
appParams
setValue
:
_currentCityId
forKey
:
@"current_city_id"
];
[
appParams
setValue
:
@
(
_serialId
++
)
forKey
:
@"serial_id"
];
if
(
_signingType
==
PhobosSigningTypeDebug
||
_signingType
==
PhobosSigningTypeRelease
)
{
[
dict
setObject
:
@
(
0
)
forKey
:
@"is_release"
];
}
[
dict
setObject
:
event
Id
forKey
:
@"type"
];
[
dict
setObject
:
event
Name
forKey
:
@"type"
];
[
dict
setObject
:
appParams
forKey
:
@"app"
];
[
dict
setObject
:
sdkVersion
forKey
:
@"version"
];
[
dict
setObject
:
deviceParams
forKey
:
@"device"
];
...
...
@@ -435,33 +395,174 @@ static NSString *sdkVersion = @"110";
return
dict
;
}
#pragma mark - helpers
-
(
void
)
catchNullForEvent
:
(
NSString
*
)
eventName
attributes
:
(
NSDictionary
*
)
attributes
{
dispatch_async
(
dispatch_get_global_queue
(
0
,
0
),
^
{
@try
{
for
(
NSString
*
key
in
attributes
.
allKeys
)
{
if
([
attributes
[
key
]
isMemberOfClass
:[
NSNull
class
]])
{
if
(
self
.
captureNullExpection
)
{
self
.
captureNullExpection
(
eventName
,
attributes
);
}
break
;
}
}
}
@catch
(
NSException
*
exception
)
{
}
});
}
#pragma mark - track event handler
+
(
void
)
trackJsEvent
:
(
NSString
*
)
jsonString
{
@try
{
NSData
*
data
=
[
jsonString
dataUsingEncoding
:
NSUnicodeStringEncoding
];
NSMutableDictionary
*
dict
=
[
NSJSONSerialization
JSONObjectWithData
:
data
options
:
NSJSONReadingAllowFragments
error
:
nil
];
id
pa
=
dict
[
@"params"
];
NSDictionary
*
json
;
if
([
pa
isKindOfClass
:[
NSString
class
]])
{
NSError
*
jsonError
;
NSData
*
objectData
=
[
pa
dataUsingEncoding
:
NSUTF8StringEncoding
];
json
=
[
NSJSONSerialization
JSONObjectWithData
:
objectData
options
:
NSJSONReadingMutableContainers
error
:&
jsonError
];
[
Phobos
track
:
dict
[
@"type"
]
attributes
:
json
];
}
else
{
[
Phobos
track
:
dict
[
@"type"
]];
}
}
@catch
(
NSException
*
exception
)
{
phobosLog
(
exception
);
}
}
+
(
void
)
track
:
(
NSString
*
)
eventName
{
[
self
track
:
eventName
attributes
:@{}
sendNow
:
NO
currentAPI
:
_sharedClient
.
serverAPI
];
}
+
(
void
)
track
:
(
NSString
*
)
eventName
attributes
:
(
NSDictionary
*
)
attributes
{
[
self
track
:
eventName
attributes
:
attributes
sendNow
:
NO
currentAPI
:
_sharedClient
.
serverAPI
];
}
+
(
void
)
track
:
(
NSString
*
)
eventName
attributes
:
(
NSDictionary
*
)
attributes
sendNow
:
(
BOOL
)
sendNow
{
[
self
track
:
eventName
attributes
:
attributes
sendNow
:
sendNow
currentAPI
:
_sharedClient
.
serverAPI
];
}
+
(
void
)
track
:
(
NSString
*
)
eventName
currentAPI
:
(
NSString
*
)
currentAPI
{
[
self
track
:
eventName
attributes
:@{}
sendNow
:
NO
currentAPI
:
currentAPI
];
}
+
(
void
)
track
:
(
NSString
*
)
eventName
attributes
:
(
NSDictionary
*
)
attributes
currentAPI
:
(
NSString
*
)
currentAPI
{
[
self
track
:
eventName
attributes
:
attributes
sendNow
:
NO
currentAPI
:
currentAPI
];
}
+
(
void
)
track
:
(
NSString
*
)
eventName
attributes
:
(
NSDictionary
*
)
attributes
sendNow
:
(
BOOL
)
sendNow
currentAPI
:
(
NSString
*
)
currentAPI
{
NSDictionary
*
dataDict
=
[
_sharedClient
prepareDictionaryForEvent
:
eventName
attributes
:
attributes
];
if
(
sendNow
)
{
[
_sharedClient
sendImmediatelyPhobosWithURL
:
currentAPI
data
:
dataDict
];
}
else
{
[
_sharedClient
trackPhobosWithURL
:
currentAPI
data
:
dataDict
];
}
}
#pragma mark - 事件存储、发送
/**
* @brief 保存数据到缓存层
*
* @param data 数据
*
* @since 0.0.1
* 普通埋点
* @param url 接口url
* @param dataArray 埋点数据
* @param nowSend 是否需要发送当前缓存数据(app进入到后台、前台等情况)
*/
-
(
void
)
save
:
(
NSDictionary
*
)
data
{
if
(
_logEnabled
)
{
phobosLog
([
NSString
stringWithFormat
:
@"save dictionary: %@"
,
data
]);
-
(
void
)
sendImmediatelyNormalData
{
[
self
trackPhobosWithURL
:
nil
data
:
nil
immediate
:
YES
];
}
-
(
void
)
trackPhobosWithURL
:
(
NSString
*
)
url
data
:
(
NSDictionary
*
)
data
{
[
self
trackPhobosWithURL
:
url
data
:
data
immediate
:
NO
];
}
-
(
void
)
trackPhobosWithURL
:
(
NSString
*
)
url
data
:
(
NSDictionary
*
)
data
immediate
:
(
BOOL
)
immediate
{
dispatch_semaphore_wait
(
_normalSemaphore
,
DISPATCH_TIME_FOREVER
);
NSMutableDictionary
*
dataDict
=
[[
GMCache
fetchObjectAtDocumentPathWithkey
:
PhobosNormalCacheKey
]
mutableCopy
];
_normalCount
++
;
if
(
!
immediate
)
{
dataDict
=
[
self
dataDict
:
dataDict
setObject
:
data
forKey
:
url
];
[
GMCache
storeObjectAtDocumentPathWithkey
:
PhobosNormalCacheKey
object
:
dataDict
];
}
if
(
immediate
||
self
.
normalCount
>=
50
)
{
// 数据超过一定数量 或 进入后台等逻辑,统一进行发送普通埋点数据
[
dataDict
enumerateKeysAndObjectsUsingBlock
:
^
(
NSString
*
_Nonnull
key
,
NSArray
*
_Nonnull
obj
,
BOOL
*
_Nonnull
stop
)
{
if
(
obj
&&
obj
.
count
>
0
)
{
[
self
sendImmediatelyPhobosWithURL
:
key
data
:
obj
];
}
}];
[
GMCache
removeObjectAtDocumentPathWithkey
:
PhobosNormalCacheKey
];
}
dispatch_semaphore_signal
(
_normalSemaphore
);
}
NSMutableArray
*
dataArray
=
[
GMCache
fetchObjectAtDocumentPathWithkey
:
PhobosCacheKey
];
if
(
dataArray
)
{
#ifdef POD_CONFIGURATION_APP_STORE
[
dataArray
addObject
:
data
];
#else
if
(
data
[
@"type"
]
&&
[
data
[
@"type"
]
isEqualToString
:
@"page_view"
])
{
NSDictionary
*
pageParams
=
data
[
@"params"
];
/**
* 即时发送埋点接口
* @param url : 接口url
* @param data : 使用id类型是因为直接调用实时埋点传过来的是Dict,而普通埋点过来的则是Array类型
*/
-
(
void
)
sendImmediatelyPhobosWithURL
:
(
NSString
*
)
url
data
:
(
id
)
data
{
dispatch_semaphore_wait
(
_immediatelySemaphore
,
DISPATCH_TIME_FOREVER
);
__block
NSMutableDictionary
*
dataDict
=
[[
GMCache
fetchObjectAtDocumentPathWithkey
:
PhobosImmediatelyCacheKey
]
mutableCopy
];
dataDict
=
[
self
dataDict
:
dataDict
setObject
:
data
forKey
:
url
];
NSInteger
allCount
=
dataDict
.
allKeys
.
count
;
// 请求个数
__block
finishCount
=
0
;
// 请求完成次数,不是请求成功次数,能在最后保证未发送成功的数据,能一次保存下来,等待下次发送
dispatch_semaphore_t
semaphore
=
dispatch_semaphore_create
(
1
);
// 因为网络请求是异步回调,需要保证数据安全
[
dataDict
enumerateKeysAndObjectsUsingBlock
:
^
(
NSString
*
_Nonnull
key
,
NSArray
*
_Nonnull
obj
,
BOOL
*
_Nonnull
stop
)
{
[
self
sendDataWithAPI
:
key
data
:
obj
successBlock
:^
(
BOOL
success
)
{
dispatch_semaphore_wait
(
semaphore
,
DISPATCH_TIME_FOREVER
);
finishCount
++
;
if
(
success
)
{
// 如果数据请求成功,删除当前数据的缓存
[
dataDict
removeObjectForKey
:
key
];
}
if
(
finishCount
==
allCount
)
{
// 所有数据都请求完成,重新进行数据缓存
[
GMCache
storeObjectAtDocumentPathWithkey
:
PhobosImmediatelyCacheKey
object
:
dataDict
];
dispatch_semaphore_signal
(
_immediatelySemaphore
);
}
dispatch_semaphore_signal
(
semaphore
);
phobosLog
(
@"✈ ---------- ✈ data arrived Mars"
);
}];
}];
}
/**
* 将数据存入到字典中
* @param dataDict 需要存入的字典
* @param object 需要存入的数据
* @param key 需要将数据存入到dataDict的key所在的数据中
*/
-
(
NSMutableDictionary
*
)
dataDict
:
(
NSMutableDictionary
*
)
dataDict
setObject
:
(
id
)
object
forKey
:
(
NSString
*
)
key
{
if
(
!
dataDict
)
{
dataDict
=
[
NSMutableDictionary
new
];
}
// 判断数据类型,统一转换成数组
NSMutableArray
*
dataArray
=
[
dataDict
.
allKeys
containsObject
:
key
]
?
[
dataDict
[
key
]
mutableCopy
]
:
[
NSMutableArray
new
];
NSArray
*
data
=
[
object
isKindOfClass
:[
NSArray
class
]]
?
object
:@[
object
];
#ifndef POD_CONFIGURATION_APP_STORE
[
self
verifyPVPhobos
:
dataArray
data
:
object
];
#endif
[
dataArray
addObjectsFromArray
:
data
];
[
dataDict
setValue
:
dataArray
forKey
:
key
];
return
dataDict
;
}
// 校验PV埋点是否有问题,默认返回NO
-
(
BOOL
)
verifyPVPhobos
:
(
NSArray
*
)
dataArray
data
:
(
id
)
data
{
if
([
data
isKindOfClass
:[
NSDictionary
class
]])
{
NSDictionary
*
dataDict
=
(
NSDictionary
*
)
data
;
if
(
dataDict
[
@"type"
]
&&
[
dataDict
[
@"type"
]
isEqualToString
:
@"page_view"
])
{
NSDictionary
*
pageParams
=
dataDict
[
@"params"
];
long
long
pageInTime
=
[
pageParams
[
@"in"
]
longLongValue
];
long
long
pageOutTime
=
[
pageParams
[
@"out"
]
longLongValue
];
// phobosLog(@"pageInTime------%lld",pageInTime);
// phobosLog(@"pageOutTime------%lld",pageOutTime);
if
(
pageInTime
&&
pageOutTime
)
{
__block
BOOL
checkTimeError
;
BOOL
checkTimeError
;
for
(
int
i
=
0
;
i
<
dataArray
.
count
;
i
++
)
{
NSDictionary
*
obj
=
dataArray
[
i
];
...
...
@@ -482,77 +583,30 @@ static NSString *sdkVersion = @"110";
break
;
}
}
}
return
checkTimeError
;
}
}
// 不管成功还是失败 给开发提示方便DEBUG
// phobosLog(@"%s____数据校验成功", __func__);
[
dataArray
addObject
:
data
];
#endif
}
else
{
dataArray
=
[
NSMutableArray
arrayWithObject
:
data
];
}
[
GMCache
storeObjectAtDocumentPathWithkey
:
PhobosCacheKey
object
:
dataArray
];
}
/**
* @brief 保存数据到缓存层
*
* @param data 数据
*
*/
-
(
void
)
save
:
(
NSDictionary
*
)
data
currentAPI
:
(
NSString
*
)
currentAPI
{
if
(
_logEnabled
)
{
phobosLog
([
NSString
stringWithFormat
:
@"save dictionary: %@"
,
data
]);
}
NSMutableArray
*
dataArray
=
[
GMCache
fetchObjectAtDocumentPathWithkey
:[
PhobosUtil
MD5String
:
currentAPI
]];
if
(
dataArray
)
{
[
dataArray
addObject
:
data
];
}
else
{
dataArray
=
[
NSMutableArray
arrayWithObject
:
data
];
}
[
GMCache
storeObjectAtDocumentPathWithkey
:[
PhobosUtil
MD5String
:
currentAPI
]
object
:
dataArray
];
}
/**
* @brief 从缓存中获取数据,并发送
*
* @since 0.0.1
*/
-
(
void
)
fetchDataAndSend
{
NSArray
*
paramsArray
=
[
GMCache
fetchObjectAtDocumentPathWithkey
:
PhobosCacheKey
];
if
(
paramsArray
.
count
>
0
)
{
[
self
sendArray
:
paramsArray
cleanCacheRightNow
:
YES
];
}
// 其他接口的埋点
for
(
NSString
*
newApi
in
self
.
APIArray
)
{
NSArray
*
paramsArray
=
[
GMCache
fetchObjectAtDocumentPathWithkey
:[
PhobosUtil
MD5String
:
newApi
]];
if
(
paramsArray
.
count
>
0
)
{
[
self
sendArray
:
paramsArray
currentAPI
:
newApi
cleanCacheRightNow
:
YES
];
}
}
return
NO
;
}
/*
从缓存区获取数据,发给服务器,请求成功的时候,把缓存区的数据删除掉
*/
-
(
void
)
sendArray
{
NSMutableArray
*
dataArray
=
[
GMCache
fetchObjectAtDocumentPathWithkey
:
PhobosTempCacheKey
];
// 发送埋点数据
-
(
void
)
sendDataWithAPI
:
(
NSString
*
)
api
data
:
(
NSArray
*
)
dataArray
successBlock
:
(
SendDataSuccessBlock
)
successBlock
{
if
(
_logEnabled
)
{
NSData
*
data
=
[
NSJSONSerialization
dataWithJSONObject
:
dataArray
options
:
NSJSONWritingPrettyPrinted
error
:
nil
];
NSString
*
jsonString
=
[[
NSString
alloc
]
initWithData
:
data
encoding
:
NSUTF8StringEncoding
];
phobosLog
([
NSString
stringWithFormat
:
@"array prepare to fly --✈: %@"
,
jsonString
]);
}
@try
{
if
(
self
.
phobosSendDataBlock
)
{
self
.
phobosSendDataBlock
(
dataArray
);
}
NSData
*
JSON
=
[
PhobosUtil
encodeJSON
:
dataArray
];
NSData
*
compressedData
=
[
PhobosUtil
compressData
:
JSON
];
if
(
compressedData
)
{
[
PhobosUtil
sendData
:
compressedData
success
:
^
(
NSInteger
code
)
{
phobosLog
(
@"✈ ---------- ✈ data arrived Mars"
);
[
GMCache
removeObjectAtDocumentPathWithkey
:
PhobosTempCacheKey
];
}];
[
PhobosUtil
sendData
:
compressedData
currentAPI
:
api
success
:
successBlock
];
}
}
@catch
(
NSException
*
exception
)
{
...
...
@@ -560,109 +614,68 @@ static NSString *sdkVersion = @"110";
}
}
/*
从缓存区获取数据,发给服务器,请求成功的时候,把缓存区的数据删除掉
*/
-
(
void
)
sendArrayWithCurrentAPI
:
(
NSString
*
)
currentAPI
{
NSString
*
PhobosTempCacheKeyStr
=
[
PhobosUtil
MD5String
:[
PhobosUtil
MD5String
:
currentAPI
]];
// 两次加密作为key值,和缓存的key值作区分
NSMutableArray
*
dataArray
=
[
GMCache
fetchObjectAtDocumentPathWithkey
:
PhobosTempCacheKeyStr
];
if
(
_logEnabled
)
{
NSData
*
data
=
[
NSJSONSerialization
dataWithJSONObject
:
dataArray
options
:
NSJSONWritingPrettyPrinted
error
:
nil
];
NSString
*
jsonString
=
[[
NSString
alloc
]
initWithData
:
data
encoding
:
NSUTF8StringEncoding
];
phobosLog
([
NSString
stringWithFormat
:
@"array prepare to fly --✈: %@"
,
jsonString
]);
}
@try
{
NSData
*
JSON
=
[
PhobosUtil
encodeJSON
:
dataArray
];
NSData
*
compressedData
=
[
PhobosUtil
compressData
:
JSON
];
if
(
compressedData
)
{
[
PhobosUtil
sendData
:
compressedData
currentAPI
:
currentAPI
success
:^
(
NSInteger
code
)
{
phobosLog
(
@"✈ ---------- ✈ data arrived Mars"
);
[
GMCache
removeObjectAtDocumentPathWithkey
:
PhobosTempCacheKeyStr
];
}];
}
}
@catch
(
NSException
*
exception
)
{
phobosLog
(
exception
);
}
@end
@implementation
Phobos
(
UtilTest
)
/** 获取所有非立即发送埋点数量 */
+
(
NSInteger
)
normalPhobosCount
{
return
Phobos
.
sharedClient
.
normalCount
;
}
/**
该方法有改动,现在的逻辑是:当前方法只接受发送的请求,然后把数据转存到另一个缓存区,
让sendArray方法负责发送,数据一旦转移到缓存区,就把原有的数据干掉。
@author zhaiguojun 16-10-17 in (null)
@param array 参数
@param clean 是否立即清楚缓存
*/
-
(
void
)
sendArray
:
(
NSArray
*
)
array
cleanCacheRightNow
:
(
BOOL
)
clean
{
@try
{
//1.获取缓存区的数据,把新数据追加进去
NSMutableArray
*
dataArray
=
[
GMCache
fetchObjectAtDocumentPathWithkey
:
PhobosTempCacheKey
];
if
(
dataArray
)
{
[
dataArray
addObjectsFromArray
:
array
];
}
else
{
dataArray
=
[
NSMutableArray
arrayWithArray
:
array
];
}
[
GMCache
storeObjectAtDocumentPathWithkey
:
PhobosTempCacheKey
object
:
dataArray
];
//2.把缓存区的数据发送给服务器
[
self
sendArray
];
//3.把原有的数据删除
if
(
clean
)
{
[
GMCache
removeObjectAtDocumentPathWithkey
:
PhobosCacheKey
];
}
}
@catch
(
NSException
*
exception
)
{
phobosLog
(
exception
);
}
/** 获取所有非立即发送埋点数据 */
+
(
NSDictionary
*
)
normalPhobosData
{
return
[
GMCache
fetchObjectAtDocumentPathWithkey
:
PhobosNormalCacheKey
];
}
/**
上边方法新加了一个API字段
*/
-
(
void
)
sendArray
:
(
NSArray
*
)
array
currentAPI
:
(
NSString
*
)
currentAPI
cleanCacheRightNow
:
(
BOOL
)
clean
{
@try
{
//1.获取缓存区的数据,把新数据追加进去
NSString
*
PhobosTempCacheKeyStr
=
[
PhobosUtil
MD5String
:[
PhobosUtil
MD5String
:
currentAPI
]];
// 两次加密作为key值,和缓存的key值作区分
NSMutableArray
*
dataArray
=
[
GMCache
fetchObjectAtDocumentPathWithkey
:
PhobosTempCacheKeyStr
];
if
(
dataArray
)
{
[
dataArray
addObjectsFromArray
:
array
];
}
else
{
dataArray
=
[
NSMutableArray
arrayWithArray
:
array
];
}
[
GMCache
storeObjectAtDocumentPathWithkey
:
PhobosTempCacheKeyStr
object
:
dataArray
];
//2.把缓存区的数据发送给服务器
[
self
sendArrayWithCurrentAPI
:
currentAPI
];
//3.把原有的数据删除
[
GMCache
removeObjectAtDocumentPathWithkey
:[
PhobosUtil
MD5String
:
currentAPI
]];
}
@catch
(
NSException
*
exception
)
{
phobosLog
(
exception
);
}
/** 获取url的非立即发送埋点数量 */
+
(
NSUInteger
)
normalPhobosCountForURL
:
(
NSString
*
)
url
{
NSDictionary
*
dict
=
[
GMCache
fetchObjectAtDocumentPathWithkey
:
PhobosNormalCacheKey
];
NSArray
*
urlData
=
dict
[
url
];
return
urlData
?
urlData
.
count
:
0
;
}
#pragma mark - helpers
-
(
void
)
catchNullForEvent
:
(
NSString
*
)
eventId
attributes
:
(
NSDictionary
*
)
attributes
{
dispatch_async
(
dispatch_get_global_queue
(
0
,
0
),
^
{
@try
{
for
(
NSString
*
key
in
attributes
.
allKeys
)
{
if
([
attributes
[
key
]
isMemberOfClass
:[
NSNull
class
]])
{
if
(
self
.
captureNullExpection
)
{
self
.
captureNullExpection
(
eventId
,
attributes
);
}
break
;
}
}
}
@catch
(
NSException
*
exception
)
{
}
});
/** 获取url的非立即发送埋点数据 */
+
(
NSArray
*
)
normalPhobosDataForURL
:
(
NSString
*
)
url
{
NSDictionary
*
dict
=
[
GMCache
fetchObjectAtDocumentPathWithkey
:
PhobosNormalCacheKey
];
return
dict
[
url
];
}
/** 获取所有立即发送埋点数据 */
+
(
NSDictionary
*
)
immediatelyPhobosData
{
return
[
GMCache
fetchObjectAtDocumentPathWithkey
:
PhobosImmediatelyCacheKey
];
}
-
(
void
)
addNewApi
:
(
NSString
*
)
api
{
for
(
NSString
*
item
in
self
.
APIArray
)
{
if
([
api
isEqualToString
:
item
])
{
break
;
}
[
self
.
APIArray
addObject
:
api
];
}
/** 获取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
{
Phobos
.
sharedClient
.
normalCount
=
0
;
[
GMCache
removeObjectAtDocumentPathWithkey
:
PhobosNormalCacheKey
];
}
/** 清除立即发送埋点数据缓存 */
+
(
void
)
removeAllImmediatelyPhobosData
{
[
GMCache
removeObjectAtDocumentPathWithkey
:
PhobosImmediatelyCacheKey
];
}
-
(
void
)
setPhobosSendDataBlock
:
(
void
(
^
)(
NSArray
*
))
phobosSendDataBlock
{
objc_setAssociatedObject
(
self
,
@selector
(
phobosSendDataBlock
),
phobosSendDataBlock
,
OBJC_ASSOCIATION_COPY_NONATOMIC
);
}
-
(
void
(
^
)(
NSArray
*
))
phobosSendDataBlock
{
return
objc_getAssociatedObject
(
self
,
@selector
(
phobosSendDataBlock
));
}
@end
GMPhobos/Classes/PhobosConfig.h
View file @
e58799c9
...
...
@@ -18,8 +18,8 @@
#define PhobosHaveOpenApp @"PhobosHaveOpenApp" //是否打开过APP
#define PhobosBeginTime @"PhobosBeginTime" //记录APP打开|从后台启动时的时间戳
#define PhobosEndTime @"PhobosEndTime" //记录APP退出|退到后台时的时间戳
#define Phobos
CacheKey @"PhobosCacheKey"
//存放持久化埋点数据的key
#define Phobos
TempCacheKey @"PhobosTempCacheKey" //临时存放待发送
埋点数据的key
#define Phobos
NormalCacheKey @"PhobosNormalCacheKey"
//存放持久化埋点数据的key
#define Phobos
ImmediatelyCacheKey @"PhobosImmediatelyCacheKey" //存放持久化实时
埋点数据的key
#define PhobosShardCount 50 //收集数据分段发送的个数
...
...
GMPhobos/Classes/PhobosUtil.h
View file @
e58799c9
...
...
@@ -8,7 +8,7 @@
#import <Foundation/Foundation.h>
typedef
void
(
^
SendDataSuccessBlock
)(
NSInteger
code
);
typedef
void
(
^
SendDataSuccessBlock
)(
BOOL
success
);
@interface
PhobosUtil
:
NSObject
...
...
GMPhobos/Classes/PhobosUtil.m
View file @
e58799c9
...
...
@@ -123,11 +123,8 @@
// sendAsynchronousRequest 在iOS9以后y被废除了
NSURLSession
*
session
=
[
NSURLSession
sharedSession
];
NSURLSessionDataTask
*
dataTask
=
[
session
dataTaskWithRequest
:
request
completionHandler
:
^
(
NSData
*
_Nullable
data
,
NSURLResponse
*
_Nullable
response
,
NSError
*
_Nullable
error
)
{
if
(
!
error
)
{
//没有错误,返回正确;
if
(
success
)
{
success
(
200
);
}
if
(
success
)
{
success
(
!
error
?
YES
:
NO
);
}
}];
[
dataTask
resume
];
...
...
乔金柱
@qiaojinzhu
mentioned in commit
e56ff462
·
Aug 08, 2019
mentioned in commit
e56ff462
mentioned in commit e56ff4621c14f175bc8f2d2e1cdb91f3aa2665aa
Toggle commit list
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