Commit 0e425556 authored by 汪洋's avatar 汪洋

- 使用onPageStart与onPageEnd都替换为onPVStart,onPVEnd

- 优化onPageStart,让其真正有用
- PV参数使用协议,这样view也可以使用这些PV属性。例子:GMWelfarePopView
- selectedNavigationController的安全性,已经优化为visibleController
- 优化了referer的获取
- netStatus获取优化
- GMPhobosPV 优化
- GPS优化
- 精简了handlePVEventAppInForeground、handlePVEventAppInBackgound
- onPVStart真正变得有用途
- 添加catchNullInAttributes
parent 47af589f
......@@ -23,6 +23,7 @@
6003F5BC195388D20070C39A /* Tests.m in Sources */ = {isa = PBXBuildFile; fileRef = 6003F5BB195388D20070C39A /* Tests.m */; };
873B8AEB1B1F5CCA007FD442 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 873B8AEA1B1F5CCA007FD442 /* Main.storyboard */; };
9822812B60126E270C6B388F /* Pods_GMPhobos_Tests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E3D30FF32AFC059EC87D69DA /* Pods_GMPhobos_Tests.framework */; };
D3435C101E49662000A93ED8 /* GMPhobosController.m in Sources */ = {isa = PBXBuildFile; fileRef = D3435C0F1E49662000A93ED8 /* GMPhobosController.m */; };
E49977061C59F40000623ABA /* GMPhotoTest.m in Sources */ = {isa = PBXBuildFile; fileRef = E49977051C59F40000623ABA /* GMPhotoTest.m */; };
E4AF92C01C71C6C700CF0B64 /* GMPhobosUtilTest.m in Sources */ = {isa = PBXBuildFile; fileRef = E4AF92BF1C71C6C700CF0B64 /* GMPhobosUtilTest.m */; };
/* End PBXBuildFile section */
......@@ -65,6 +66,8 @@
606FC2411953D9B200FFA9A0 /* Tests-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Tests-Prefix.pch"; sourceTree = "<group>"; };
873B8AEA1B1F5CCA007FD442 /* Main.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = Main.storyboard; sourceTree = "<group>"; };
94F09197043C44CCA8756031 /* Pods-GMPhobos_Example.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-GMPhobos_Example.debug.xcconfig"; path = "Pods/Target Support Files/Pods-GMPhobos_Example/Pods-GMPhobos_Example.debug.xcconfig"; sourceTree = "<group>"; };
D3435C0E1E49662000A93ED8 /* GMPhobosController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GMPhobosController.h; sourceTree = "<group>"; };
D3435C0F1E49662000A93ED8 /* GMPhobosController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GMPhobosController.m; sourceTree = "<group>"; };
E2E7FEEA45FF5DF8941CEE34 /* LICENSE */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; name = LICENSE; path = ../LICENSE; sourceTree = "<group>"; };
E3D30FF32AFC059EC87D69DA /* Pods_GMPhobos_Tests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_GMPhobos_Tests.framework; sourceTree = BUILT_PRODUCTS_DIR; };
E49977051C59F40000623ABA /* GMPhotoTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GMPhotoTest.m; sourceTree = "<group>"; };
......@@ -164,6 +167,8 @@
children = (
E4AF92BF1C71C6C700CF0B64 /* GMPhobosUtilTest.m */,
E49977051C59F40000623ABA /* GMPhotoTest.m */,
D3435C0E1E49662000A93ED8 /* GMPhobosController.h */,
D3435C0F1E49662000A93ED8 /* GMPhobosController.m */,
6003F5BB195388D20070C39A /* Tests.m */,
6003F5B6195388D20070C39A /* Supporting Files */,
);
......@@ -252,7 +257,7 @@
isa = PBXProject;
attributes = {
CLASSPREFIX = GM;
LastUpgradeCheck = 0720;
LastUpgradeCheck = 0820;
ORGANIZATIONNAME = licong;
TargetAttributes = {
6003F589195388D20070C39A = {
......@@ -401,6 +406,7 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
D3435C101E49662000A93ED8 /* GMPhobosController.m in Sources */,
6003F59E195388D20070C39A /* GMAppDelegate.m in Sources */,
6003F5A7195388D20070C39A /* GMViewController.m in Sources */,
6003F59A195388D20070C39A /* main.m in Sources */,
......@@ -460,14 +466,19 @@
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_DYNAMIC_NO_PIC = NO;
GCC_NO_COMMON_BLOCKS = YES;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
......@@ -500,13 +511,18 @@
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = YES;
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
......
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0720"
LastUpgradeVersion = "0820"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
......
......@@ -7,7 +7,7 @@
//
#import "GMViewController.h"
//#import <GMPhobos/GMPhobos.h>
#import <GMPhobos/Phobos.h>
@interface GMViewController ()
......
......@@ -10,7 +10,7 @@ PODS:
- Masonry (= 1.0.1)
- SDWebImage (= 3.7.6)
- GMOCConstant (0.0.3)
- GMPhobos (0.2.25):
- GMPhobos (0.2.26):
- GMCache (~> 0.1.1)
- GMKit
- Masonry (1.0.1)
......@@ -32,7 +32,7 @@ SPEC CHECKSUMS:
GMFoundation: 08b2e6e12c211ed37aa5dce3588f645a133b9165
GMKit: 04a30d67c6b5468f07c8d9f60d0f8b12dd90b162
GMOCConstant: 39371248b4d8d54929391bfcd2c5883776436c4b
GMPhobos: 8ed65f89b1e814b3ca1cd3446e9a26599efec9ff
GMPhobos: 853ef8239bee6c908286c9cbb3d8b39fa1c70e97
Masonry: a1a931a0d08870ed8ae415a2ea5ea68ebcac77df
SDWebImage: c325cf02c30337336b95beff20a13df489ec0ec9
TMCache: 95ebcc9b3c7e90fb5fd8fc3036cba3aa781c9bed
......
{
"name": "GMPhobos",
"version": "0.2.25",
"version": "0.2.26",
"summary": "GM statistic data sdk",
"description": "GM event track sdk.",
"homepage": "http://git.gengmei.cc/gengmeiios/GMPhobos",
......@@ -10,7 +10,7 @@
},
"source": {
"git": "git@git.gengmei.cc:gengmeiios/GMPhobos.git",
"tag": "0.2.25"
"tag": "0.2.26"
},
"platforms": {
"ios": "8.0"
......
......@@ -10,7 +10,7 @@ PODS:
- Masonry (= 1.0.1)
- SDWebImage (= 3.7.6)
- GMOCConstant (0.0.3)
- GMPhobos (0.2.25):
- GMPhobos (0.2.26):
- GMCache (~> 0.1.1)
- GMKit
- Masonry (1.0.1)
......@@ -32,7 +32,7 @@ SPEC CHECKSUMS:
GMFoundation: 08b2e6e12c211ed37aa5dce3588f645a133b9165
GMKit: 04a30d67c6b5468f07c8d9f60d0f8b12dd90b162
GMOCConstant: 39371248b4d8d54929391bfcd2c5883776436c4b
GMPhobos: 8ed65f89b1e814b3ca1cd3446e9a26599efec9ff
GMPhobos: 853ef8239bee6c908286c9cbb3d8b39fa1c70e97
Masonry: a1a931a0d08870ed8ae415a2ea5ea68ebcac77df
SDWebImage: c325cf02c30337336b95beff20a13df489ec0ec9
TMCache: 95ebcc9b3c7e90fb5fd8fc3036cba3aa781c9bed
......
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -4,8 +4,9 @@
#import "Phobos.h"
#import "PhobosConfig.h"
#import "PhobosPVProtocol.h"
#import "PhobosUtil.h"
#import "UIViewController+Phobos.h"
#import "UIResponder+PhobosPV.h"
FOUNDATION_EXPORT double GMPhobosVersionNumber;
FOUNDATION_EXPORT const unsigned char GMPhobosVersionString[];
......
......@@ -15,7 +15,7 @@
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>0.2.25</string>
<string>0.2.26</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
......
......@@ -104,12 +104,12 @@ THE SOFTWARE.
</dict>
<dict>
<key>FooterText</key>
<string>Copyright (c) 2016 &#21271;&#20140;&#26356;&#32654;&#20114;&#21160;&#20449;&#24687;&#31185;&#25216;&#26377;&#38480;&#20844;&#21496;
<string>Copyright (c) 2016 北京更美互动信息科技有限公司
&#20165;&#38480;&#21271;&#20140;&#26356;&#32654;&#20114;&#21160;&#20449;&#24687;&#31185;&#25216;&#26377;&#38480;&#20844;&#21496;&#20869;&#37096;&#20351;&#29992;
仅限北京更美互动信息科技有限公司内部使用
</string>
<key>License</key>
<string>&#20165;&#38480;&#21271;&#20140;&#26356;&#32654;&#20114;&#21160;&#20449;&#24687;&#31185;&#25216;&#26377;&#38480;&#20844;&#21496;&#20869;&#37096;&#20351;&#29992;</string>
<string>仅限北京更美互动信息科技有限公司内部使用</string>
<key>Title</key>
<string>GMKit</string>
<key>Type</key>
......
//
// GMPhobosController.h
// GMPhobos
//
// Created by wangyang on 2017/2/7.
// Copyright © 2017年 licong. All rights reserved.
//
#import <UIKit/UIKit.h>
@import GMPhobos;
@interface GMPhobosController : UIViewController
@end
//
// GMPhobosController.m
// GMPhobos
//
// Created by wangyang on 2017/2/7.
// Copyright © 2017年 licong. All rights reserved.
//
#import "GMPhobosController.h"
@interface GMPhobosController ()
@end
@implementation GMPhobosController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
// 导航栏隐藏在 viewWillAppear 里控制的原因是在viewDidLoad时,有可能 navigationController 与 self 并没有关系
self.navigationController.navigationBarHidden = YES;
[[Phobos sharedClient] onPVStart:self];
}
- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
// 如果栈内的层级小于等于两个,取消隐藏下面的tabbar
if (self.navigationController.childViewControllers.count <= 2) {
[self setHidesBottomBarWhenPushed:NO];
}
if (self.pageName.length > 0) {
[[Phobos sharedClient] onPVEnd:self];
}
}
@end
......@@ -9,7 +9,7 @@
#import <XCTest/XCTest.h>
#import <GMPhobos/Phobos.h>
#import <GMCache/WMCacheService.h>
#import "GMPhobosController.h"
#define PhobosCacheKey @"PhobosCacheKey"
NSString *const MockAppName = @"gengmei_test";
......@@ -113,33 +113,39 @@ NSString *const MockCityId = @"beijing";
XCTAssertTrue([keys containsObject:@"params"], @"Missing params");
}
- (void)testOnPageStartThenOnPageEnd {
[_client onPageStart:nil businessId:nil referer:nil];
NSDictionary *pageEnterParam1 = [_client valueForKey:@"_pageEnterParam"];
XCTAssertTrue(pageEnterParam1 != nil, @"pageEnterParam 应该实例化成功");
XCTAssertTrue(pageEnterParam1.allKeys.count == 4, @"pageEnterParam 应该有4个key");
[_client onPageStart:@"aaa" businessId:@"adf" referer:nil];
NSDictionary *pageEnterParam2 = [_client valueForKey:@"_pageEnterParam"];
XCTAssertTrue(pageEnterParam2 != nil, @"pageEnterParam 应该实例化成功");
XCTAssertTrue(pageEnterParam2.allKeys.count == 4, @"pageEnterParam 应该有4个key");
[_client onPageEnd];
[self paramUnNilCheck];
- (void)testCatchNullInAttributes {
_client.captureNullExpection = ^(NSDictionary *att) {
NSCAssert([att[@"bussness_id"] integerValue] == 1244, @"testCatchNullInAttributes 没有捕获到有用信息");
};
NSDictionary *attributes = @{@"key": [NSNull null],
@"bussness_id": @1244};
[Phobos track:@"testCatchNullInAttributes" attributes:attributes];
}
NSDictionary *pageEnterParam3 = [_client valueForKey:@"_pageEnterParam"];
XCTAssertTrue(pageEnterParam3.allKeys.count == 0, @"pageEnterParam 应该在onPageEnd后为空的");
// 某种情况下没有先走 onPageStart,只走了OnPageEnd,此时数据应该完整,某个key对应的value可以是空
- (void)testOnPageStart {
GMPhobosController *controller = [GMPhobosController new];
controller.pageName = @"pageNameTest";
controller.businessId = @"businessIdTest";
controller.referrerId = @"rreferrerIdTest";
[controller viewWillAppear:true];
XCTAssertTrue(controller.inTime.integerValue > 0, "inTime 应该有值");
}
// 某种情况下没有先走 onPageStart,只走了OnPageEnd,此时数据应该完整,某个key对应的value可以是空
- (void)testOnPageEnd {
[_client setValue:nil forKey:@"_pageEnterParam"];
[_client onPageEnd];
GMPhobosController *controller = [GMPhobosController new];
controller.pageName = @"pageNameTest";
controller.businessId = @"businessIdTest";
controller.referrerId = @"rreferrerIdTest";
[controller viewWillAppear:true];
[controller viewWillDisappear:true];
[self paramUnNilCheck];
}
- (void)testSimulativePageViewEvent {
[_client simulativePageViewEventWithPageName:nil BusinessId:nil referer:nil];
[_client simulativePV:nil businessId:nil referer:nil];
[self paramUnNilCheck];
}
......@@ -148,9 +154,24 @@ NSString *const MockCityId = @"beijing";
XCTAssertTrue(array.count != 0, @"PhobosCacheKey 下面应该有数据");
NSDictionary *dic = array[0][@"params"];
XCTAssertTrue(dic[@"page_name"] != nil, @"page_name至少使用默认的空字符串");
XCTAssertTrue(dic[@"referer"] != nil, @"referer至少使用默认的空字符串");
XCTAssertTrue([dic[@"referer"] integerValue] >= 0, @"referer至少使用默认的空字符串");
XCTAssertTrue(dic[@"business_id"] != nil, @"business_id至少使用默认的空字符串");
}
#pragma mark - 属性test
- (void)testNeedLogPV {
UIViewController *controller = [UIViewController new];
XCTAssertTrue(controller.needLogPV, @"needLogPV应该默认为YES");
controller.needLogPV = NO;
XCTAssertFalse(controller.needLogPV, @"needLogPV赋值为NO时应该NO");
}
#pragma mark - 其它方法test
- (void)testVisibleController {
}
@end
......@@ -7,16 +7,11 @@
//
#import <Foundation/Foundation.h>
#import "PhobosPVProtocol.h"
#import <CoreLocation/CLLocation.h>
@interface Phobos : NSObject
@property (strong, nonatomic) UINavigationController *selectedNavigationController;
/**
网络状态
*/
@property (nonatomic, copy) NSString *netStatus;
/**
* @brief 开启Phobos统计,默认以BATCH方式发送log.
*
......@@ -34,6 +29,17 @@
+ (void)setSharedClient:(Phobos *)client;
#pragma mark - SDK配置
// Phobos在处理业务端传递来的参数时会检查是否某个value为空,如果为空会调用这个block以通知业务层,业务层可以上报这个异常,以助解决问题
@property(nonatomic, copy) void (^captureNullExpection) (NSDictionary *info);
/**
网络状态 wifi=1, mobile=0, 不连通=-1
*/
@property (nonatomic, copy) NSString *netStatus;
/**
* @brief 设置是否打印sdk的log信息,默认不开启
*
......@@ -41,7 +47,7 @@
*
* @since 0.0.1
*/
- (void)setLogEnabled:(BOOL)value;
@property (assign, nonatomic) BOOL logEnabled;
/**
* @brief 设置当前登录用户的ID,如果没有默认为@""
......@@ -50,7 +56,7 @@
*
* @since 0.0.2
*/
- (void)setUserId:(NSInteger)userId;
@property (assign, nonatomic) NSInteger userId;
/*!
* @author zhaiguojun, 16-05-31
......@@ -61,9 +67,11 @@
*
* @since 0.2.7
*/
- (void)setCurrentCityId:(NSString *)currentCityId;
@property (strong, nonatomic) NSString *currentCityId;
- (void)setGPS:(NSDictionary *)gps;
@property (strong, nonatomic) CLLocation *gps;
#pragma mark - 事件采集
/**
* @brief 自定义事件,数量统计.
......@@ -77,6 +85,7 @@
+ (void)track:(NSString *)eventId attributes:(NSDictionary *)attributes;
+ (void)track:(NSString *)eventId attributes:(NSDictionary *)attributes sendNow:(BOOL)sendNow;
+ (void)track:(NSString *)eventId;
/**
* @author 翟国钧, 16-02-03 16:02:30
*
......@@ -89,22 +98,13 @@
+ (void)trackJsEvent:(NSString *)jsonString;
/**
* @brief 当页面加载时的PV处理
*
* @param pageName 页面唯一编码
* @param businessId 页面中的业务ID,比如美购详情页美购ID
* @param refererPageName 目标页面的上一个页面的pageName
*
* @since 0.0.8
* @brief PV事件开始。当controller viewWillAppear时调用
*/
- (void)onPageStart:(NSString *)pageName businessId:(NSString *)businessId referer:(NSString *)refererPageName inTime:(NSString *)time;
- (void)onPVStart:(UIResponder<PhobosPVProtocol> *)page;
/**
* @brief 当页面结束时的PV处理,在此方法中记录当前页面的停留时间和记录本次埋点事件
*
* @since 0.0.8
* @brief PV事件结束。当controller viewWillDisAppear时调用
*/
- (void)onPageEnd:(NSString *)pageName businessId:(NSString *)businessId referer:(NSString *)refererPageName inTime:(NSString *)time referrerId: (NSString *)referrerId;
- (void)onPVEnd:(UIResponder<PhobosPVProtocol> *)page;
/**
* @author 翟国钧, 16-03-08 11:03:45
......@@ -117,6 +117,6 @@
*
* @since 5.9.1
*/
- (void)simulativePageViewEventWithPageName:(NSString *)pageName BusinessId:(NSString *)bid referer:(NSString *)referer;
- (void)simulativePV:(NSString *)pageName businessId:(NSString *)bid referer:(NSString *)referer;
@end
......@@ -11,24 +11,20 @@
#import <AdSupport/AdSupport.h>
#import "PhobosUtil.h"
#import "PhobosConfig.h"
#import "UIViewController+Phobos.h"
#import "UIResponder+PhobosPV.h"
#import "UIDevice+Resolutions.h"
#import "PhobosUtil.h"
static Phobos *sharedClient = nil;
static NSString *sdkVersion = @"110";
@interface Phobos ()
@property (strong, nonatomic) UIViewController *visibleController;
@property (strong, nonatomic) NSDateFormatter *dateFormatter;
@property (strong, nonatomic) NSString *appName;
@property (strong, nonatomic) NSString *channelId;
@property (strong, nonatomic) NSString *currentCityId;
@property (strong, nonatomic) NSString *appVersion;
@property (assign, nonatomic) NSInteger userId;
@property (assign, nonatomic) BOOL logEnabled;
@property (strong, nonatomic) NSString *sessionId;
@property (strong, nonatomic) NSString *lng;
@property (strong, nonatomic) NSString *lat;
@end
......@@ -54,11 +50,9 @@ static NSString *sdkVersion = @"110";
_channelId = channelId;
_logEnabled = NO;
_userId = 0;
_lat = @"";
_lng = @"";
_netStatus = @"";
_currentCityId = @"";
_appVersion = [self getAppVersion];
_appVersion = [PhobosUtil getAppVersion];
[self setupNotification];
[self handleSessionStart];
......@@ -67,27 +61,9 @@ static NSString *sdkVersion = @"110";
return self;
}
- (void)setLogEnabled:(BOOL)value{
_logEnabled = value;
}
- (void)setUserId:(NSInteger)userId{
_userId = userId;
}
- (void)setCurrentCityId:(NSString *)currentCityId
{
_currentCityId = currentCityId;
}
- (void)setGPS:(NSDictionary *)gps {
@try {
NSString *lng = gps[@"lng"];
NSString *lat = gps[@"lat"];
_lng = lng;
_lat = lat;
} @catch (NSException *exception) {
phobosLog(exception);
- (void)dealloc{
if (self) {
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
}
......@@ -105,17 +81,20 @@ static NSString *sdkVersion = @"110";
}
}
- (UINavigationController *)selectedNavigationController{
if ([[UIApplication sharedApplication].keyWindow.rootViewController isKindOfClass:[UITabBarController class]]) {
UITabBarController *tabbar = (UITabBarController *)[UIApplication sharedApplication].keyWindow.rootViewController;
- (UIViewController *)visibleController {
id visibleController = [UIApplication sharedApplication].keyWindow.rootViewController;
if ([visibleController isKindOfClass:[UITabBarController class]]) {
UITabBarController *tabbar = (UITabBarController *)visibleController;
UINavigationController *navigationController = (UINavigationController *)tabbar.selectedViewController;
return navigationController;
}else{
return nil;
return navigationController.visibleViewController;
} else if ([visibleController isKindOfClass:[UINavigationController class]]) {
UINavigationController *navigationController = (UINavigationController *)visibleController;
return navigationController.visibleViewController;
} else {
return visibleController;
}
}
#pragma mark - notification handler
/**
* @brief 设置对APP的通知监听
......@@ -137,7 +116,7 @@ static NSString *sdkVersion = @"110";
- (void)handleSessionStart{
_sessionId = [[NSUUID UUID] UUIDString];
WMCacheService *cache = [WMCacheService sharedInstance];
[cache storeObjectAtDiskWithkey:PhobosBeginTime object:[self currentTime]];
[cache storeObjectAtDiskWithkey:PhobosBeginTime object:[PhobosUtil currentTime]];
}
/**
......@@ -205,11 +184,9 @@ static NSString *sdkVersion = @"110";
@author zhaiguojun 16-10-11 in (null)
*/
- (void)handlePVEventAppInForeground {
NSString *pageName = self.selectedNavigationController.visibleViewController.pageName;
NSString *businessId = self.selectedNavigationController.visibleViewController.businessId;
NSString *regerer = self.selectedNavigationController.visibleViewController.referer;
self.selectedNavigationController.visibleViewController.inTime = [self currentTime];
[self onPageStart:pageName businessId:businessId referer:regerer inTime:[self currentTime]];
if (self.visibleController != nil) {
[self onPVStart:self.visibleController];
}
}
/**
......@@ -217,16 +194,12 @@ static NSString *sdkVersion = @"110";
@author zhaiguojun 16-10-11 in (null)
*/
- (void)handlePVEventAppInBackgound {
NSString *pageName = self.selectedNavigationController.visibleViewController.pageName;
NSString *businessId = self.selectedNavigationController.visibleViewController.businessId;
NSString *referer = self.selectedNavigationController.visibleViewController.referer;
NSString *inTime = self.selectedNavigationController.visibleViewController.inTime;
NSString *referrerId = self.selectedNavigationController.visibleViewController.referrerId;
[self onPageEnd:pageName businessId:businessId referer:referer inTime:inTime referrerId:referrerId];
if (self.visibleController != nil) {
[self onPVEnd:self.visibleController];
}
}
#pragma mark - track event handler
#pragma mark - track event handler
+ (void)track:(NSString *)eventId{
[Phobos track:eventId attributes:@{}];
}
......@@ -274,26 +247,27 @@ static NSString *sdkVersion = @"110";
}
}
#pragma mark - pv
- (void)onPageStart:(NSString *)pageName businessId:(NSString *)businessId referer:(NSString *)refererPageName inTime:(NSString *)time{
//目前来说,变成了空方法,其主要功能是给当前VC的属性赋值,下个版本优化,挪到UIViewController+Phobos里去
#pragma mark - PV
- (void)onPVStart:(UIResponder<PhobosPVProtocol> *)page {
// 必须在此处调用一下referer,因为onControllerStart
[page initReferer];
page.inTime = [PhobosUtil currentTime];
}
- (void)onPageEnd:(NSString *)pageName businessId:(NSString *)businessId referer:(NSString *)refererPageName inTime:(NSString *)time referrerId: (NSString *)referrerId {
if (![self isNonEmpty:pageName]) {
- (void)onPVEnd:(UIResponder<PhobosPVProtocol> *)page {
if (![PhobosUtil isNonEmpty:page.pageName] || !page.needLogPV) {
return;
}
NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
@try {
[dict setObject:[self currentTime] forKey:@"out"];
[dict setObject:time?:@"" forKey:@"in"];
[dict setObject:pageName forKey:@"page_name"];
[dict setObject:businessId?:@"" forKey:@"business_id"];
[dict setObject:refererPageName?:@"" forKey:@"referer"];
[dict setObject:[PhobosUtil currentTime] forKey:@"out"];
[dict setObject:page.inTime?:@"" forKey:@"in"];
[dict setObject:page.pageName forKey:@"page_name"];
[dict setObject:page.businessId?:@"" forKey:@"business_id"];
[dict setObject:page.referer?:@"" forKey:@"referer"];
[dict setObject:@(0) forKey:@"fake"];
[dict setObject:referrerId ? : @"" forKey:@"referrer_id"];
[dict setObject:page.referrerId ? : @"" forKey:@"referrer_id"];
[Phobos track:@"page_view" attributes:dict];
}
@catch (NSException *exception) {
......@@ -301,11 +275,12 @@ static NSString *sdkVersion = @"110";
}
}
- (void)simulativePageViewEventWithPageName:(NSString *)pageName BusinessId:(NSString *)bid referer:(NSString *)referer{
- (void)simulativePV:(NSString *)pageName businessId:(NSString *)bid referer:(NSString *)referer{
NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
@try {
[dict setObject:[self currentTime] forKey:@"in"];
[dict setObject:[self currentTime] forKey:@"out"];
// fake(模拟)的事件,所以in与out一样,就是这么规定的
[dict setObject:[PhobosUtil currentTime] forKey:@"in"];
[dict setObject:[PhobosUtil currentTime] forKey:@"out"];
[dict setObject:pageName?:@"" forKey:@"page_name"];
[dict setObject:bid?:@"" forKey:@"business_id"];
[dict setObject:referer?:@"" forKey:@"referer"];
......@@ -318,6 +293,9 @@ static NSString *sdkVersion = @"110";
}
}
#pragma mark - 事件存储、发送
/**
* @brief 将埋点时间封装成词典数据
*
......@@ -326,17 +304,18 @@ static NSString *sdkVersion = @"110";
* @since 0.0.1
*/
- (NSDictionary *)prepareDictionaryForEvent:(NSString *)eventId attributes:(NSDictionary *)attributes{
[self performSelectorInBackground:@selector(catchNullInAttributes:) withObject:attributes];
NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
@try {
NSString *currentTime = [self currentTime];
NSString *currentTime = [PhobosUtil currentTime];
NSMutableDictionary *deviceParams = [NSMutableDictionary dictionaryWithObjectsAndKeys:
[[[ASIdentifierManager sharedManager] advertisingIdentifier] UUIDString],@"idfa",
[[[UIDevice currentDevice] identifierForVendor] UUIDString],@"idfv",
[UIDevice deviceId],@"device_id",
@"ios",@"device_type",
@"Apple",@"manufacturer",
_lat,@"lat",
_lng,@"lng",
@(self.gps.coordinate.latitude),@"lat",
@(self.gps.coordinate.longitude),@"lng",
_netStatus,@"is_WiFi",nil];
NSMutableDictionary *appParams = [NSMutableDictionary dictionaryWithObjectsAndKeys:
self.appName, @"name",
......@@ -404,7 +383,7 @@ static NSString *sdkVersion = @"110";
phobosLog([NSString stringWithFormat:@"array prepare to fly --✈: %@",array]);
}
@try {
NSData *JSON = [self encodeJSON:array];
NSData *JSON = [PhobosUtil encodeJSON:array];
NSData *compressedData = [PhobosUtil compressData:JSON];
if (compressedData) {
[PhobosUtil sendData:compressedData success:^(NSInteger code) {
......@@ -421,68 +400,18 @@ static NSString *sdkVersion = @"110";
}
#pragma mark - helpers
/**
* @brief 将对象转成JSON格式数据
*
* @param obj
*
* @return
*
* @since 0.0.1
*/
- (NSData *)encodeJSON:(id)obj {
NSData *data = [NSJSONSerialization dataWithJSONObject:obj options:0 error:nil];
return data;
}
/**
* @brief 获取当前时间的毫秒数
*
* @return
*
* @since 0.0.1
*/
- (NSString *)currentTime {
NSDate *date = [NSDate date];
NSTimeInterval interval = [date timeIntervalSince1970];
NSString *timeIntervalStr = [NSString stringWithFormat:@"%ld",(long)interval];
return timeIntervalStr;
}
/**
* @brief 获取当前APP的版本号
*
* @return
*
* @since 0.0.1
*/
- (NSString *)getAppVersion{
NSString *buildVersion = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleShortVersionString"];
if (buildVersion) {
return buildVersion;
}else{
return @"";
}
}
- (BOOL)isNonEmpty:(NSString *)string {
if (!string) {
return NO;
}
NSMutableCharacterSet *emptyStringSet = [[NSMutableCharacterSet alloc] init];
[emptyStringSet formUnionWithCharacterSet: [NSCharacterSet whitespaceAndNewlineCharacterSet]];
[emptyStringSet formUnionWithCharacterSet: [NSCharacterSet characterSetWithCharactersInString: @" "]];
if ([string length] == 0) {
return NO;
}
NSString* str = [string stringByTrimmingCharactersInSet:emptyStringSet];
return [str length] > 0;
}
- (void)catchNullInAttributes:(NSDictionary *)attributes {
@try {
for (NSString *key in attributes.allKeys) {
if ([attributes[key] isMemberOfClass:[NSNull class]]) {
if (self.captureNullExpection) {
self.captureNullExpection(attributes);
}
break;
}
}
} @catch (NSException *exception) {
- (void)dealloc{
if (self) {
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
}
......
//
// UIViewController+Phobos.h
// PhobosPVProtocol.h
// Pods
//
// Created by wangyang on 16/7/12.
// Created by wangyang on 2017/2/7.
//
//
#import <UIKit/UIKit.h>
@interface UIViewController (Phobos)
#import <Foundation/Foundation.h>
@protocol PhobosPVProtocol <NSObject>
/**
* @author 翟国钧, 16-02-24 17:02:22
......@@ -21,31 +20,38 @@
@property (nonatomic, copy, nonnull) NSString *businessId;
/**
* @author 翟国钧 in 16-02-25 19:02:32
*
* @brief 获取前一个页面的pageName
* @author 翟国钧 in 16-02-25 19:02:32
*
* 埋点pv事件中当前页面的别名
* @since 5.9.1
*/
@property (nonatomic, copy, nonnull) NSString *referer;
@property (nonatomic, copy, nonnull) NSString *pageName;
/**
* @author 翟国钧 in 16-02-25 19:02:32
* @author 翟国钧 in 16-02-25 19:02:32
*
* @brief 获取前一个页面的pageName。
* 只读,以后如果业务涉及到referer的set方法,那么再升级Phobos,此时先不做过多考虑 by wangyang at 2017-2-7
*
* 埋点pv事件中当前页面的别名
* @since 5.9.1
*/
@property (nonatomic, copy, nonnull) NSString *pageName;
@property (nonatomic, readonly, nonnull) NSString *referer;
/**
当前VC.view 显示的时候的时间戳
@author zhaiguojun 16-10-12 in (null)
@author zhaiguojun 16-10-12
*/
@property (nonatomic, copy, nonnull) NSString *inTime;
/**
hu
前一个页面的businessId。该属性有可能为空字符串
*/
@property (nonatomic, copy, nonnull) NSString *referrerId;
/**
controller是否需要记录pv事件,默认为YES。
controller作为childController时,需要设置childController.needLogPV = NO,以防止影响containerController的pv事件
*/
@property(nonatomic, assign) BOOL needLogPV;
@end
......@@ -32,4 +32,8 @@ typedef void (^SendDataSuccessBlock)(NSInteger code);
*/
+ (void)sendData:(NSData *)data success:(SendDataSuccessBlock)success;
+ (NSString *)currentTime;
+ (NSString *)getAppVersion;
+ (BOOL)isNonEmpty:(NSString *)string;
+ (NSData *)encodeJSON:(id)obj;
@end
......@@ -122,4 +122,64 @@
}
}
/**
* @brief 将对象转成JSON格式数据
*
* @param obj
*
* @return
*
* @since 0.0.1
*/
+ (NSData *)encodeJSON:(id)obj {
NSData *data = [NSJSONSerialization dataWithJSONObject:obj options:0 error:nil];
return data;
}
/**
* @brief 获取当前时间的毫秒数
*
* @return
*
* @since 0.0.1
*/
+ (NSString *)currentTime {
NSDate *date = [NSDate date];
NSTimeInterval interval = [date timeIntervalSince1970];
NSString *timeIntervalStr = [NSString stringWithFormat:@"%ld",(long)interval];
return timeIntervalStr;
}
/**
* @brief 获取当前APP的版本号
*
* @return
*
* @since 0.0.1
*/
+ (NSString *)getAppVersion {
NSString *buildVersion = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleShortVersionString"];
if (buildVersion) {
return buildVersion;
}else{
return @"";
}
}
+ (BOOL)isNonEmpty:(NSString *)string {
if (!string) {
return NO;
}
NSMutableCharacterSet *emptyStringSet = [[NSMutableCharacterSet alloc] init];
[emptyStringSet formUnionWithCharacterSet: [NSCharacterSet whitespaceAndNewlineCharacterSet]];
[emptyStringSet formUnionWithCharacterSet: [NSCharacterSet characterSetWithCharactersInString: @" "]];
if ([string length] == 0) {
return NO;
}
NSString* str = [string stringByTrimmingCharactersInSet:emptyStringSet];
return [str length] > 0;
}
@end
//
// UIResponder+PhobosPV.h
// Pods
//
// Created by wangyang on 2017/2/7.
//
//
#import <UIKit/UIKit.h>
#import "PhobosPVProtocol.h"
@interface UIResponder (PhobosPV) <PhobosPVProtocol>
- (void)initReferer;
@end
//
// UIViewController+Phobos.m
// UIResponder+PhobosPV.m
// Pods
//
// Created by wangyang on 16/7/12.
// Created by wangyang on 2017/2/7.
//
//
#import "UIViewController+Phobos.h"
#import "UIResponder+PhobosPV.h"
#import <objc/runtime.h>
#import "PhobosUtil.h"
@implementation UIResponder (PhobosPV)
@implementation UIViewController (Phobos)
/**
* @author 翟国钧, 16-03-01 15:03:24
*
......@@ -19,15 +21,18 @@
*
* @since 5.9.1
*/
- (void)setReferer:(NSString *)referer {
NSArray *navigationPool = self.navigationController.viewControllers;
NSInteger refererIndex = navigationPool.count - 2;
if (refererIndex < 0 ) {
return ;
- (void)initReferer {
if ([self isKindOfClass:[UIViewController class]]) {
NSArray *navigationPool = ((UIViewController *)self).navigationController.viewControllers;
NSInteger refererIndex = navigationPool.count - 2;
if (refererIndex < 0 ) {
return ;
}
UIViewController *controller = navigationPool[refererIndex];
objc_setAssociatedObject(self, @selector(referer), controller.pageName, OBJC_ASSOCIATION_COPY);
} else {
objc_setAssociatedObject(self, @selector(referer), @"", OBJC_ASSOCIATION_COPY);
}
UIViewController *controller = navigationPool[refererIndex];
objc_setAssociatedObject(self, @selector(referer), controller.pageName, OBJC_ASSOCIATION_COPY);
}
- (NSString *)referer
......@@ -60,7 +65,7 @@
/**
这个地方inTime的值为nil的情况不做考虑,因为Phobos不会发送
这个地方inTime的值为nil的情况不做考虑,因为Phobos不会发送。inTime必须在controller viewWillAppear时赋值
*/
- (NSString *)inTime {
NSString *inTime = objc_getAssociatedObject(self, @selector(inTime));
......@@ -75,4 +80,13 @@
NSString *referrerId = objc_getAssociatedObject(self, @selector(referrerId));
return referrerId == nil ? @"" : referrerId;
}
- (BOOL)needLogPV {
NSNumber *needLogPV = objc_getAssociatedObject(self, @selector(needLogPV));
return needLogPV == nil ? YES : needLogPV.boolValue;
}
- (void)setNeedLogPV:(BOOL)needLogPV {
objc_setAssociatedObject(self, @selector(needLogPV), @(needLogPV), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
@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