Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Misc Fixes #884

Merged
merged 12 commits into from
May 12, 2020
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,4 @@ Carthage
# itself has no pod dependencies, only our tests do.
Pods/
.clang-format
.idea
12 changes: 12 additions & 0 deletions Analytics.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@

/* Begin PBXBuildFile section */
067E6A3191007B3442DB29F0 /* Pods_AnalyticsTestsTVOS.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 66058A0DB75544E7C2766C31 /* Pods_AnalyticsTestsTVOS.framework */; };
5AF0E8AE77F57B356DACCFE7 /* AutoScreenReportingTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5AF0E8457CCFC077382BF449 /* AutoScreenReportingTest.swift */; };
630FC8EA2107F2A500A759C5 /* SEGScreenReporting.h in Headers */ = {isa = PBXBuildFile; fileRef = 5AF0EDFEDC0EE79A0A0EB713 /* SEGScreenReporting.h */; settings = {ATTRIBUTES = (Public, ); }; };
6E265C791FB1178C0030E08E /* IntegrationsManagerTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6E265C781FB1178C0030E08E /* IntegrationsManagerTest.swift */; };
6EEC1C712017EA370089C478 /* EndToEndTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6EEC1C702017EA370089C478 /* EndToEndTests.swift */; };
9D8CE59023EE014E00197D0C /* CryptoTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = EADEB8E91DECD335005322DA /* CryptoTest.swift */; };
Expand All @@ -27,6 +29,7 @@
9D8CE59E23EE014E00197D0C /* TestUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = EADEB8E41DECD335005322DA /* TestUtils.swift */; };
9D8CE5A023EE014E00197D0C /* Analytics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EADEB85B1DECD080005322DA /* Analytics.framework */; };
A31958EF2385AC3A00A47EFA /* SerializationTests.m in Sources */ = {isa = PBXBuildFile; fileRef = A31958EE2385AC3A00A47EFA /* SerializationTests.m */; };
A31CAFC224635F8400443BA4 /* AutoScreenReportingTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5AF0E8457CCFC077382BF449 /* AutoScreenReportingTest.swift */; };
A352176023AD5825005B07F6 /* SEGMacros.h in Headers */ = {isa = PBXBuildFile; fileRef = A352175F23AD5825005B07F6 /* SEGMacros.h */; settings = {ATTRIBUTES = (Private, ); }; };
E4ACAD51DB827114D8626C74 /* Pods_AnalyticsTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5238C0454BF56A36A536C5C1 /* Pods_AnalyticsTests.framework */; };
EA88A5981DED7608009FB66A /* SEGSerializableValue.h in Headers */ = {isa = PBXBuildFile; fileRef = EA88A5971DED7608009FB66A /* SEGSerializableValue.h */; settings = {ATTRIBUTES = (Public, ); }; };
Expand Down Expand Up @@ -117,6 +120,9 @@
03630CF57D6F100AC46A95FD /* Pods-AnalyticsTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-AnalyticsTests.release.xcconfig"; path = "Target Support Files/Pods-AnalyticsTests/Pods-AnalyticsTests.release.xcconfig"; sourceTree = "<group>"; };
4E5B177C4F6C1CAE4837FF7B /* Pods-AnalyticsTestsTVOS.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-AnalyticsTestsTVOS.debug.xcconfig"; path = "Target Support Files/Pods-AnalyticsTestsTVOS/Pods-AnalyticsTestsTVOS.debug.xcconfig"; sourceTree = "<group>"; };
5238C0454BF56A36A536C5C1 /* Pods_AnalyticsTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_AnalyticsTests.framework; sourceTree = BUILT_PRODUCTS_DIR; };
5AF0E8457CCFC077382BF449 /* AutoScreenReportingTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AutoScreenReportingTest.swift; sourceTree = "<group>"; };
5AF0EDFEDC0EE79A0A0EB713 /* SEGScreenReporting.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SEGScreenReporting.h; sourceTree = "<group>"; };
63E090D722DD49C300DEC7EC /* UIViewController+SegScreenTest.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "UIViewController+SegScreenTest.h"; sourceTree = "<group>"; };
66058A0DB75544E7C2766C31 /* Pods_AnalyticsTestsTVOS.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_AnalyticsTestsTVOS.framework; sourceTree = BUILT_PRODUCTS_DIR; };
6E265C781FB1178C0030E08E /* IntegrationsManagerTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IntegrationsManagerTest.swift; sourceTree = "<group>"; };
6EEC1C702017EA370089C478 /* EndToEndTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EndToEndTests.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -312,6 +318,8 @@
6E265C781FB1178C0030E08E /* IntegrationsManagerTest.swift */,
6EEC1C702017EA370089C478 /* EndToEndTests.swift */,
A31958EE2385AC3A00A47EFA /* SerializationTests.m */,
5AF0E8457CCFC077382BF449 /* AutoScreenReportingTest.swift */,
63E090D722DD49C300DEC7EC /* UIViewController+SegScreenTest.h */,
);
indentWidth = 2;
path = AnalyticsTests;
Expand Down Expand Up @@ -393,6 +401,7 @@
A352175F23AD5825005B07F6 /* SEGMacros.h */,
EADEB8A21DECD12B005322DA /* UIViewController+SEGScreen.h */,
EADEB8A31DECD12B005322DA /* UIViewController+SEGScreen.m */,
5AF0EDFEDC0EE79A0A0EB713 /* SEGScreenReporting.h */,
);
path = Internal;
sourceTree = "<group>";
Expand Down Expand Up @@ -461,6 +470,7 @@
EADEB8601DECD080005322DA /* Analytics.h in Headers */,
EADEB8C31DECD12B005322DA /* SEGAnalyticsUtils.h in Headers */,
EADEB8B91DECD12B005322DA /* SEGIntegrationsManager.h in Headers */,
630FC8EA2107F2A500A759C5 /* SEGScreenReporting.h in Headers */,
EADEB8AE1DECD12B005322DA /* SEGAES256Crypto.h in Headers */,
EADEB8C51DECD12B005322DA /* SEGFileStorage.h in Headers */,
EAA5427D1EB42B8C00945DA7 /* SEGReachability.h in Headers */,
Expand Down Expand Up @@ -712,6 +722,7 @@
9D8CE59823EE014E00197D0C /* AnalyticsUtilTests.swift in Sources */,
9D8CE59923EE014E00197D0C /* StoreKitTrackerTests.swift in Sources */,
9D8CE59A23EE014E00197D0C /* MiddlewareTests.swift in Sources */,
A31CAFC224635F8400443BA4 /* AutoScreenReportingTest.swift in Sources */,
9D8CE59B23EE014E00197D0C /* IntegrationsManagerTest.swift in Sources */,
9D8CE59C23EE014E00197D0C /* NSData+SEGGUNZIPP.m in Sources */,
9D8CE59D23EE014E00197D0C /* EndToEndTests.swift in Sources */,
Expand Down Expand Up @@ -768,6 +779,7 @@
EADEB8EF1DECD335005322DA /* NSData+SEGGUNZIPP.m in Sources */,
6EEC1C712017EA370089C478 /* EndToEndTests.swift in Sources */,
EADEB8F01DECD335005322DA /* TestUtils.swift in Sources */,
5AF0E8AE77F57B356DACCFE7 /* AutoScreenReportingTest.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down
14 changes: 0 additions & 14 deletions Analytics.xcodeproj/xcshareddata/xcschemes/Analytics.xcscheme
Original file line number Diff line number Diff line change
Expand Up @@ -20,20 +20,6 @@
ReferencedContainer = "container:Analytics.xcodeproj">
</BuildableReference>
</BuildActionEntry>
<BuildActionEntry
buildForTesting = "NO"
buildForRunning = "NO"
buildForProfiling = "NO"
buildForArchiving = "NO"
buildForAnalyzing = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "9D8CE58B23EE014E00197D0C"
BuildableName = "AnalyticsTestsTVOS.xctest"
BlueprintName = "AnalyticsTestsTVOS"
ReferencedContainer = "container:Analytics.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
Expand Down
1 change: 1 addition & 0 deletions Analytics/Analytics.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,4 @@ FOUNDATION_EXPORT const unsigned char AnalyticsVersionString[];
#import "SEGSegmentIntegrationFactory.h"
#import "SEGContext.h"
#import "SEGMiddleware.h"
#import "SEGScreenReporting.h"
6 changes: 6 additions & 0 deletions Analytics/Classes/Integrations/SEGIntegrationsManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,12 @@
#import <Foundation/Foundation.h>
#import "SEGMiddleware.h"

/**
* Filenames of "Application Support" files where essential data is stored.
*/
extern NSString *_Nonnull const kSEGAnonymousIdFilename;
extern NSString *_Nonnull const kSEGCachedSettingsFilename;

