Authored by 周蓉君

更新YH_Analytics及其测试用例。启动会话应用策略,获取新策略存储在本地,下次启动会话应用新策略。Review by 阿瑟。

... ... @@ -19,17 +19,11 @@
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
// 设置发送策略
// [YH_Analytics sharedInstance].logStrategy = LogStrategyCustom;
// 自定义发送时间,从服务器获取
[YH_Analytics sharedInstance].customInterval = 1000;
// 设置用户id
[YH_Analytics sharedInstance].uid = @"0000001";
// 启动
[[YH_Analytics sharedInstance]startWithAppId:@"appid"];
[[YH_Analytics sharedInstance] startWithAppId:@"appid"];
NSLog(@"logStrategy == %d", [YH_Analytics sharedInstance].logStrategy);
return YES;
... ...
... ... @@ -59,24 +59,28 @@
NSLog(@"Index %li", (long)index);
YHLogStrategy strategy = LogStrategyAppLaunch;
NSTimeInterval interval = 0;
switch (index) {
case 0: {
[YH_Analytics sharedInstance].logStrategy = LogStrategyAppLaunch;
strategy = LogStrategyAppLaunch;
break;
}
case 1: {
[YH_Analytics sharedInstance].logStrategy = LogStrategyCustom;
[[NSUserDefaults standardUserDefaults] setDouble:60 forKey:kKeyUserDefaultsCustomInterval];
[[NSUserDefaults standardUserDefaults] synchronize];
strategy = LogStrategyCustom;
interval = 1000;
break;
}
case 2: {
[YH_Analytics sharedInstance].logStrategy = LogStrategyImmedi;;
strategy = LogStrategyImmedi;;
break;
}
default:
break;
}
[[YH_Analytics sharedInstance] updateLogStrategy:strategy customInterval:interval];
}
@end
... ...
... ... @@ -16,7 +16,6 @@
//阀值
#define kMaxLocalEventsCount 3000 // 本地持久化event最大条数
#define kMaxLocalRecoderFileSize (1024 * 300) // 本地持久化文件大小(300KB)
#define kMinInterval 3600
extern NSString * const JsonKeyDataTypeDevice;
extern NSString * const JsonKeyDataTypeStatus;
... ...
... ... @@ -13,9 +13,11 @@
#define kKeyUserDefaultsLastUploadTimestamp @"lastSendTimestampKey"
#define kKeyUserDefaultsCustomInterval @"customInterval"
#define kUserDefaultLogStrategy @"LOGSTRATEGY"
#define kKeyUserDefaultsLogStrategy @"LOGSTRATEGY"
#define kMinInterval 60
typedef enum _YohoMobStatLogStrategy {
typedef enum _YHLogStrategy {
LogStrategyAppLaunch = 0, //每次程序启动
LogStrategyCustom = 1, //根据时间间隔接口发送
LogStrategyImmedi // 立即发送
... ... @@ -25,22 +27,27 @@ typedef enum _YohoMobStatLogStrategy {
/**
* 获取统计对象的实例
*/
+ (YH_Analytics*) sharedInstance;
+ (YH_Analytics*)sharedInstance;
/**
* 此处AppId即为应用的appKey
*/
-(void) startWithAppId:(NSString*) appId;
- (void)startWithAppId:(NSString*) appId;
/**
* 更新发送策略
*/
- (void)updateLogStrategy:(YHLogStrategy)logStrategy customInterval:(NSTimeInterval)customInterval;
/**
*logEvent 事件ID和事件参数
*/
-(void) logEvent:(NSString*) eventId parameters:(NSDictionary * )param;
- (void)logEvent:(NSString*) eventId parameters:(NSDictionary * )param;
/**
*logError errorID和错误参数
*/
-(void) logError:(NSString*) errorType parameters:(NSDictionary * )param;
- (void)logError:(NSString*) errorType parameters:(NSDictionary * )param;
/**
*logError 传入NSError
... ... @@ -49,38 +56,26 @@ typedef enum _YohoMobStatLogStrategy {
/**
* 设置或者获取渠道Id。
* 可以不设置, 此时系统会处理为AppStore渠道
*/
@property (nonatomic, strong) NSString* channelId;
/**
* 是否启用异常日志收集
* 用户id
*/
@property (nonatomic) BOOL enableExceptionLog;
@property (strong, nonatomic) NSString *uid;
/**
*
* 设置日志发送策略, 默认采用BaiduMobStatLogStrategyAppLaunch:启动发送
* 设置或者获取渠道Id。
* 可以不设置, 此时系统会处理为AppStore渠道
*/
@property (nonatomic) YHLogStrategy logStrategy;
@property (strong, nonatomic) NSString* channelId;
/**
*
* 开发者可以调用此接口来打印SDK中的日志,用于调试
*/
@property (nonatomic) BOOL enableDebugOn;
/**
* 间隔发送策略下,间隔
* 设置日志发送策略, 默认采用启动发送
*/
@property (nonatomic) NSTimeInterval customInterval;
@property (assign, nonatomic, readonly) YHLogStrategy logStrategy;
/**
* 用户id
* 间隔发送策略下,间隔时间
*/
@property (strong, nonatomic) NSString *uid;
@property (assign, nonatomic, readonly) NSTimeInterval currentInterval;
/**
* 发送的事件
... ... @@ -93,8 +88,14 @@ typedef enum _YohoMobStatLogStrategy {
@property (strong, nonatomic, readonly) YHError *error;
/**
* 定位服务
* 是否启用异常日志收集
*/
@property (nonatomic) BOOL enableExceptionLog;
/**
*
* 开发者可以调用此接口来打印SDK中的日志,用于调试
*/
@property (strong, nonatomic) CLLocationManager *locationManager;
@property (nonatomic) BOOL enableDebugOn;
@end
... ...
... ... @@ -29,18 +29,48 @@
@interface YH_Analytics ()
@property (assign, nonatomic) BOOL isLogSystemWorking;
/**
* 定位服务
*/
@property (strong, nonatomic) CLLocationManager *locationManager;
/**
* 当前会话ID
*/
@property (strong, nonatomic) NSString *session;
@property (assign, nonatomic) NSUInteger eventIndex; // 操作序数
/**
* 操作序数
*/
@property (assign, nonatomic) NSUInteger eventIndex;
/**
* 发送策略
*/
@property (assign, nonatomic) YHLogStrategy logStrategy;
/**
* 间隔发送定时器
*/
@property (strong, nonatomic) NSTimer *timer;
/**
* 间隔发送时间
*/
@property (assign, nonatomic) NSTimeInterval currentInterval;
/**
* 最近一个时间
*/
@property (strong, nonatomic) YHEvent *event;
/**
* 最近一个错误
*/
@property (strong, nonatomic) YHError *error;
- (NSString *)timestamp;
- (void)startObserverNetworkReachabilityStatus;
- (void)startLocationService;
- (void)registerCrashReporter;
- (void)registerAppWillEnterForegroundNotification;
- (void)resetSession;
- (void)uploadDiskData;
- (void)tryUploadDiskData;
@end
... ... @@ -64,7 +94,17 @@
self = [super init];
if (self) {
// 初始化策略
_logStrategy = [[[NSUserDefaults standardUserDefaults] objectForKey:kUserDefaultLogStrategy] intValue];
_logStrategy = [[[NSUserDefaults standardUserDefaults] objectForKey:kKeyUserDefaultsLogStrategy] intValue];
if (_logStrategy == LogStrategyCustom) {
// 获取上次启动时服务端给的时间间隔
NSTimeInterval interval = [[NSUserDefaults standardUserDefaults] doubleForKey:kKeyUserDefaultsCustomInterval];
_currentInterval = MAX(kMinInterval, interval);
} else {
_currentInterval = 0;
}
NSLog(@"logStrategy = %d currentInterval = %0.1f", _logStrategy, _currentInterval);
}
return self;
... ... @@ -104,27 +144,6 @@
return _locationManager;
}
- (void)setLogStrategy:(YHLogStrategy)strategyNumber
{
// 关闭计时器
if (self.timer) {
[self.timer invalidate];
self.timer = nil;
}
_logStrategy = strategyNumber;
// 保存策略
NSUserDefaults *strategy = [NSUserDefaults standardUserDefaults];
[strategy setObject: [NSNumber numberWithInteger:strategyNumber] forKey:kUserDefaultLogStrategy];
[strategy synchronize];
}
- (YHLogStrategy)logStrategy
{
return _logStrategy;
}
#pragma mark - Private Method
// 添加网络监测回调block
... ... @@ -207,7 +226,8 @@
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(resetSession) name:UIApplicationWillEnterForegroundNotification object:nil];
}
- (void)resetSession {
- (void)resetSession
{
NSLog(@"app will enter foreground !!");
self.session = nil;
}
... ... @@ -240,6 +260,17 @@
}
}
- (void)updateLogStrategy:(YHLogStrategy)logStrategy customInterval:(NSTimeInterval)customInterval
{
// 保存策略
NSUserDefaults *strategy = [NSUserDefaults standardUserDefaults];
[strategy setObject: [NSNumber numberWithInteger:logStrategy] forKey:kKeyUserDefaultsLogStrategy];
if (logStrategy == LogStrategyCustom) {
[strategy setObject:[NSNumber numberWithDouble:customInterval] forKey:kKeyUserDefaultsCustomInterval];
}
[strategy synchronize];
}
#pragma mark - Public Method
- (void)startWithAppId:(NSString *)appId
... ... @@ -262,32 +293,20 @@
检查发送模式
*/
// 启动是发送
if (self.logStrategy == LogStrategyAppLaunch) {
if (self.logStrategy == LogStrategyAppLaunch) { // 启动时发送
[self uploadDiskData];
} else if (self.logStrategy == LogStrategyCustom) { // 间隔发送
// double tmp = [[[NSUserDefaults standardUserDefaults] objectForKey:kKeyUserDefaultsCustomInterval] doubleValue];
// NSLog(@"tmp = %f",tmp);
// 获取上次启动时服务端给的时间间隔
if ([[NSUserDefaults standardUserDefaults] objectForKey:kKeyUserDefaultsCustomInterval]) {
self.currentInterval = [[NSUserDefaults standardUserDefaults]doubleForKey:kKeyUserDefaultsCustomInterval];
}else {
self.currentInterval = kMinInterval;
}
NSLog(@"currentInterval = %0.1f", self.currentInterval);
} else if (self.logStrategy == LogStrategyCustom) { // 间隔发送
[self tryUploadDiskData];
self.timer = [NSTimer scheduledTimerWithTimeInterval:self.currentInterval target:self selector:@selector(tryUploadDiskData) userInfo:nil repeats:YES];
//
// // 从服务端获取新的发送策略,该策略在下一次APP启动后生效
// if (self.customInterval) {
// [[NSUserDefaults standardUserDefaults]setDouble:self.customInterval forKey:kKeyUserDefaultsCustomInterval];
// }
}
// 从服务端获取新的发送策略,该策略在下一次APP启动后生效
// [self updateLogStrategy:LogStrategyCustom customInterval:1000];
}
// 记录event
... ... @@ -358,7 +377,6 @@
// }
//}
#pragma mark - CLLocationManagerDelegate
- (void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status
... ...
... ... @@ -17,6 +17,14 @@
#import "FakeLocationManager.h"
@interface YH_Analytics (XCTestCase)
@property (assign, nonatomic) YHLogStrategy logStrategy;
@property (assign, nonatomic) NSTimeInterval currentInterval;
@property (strong, nonatomic) CLLocationManager *locationManager;
@end
@interface YH_AnalyticsLogicTests : XCTestCase {
@private
id assemblyAssistantMock;
... ... @@ -34,7 +42,7 @@
// Put setup code here. This method is called before the invocation of each test method in the class.
// 开始每个测试时,恢复初始化设置
[[NSUserDefaults standardUserDefaults] removeObjectForKey:kKeyUserDefaultsLastUploadTimestamp];
[[NSUserDefaults standardUserDefaults] removeObjectForKey:kUserDefaultLogStrategy];
[[NSUserDefaults standardUserDefaults] removeObjectForKey:kKeyUserDefaultsLogStrategy];
[[NSUserDefaults standardUserDefaults] removeObjectForKey:kKeyUserDefaultsCustomInterval];
[[NSUserDefaults standardUserDefaults] synchronize];
... ... @@ -63,7 +71,7 @@
+ (void)tearDown {
// 结束时恢复初始化设置
[[NSUserDefaults standardUserDefaults] removeObjectForKey:kKeyUserDefaultsLastUploadTimestamp];
[[NSUserDefaults standardUserDefaults] removeObjectForKey:kUserDefaultLogStrategy];
[[NSUserDefaults standardUserDefaults] removeObjectForKey:kKeyUserDefaultsLogStrategy];
[[NSUserDefaults standardUserDefaults] removeObjectForKey:kKeyUserDefaultsCustomInterval];
[[NSUserDefaults standardUserDefaults] synchronize];
... ... @@ -88,20 +96,6 @@
NSLog(@"%@ end", self.name);
}
- (void)testStartWithAppIdMethodReceiveNotification {
NSLog(@"%@ start", self.name);
// NSNotificationCenter *center = [[NSNotificationCenter alloc] init];
// id observerMock = [OCMockObject observerMock];
//
// [center addMockObserver:observerMock name:UIApplicationWillEnterForegroundNotification object:nil];
// [[observerMock expect] notificationWithName:UIApplicationWillEnterForegroundNotification object:[OCMArg any]];
NSLog(@"%@ end", self.name);
}
- (void)testStartWithAppIdMethodWithLogStrategyAppLaunch {
NSLog(@"%@ start", self.name);
... ... @@ -120,6 +114,7 @@
NSLog(@"%@ start", self.name);
analytics.logStrategy = LogStrategyCustom;
analytics.currentInterval = 100;
OCMExpect([assemblyAssistantMock uploadDiskData]);
... ... @@ -256,6 +251,42 @@
NSLog(@"%@ end", self.name);
}
- (void)testUpdateLogStrategyMethodWithAppLaunch {
NSLog(@"%@ start", self.name);
[analytics updateLogStrategy:LogStrategyAppLaunch customInterval:0];
YHLogStrategy logStrategy = [[[NSUserDefaults standardUserDefaults] objectForKey:kKeyUserDefaultsLogStrategy] intValue];
NSTimeInterval interval = [[NSUserDefaults standardUserDefaults] doubleForKey:kKeyUserDefaultsCustomInterval];
XCTAssertEqual(logStrategy, LogStrategyAppLaunch);
XCTAssertEqual(interval, 0);
NSLog(@"%@ end", self.name);
}
- (void)testUpdateLogStrategyMethodWithImmediate{
NSLog(@"%@ start", self.name);
[analytics updateLogStrategy:LogStrategyImmedi customInterval:0];
YHLogStrategy logStrategy = [[[NSUserDefaults standardUserDefaults] objectForKey:kKeyUserDefaultsLogStrategy] intValue];
NSTimeInterval interval = [[NSUserDefaults standardUserDefaults] doubleForKey:kKeyUserDefaultsCustomInterval];
XCTAssertEqual(logStrategy, LogStrategyImmedi);
XCTAssertEqual(interval, 0);
NSLog(@"%@ end", self.name);
}
- (void)testUpdateLogStrategyMethodWithCustom {
NSLog(@"%@ start", self.name);
[analytics updateLogStrategy:LogStrategyCustom customInterval:100];
YHLogStrategy logStrategy = [[[NSUserDefaults standardUserDefaults] objectForKey:kKeyUserDefaultsLogStrategy] intValue];
NSTimeInterval interval = [[NSUserDefaults standardUserDefaults] doubleForKey:kKeyUserDefaultsCustomInterval];
XCTAssertEqual(logStrategy, LogStrategyCustom);
XCTAssertEqual(interval, 100);
NSLog(@"%@ end", self.name);
}
#pragma mark - Test Location Sevice
- (void)testLocationUpdateSuccess {
... ...
... ... @@ -40,7 +40,7 @@
- (void)testStartWithAppIdMethodWithConstraint {
NSLog(@"%@ start", self.name); // self.name is the name of the test-case method.
[[mock stub] startWithAppId:[OCMArg isKindOfClass:[NSString class]]];
[[mock expect] startWithAppId:[OCMArg isKindOfClass:[NSString class]]];
[mock startWithAppId:@"appId"];
NSLog(@"%@ end", self.name);
... ... @@ -49,7 +49,7 @@
- (void)testLogEventMethodWithConstraint {
NSLog(@"%@ start", self.name);
[[mock stub] logEvent:[OCMArg isKindOfClass:[NSString class]] parameters:[OCMArg isKindOfClass:[NSDictionary class]]];
[[mock expect] logEvent:[OCMArg isKindOfClass:[NSString class]] parameters:[OCMArg isKindOfClass:[NSDictionary class]]];
[mock logEvent:@"event" parameters:nil];
NSLog(@"%@ end", self.name);
... ... @@ -58,26 +58,72 @@
- (void)testLogErrorMethodWithConstraint {
NSLog(@"%@ start", self.name);
[[mock stub] logError:[OCMArg isKindOfClass:[NSString class]] parameters:[OCMArg isKindOfClass:[NSDictionary class]]];
[[mock expect] logError:[OCMArg isKindOfClass:[NSString class]] parameters:[OCMArg isKindOfClass:[NSDictionary class]]];
[mock logError:@"error" parameters:nil];
NSLog(@"%@ end", self.name);
}
- (void)testUpdateLogStrategyCustomIntervalMethod {
NSLog(@"%@ start", self.name);
[[mock expect] updateLogStrategy:LogStrategyCustom customInterval:1000];
[mock updateLogStrategy:LogStrategyCustom customInterval:1000];
NSLog(@"%@ end", self.name);
}
#pragma mark - Test Property
- (void)testUid {
NSLog(@"%@ start", self.name);
[[mock expect] uid];
[mock uid];
NSLog(@"%@ end", self.name);
}
- (void)testChannelId {
NSLog(@"%@ start", self.name);
[[mock expect] channelId];
[mock channelId];
NSLog(@"%@ end", self.name);
}
- (void)testLogStrategy {
NSLog(@"%@ start", self.name);
[[mock stub] logStrategy];
[[mock expect] logStrategy];
[mock logStrategy];
NSLog(@"%@ end", self.name);
}
- (void)testSetLogStrategyWithSpecificArgument {
- (void)testCurrentInterval {
NSLog(@"%@ start", self.name);
[[mock expect] currentInterval];
[mock currentInterval];
NSLog(@"%@ end", self.name);
}
- (void)testEvent {
NSLog(@"%@ start", self.name);
[[mock expect] event];
[mock event];
NSLog(@"%@ end", self.name);
}
- (void)testError {
NSLog(@"%@ start", self.name);
[[mock stub] setLogStrategy:LogStrategyAppLaunch];
[mock setLogStrategy:LogStrategyAppLaunch];
[[mock expect] error];
[mock error];
NSLog(@"%@ end", self.name);
}
... ...