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

[tvOS] Move SEGQueue from UserDefaults to caches directory #861

Merged
merged 22 commits into from
Feb 11, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
4f58f22
Stops using UserDefaults for queue on tvOS and uses NSCachesDirectory
Feb 7, 2020
7fec16e
Adds a constant for key. Seperate cache dir and appSupport dir functi…
Feb 7, 2020
dc7677e
Adds functionality to remove old UserDefaults queue on tvOS.
Feb 10, 2020
151622d
Merge pull request #1 from Zanchee/bug/move-queue-to-cache-on-tvos
connor-ricks Feb 10, 2020
d36d59c
Adds tvOS unit test target
iMacHumphries Feb 7, 2020
6f55d62
Add tvOS options for make file
iMacHumphries Feb 10, 2020
fb5ad87
Enabled code coverage on tvOS tests
iMacHumphries Feb 10, 2020
6565655
Fix up unit test warning
iMacHumphries Feb 10, 2020
2ee850f
Adds test to ensure that UserDefaults SEGQueue is cleared on initiali…
iMacHumphries Feb 10, 2020
77cc3a7
Adds test to ensure SEGQueue is empty when missing form file storage
iMacHumphries Feb 10, 2020
077e8c5
Reverts unnecessary import for QuickTVOS
iMacHumphries Feb 10, 2020
446a2b7
Adds test for FileStorage caches directory helper
iMacHumphries Feb 10, 2020
3bdf861
Merge pull request #2 from Zanchee/unit-test-move-queue-to-cache-on-tvos
iMacHumphries Feb 10, 2020
9993d87
Fix up: Adds SwiftTryCatch pod to tvOS test target
iMacHumphries Feb 10, 2020
d6b65fd
Fix up makefile to have correct build target for build-ios & build-tvos
iMacHumphries Feb 10, 2020
d8bf874
Merge branch 'master' of https://github.com/segmentio/analytics-ios
iMacHumphries Feb 10, 2020
873a85e
Fix up: updates xcodebuild destination to match devices found on circ…
iMacHumphries Feb 10, 2020
305a465
Break up ios and tvos build/test steps
iMacHumphries Feb 10, 2020
5b3f6e9
Circleci: Cache pods
iMacHumphries Feb 11, 2020
9d4a735
Fix up: tvOS test build
iMacHumphries Feb 11, 2020
2407e7d
Fix up spacing
iMacHumphries Feb 11, 2020
71a0a55
Fix up flaky unit test
iMacHumphries Feb 11, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 16 additions & 5 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,24 @@ jobs:
sudo gem install xcpretty
sudo gem install cocoapods -v $(var=$(tail -1 Podfile.lock); echo ${var##COCOAPODS:})

- restore_cache:
key: 1-pods-{{ checksum "Podfile.lock" }}
- run:
name: Fetch Cocoapods specs
command: curl https://cocoapods-specs.circleci.com/fetch-cocoapods-repo-from-s3.sh | bash -s cf
name: Install CocoaPods
command: |
if [ ! -d "Pods" ]
then
make dependencies
fi
- save_cache:
key: 1-pods-{{ checksum "Podfile.lock" }}
paths:
- ./Pods

- run: make dependencies
- run: make build-pretty
- run: make test-pretty
- run: make build-ios
- run: make test-ios
- run: make build-tvos
- run: make test-tvos
- run: make lint
- run: make carthage

Expand Down
246 changes: 218 additions & 28 deletions Analytics.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

10 changes: 10 additions & 0 deletions Analytics.xcodeproj/xcshareddata/xcschemes/Analytics.xcscheme
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,16 @@
ReferencedContainer = "container:Analytics.xcodeproj">
</BuildableReference>
</TestableReference>
<TestableReference
skipped = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "9D8CE58B23EE014E00197D0C"
BuildableName = "AnalyticsTestsTVOS.xctest"
BlueprintName = "AnalyticsTestsTVOS"
ReferencedContainer = "container:Analytics.xcodeproj">
</BuildableReference>
</TestableReference>
</Testables>
</TestAction>
<LaunchAction
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1130"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES"
codeCoverageEnabled = "YES">
<Testables>
<TestableReference
skipped = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "9D8CE58B23EE014E00197D0C"
BuildableName = "AnalyticsTestsTVOS.xctest"
BlueprintName = "AnalyticsTestsTVOS"
ReferencedContainer = "container:Analytics.xcodeproj">
</BuildableReference>
</TestableReference>
</Testables>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>
48 changes: 32 additions & 16 deletions Analytics/Classes/Integrations/SEGIntegrationsManager.m
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
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";


@interface SEGAnalyticsConfiguration (Private)
Expand All @@ -51,7 +52,8 @@ @interface SEGIntegrationsManager ()
@property (nonatomic, copy) NSString *cachedAnonymousId;
@property (nonatomic, strong) SEGHTTPClient *httpClient;
@property (nonatomic, strong) NSURLSessionDataTask *settingsRequest;
@property (nonatomic, strong) id<SEGStorage> storage;
@property (nonatomic, strong) id<SEGStorage> userDefaultsStorage;
@property (nonatomic, strong) id<SEGStorage> fileStorage;

@end

Expand All @@ -71,14 +73,17 @@ - (instancetype _Nonnull)initWithAnalytics:(SEGAnalytics *_Nonnull)analytics
self.serialQueue = seg_dispatch_queue_create_specific("io.segment.analytics", DISPATCH_QUEUE_SERIAL);
self.messageQueue = [[NSMutableArray alloc] init];
self.httpClient = [[SEGHTTPClient alloc] initWithRequestFactory:configuration.requestFactory];
#if TARGET_OS_TV
self.storage = [[SEGUserDefaultsStorage alloc] initWithDefaults:[NSUserDefaults standardUserDefaults] namespacePrefix:nil crypto:configuration.crypto];
#else
self.storage = [[SEGFileStorage alloc] initWithFolder:[SEGFileStorage applicationSupportDirectoryURL] crypto:configuration.crypto];
#endif

self.userDefaultsStorage = [[SEGUserDefaultsStorage alloc] initWithDefaults:[NSUserDefaults standardUserDefaults] namespacePrefix:nil crypto:configuration.crypto];
#if TARGET_OS_TV
self.fileStorage = [[SEGFileStorage alloc] initWithFolder:[SEGFileStorage cachesDirectoryURL] crypto:configuration.crypto];
#else
self.fileStorage = [[SEGFileStorage alloc] initWithFolder:[SEGFileStorage applicationSupportDirectoryURL] crypto:configuration.crypto];
#endif

self.cachedAnonymousId = [self loadOrGenerateAnonymousID:NO];
NSMutableArray *factories = [[configuration factories] mutableCopy];
[factories addObject:[[SEGSegmentIntegrationFactory alloc] initWithHTTPClient:self.httpClient storage:self.storage]];
[factories addObject:[[SEGSegmentIntegrationFactory alloc] initWithHTTPClient:self.httpClient fileStorage:self.fileStorage userDefaultsStorage:self.userDefaultsStorage]];
self.factories = [factories copy];
self.integrations = [NSMutableDictionary dictionaryWithCapacity:factories.count];
self.registeredIntegrations = [NSMutableDictionary dictionaryWithCapacity:factories.count];
Expand Down Expand Up @@ -285,9 +290,9 @@ - (NSString *)getAnonymousId;
- (NSString *)loadOrGenerateAnonymousID:(BOOL)reset
{
#if TARGET_OS_TV
NSString *anonymousId = [self.storage stringForKey:SEGAnonymousIdKey];
NSString *anonymousId = [self.userDefaultsStorage stringForKey:SEGAnonymousIdKey];
#else
NSString *anonymousId = [self.storage stringForKey:kSEGAnonymousIdFilename];
NSString *anonymousId = [self.fileStorage stringForKey:kSEGAnonymousIdFilename];
#endif

if (!anonymousId || reset) {
Expand All @@ -297,9 +302,9 @@ - (NSString *)loadOrGenerateAnonymousID:(BOOL)reset
anonymousId = GenerateUUIDString();
SEGLog(@"New anonymousId: %@", anonymousId);
#if TARGET_OS_TV
[self.storage setString:anonymousId forKey:SEGAnonymousIdKey];
[self.userDefaultsStorage setString:anonymousId forKey:SEGAnonymousIdKey];
#else
[self.storage setString:anonymousId forKey:kSEGAnonymousIdFilename];
[self.fileStorage setString:anonymousId forKey:kSEGAnonymousIdFilename];
#endif
}
return anonymousId;
Expand All @@ -309,9 +314,9 @@ - (void)saveAnonymousId:(NSString *)anonymousId
{
self.cachedAnonymousId = anonymousId;
#if TARGET_OS_TV
[self.storage setString:anonymousId forKey:SEGAnonymousIdKey];
[self.userDefaultsStorage setString:anonymousId forKey:SEGAnonymousIdKey];
#else
[self.storage setString:anonymousId forKey:@"segment.anonymousId"];
[self.fileStorage setString:anonymousId forKey:kSEGAnonymousIdFilename];
#endif
}

Expand All @@ -324,8 +329,14 @@ - (void)flush

- (NSDictionary *)cachedSettings
{
if (!_cachedSettings)
_cachedSettings = [self.storage dictionaryForKey:@"analytics.settings.v2.plist"] ?: @{};
if (!_cachedSettings) {
#if TARGET_OS_TV
_cachedSettings = [self.userDefaultsStorage dictionaryForKey:SEGCachedSettingsKey] ?: @{};
#else
_cachedSettings = [self.fileStorage dictionaryForKey:SEGCachedSettingsKey] ?: @{};
#endif
}

return _cachedSettings;
}

Expand All @@ -336,7 +347,12 @@ - (void)setCachedSettings:(NSDictionary *)settings
// [@{} writeToURL:settingsURL atomically:YES];
return;
}
[self.storage setDictionary:_cachedSettings forKey:@"analytics.settings.v2.plist"];

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

[self updateIntegrationsWithSettings:settings[@"integrations"]];
}
Expand Down
2 changes: 1 addition & 1 deletion Analytics/Classes/Internal/SEGFileStorage.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,11 @@

@property (nonatomic, strong, nullable) id<SEGCrypto> crypto;

- (instancetype _Nonnull)init;
- (instancetype _Nonnull)initWithFolder:(NSURL *_Nonnull)folderURL crypto:(id<SEGCrypto> _Nullable)crypto;

- (NSURL *_Nonnull)urlForKey:(NSString *_Nonnull)key;

+ (NSURL *_Nullable)applicationSupportDirectoryURL;
+ (NSURL *_Nullable)cachesDirectoryURL;

@end
17 changes: 10 additions & 7 deletions Analytics/Classes/Internal/SEGFileStorage.m
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,6 @@ @interface SEGFileStorage ()

@implementation SEGFileStorage

- (instancetype)init
{
return [self initWithFolder:[SEGFileStorage applicationSupportDirectoryURL] crypto:nil];
}

- (instancetype)initWithFolder:(NSURL *)folderURL crypto:(id<SEGCrypto>)crypto
{
if (self = [super init]) {
Expand Down Expand Up @@ -121,11 +116,19 @@ - (void)setString:(NSString *)string forKey:(NSString *)key
[self setJSON:data forKey:key];
}


+ (NSURL *)applicationSupportDirectoryURL
{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES);
NSString *supportPath = [paths firstObject];
return [NSURL fileURLWithPath:supportPath];
NSString *storagePath = [paths firstObject];
return [NSURL fileURLWithPath:storagePath];
}

+ (NSURL *)cachesDirectoryURL
{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
NSString *storagePath = [paths firstObject];
return [NSURL fileURLWithPath:storagePath];
}

- (NSURL *)urlForKey:(NSString *)key
Expand Down
2 changes: 1 addition & 1 deletion Analytics/Classes/Internal/SEGSegmentIntegration.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ extern NSString *const SEGSegmentRequestDidFailNotification;

@interface SEGSegmentIntegration : NSObject <SEGIntegration>

- (id)initWithAnalytics:(SEGAnalytics *)analytics httpClient:(SEGHTTPClient *)httpClient storage:(id<SEGStorage>)storage;
- (id)initWithAnalytics:(SEGAnalytics *)analytics httpClient:(SEGHTTPClient *)httpClient fileStorage:(id<SEGStorage>)fileStorage userDefaultsStorage:(id<SEGStorage>)userDefaultsStorage;

@end

Expand Down
Loading