/**
* NSNotification name, that is posted after integrations are loaded.
*/
Expand Down
14 changes: 7 additions & 7 deletions Analytics/Classes/Integrations/SEGIntegrationsManager.m
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,9 @@
#import "SEGAliasPayload.h"

NSString *SEGAnalyticsIntegrationDidStart = @"io.segment.analytics.integration.did.start";
static NSString *const SEGAnonymousIdKey = @"SEGAnonymousId";
static NSString *const kSEGAnonymousIdFilename = @"segment.anonymousId";
static NSString *const SEGCachedSettingsKey = @"analytics.settings.v2.plist";
NSString *const SEGAnonymousIdKey = @"SEGAnonymousId";
NSString *const kSEGAnonymousIdFilename = @"segment.anonymousId";
NSString *const kSEGCachedSettingsFilename = @"analytics.settings.v2.plist";


@interface SEGIdentifyPayload (AnonymousId)
Expand Down Expand Up @@ -357,9 +357,9 @@ - (NSDictionary *)cachedSettings
{
if (!_cachedSettings) {
#if TARGET_OS_TV
_cachedSettings = [self.userDefaultsStorage dictionaryForKey:SEGCachedSettingsKey] ?: @{};
_cachedSettings = [self.userDefaultsStorage dictionaryForKey:kSEGCachedSettingsFilename] ?: @{};
#else
_cachedSettings = [self.fileStorage dictionaryForKey:SEGCachedSettingsKey] ?: @{};
_cachedSettings = [self.fileStorage dictionaryForKey:kSEGCachedSettingsFilename] ?: @{};
#endif
}

Expand All @@ -375,9 +375,9 @@ - (void)setCachedSettings:(NSDictionary *)settings
}

