diff --git a/Example/Podfile b/Example/Podfile index 29bdc42..a019508 100644 --- a/Example/Podfile +++ b/Example/Podfile @@ -1,6 +1,5 @@ source 'https://github.com/CocoaPods/Specs.git' platform :ios, '10.0' -plugin 'cocoapods-repo-update' # Do not use_frameworks due to iOS 7 support # use_frameworks! diff --git a/Example/Podfile.lock b/Example/Podfile.lock index a153bb0..7327caf 100644 --- a/Example/Podfile.lock +++ b/Example/Podfile.lock @@ -1,11 +1,11 @@ PODS: - - Amplitude (5.2.1) - - Analytics (4.0.3) + - Amplitude (7.0.1) + - Analytics (4.0.5) - Expecta (1.0.6) - OCHamcrest (7.1.2) - OCMockito (5.1.3): - OCHamcrest (~> 7.0) - - Segment-Amplitude (3.0.2): + - Segment-Amplitude (3.2.0): - Amplitude - Analytics - Specta (1.0.7) @@ -30,14 +30,14 @@ EXTERNAL SOURCES: :path: "../" SPEC CHECKSUMS: - Amplitude: 9774e93d48d9f41f271a4479e06369a30ab31db1 - Analytics: 54b0551629871648686cb4ee1d243bf4f703f2c2 + Amplitude: 31a9038dca905b78294418ed277da9c2e07658ad + Analytics: 4bcf052c91e1f3339219e83d6a036fb2bd7c218d Expecta: 3b6bd90a64b9a1dcb0b70aa0e10a7f8f631667d5 OCHamcrest: b284c9592c28c1e4025a8542e67ea41a635d0d73 OCMockito: 677cbb4a18fd492b5a4fb10144dada4de5ddb877 - Segment-Amplitude: 4dacdc8b53bd30ee39a936f5024c7d5ed626879b + Segment-Amplitude: 300e2888691b75b8364389b2c242f6b953932945 Specta: 3e1bd89c3517421982dc4d1c992503e48bd5fe66 PODFILE CHECKSUM: a7bf6ef16f54033a66dc8c09524260667af4e881 -COCOAPODS: 1.9.1 +COCOAPODS: 1.10.0.rc.1 diff --git a/Example/Segment-Amplitude.xcodeproj/project.pbxproj b/Example/Segment-Amplitude.xcodeproj/project.pbxproj index d3f9520..88f875f 100644 --- a/Example/Segment-Amplitude.xcodeproj/project.pbxproj +++ b/Example/Segment-Amplitude.xcodeproj/project.pbxproj @@ -22,6 +22,7 @@ 6003F5BA195388D20070C39A /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 6003F5B8195388D20070C39A /* InfoPlist.strings */; }; 6003F5BC195388D20070C39A /* Tests.m in Sources */ = {isa = PBXBuildFile; fileRef = 6003F5BB195388D20070C39A /* Tests.m */; }; 873B8AEB1B1F5CCA007FD442 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 873B8AEA1B1F5CCA007FD442 /* Main.storyboard */; }; + A3585CD2251BCF0A00F46088 /* TestSetupBlock.m in Sources */ = {isa = PBXBuildFile; fileRef = A3585CD1251BCF0A00F46088 /* TestSetupBlock.m */; }; CE22D33DED2C8C1F20382F06 /* libPods-Segment-Amplitude_Example.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 1A31B91CBBB7876EE6D25775 /* libPods-Segment-Amplitude_Example.a */; }; /* End PBXBuildFile section */ @@ -63,6 +64,7 @@ 91AECAC26A53C35405CA5402 /* Pods-Segment-Amplitude_Example.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Segment-Amplitude_Example.release.xcconfig"; path = "Pods/Target Support Files/Pods-Segment-Amplitude_Example/Pods-Segment-Amplitude_Example.release.xcconfig"; sourceTree = ""; }; 97DEF26D0B2C6B8BB484FE4F /* Pods-Segment-Amplitude_Tests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Segment-Amplitude_Tests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-Segment-Amplitude_Tests/Pods-Segment-Amplitude_Tests.debug.xcconfig"; sourceTree = ""; }; 9EEA123C7A20DF690C5D6E46 /* README.md */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = net.daringfireball.markdown; name = README.md; path = ../README.md; sourceTree = ""; }; + A3585CD1251BCF0A00F46088 /* TestSetupBlock.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = TestSetupBlock.m; sourceTree = ""; }; D499617867A9269C55AA5760 /* Pods_Segment_Amplitude_Tests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Segment_Amplitude_Tests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; F26E1DEACA3B4F2A695BCDD1 /* Segment-Amplitude.podspec */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; name = "Segment-Amplitude.podspec"; path = "../Segment-Amplitude.podspec"; sourceTree = ""; }; /* End PBXFileReference section */ @@ -168,6 +170,7 @@ isa = PBXGroup; children = ( 6003F5BB195388D20070C39A /* Tests.m */, + A3585CD1251BCF0A00F46088 /* TestSetupBlock.m */, 6003F5B6195388D20070C39A /* Supporting Files */, ); path = Tests; @@ -391,6 +394,7 @@ buildActionMask = 2147483647; files = ( 6003F5BC195388D20070C39A /* Tests.m in Sources */, + A3585CD2251BCF0A00F46088 /* TestSetupBlock.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/Example/Tests/TestSetupBlock.m b/Example/Tests/TestSetupBlock.m new file mode 100644 index 0000000..266d194 --- /dev/null +++ b/Example/Tests/TestSetupBlock.m @@ -0,0 +1,57 @@ +// +// TestSetupBlock.m +// Segment-Amplitude_Tests +// +// Created by Brandon Sneed on 9/23/20. +// Copyright © 2020 Prateek Srivastava. All rights reserved. +// + +#import + +#import "SEGAmplitudeIntegrationFactory.h" + +@interface TestSetupBlock : XCTestCase + +@end + +@implementation TestSetupBlock + +- (void)setUp { + // Put setup code here. This method is called before the invocation of each test method in the class. +} + +- (void)tearDown { + // Put teardown code here. This method is called after the invocation of each test method in the class. +} + +- (void)testSetupBlockCalled { + __block Amplitude *amp = nil; + + SEGAmplitudeIntegrationFactory *factory = [SEGAmplitudeIntegrationFactory instanceWithSetupBlock:^(Amplitude *amplitude) { + amp = amplitude; + amplitude.adSupportBlock = ^NSString * _Nonnull{ + return @"1234"; + }; + amplitude.locationInfoBlock = ^NSDictionary * _Nullable{ + return @{ + @"lat" : @37.7, + @"lng" : @122.4 + }; + }; + }]; + + SEGAnalytics *analytics = [[SEGAnalytics alloc] init]; + SEGAmplitudeIntegration *integration = [factory createWithSettings:@{} forAnalytics:analytics]; + + XCTAssertTrue(amp != nil); + XCTAssertTrue(amp.adSupportBlock != nil); + XCTAssertTrue(amp.locationInfoBlock != nil); + + NSString *idfa = amp.adSupportBlock(); + NSDictionary *location = amp.locationInfoBlock(); + + XCTAssertTrue([idfa isEqualToString:@"1234"]); + XCTAssertTrue([[location objectForKey:@"lat"] isEqual:@37.7]); +} + +@end diff --git a/Example/Tests/Tests.m b/Example/Tests/Tests.m index 07fee5c..b2e10ff 100644 --- a/Example/Tests/Tests.m +++ b/Example/Tests/Tests.m @@ -41,7 +41,7 @@ amplitude = mock([Amplitude class]); amprevenue = mock([AMPRevenue class]); identify = mock([AMPIdentify class]); - integration = [[SEGAmplitudeIntegration alloc] initWithSettings:@{} andAmplitude:amplitude andAmpRevenue:amprevenue andAmpIdentify:identify]; + integration = [[SEGAmplitudeIntegration alloc] initWithSettings:@{} andAmplitude:amplitude andAmpRevenue:amprevenue andAmpIdentify:identify setupBlock:nil]; }); describe(@"Identify", ^{ @@ -51,7 +51,8 @@ @"traitsToSetOnce" : [NSNull null] } andAmplitude:amplitude andAmpRevenue:amprevenue - andAmpIdentify:identify]; + andAmpIdentify:identify + setupBlock:nil]; SEGIdentifyPayload *payload = [[SEGIdentifyPayload alloc] initWithUserId:@"1111" anonymousId:nil traits:@{} context:@{} integrations:@{}]; [integration identify:payload]; @@ -63,7 +64,8 @@ @"traitsToSetOnce" : @[] } andAmplitude:amplitude andAmpRevenue:amprevenue - andAmpIdentify:identify]; + andAmpIdentify:identify + setupBlock:nil]; SEGIdentifyPayload *payload = [[SEGIdentifyPayload alloc] initWithUserId:@"7891" anonymousId:nil traits:@{ @"name" : @"George Costanza", @"gender" : @"male", @@ -91,7 +93,7 @@ }); it(@"increments identify trait", ^{ - integration = [[SEGAmplitudeIntegration alloc] initWithSettings:@{ @"traitsToIncrement" : @[ @"karma", @"store_credit" ] } andAmplitude:amplitude andAmpRevenue:amprevenue andAmpIdentify:identify]; + integration = [[SEGAmplitudeIntegration alloc] initWithSettings:@{ @"traitsToIncrement" : @[ @"karma", @"store_credit" ] } andAmplitude:amplitude andAmpRevenue:amprevenue andAmpIdentify:identify setupBlock:nil]; SEGIdentifyPayload *payload = [[SEGIdentifyPayload alloc] initWithUserId:@"3290842" anonymousId:nil traits:@{ @"karma" : @0.23, @"store_credit" : @20, @@ -106,7 +108,7 @@ }); it(@"sets identify trait once", ^{ - integration = [[SEGAmplitudeIntegration alloc] initWithSettings:@{ @"traitsToSetOnce" : @[ @"sign_up_date" ] } andAmplitude:amplitude andAmpRevenue:amprevenue andAmpIdentify:identify]; + integration = [[SEGAmplitudeIntegration alloc] initWithSettings:@{ @"traitsToSetOnce" : @[ @"sign_up_date" ] } andAmplitude:amplitude andAmpRevenue:amprevenue andAmpIdentify:identify setupBlock:nil]; SEGIdentifyPayload *payload = [[SEGIdentifyPayload alloc] initWithUserId:@"3290842" anonymousId:nil traits:@{ @"sign_up_date" : @"2015-08-24", @"city" : @"los angeles" } @@ -123,7 +125,8 @@ @"traitsToIncrement" : @[ @"age" ] } andAmplitude:amplitude andAmpRevenue:amprevenue - andAmpIdentify:identify]; + andAmpIdentify:identify + setupBlock:nil]; SEGIdentifyPayload *payload = [[SEGIdentifyPayload alloc] initWithUserId:@"3290842" anonymousId:nil traits:@{ @"address" : @{ @"street" : @"California st", @@ -149,7 +152,7 @@ describe(@"Screen", ^{ it(@"does not call screen if trackAllPages = false", ^{ - integration = [[SEGAmplitudeIntegration alloc] initWithSettings:@{ @"trackAllPages" : @false } andAmplitude:amplitude andAmpRevenue:amprevenue andAmpIdentify:identify]; + integration = [[SEGAmplitudeIntegration alloc] initWithSettings:@{ @"trackAllPages" : @false } andAmplitude:amplitude andAmpRevenue:amprevenue andAmpIdentify:identify setupBlock:nil]; SEGScreenPayload *payload = [[SEGScreenPayload alloc] initWithName:@"Shirts" properties:@{} context:@{} integrations:@{}]; [integration screen:payload]; @@ -157,7 +160,7 @@ }); it(@"trackAllPages", ^{ - integration = [[SEGAmplitudeIntegration alloc] initWithSettings:@{ @"trackAllPages" : @true } andAmplitude:amplitude andAmpRevenue:amprevenue andAmpIdentify:identify]; + integration = [[SEGAmplitudeIntegration alloc] initWithSettings:@{ @"trackAllPages" : @true } andAmplitude:amplitude andAmpRevenue:amprevenue andAmpIdentify:identify setupBlock:nil]; SEGScreenPayload *payload = [[SEGScreenPayload alloc] initWithName:@"Shirts" properties:@{} context:@{} integrations:@{}]; [integration screen:payload]; @@ -165,7 +168,7 @@ }); it(@"trackAllPagesV2", ^{ - integration = [[SEGAmplitudeIntegration alloc] initWithSettings:@{ @"trackAllPagesV2" : @true } andAmplitude:amplitude andAmpRevenue:amprevenue andAmpIdentify:identify]; + integration = [[SEGAmplitudeIntegration alloc] initWithSettings:@{ @"trackAllPagesV2" : @true } andAmplitude:amplitude andAmpRevenue:amprevenue andAmpIdentify:identify setupBlock:nil]; SEGScreenPayload *payload = [[SEGScreenPayload alloc] initWithName:@"Shirts" properties:@{ @"url" : @"seinfeld.wikia.com/wiki/The_Puffy_Shirt", @"Feed Type" : @"private" } @@ -191,7 +194,8 @@ @"groupTypeTrait" : @"industry" } andAmplitude:amplitude andAmpRevenue:amprevenue - andAmpIdentify:identify]; + andAmpIdentify:identify + setupBlock:nil]; SEGGroupPayload *payload = [[SEGGroupPayload alloc] initWithGroupId:@"32423084" traits:@{ @"company" : @"Segment", @"industry" : @"Technology" @@ -289,7 +293,7 @@ it(@"tracks Order Completed with revenue if both total and revenue are present", ^{ - integration = [[SEGAmplitudeIntegration alloc] initWithSettings:@{ @"useLogRevenueV2" : @true } andAmplitude:amplitude andAmpRevenue:amprevenue andAmpIdentify:identify]; + integration = [[SEGAmplitudeIntegration alloc] initWithSettings:@{ @"useLogRevenueV2" : @true } andAmplitude:amplitude andAmpRevenue:amprevenue andAmpIdentify:identify setupBlock:nil]; NSDictionary *props = @{ @"checkout_id" : @"9bcf000000000000", @@ -321,7 +325,7 @@ }); it(@"tracks Order Completed with total if revenue is not present", ^{ - integration = [[SEGAmplitudeIntegration alloc] initWithSettings:@{ @"useLogRevenueV2" : @true } andAmplitude:amplitude andAmpRevenue:amprevenue andAmpIdentify:identify]; + integration = [[SEGAmplitudeIntegration alloc] initWithSettings:@{ @"useLogRevenueV2" : @true } andAmplitude:amplitude andAmpRevenue:amprevenue andAmpIdentify:identify setupBlock:nil]; NSDictionary *props = @{ @"checkout_id" : @"9bcf000000000000", @@ -353,7 +357,7 @@ }); it(@"tracks Order Completed with revenue of type String", ^{ - integration = [[SEGAmplitudeIntegration alloc] initWithSettings:@{ @"useLogRevenueV2" : @true } andAmplitude:amplitude andAmpRevenue:amprevenue andAmpIdentify:identify]; + integration = [[SEGAmplitudeIntegration alloc] initWithSettings:@{ @"useLogRevenueV2" : @true } andAmplitude:amplitude andAmpRevenue:amprevenue andAmpIdentify:identify setupBlock:nil]; NSDictionary *props = @{ @"checkout_id" : @"9bcf000000000000", @@ -386,7 +390,7 @@ // NOTE: This is against our spec. We do not have a v1/v2 ECommerce event that sends both revenue and price/quantity as a tope level property it(@"tracks with top level price and quantity", ^{ - integration = [[SEGAmplitudeIntegration alloc] initWithSettings:@{ @"useLogRevenueV2" : @true } andAmplitude:amplitude andAmpRevenue:amprevenue andAmpIdentify:identify]; + integration = [[SEGAmplitudeIntegration alloc] initWithSettings:@{ @"useLogRevenueV2" : @true } andAmplitude:amplitude andAmpRevenue:amprevenue andAmpIdentify:identify setupBlock:nil]; SEGTrackPayload *payload = [[SEGTrackPayload alloc] initWithEvent:@"Viewed Product" properties:@{ @"revenue" : @20.99, @@ -406,7 +410,7 @@ }); it(@"tracks Amplitude ecommerce fields", ^{ - integration = [[SEGAmplitudeIntegration alloc] initWithSettings:@{ @"useLogRevenueV2" : @true } andAmplitude:amplitude andAmpRevenue:amprevenue andAmpIdentify:identify]; + integration = [[SEGAmplitudeIntegration alloc] initWithSettings:@{ @"useLogRevenueV2" : @true } andAmplitude:amplitude andAmpRevenue:amprevenue andAmpIdentify:identify setupBlock:nil]; SEGTrackPayload *payload = [[SEGTrackPayload alloc] initWithEvent:@"Viewed Product" properties:@{ @"revenue" : @20.00, diff --git a/Pod/Classes/SEGAmplitudeIntegration.h b/Pod/Classes/SEGAmplitudeIntegration.h index c76dcb1..db2e3f6 100644 --- a/Pod/Classes/SEGAmplitudeIntegration.h +++ b/Pod/Classes/SEGAmplitudeIntegration.h @@ -9,6 +9,7 @@ #import #endif +typedef void(^SEGAmplitudeSetupBlock)(Amplitude *amplitude); @interface SEGAmplitudeIntegration : NSObject @@ -19,7 +20,7 @@ @property NSSet *traitsToIncrement; @property NSSet *traitsToSetOnce; -- (id)initWithSettings:(NSDictionary *)settings; -- (id)initWithSettings:(NSDictionary *)settings andAmplitude:(Amplitude *)amplitude andAmpRevenue:(AMPRevenue *)amprevenue andAmpIdentify:(AMPIdentify *)identify; +- (id)initWithSettings:(NSDictionary *)settings setupBlock:(SEGAmplitudeSetupBlock)setupBlock; +- (id)initWithSettings:(NSDictionary *)settings andAmplitude:(Amplitude *)amplitude andAmpRevenue:(AMPRevenue *)amprevenue andAmpIdentify:(AMPIdentify *)identify setupBlock:(SEGAmplitudeSetupBlock)setupBlock; @end diff --git a/Pod/Classes/SEGAmplitudeIntegration.m b/Pod/Classes/SEGAmplitudeIntegration.m index 976d49e..607c540 100644 --- a/Pod/Classes/SEGAmplitudeIntegration.m +++ b/Pod/Classes/SEGAmplitudeIntegration.m @@ -4,12 +4,12 @@ @implementation SEGAmplitudeIntegration -- (id)initWithSettings:(NSDictionary *)settings +- (id)initWithSettings:(NSDictionary *)settings setupBlock:(SEGAmplitudeSetupBlock)setupBlock { - return [self initWithSettings:settings andAmplitude:[Amplitude instance] andAmpRevenue:[AMPRevenue revenue] andAmpIdentify:[AMPIdentify identify]]; + return [self initWithSettings:settings andAmplitude:[Amplitude instance] andAmpRevenue:[AMPRevenue revenue] andAmpIdentify:[AMPIdentify identify] setupBlock:setupBlock]; } -- (id)initWithSettings:(NSDictionary *)settings andAmplitude:(Amplitude *)amplitude andAmpRevenue:(AMPRevenue *)amprevenue andAmpIdentify:(AMPIdentify *)identify +- (id)initWithSettings:(NSDictionary *)settings andAmplitude:(Amplitude *)amplitude andAmpRevenue:(AMPRevenue *)amprevenue andAmpIdentify:(AMPIdentify *)identify setupBlock:(SEGAmplitudeSetupBlock)setupBlock { if (self = [super init]) { self.settings = settings; @@ -24,15 +24,17 @@ - (id)initWithSettings:(NSDictionary *)settings andAmplitude:(Amplitude *)amplit self.traitsToSetOnce = [NSSet setWithArray:self.settings[@"traitsToSetOnce"]]; } + // NOTE: As of Amplitude-iOS 7.0.1, this is no longer available. A callback is used instead. + // Amplitude states that if you want location tracking disabled on startup of the app, // Call before initializing the apiKey - if ([(NSNumber *)self.settings[@"enableLocationListening"] boolValue]) { + /*if ([(NSNumber *)self.settings[@"enableLocationListening"] boolValue]) { [self.amplitude enableLocationListening]; SEGLog(@"[Ampltidue enableLocationListening]"); } else { [self.amplitude disableLocationListening]; SEGLog(@"[Ampltidue disableLocationListening]"); - } + }*/ NSString *apiKey = self.settings[@"apiKey"]; [self.amplitude initializeApiKey:apiKey]; @@ -46,6 +48,10 @@ - (id)initWithSettings:(NSDictionary *)settings andAmplitude:(Amplitude *)amplit if ([(NSNumber *)self.settings[@"useAdvertisingIdForDeviceId"] boolValue]) { [self.amplitude useAdvertisingIdForDeviceId]; } + + if (setupBlock != nil) { + setupBlock(self.amplitude); + } } return self; } diff --git a/Pod/Classes/SEGAmplitudeIntegrationFactory.h b/Pod/Classes/SEGAmplitudeIntegrationFactory.h index 5f9ee55..fa67525 100644 --- a/Pod/Classes/SEGAmplitudeIntegrationFactory.h +++ b/Pod/Classes/SEGAmplitudeIntegrationFactory.h @@ -1,9 +1,33 @@ #import #import +#import "SEGAmplitudeIntegration.h" + @interface SEGAmplitudeIntegrationFactory : NSObject + (instancetype)instance; +/** + This method can be used to set Amplitude's adSupportBlock and locationInfoBlock. + + Example: + + SEGAmplitudeIntegrationFactory *factory = [SEGAmplitudeIntegrationFactory instanceWithSetupBlock:^{ + amplitude.adSupportBlock = ^{ + return [[ASIdentifierManager sharedManager] advertisingIdentifier]; + }; + amplitude.locationInfoBlock = ^{ + return @{ + @"lat" : @37.7, + @"lng" : @122.4 + }; + }; + }]; + ... + [analyticsConfiguration use:factory]; + + */ ++ (instancetype)instanceWithSetupBlock:(SEGAmplitudeSetupBlock)setupBlock; + @end diff --git a/Pod/Classes/SEGAmplitudeIntegrationFactory.m b/Pod/Classes/SEGAmplitudeIntegrationFactory.m index 19824ee..d2c5ee7 100644 --- a/Pod/Classes/SEGAmplitudeIntegrationFactory.m +++ b/Pod/Classes/SEGAmplitudeIntegrationFactory.m @@ -2,7 +2,9 @@ #import "SEGAmplitudeIntegration.h" -@implementation SEGAmplitudeIntegrationFactory +@implementation SEGAmplitudeIntegrationFactory { + __strong SEGAmplitudeSetupBlock setupBlock; +} + (instancetype)instance { @@ -14,15 +16,23 @@ + (instancetype)instance return sharedInstance; } ++ (instancetype)instanceWithSetupBlock:(SEGAmplitudeSetupBlock)setupBlock +{ + SEGAmplitudeIntegrationFactory *factory = [SEGAmplitudeIntegrationFactory instance]; + factory->setupBlock = setupBlock; + return factory; +} + - (id)init { self = [super init]; + self->setupBlock = nil; return self; } - (id)createWithSettings:(NSDictionary *)settings forAnalytics:(SEGAnalytics *)analytics { - return [[SEGAmplitudeIntegration alloc] initWithSettings:settings]; + return [[SEGAmplitudeIntegration alloc] initWithSettings:settings setupBlock:setupBlock]; } - (NSString *)key diff --git a/Segment-Amplitude.podspec b/Segment-Amplitude.podspec index 1180b9d..604271f 100644 --- a/Segment-Amplitude.podspec +++ b/Segment-Amplitude.podspec @@ -22,5 +22,5 @@ Pod::Spec.new do |s| s.source_files = 'Pod/Classes/**/*' s.dependency 'Analytics' - s.dependency 'Amplitude', '~> 5.2.1' + s.dependency 'Amplitude' end