Skip to content

Commit 58339b7

Browse files
committed
Changed Analytics to use SHA256 from MD5 since MD5 has been deprecated from iOS 13. Bumped podspec version.
1 parent d9161c0 commit 58339b7

File tree

4 files changed

+40
-20
lines changed

4 files changed

+40
-20
lines changed

Classes/GTXAnalyticsUtils.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,11 @@ NS_ASSUME_NONNULL_BEGIN
4343
*/
4444
+ (NSString *)clientID;
4545

46+
/**
47+
@return An appropriate clientID for analytics that is based on hash of given @c bundleID.
48+
*/
49+
+ (NSString *)clientIDForBundleID:(NSString *)bundleID;
50+
4651
@end
4752

4853
NS_ASSUME_NONNULL_END

Classes/GTXAnalyticsUtils.m

Lines changed: 25 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
//
1616

1717
#import "GTXAnalyticsUtils.h"
18+
#import "GTXAssertions.h"
1819
#import "GTXLogging.h"
1920

2021
#import <CommonCrypto/CommonDigest.h>
@@ -28,30 +29,37 @@
2829

2930
@implementation GTXAnalyticsUtils
3031

31-
/**
32-
@return The clientID to be used by GTXiLib analytics, this is a hash of App's bundle ID.
33-
*/
32+
+ (NSString *)clientIDForBundleID:(NSString *)bundleID {
33+
// Get SHA256 value of the given string.
34+
unsigned char sha256Value[CC_SHA256_DIGEST_LENGTH];
35+
const char *stringCPtr = [bundleID UTF8String];
36+
CC_SHA256(stringCPtr, (CC_LONG)strlen(stringCPtr), sha256Value);
37+
38+
// Parse SHA256 value into individual hex values. Note that Google Analytics client ID must be
39+
// 128bits long, but SHA256 is 256 bits and there is no standard way to compress hashes, in our
40+
// case we use bitwise XOR of the two 128 bit hashes inside the 256 bit hash to produce a 128bit
41+
// hash.
42+
NSMutableString *stringWithHexValues = [[NSMutableString alloc] init];
43+
const NSInteger kClientIDSize = 16;
44+
GTX_ASSERT(kClientIDSize * 2 == CC_SHA256_DIGEST_LENGTH,
45+
@"CC_SHA256_DIGEST_LENGTH must be 32 it was %d", (int)CC_SHA256_DIGEST_LENGTH);
46+
for (int i = 0; i < kClientIDSize; i++) {
47+
[stringWithHexValues appendFormat:@"%02x", sha256Value[i] ^ sha256Value[kClientIDSize + i]];
48+
}
49+
return stringWithHexValues;
50+
}
51+
3452
+ (NSString *)clientID {
3553
static NSString *clientID;
3654
static dispatch_once_t onceToken;
3755
dispatch_once(&onceToken, ^{
38-
NSString *bundleIDMD5 = [[NSBundle mainBundle] bundleIdentifier];
39-
if (!bundleIDMD5) {
56+
NSString *bundleID = [[NSBundle mainBundle] bundleIdentifier];
57+
if (!bundleID) {
4058
// If bundle ID is not available we use a placeholder.
41-
bundleIDMD5 = @"<Missing Bundle ID>";
59+
bundleID = @"<Missing Bundle ID>";
4260
}
4361

44-
// Get MD5 value of the given string.
45-
unsigned char md5Value[CC_MD5_DIGEST_LENGTH];
46-
const char *stringCPtr = [bundleIDMD5 UTF8String];
47-
CC_MD5(stringCPtr, (CC_LONG)strlen(stringCPtr), md5Value);
48-
49-
// Parse MD5 value into individual hex values.
50-
NSMutableString *stringWithHexMd5Values = [[NSMutableString alloc] init];
51-
for (int i = 0; i < CC_MD5_DIGEST_LENGTH; i++) {
52-
[stringWithHexMd5Values appendFormat:@"%02x", md5Value[i]];
53-
}
54-
clientID = [stringWithHexMd5Values copy];
62+
clientID = [self clientIDForBundleID:bundleID];
5563
});
5664

5765
return clientID;

GTXiLib.podspec

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
Pod::Spec.new do |s|
22
s.name = "GTXiLib"
3-
s.version = "4.4"
3+
s.version = "4.5"
44
s.summary = "iOS Accessibility testing library."
55
s.description = <<-DESC
66
iOS Accessibility testing library that works with XCTest based frameworks.
@@ -9,7 +9,7 @@ Pod::Spec.new do |s|
99
s.license = "Apache License 2.0"
1010
s.author = "j-sid"
1111
s.platform = :ios
12-
s.source = { :git => "https://github.com/google/GTXiLib.git", :tag => "4.4.0" }
12+
s.source = { :git => "https://github.com/google/GTXiLib.git", :tag => "4.5.0" }
1313
s.source_files = "{Classes,OOPClasses}/**/*.{h,m,swift,mm,cc}"
1414
s.public_header_files = "Classes/**/*.h"
1515
s.private_header_files = [
@@ -22,4 +22,4 @@ Pod::Spec.new do |s|
2222
s.ios.deployment_target = '9.0'
2323
s.libraries = 'c++'
2424
s.dependency 'Protobuf-C++'
25-
end
25+
end

Tests/GTXTests/UnitTests/GTXAnalyticsTests.m

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#import <XCTest/XCTest.h>
1919

2020
#import "GTXAnalytics.h"
21+
#import "GTXAnalyticsUtils.h"
2122
#import "GTXToolKit.h"
2223
#import "GTXBaseTestCase.h"
2324

@@ -43,6 +44,12 @@ - (void)tearDown {
4344
[super tearDown];
4445
}
4546

47+
- (void)testClientIDIsAccurate {
48+
NSString *expectedClientID = @"90940a64d60ad6c98c3fb6c6307e1d36";
49+
XCTAssertEqualObjects(expectedClientID,
50+
[GTXAnalyticsUtils clientIDForBundleID:@"com.google.gtx.test"]);
51+
}
52+
4653
- (void)testCheckElementReportsAnalyticsCorrectly {
4754
GTXToolKit *toolkit = [GTXToolKit toolkitWithNoChecks];
4855
__block NSInteger successEventsCount = 0;

0 commit comments

Comments
 (0)