#if TARGET_OS_TV
[self.userDefaultsStorage setDictionary:_cachedSettings forKey:SEGCachedSettingsKey];
[self.userDefaultsStorage setDictionary:_cachedSettings forKey:kSEGCachedSettingsFilename];
#else
[self.fileStorage setDictionary:_cachedSettings forKey:SEGCachedSettingsKey];
[self.fileStorage setDictionary:_cachedSettings forKey:kSEGCachedSettingsFilename];
#endif

[self updateIntegrationsWithSettings:settings[@"integrations"]];
Expand Down
3 changes: 0 additions & 3 deletions Analytics/Classes/Internal/SEGAnalyticsUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,6 @@ NS_ASSUME_NONNULL_BEGIN

NSString *GenerateUUIDString(void);

// Validation Utils
BOOL serializableDictionaryTypes(NSDictionary *dict);

// Date Utils
NSString *iso8601FormattedString(NSDate *date);
NSString *iso8601NanoFormattedString(NSDate *date);
Expand Down
12 changes: 10 additions & 2 deletions Analytics/Classes/Internal/SEGFileStorage.m
Original file line number Diff line number Diff line change
Expand Up @@ -109,10 +109,18 @@ - (void)setArray:(nullable NSArray *)array forKey:(NSString *)key

- (nullable NSString *)stringForKey:(NSString *)key
{
NSDictionary *data = [self jsonForKey:key];
if (data) {
id data = [self jsonForKey:key];

if (data == nil) {
return nil;
}

if ([data isKindOfClass:[NSString class]]) {
return data;
} else if ([data isKindOfClass:[NSDictionary class]]) {
return data[key];
}

return nil;
}

Expand Down
17 changes: 17 additions & 0 deletions Analytics/Classes/Internal/SEGScreenReporting.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#import <UIKit/UIKit.h>
#import "SEGSerializableValue.h"

/** Implement this protocol to override automatic screen reporting
*/

NS_ASSUME_NONNULL_BEGIN

@protocol SEGScreenReporting
@optional
-(void) seg_trackScreen:(UIViewController*)screen name:(NSString*)name;
@property (readonly, nullable) UIViewController *seg_mainViewController;
@end

NS_ASSUME_NONNULL_END


7 changes: 7 additions & 0 deletions Analytics/Classes/Internal/SEGSegmentIntegration.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,13 @@ extern NSString *const SEGSegmentDidSendRequestNotification;
extern NSString *const SEGSegmentRequestDidSucceedNotification;
extern NSString *const SEGSegmentRequestDidFailNotification;

/**
* Filenames of "Application Support" files where essential data is stored.
*/
extern NSString *const kSEGUserIdFilename;
extern NSString *const kSEGQueueFilename;
extern NSString *const kSEGTraitsFilename;


@interface SEGSegmentIntegration : NSObject <SEGIntegration>

Expand Down
3 changes: 2 additions & 1 deletion Analytics/Classes/Internal/UIViewController+SEGScreen.h
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
#import <UIKit/UIKit.h>

#import "SEGSerializableValue.h"

@interface UIViewController (SEGScreen)

+ (void)seg_swizzleViewDidAppear;
+ (UIViewController *)seg_topViewController;

@end

46 changes: 42 additions & 4 deletions Analytics/Classes/Internal/UIViewController+SEGScreen.m
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#import <objc/runtime.h>
#import "SEGAnalytics.h"
#import "SEGAnalyticsUtils.h"
#import "SEGScreenReporting.h"


@implementation UIViewController (SEGScreen)
Expand Down Expand Up @@ -43,18 +44,48 @@ + (UIViewController *)seg_topViewController
}

