Skip to content

Commit

Permalink
Release 1.1.0
Browse files Browse the repository at this point in the history
  • Loading branch information
yaoyue committed Jan 3, 2025
1 parent 8b07b83 commit 6036ece
Show file tree
Hide file tree
Showing 14 changed files with 196 additions and 57 deletions.
11 changes: 8 additions & 3 deletions Example/Example-iOS/AppDelegate.m
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,10 @@
#import <SensorsABTest.h>

/// 测试环境,获取试验地址
static NSString* kSABResultsTestURL = @"http://10.1.131.245:8202/api/v2/abtest/online/results?project-key=D9493739E8353F0917275C992F0C605A31D120AB";
static NSString* kSABResultsTestURL = @"http://10.1.132.85:8202/api/v2/abtest/online/results?project-key=CDF5B1BE9CDCBEB289EA0589066A263D741742BD";

// 测试环境,数据接收地址
static NSString* kSABTestServerURL = @"http://10.1.137.85:8106/sa?project=default";
static NSString* kSABTestServerURL = @"http://10.1.132.86:8106/sa?project=default";

@interface AppDelegate ()

Expand All @@ -48,7 +48,7 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(
- (void)startSensorsAnalyticsSDKWithConfigOptions:(NSDictionary *)launchOptions {
SAConfigOptions *options = [[SAConfigOptions alloc] initWithServerURL:kSABTestServerURL launchOptions:launchOptions];
// options.autoTrackEventType = SensorsAnalyticsEventTypeAppStart | SensorsAnalyticsEventTypeAppEnd | SensorsAnalyticsEventTypeAppClick | SensorsAnalyticsEventTypeAppViewScreen;
options.autoTrackEventType = SensorsAnalyticsEventTypeAppStart | SensorsAnalyticsEventTypeAppEnd | SensorsAnalyticsEventTypeAppViewScreen;
// options.autoTrackEventType = SensorsAnalyticsEventTypeAppStart | SensorsAnalyticsEventTypeAppEnd | SensorsAnalyticsEventTypeAppViewScreen;

options.enableHeatMap = YES;
options.enableVisualizedAutoTrack = YES;
Expand All @@ -60,10 +60,15 @@ - (void)startSensorsAnalyticsSDKWithConfigOptions:(NSDictionary *)launchOptions

[SensorsAnalyticsSDK startWithConfigOptions:options];

// [SensorsAnalyticsSDK.sharedInstance identify:@"cqs_identify_20241230001"];

[[SensorsAnalyticsSDK sharedInstance] track:@"test_track" withProperties:@{@"city": @"beijing"}];

}

- (void)startSensorsABTest {
SensorsABTestConfigOptions *abtestConfigOptions = [[SensorsABTestConfigOptions alloc] initWithURL:kSABResultsTestURL];
// abtestConfigOptions.customProperties = @{@"ab_city": @"beijing"};
[SensorsABTest startWithConfigOptions:abtestConfigOptions];

// [SensorsABTest.sharedInstance setCustomIDs:@{@"custom_subject_id":@"iOS自定义主体333"}];
Expand Down
88 changes: 55 additions & 33 deletions Example/Example-iOS/Base.lproj/Main.storyboard

Large diffs are not rendered by default.

26 changes: 19 additions & 7 deletions Example/Example-iOS/ViewController.m
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,8 @@ - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath
break;

case 2: { // STRING
id result = [[SensorsABTest sharedInstance] fetchCacheABTestWithParamName:@"hef_tes" defaultValue:@"默认值字符串"];
NSLog(@"fetchCacheABTest,paramName:%@ - result:%@\n", @"hef_tes", result);
id result = [[SensorsABTest sharedInstance] fetchCacheABTestWithParamName:@"shiyan1" defaultValue:@"默认值字符串"];
NSLog(@"fetchCacheABTest,paramName:%@ - result:%@\n", @"shiyan1", result);
}
break;

Expand Down Expand Up @@ -137,8 +137,8 @@ - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath
break;

case 2: { // STRING
[[SensorsABTest sharedInstance] fastFetchABTestWithParamName:@"color2" defaultValue:@"默认值字符串" completionHandler:^(id _Nullable result) {
NSLog(@"fastFetchABTest,paramName:%@ - result:%@\n", @"color2", result);
[[SensorsABTest sharedInstance] fastFetchABTestWithParamName:@"shiyan1" defaultValue:@"默认值字符串" completionHandler:^(id _Nullable result) {
NSLog(@"fastFetchABTest,paramName:%@ - result:%@\n", @"shiyan1", result);
}];
}
break;
Expand Down Expand Up @@ -174,12 +174,24 @@ - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath
}
break;
case 3: { // 自定义属性试验
SensorsABTestExperiment *experiment = [[SensorsABTestExperiment alloc] initWithParamName:@"cqs_device" defaultValue:@"设备默认值"];
experiment.properties = @{@"device": @"iPhone"};
SensorsABTestExperiment *experiment = [[SensorsABTestExperiment alloc] initWithParamName:@"shiyan1" defaultValue:@"设备默认值"];
// experiment.properties = @{@"device": @"iPhone"};
experiment.properties = @{@"ab_city": @"beijing002", @"ab_lv": @"iPhone"};
[[SensorsABTest sharedInstance] fastFetchABTestWithExperiment:experiment completionHandler:^(id _Nullable result) {

NSLog(@"fastFetchABTestWithExperiment,自定义属性 device 试验,paramName:%@ - result:%@\n", @"cqs_device", result);
NSLog(@"fastFetchABTestWithExperiment,自定义属性 shiyan1 试验,paramName:%@ - result:%@\n", @"shiyan1", result);
}];
// [[SensorsABTest sharedInstance] asyncFetchABTestWithExperiment:experiment completionHandler:^(id _Nullable result) {
//
// NSLog(@"asyncFetchABTestWithExperiment,自定义属性 shiyan1 试验,paramName:%@ - result:%@\n", @"shiyan1", result);
//
// }];

}
break;
case 4: { // 重置自定义属性
[SensorsABTest.sharedInstance setCustomProperties:@{@"ab_city": @"beijing"}];

}
break;
default:
Expand Down
8 changes: 4 additions & 4 deletions SensorsABTest.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@
4D6ED41225303900002ACB41 /* SABUtilsTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 4D6ED41125303900002ACB41 /* SABUtilsTests.m */; };
4D73D61C254BC6110020E711 /* SABNetwork.m in Sources */ = {isa = PBXBuildFile; fileRef = 4D73D5FA254BC6100020E711 /* SABNetwork.m */; };
4D73D61D254BC6110020E711 /* SABNetwork.h in Headers */ = {isa = PBXBuildFile; fileRef = 4D73D5FB254BC6100020E711 /* SABNetwork.h */; };
4D73D61E254BC6110020E711 /* SensorsABTest.h in Headers */ = {isa = PBXBuildFile; fileRef = 4D73D5FC254BC6100020E711 /* SensorsABTest.h */; settings = {ATTRIBUTES = (Public, ); }; };
4D73D61F254BC6110020E711 /* SABRequest.h in Headers */ = {isa = PBXBuildFile; fileRef = 4D73D5FD254BC6100020E711 /* SABRequest.h */; };
4D73D620254BC6110020E711 /* SABRequest.m in Sources */ = {isa = PBXBuildFile; fileRef = 4D73D5FE254BC6100020E711 /* SABRequest.m */; };
4D73D621254BC6110020E711 /* SABManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 4D73D5FF254BC6100020E711 /* SABManager.h */; };
Expand Down Expand Up @@ -53,6 +52,7 @@
4D73D639254BC6110020E711 /* NSString+SABHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = 4D73D61A254BC6110020E711 /* NSString+SABHelper.m */; };
4D73D63A254BC6110020E711 /* SABJSONUtils.m in Sources */ = {isa = PBXBuildFile; fileRef = 4D73D61B254BC6110020E711 /* SABJSONUtils.m */; };
4D9E708A2539793900DE11D6 /* 数据格式说明.md in Resources */ = {isa = PBXBuildFile; fileRef = 4D9E70892539793900DE11D6 /* 数据格式说明.md */; };
4DD58CFD2D1D3D08005BE4F8 /* SensorsABTest.h in Headers */ = {isa = PBXBuildFile; fileRef = 4DD58CFC2D1D3D08005BE4F8 /* SensorsABTest.h */; };
4DE5FBCA258C4B3B00F0E18A /* ABTestTests_result.json in Resources */ = {isa = PBXBuildFile; fileRef = 4DE5FBC9258C4B3B00F0E18A /* ABTestTests_result.json */; };
4DE5FBD2258C508B00F0E18A /* SABFetchResultResponseTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 4DE5FBD1258C508B00F0E18A /* SABFetchResultResponseTests.m */; };
4DFCBB0827699ED600257689 /* SABFileStorePlugin.h in Headers */ = {isa = PBXBuildFile; fileRef = 4DFCBB0427699ED600257689 /* SABFileStorePlugin.h */; };
Expand Down Expand Up @@ -99,7 +99,6 @@
4D6ED41125303900002ACB41 /* SABUtilsTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SABUtilsTests.m; sourceTree = "<group>"; };
4D73D5FA254BC6100020E711 /* SABNetwork.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SABNetwork.m; sourceTree = "<group>"; };
4D73D5FB254BC6100020E711 /* SABNetwork.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SABNetwork.h; sourceTree = "<group>"; };
4D73D5FC254BC6100020E711 /* SensorsABTest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SensorsABTest.h; sourceTree = "<group>"; };
4D73D5FD254BC6100020E711 /* SABRequest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SABRequest.h; sourceTree = "<group>"; };
4D73D5FE254BC6100020E711 /* SABRequest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SABRequest.m; sourceTree = "<group>"; };
4D73D5FF254BC6100020E711 /* SABManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SABManager.h; sourceTree = "<group>"; };
Expand Down Expand Up @@ -127,6 +126,7 @@
4D73D61A254BC6110020E711 /* NSString+SABHelper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSString+SABHelper.m"; sourceTree = "<group>"; };
4D73D61B254BC6110020E711 /* SABJSONUtils.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SABJSONUtils.m; sourceTree = "<group>"; };
4D9E70892539793900DE11D6 /* 数据格式说明.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = "数据格式说明.md"; sourceTree = "<group>"; };
4DD58CFC2D1D3D08005BE4F8 /* SensorsABTest.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SensorsABTest.h; sourceTree = "<group>"; };
4DE5FBC9258C4B3B00F0E18A /* ABTestTests_result.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = ABTestTests_result.json; sourceTree = "<group>"; };
4DE5FBD1258C508B00F0E18A /* SABFetchResultResponseTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SABFetchResultResponseTests.m; sourceTree = "<group>"; };
4DFCBB0427699ED600257689 /* SABFileStorePlugin.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SABFileStorePlugin.h; sourceTree = "<group>"; };
Expand Down Expand Up @@ -182,7 +182,7 @@
4D15CF3B24EE83B1003D2748 /* SensorsABTest */ = {
isa = PBXGroup;
children = (
4D73D5FC254BC6100020E711 /* SensorsABTest.h */,
4DD58CFC2D1D3D08005BE4F8 /* SensorsABTest.h */,
4D73D607254BC6110020E711 /* SensorsABTest.m */,
FC2BE2B727293A850043C1FA /* SensorsABTestExperiment.h */,
FC2BE2B627293A850043C1FA /* SensorsABTestExperiment.m */,
Expand Down Expand Up @@ -312,13 +312,13 @@
4D04037E2657C7820006D84D /* SABSwizzler.h in Headers */,
4D73D61D254BC6110020E711 /* SABNetwork.h in Headers */,
FC2BE2B5272939BD0043C1FA /* SABPropertyValidator.h in Headers */,
4DD58CFD2D1D3D08005BE4F8 /* SensorsABTest.h in Headers */,
4D73D62E254BC6110020E711 /* SensorsABTestConfigOptions.h in Headers */,
FC97219E274C8F420092812F /* SABRequestManager.h in Headers */,
4D63FFBC297A32F70069CDEA /* SABHitExperimentRecordSources.h in Headers */,
4D73D62F254BC6110020E711 /* SABConstants.h in Headers */,
FC2BE2B927293A850043C1FA /* SensorsABTestExperiment.h in Headers */,
4D63FFB5297A32F70069CDEA /* SABHitExperimentRecordsManager.h in Headers */,
4D73D61E254BC6110020E711 /* SensorsABTest.h in Headers */,
4D73D62C254BC6110020E711 /* SABBridge.h in Headers */,
4D73D623254BC6110020E711 /* SABExperimentDataManager.h in Headers */,
4D73D637254BC6110020E711 /* SABValidUtils.h in Headers */,
Expand Down
1 change: 0 additions & 1 deletion SensorsABTest/Network/SABRequest.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ NS_ASSUME_NONNULL_BEGIN

extern NSString *const kSABRequestBodyCustomIDs;
extern NSString *const kSABRequestBodyCustomProperties;
extern NSString *const kSABRequestBodyParamName;

@protocol SABRequestProtocol <NSObject>

Expand Down
2 changes: 0 additions & 2 deletions SensorsABTest/Network/SABRequest.m
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@
NSString *const kSABRequestBodyLoginID = @"login_id";
NSString *const kSABRequestBodyAnonymousID = @"anonymous_id";
NSString *const kSABRequestBodyTimeoutInterval = @"timeout_interval";
NSString *const kSABRequestBodyParamName = @"param_name";

@interface SABExperimentRequest()

Expand Down Expand Up @@ -123,7 +122,6 @@ - (NSDictionary *)compareParams {
params[kSABRequestBodyLoginID] = self.body[kSABRequestBodyLoginID];
params[kSABRequestBodyAnonymousID] = self.body[kSABRequestBodyAnonymousID];
params[kSABRequestBodyTimeoutInterval] = @(self.timeoutInterval);
params[kSABRequestBodyParamName] = self.body[kSABRequestBodyParamName];
params[kSABRequestBodyCustomProperties] = self.body[kSABRequestBodyCustomProperties];
params[kSABRequestBodyCustomIDs] = self.body[kSABRequestBodyCustomIDs];
return params;
Expand Down
2 changes: 1 addition & 1 deletion SensorsABTest/SABConstants.m
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
#import "SABConstants.h"

// 当前版本号
NSString *const kSABLibVersion = @"1.0.5";
NSString *const kSABLibVersion = @"1.1.0";

// SA 最低支持版本
NSString *const kSABMinSupportedSALibVersion = @"4.5.6";
Expand Down
14 changes: 14 additions & 0 deletions SensorsABTest/SABManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,20 @@ NS_ASSUME_NONNULL_BEGIN
/// @param customIDs 自定义主体 ID
- (void)setCustomIDs:(NSDictionary <NSString*, NSString*> *)customIDs;

/**
设置自定义属性
设置多次时以后次为准,会直接覆盖前次设置内容
设置自定义属性,下次 SDK 初始化后重置
@param customProperties 设置的自定义属性内容
*/
- (void)setCustomProperties:(nullable NSDictionary <NSString*, id>*)customProperties;

/**
* 获取当前的自定义属性
*
* @return 当前的 customProperties 的副本
*/
- (nullable NSDictionary *)customProperties;
@end

NS_ASSUME_NONNULL_END
55 changes: 51 additions & 4 deletions SensorsABTest/SABManager.m
Original file line number Diff line number Diff line change
Expand Up @@ -191,8 +191,12 @@ - (void)messageFromH5:(NSNotification *)notification {
"timeout":XXXXX //H5 的 timeout
"properties":{}, //App 端 A/B Testing 特定的属性,暂未添加
"request_body": { // H5 请求需要增加的参数
"origin_platform": 'H5'
}
"origin_platform": 'H5', // 原始平台
"custom_properties": { // 新增字段:H5 端的自定义属性内容
custom1: xxx,
custom2: xxx
}
}
}
}")
*/
Expand Down Expand Up @@ -243,6 +247,9 @@ - (void)changeUserIdentyAction:(NSNotification *)notification {
/// 更新用户信息
[self.dataManager updateUserIdenty];

// 切换用户,清除自定义属性
self.configOptions.customProperties = nil;

SABLogDebug(@"Receive notification: %@ and reload ABTest results", notification.name);
[self reloadAllABTestResult];
}
Expand Down Expand Up @@ -362,9 +369,14 @@ - (void)fetchAsyncABTestWithExperiment:(SensorsABTestExperiment *)experiment {
// 异步请求
SABExperimentRequest *requestData = [[SABExperimentRequest alloc] initWithBaseURL:self.configOptions.baseURL projectKey:self.configOptions.projectKey userIdenty:self.dataManager.currentUserIndenty];
requestData.timeoutInterval = experiment.timeoutInterval;

// 包含自定义属性
if (properties.count > 0 && experiment.paramName) {
[requestData appendRequestBody:@{kSABRequestBodyCustomProperties: properties, kSABRequestBodyParamName: experiment.paramName}];
if (self.configOptions.customProperties.count > 0) {
[requestData appendRequestBody:@{kSABRequestBodyCustomProperties: self.configOptions.customProperties}];
}
// 接口设置自定义属性,优先级更高,并且不影响全局设置
if (properties.count) {
[requestData appendRequestBody:@{kSABRequestBodyCustomProperties: properties}];
}

// 检查当前请求是否已存在相同的请求任务,当前只针对 Fast 模式下的请求生效
Expand Down Expand Up @@ -429,6 +441,11 @@ - (void)fetchAllABTestResultWithTimes:(NSInteger)times {

SABExperimentRequest *requestData = [[SABExperimentRequest alloc] initWithBaseURL:self.configOptions.baseURL projectKey:self.configOptions.projectKey userIdenty:self.dataManager.currentUserIndenty];

// 包含自定义属性
if (self.configOptions.customProperties.count > 0) {
[requestData appendRequestBody:@{kSABRequestBodyCustomProperties: self.configOptions.customProperties}];
}

[self.dataManager asyncFetchAllExperimentWithRequest:requestData completionHandler:^(SABFetchResultResponse *_Nullable responseData, NSError *_Nullable error) {
if (fetchIndex <= 0 || !error) {
return;
Expand Down Expand Up @@ -541,6 +558,36 @@ - (void)setCustomIDs:(NSDictionary <NSString*, NSString*> *)customIDs {
[self reloadAllABTestResult];
}

// 设置自定义属性
- (void)setCustomProperties:(NSDictionary <NSString*, id>*)customProperties {
NSError *error;
// 验证自定义属性合法性,并统一修改自定义属性值为 String 类型
NSDictionary *properties = [SABPropertyValidator validateProperties:customProperties error:&error];
if (error) {
SABLogError(@"setCustomProperties error,%@", error.localizedDescription);
return;
}
// 自定义属性未发生变更
if ([properties isEqualToDictionary:self.configOptions.customProperties]) {
SABLogDebug(@"setCustomProperties to match the current customProperties and do not process");
return;
}
// 自定义属性无效
if (properties.count == 0 && self.configOptions.customProperties.count == 0) {
return;
}

SABLogDebug(@"setCustomProperties,reloadAllABTestResult");

self.configOptions.customProperties = customProperties;
[self reloadAllABTestResult];
}

// 获取当前的自定义属性
- (NSDictionary *)customProperties {
return [self.configOptions.customProperties copy];
}

- (void)dealloc {
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
Expand Down
10 changes: 10 additions & 0 deletions SensorsABTest/SensorsABTest.m
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,16 @@ - (void)setCustomIDs:(NSDictionary <NSString*, NSString*> *)customIDs {
[self.manager setCustomIDs:customIDs];
}

// 设置自定义属性
- (void)setCustomProperties:(NSDictionary <NSString*, id>*)customProperties {
[self.manager setCustomProperties:customProperties];
}

// 获取当前的自定义属性
- (NSDictionary *)customProperties {
return [self.manager customProperties];
}

+ (BOOL)isSupportedSAVersion {
return [SABBridge.libVersion sensorsabtest_compareVersion:kSABMinSupportedSALibVersion] != NSOrderedAscending ;
}
Expand Down
16 changes: 16 additions & 0 deletions SensorsABTest/SensorsABTestConfigOptions.m
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@

#import "SensorsABTestConfigOptions.h"
#import "SABURLUtils.h"
#import "SABPropertyValidator.h"
#import "SABLogBridge.h"

@interface SensorsABTestConfigOptions ()

Expand Down Expand Up @@ -54,6 +56,20 @@ - (id)copyWithZone:(nullable NSZone *)zone {
SensorsABTestConfigOptions *options = [[[self class] allocWithZone:zone] init];
options.baseURL = self.baseURL;
options.projectKey = self.projectKey;
options.customProperties = self.customProperties;

return options;
}

- (void)setCustomProperties:(NSDictionary *)customProperties {
NSError *error;
// 验证自定义属性合法性,并统一修改自定义属性值为 String 类型
NSDictionary *properties = [SABPropertyValidator validateProperties:customProperties error:&error];
if (error) {
SABLogError(@"%@", error.localizedDescription);
return;
}
_customProperties = properties;
}

@end
12 changes: 12 additions & 0 deletions SensorsABTest/include/SensorsABTest.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,18 @@ NS_ASSUME_NONNULL_BEGIN
/// @param customIDs 自定义主体 ID
- (void)setCustomIDs:(NSDictionary <NSString*, NSString*> *)customIDs;

/**
设置自定义属性
设置多次时以后次为准,会直接覆盖前次设置内容
设置自定义属性,下次 SDK 初始化后重置
@param customProperties 设置的自定义属性内容
*/
- (void)setCustomProperties:(nullable NSDictionary <NSString*, id>*)customProperties;

/// 获取当前的自定义属性
/// @return 当前的 customProperties 的副本
- (nullable NSDictionary *)customProperties;

@end

NS_ASSUME_NONNULL_END
2 changes: 2 additions & 0 deletions SensorsABTest/include/SensorsABTestConfigOptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ NS_ASSUME_NONNULL_BEGIN
/// @return 实例对象
- (instancetype)initWithURL:(NSString *)urlString NS_DESIGNATED_INITIALIZER;

// 设置自定义属性
@property (nonatomic, copy) NSDictionary * _Nullable customProperties;
@end

NS_ASSUME_NONNULL_END
Loading

0 comments on commit 6036ece

Please sign in to comment.