+ (UIViewController *)seg_topViewController:(UIViewController *)rootViewController
{
UIViewController *nextRootViewController = [self seg_nextRootViewController:rootViewController];
if (nextRootViewController) {
return [self seg_topViewController:nextRootViewController];
}

return rootViewController;
}

+ (UIViewController *)seg_nextRootViewController:(UIViewController *)rootViewController
{
UIViewController *presentedViewController = rootViewController.presentedViewController;
if (presentedViewController != nil) {
return [self seg_topViewController:presentedViewController];
return presentedViewController;
}

if ([rootViewController isKindOfClass:[UINavigationController class]]) {
UIViewController *lastViewController = [[(UINavigationController *)rootViewController viewControllers] lastObject];
return [self seg_topViewController:lastViewController];
UIViewController *lastViewController = ((UINavigationController *)rootViewController).viewControllers.lastObject;
return lastViewController;
}

return rootViewController;
if ([rootViewController isKindOfClass:[UITabBarController class]]) {
__auto_type *currentTabViewController = ((UITabBarController*)rootViewController).selectedViewController;
if (currentTabViewController != nil) {
return currentTabViewController;
}
}

if (rootViewController.childViewControllers.count > 0) {
if ([rootViewController conformsToProtocol:@protocol(SEGScreenReporting)] && [rootViewController respondsToSelector:@selector(seg_mainViewController)]) {
__auto_type screenReporting = (UIViewController<SEGScreenReporting>*)rootViewController;
return screenReporting.seg_mainViewController;
}

// fall back on first child UIViewController as a "best guess" assumption
__auto_type *firstChildViewController = rootViewController.childViewControllers.firstObject;
if (firstChildViewController != nil) {
return firstChildViewController;
}
}

return nil;
}

- (void)seg_viewDidAppear:(BOOL)animated
Expand All @@ -74,6 +105,13 @@ - (void)seg_viewDidAppear:(BOOL)animated
name = @"Unknown";
}
}

if ([top conformsToProtocol:@protocol(SEGScreenReporting)] && [top respondsToSelector:@selector(seg_trackScreen:name:)]) {
__auto_type screenReporting = (UIViewController<SEGScreenReporting>*)top;
[screenReporting seg_trackScreen:top name:name];
return;
}

[[SEGAnalytics sharedAnalytics] screen:name properties:nil options:nil];

[self seg_viewDidAppear:animated];
Expand Down
4 changes: 4 additions & 0 deletions Analytics/Classes/SEGAnalytics.m
Original file line number Diff line number Diff line change
Expand Up @@ -169,8 +169,12 @@ - (void)_applicationWillEnterForeground
if (!self.configuration.trackApplicationLifecycleEvents) {
return;
}
NSString *currentVersion = [[NSBundle mainBundle] infoDictionary][@"CFBundleShortVersionString"];
NSString *currentBuild = [[NSBundle mainBundle] infoDictionary][@"CFBundleVersion"];
[self track:@"Application Opened" properties:@{
@"from_background" : @YES,
@"version" : currentVersion ?: @"",
@"build" : currentBuild ?: @"",
}];
}

Expand Down
5 changes: 1 addition & 4 deletions Analytics/Classes/SEGAnalyticsConfiguration.m
Original file line number Diff line number Diff line change
Expand Up @@ -68,10 +68,7 @@ - (instancetype)init
_factories = [NSMutableArray array];
Class applicationClass = NSClassFromString(@"UIApplication");
if (applicationClass) {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Warc-performSelector-leaks"
_application = [applicationClass performSelector:NSSelectorFromString(@"sharedApplication")];
#pragma clang diagnostic pop
_application = [applicationClass performSelector:@selector(sharedApplication)];
}
}
return self;
Expand Down
3 changes: 3 additions & 0 deletions AnalyticsTests/AnalyticsTests-Bridging-Header.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,10 @@
#import <Analytics/SEGAnalyticsUtils.h>
#import <Analytics/SEGIntegrationsManager.h>
#import <Analytics/SEGUtils.h>
#import <Analytics/SEGScreenReporting.h>

#import "NSData+SEGGUNZIPP.h"
// Temp hack. We should fix the LSNocilla podspec to make this header publicly available
#import "LSMatcher.h"

#import "UIViewController+SegScreenTest.h"
Loading