From 7c3d4829a63d61fc5828b617f3963d46c9241c12 Mon Sep 17 00:00:00 2001 From: Moris Gateno Date: Tue, 3 Jan 2023 12:36:43 +0200 Subject: [PATCH 01/18] unit testing first commit --- Podfile | 21 + .../SEGAppsFlyerIntegrationTests.m | 387 ++++++++++++++++++ ...SegmentAppsFlyeriOSTests-Bridging-Header.h | 4 + .../SegmentAppsFlyeriOSTests.swift | 122 ++++++ .../project.pbxproj | 245 ++++++++++- .../SegmentAppsFlyeriOSTests.xcscheme | 53 +++ 6 files changed, 831 insertions(+), 1 deletion(-) create mode 100644 Podfile create mode 100644 SegmentAppsFlyeriOSTests/SEGAppsFlyerIntegrationTests.m create mode 100644 SegmentAppsFlyeriOSTests/SegmentAppsFlyeriOSTests-Bridging-Header.h create mode 100644 SegmentAppsFlyeriOSTests/SegmentAppsFlyeriOSTests.swift create mode 100644 segment-appsflyer-ios.xcodeproj/xcshareddata/xcschemes/SegmentAppsFlyeriOSTests.xcscheme diff --git a/Podfile b/Podfile new file mode 100644 index 0000000..c586dca --- /dev/null +++ b/Podfile @@ -0,0 +1,21 @@ +# Uncomment the next line to define a global platform for your project +# platform :ios, '9.0' + +target 'segment-appsflyer-ios' do + # Comment the next line if you don't want to use dynamic frameworks + use_frameworks! + + # Pods for segment-appsflyer-ios + pod 'Analytics' + pod 'AppsFlyerFramework' + +end + +target 'SegmentAppsFlyeriOSTests' do + # Comment the next line if you don't want to use dynamic frameworks + use_frameworks! + + # Pods for SegmentAppsFlyeriOSTests + pod 'OCMock' + +end diff --git a/SegmentAppsFlyeriOSTests/SEGAppsFlyerIntegrationTests.m b/SegmentAppsFlyeriOSTests/SEGAppsFlyerIntegrationTests.m new file mode 100644 index 0000000..a9b2e32 --- /dev/null +++ b/SegmentAppsFlyeriOSTests/SEGAppsFlyerIntegrationTests.m @@ -0,0 +1,387 @@ +// +// SEGAppsFlyerIntegrationTests.m +// SegmentAppsFlyeriOSTests +// +// Created by Moris Gateno on 27/12/2022. +// Copyright © 2022 Andrii Hahan. All rights reserved. +// + +#import +@import SegmentAppsFlyeriOS; +@import OCMock; + +@interface SEGAppsFlyerIntegration() ++ (NSDecimalNumber *)extractRevenue:(NSDictionary *)dictionary withKey:(NSString *)revenueKey; ++ (NSString *)extractCurrency:(NSDictionary *)dictionary withKey:(NSString *)currencyKey; +- (void)track:(SEGTrackPayload *)payload; +- (void)onConversionDataSuccess:(nonnull NSDictionary *)conversionInfo; +- (instancetype)initWithSettings:(NSDictionary *)settings withAppsflyer:(AppsFlyerLib *)aAppsflyer; ++(NSString *) validateNil: (NSString *) value; +@end + +@interface AppsFlyerLib() +@property(nonatomic) NSString *customDataString; +@end + +@interface NSDictionary (Stringify) + +- (NSString *)afsdk_stringify; + +@end + +@interface SEGAppsFlyerIntegrationTests : XCTestCase + +@end + +@implementation SEGAppsFlyerIntegrationTests + +- (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. +} +// +//initWithSettings +// +//struct SEGAppsFlyerIntegration_initWithSettings_testCases{ +// NSDictionary * dictionaryInput; +// NSMutableArray *boolExpectedArray; +//}SEGAppsFlyerIntegration_initWithSettings_testCases; + +- (void)testSEGAppsFlyerIntegration_initWithSettings_happyFlow{ + NSDictionary * dictionaryInput = @{@"appsFlyerDevKey" : @"devKey", + @"appleAppID" : @"appID", + @"trackAttributionData" : @"123", + }; + SEGAppsFlyerIntegration *integrationObject = [[SEGAppsFlyerIntegration alloc] initWithSettings:dictionaryInput withAnalytics:[[SEGAnalytics alloc] init] ]; + XCTAssertNotNil([integrationObject analytics]); + AppsFlyerLib *appsflyerObject = [integrationObject appsflyer]; + XCTAssertNotNil(appsflyerObject); + XCTAssertTrue([[appsflyerObject appsFlyerDevKey] isEqual:@"devKey"]); + XCTAssertTrue([[appsflyerObject appleAppID] isEqual:@"appID"]); + XCTAssertNotNil([appsflyerObject delegate]); + XCTAssertNil([appsflyerObject deepLinkDelegate]); + XCTAssertNil([integrationObject segDelegate]); + XCTAssertNil([integrationObject segDLDelegate]); + XCTAssertFalse([integrationObject manualMode]); +} + +- (void)testSEGAppsFlyerIntegration_initWithSettings_nilFlow_noDevKey{ + NSDictionary * dictionaryInput = @{@"appleAppID" : @"appID", + @"trackAttributionData" : @"123", + }; + SEGAppsFlyerIntegration *integrationObject = [[SEGAppsFlyerIntegration alloc] initWithSettings:dictionaryInput withAnalytics:nil]; + AppsFlyerLib *appsflyerObject = [integrationObject appsflyer]; + XCTAssertNotNil(appsflyerObject); + XCTAssertTrue([[appsflyerObject appsFlyerDevKey] isEqual:@""]); +} + +- (void)testSEGAppsFlyerIntegration_initWithSettings_nilFlow_noAppleID{ + NSDictionary * dictionaryInput = @{@"appsFlyerDevKey" : @"devKey", + @"trackAttributionData" : @"123", + }; + SEGAppsFlyerIntegration *integrationObject = [[SEGAppsFlyerIntegration alloc] initWithSettings:dictionaryInput withAnalytics:nil]; + AppsFlyerLib *appsflyerObject = [integrationObject appsflyer]; + XCTAssertNotNil(appsflyerObject); + XCTAssertTrue([[appsflyerObject appleAppID] isEqual:@""]); +} + +-(void)testSEGAppsFlyerIntegration_initWithSettings_nilFlow_noTrackingAttributionData{ + NSDictionary * dictionaryInput = @{@"appsFlyerDevKey" : @"devKey", + @"appleAppID" : @"appID" + }; + SEGAppsFlyerIntegration *integrationObject = [[SEGAppsFlyerIntegration alloc] initWithSettings:dictionaryInput withAnalytics:nil]; + AppsFlyerLib *appsflyerObject = [integrationObject appsflyer]; + XCTAssertNotNil(appsflyerObject); + XCTAssertNil([appsflyerObject delegate]); +} + +//this test doesn't go through because [self.appsflyer setAppsFlyerDevKey:afDevKey]; +//does not accept number value. - need to check in this function the type of devkey and apple id before setting them. +//- (void)testSEGAppsFlyerIntegration_initWithSettings_negativeFlow_devKeyIsANumber{ +// NSDictionary * dictionaryInput = @{@"appsFlyerDevKey" : @(123), +// @"appleAppID" : @"appID", +// @"trackAttributionData" : @"123" +// }; +// SEGAppsFlyerIntegration *integrationObject = [[SEGAppsFlyerIntegration alloc] initWithSettings:dictionaryInput withAnalytics:nil]; +// AppsFlyerLib *appsflyerObject = [integrationObject appsflyer]; +// XCTAssertNotNil(appsflyerObject); +// XCTAssertNil([appsflyerObject delegate]); +//} + +// +//initWithSettings andDelegate +// +- (void)testSEGAppsFlyerIntegration_initWithSettingsAndDelegate_happyFlow{ + + SEGAppsFlyerIntegration *integrationObject = [[SEGAppsFlyerIntegration alloc] initWithSettings:nil withAnalytics:nil andDelegate:self]; + XCTAssertNotNil([integrationObject segDelegate]); + XCTAssertTrue([[integrationObject segDelegate] isEqual:self]); +} + +- (void)testSEGAppsFlyerIntegration_initWithSettingsAndDelegate_nilFlow{ + SEGAppsFlyerIntegration *integrationObject = [[SEGAppsFlyerIntegration alloc] initWithSettings:nil withAnalytics:nil andDelegate:nil]; + XCTAssertNil([integrationObject segDelegate]); +} + +// +//initWithSettings andDelegate andDeepLinkDelegate andManualMode +// +- (void)testSEGAppsFlyerIntegration_initWithSettingsAndDelegateandDeepLinkDelegateandManualMode_happyFlow{ + + SEGAppsFlyerIntegration *integrationObject = [[SEGAppsFlyerIntegration alloc] initWithSettings:nil withAnalytics:nil andDelegate:self andDeepLinkDelegate:self andManualMode:false]; + XCTAssertNotNil([integrationObject segDelegate]); + XCTAssertTrue([[integrationObject segDelegate] isEqual:self]); + XCTAssertNotNil([integrationObject segDLDelegate]); + XCTAssertTrue([[integrationObject segDLDelegate] isEqual:self]); + XCTAssertFalse([integrationObject manualMode]); + integrationObject = [[SEGAppsFlyerIntegration alloc] initWithSettings:nil withAnalytics:nil andDelegate:nil andDeepLinkDelegate:self andManualMode:true]; + XCTAssertTrue([integrationObject manualMode]); +} + +- (void)testSEGAppsFlyerIntegration_initWithSettingsAndDelegateandDeepLinkDelegateandManualMode_nilFlow{ + + SEGAppsFlyerIntegration *integrationObject = [[SEGAppsFlyerIntegration alloc] initWithSettings:nil withAnalytics:nil andDelegate:nil andDeepLinkDelegate:nil andManualMode:nil]; + XCTAssertNil([integrationObject segDLDelegate]); + XCTAssertNil([integrationObject segDelegate]); + XCTAssertFalse([integrationObject manualMode]); +} + +// +//initWithSettings andDelegate aAppsflyer +// +- (void)testSEGAppsFlyerIntegration_initWithSettingsaAppsflyer_happyFlow{ + NSDictionary * dictionaryInput = @{@"appsFlyerDevKey" : @"devKey", + @"appleAppID" : @"appID", + @"trackAttributionData" : @"123", + }; + AppsFlyerLib * appsFlyerObject =[[AppsFlyerLib alloc] init]; + SEGAppsFlyerIntegration *integrationObject = [[SEGAppsFlyerIntegration alloc] initWithSettings:dictionaryInput withAppsflyer:appsFlyerObject]; + XCTAssertTrue([[[integrationObject appsflyer] appsFlyerDevKey] isEqual:@"devKey"]); + XCTAssertTrue([[[integrationObject appsflyer] appleAppID] isEqual:@"appID"]); + XCTAssertNotNil([[integrationObject appsflyer] delegate]); + XCTAssertTrue([[[integrationObject appsflyer] delegate] isEqual:integrationObject]); + XCTAssertNil([[integrationObject appsflyer] deepLinkDelegate]); +} + +- (void)testSEGAppsFlyerIntegration_initWithSettingsaAppsflyer_nilFlow{ + SEGAppsFlyerIntegration *integrationObject = [[SEGAppsFlyerIntegration alloc] initWithSettings:nil withAppsflyer:nil]; + XCTAssertNil([integrationObject appsflyer]); + XCTAssertNil([integrationObject settings]); +} + +// +// identify +// + +-(void)testSEGAppsFlyerIntegration_identify_happyFlow{ + NSDictionary * settings = @{@"appsFlyerDevKey" : @"devKey", + @"appleAppID" : @"appID", + @"trackAttributionData" : @"123", + }; + SEGAppsFlyerIntegration *integrationObject = [[SEGAppsFlyerIntegration alloc] initWithSettings:settings withAnalytics:nil]; + NSMutableDictionary * traits = @{@"email":@"moris@apps.com", @"firstName":@"Moris", @"lastName":@"Gateno", @"username":@"moris98", @"currencyCode":@"1312"}; + SEGIdentifyPayload * payload = [[SEGIdentifyPayload alloc] initWithUserId:@"moris" anonymousId:nil traits:traits context:@{} integrations:@{}]; + [integrationObject identify:payload]; + XCTAssertTrue([[[integrationObject appsflyer] currencyCode] isEqual:@"1312"]); + XCTAssertTrue([[[integrationObject appsflyer] customerUserID] isEqual:@"moris"]); + NSString * customData = [[integrationObject appsflyer] customDataString]; + + NSString * stringified = [@{@"email":@"moris@apps.com", @"firstName":@"Moris", @"lastName":@"Gateno", @"username":@"moris98"} afsdk_stringify]; + XCTAssertTrue([stringified isEqual:customData]); +} + +-(void)testSEGAppsFlyerIntegration_identify_nilFlow{ + NSDictionary * settings = @{@"appsFlyerDevKey" : @"devKey", + @"appleAppID" : @"appID", + @"trackAttributionData" : @"123", + }; + SEGAppsFlyerIntegration *integrationObject = [[SEGAppsFlyerIntegration alloc] initWithSettings:settings withAnalytics:nil]; + NSMutableDictionary * traits = nil; + SEGIdentifyPayload * payload = [[SEGIdentifyPayload alloc] initWithUserId:nil anonymousId:nil traits:traits context:nil integrations:nil]; + [integrationObject identify:payload]; + NSString * customerUserID = [[integrationObject appsflyer] customerUserID]; + NSString * customData = [[integrationObject appsflyer] customDataString]; + XCTAssertNil([[integrationObject appsflyer] currencyCode]); + XCTAssertNil([[integrationObject appsflyer] customerUserID]); + XCTAssertTrue([customData isEqual:@"{}"]); + XCTAssertNil(customerUserID); +} + +// +//track +// +- (void)testSEGAppsFlyerIntegration_track_happyFlow_withCurrencyAndRevenue{ + id appsFlyerMock = OCMClassMock([AppsFlyerLib class]); + OCMStub([appsFlyerMock logEvent:[OCMArg checkWithBlock:^BOOL(id obj) { + XCTAssertTrue([obj isEqual:@"testEvent"]); + return YES; + }] withValues:[OCMArg checkWithBlock:^BOOL(id obj) { + XCTAssertTrue([obj[@"af_currency"] isEqual: @"ILS"]); + XCTAssertTrue([obj[@"af_revenue"] isEqual: @(10.1)]); + XCTAssertTrue([obj[@"currency"] isEqual: @"ILS"]); + XCTAssertTrue([obj[@"revenue"] isEqual: @"10.1"]); + return YES; + }]]); + SEGAppsFlyerIntegration *integrationObject = [[SEGAppsFlyerIntegration alloc] init]; + [integrationObject setAppsflyer: appsFlyerMock]; + NSMutableDictionary * dictionary = @{@"revenue" : @"10.1", @"currency" : @"ILS"}; + SEGTrackPayload * payload = [[SEGTrackPayload alloc] initWithEvent:@"testEvent" properties: dictionary context:@{} integrations:@{}]; + [integrationObject track:payload]; +} + +-(void)testSEGAppsFlyerIntegration_track_nilFlow{ + id appsFlyerMock = OCMClassMock([AppsFlyerLib class]); + OCMStub([appsFlyerMock logEvent:[OCMArg checkWithBlock:^BOOL(id obj) { + XCTAssertNil(obj); + return YES; + }] withValues:[OCMArg checkWithBlock:^BOOL(id obj) { + XCTAssertNil(obj); + return YES; + }]]); + SEGAppsFlyerIntegration *integrationObject = [[SEGAppsFlyerIntegration alloc] init]; + [integrationObject setAppsflyer: appsFlyerMock]; + SEGTrackPayload * payload = [[SEGTrackPayload alloc] initWithEvent:nil properties: nil context:@{} integrations:@{}]; + [integrationObject track:payload]; +} + +-(void)testSEGAppsFlyerIntegration_track_negativeFlow_numberAsKeyWhenWhileLogEventExpectsString{ + id appsFlyerMock = OCMClassMock([AppsFlyerLib class]); + OCMStub([appsFlyerMock logEvent:[OCMArg checkWithBlock:^BOOL(id obj) { + XCTAssertNil(obj); + return YES; + }] withValues:[OCMArg checkWithBlock:^BOOL(id obj) { + XCTAssertNotNil(obj); + XCTAssertTrue([[[obj allKeys] objectAtIndex:0] isKindOfClass:[NSNumber class]]); + return YES; + }]]); + SEGAppsFlyerIntegration *integrationObject = [[SEGAppsFlyerIntegration alloc] init]; + [integrationObject setAppsflyer: appsFlyerMock]; + NSMutableDictionary * dictionary = @{@(10):@(11)}; + SEGTrackPayload * payload = [[SEGTrackPayload alloc] initWithEvent:nil properties: dictionary context:@{} integrations:@{}]; + [integrationObject track:payload]; +} + +// +//extractCurrency +// +- (void)testSEGAppsFlyerIntegration_extractCurrency_happyFlow_stringInput { + NSDictionary * dictionaryInput = @{ @"key" : @"ILS"}; + NSString * outputCurrency = [SEGAppsFlyerIntegration extractCurrency:dictionaryInput withKey:@"key"]; + XCTAssertTrue([dictionaryInput[@"key"] isEqual:outputCurrency] ); +} + +- (void)testSEGAppsFlyerIntegration_extractCurrency_nilflow { + NSDictionary * dictionaryInput = @{ @"key" : [NSNull null]}; + NSString * outputCurrency = [SEGAppsFlyerIntegration extractCurrency:dictionaryInput withKey:@"key"]; + XCTAssertFalse([dictionaryInput[@"key"] isEqual:outputCurrency]); + XCTAssertTrue([outputCurrency isEqual:@"USD"]); + dictionaryInput = @{}; + outputCurrency = [SEGAppsFlyerIntegration extractCurrency:dictionaryInput withKey:@"key"]; + XCTAssertTrue([outputCurrency isEqual:@"USD"]); +} + +- (void)testSEGAppsFlyerIntegration_extractCurrency_negativeflow_keyNotExists { + NSDictionary * dictionaryInput = @{ @"key" : @"ILS"}; + NSString * outputCurrency = [SEGAppsFlyerIntegration extractCurrency:dictionaryInput withKey:@"key2"]; + XCTAssertFalse([dictionaryInput[@"key"] isEqual:outputCurrency]); + XCTAssertTrue([outputCurrency isEqual:@"USD"]); +} + +- (void)testSEGAppsFlyerIntegration_extractCurrency_negativeFlow_intInput { + NSDictionary * dictionaryInput = @{ @"key" : @(12.0)}; + NSString * outputCurrency = [SEGAppsFlyerIntegration extractCurrency:dictionaryInput withKey:@"key"]; + XCTAssertNotEqual(dictionaryInput[@"key"], outputCurrency); + XCTAssertTrue([outputCurrency isEqual:@"USD"]); +} + + +// +//extractRevenue +// +- (void)testSEGAppsFlyerIntegration_extractRevenue_happyFlow_stringInput { + NSDictionary * dictionaryInput = @{ @"key" : @"12.1"}; + NSDecimalNumber * outputRevenue = [SEGAppsFlyerIntegration extractRevenue:dictionaryInput withKey:@"key"]; + XCTAssertTrue([outputRevenue isEqual:@(12.1)]); +} + +- (void)testSEGAppsFlyerIntegration_extractRevenue_happyFlow_numberInput { + NSDictionary * dictionaryInput = @{@"key" : @(12.1)}; + NSDecimalNumber * outputRevenue = [SEGAppsFlyerIntegration extractRevenue:dictionaryInput withKey:@"key"]; + XCTAssertTrue([outputRevenue isEqual:@(12.1)]); +} + +- (void)testSEGAppsFlyerIntegration_extractRevenue_nilFlow_valueNilForKey { + NSDictionary * dictionaryInput = @{@"key" : [NSNull null]}; + NSDecimalNumber * outputRevenue = [SEGAppsFlyerIntegration extractRevenue:dictionaryInput withKey:@"key"]; + // XCTAssertTrue([outputRevenue isEqual:@(12.1)]); + XCTAssertNil(outputRevenue); +} + +- (void)testSEGAppsFlyerIntegration_extractRevenue_nilFlow_nilForDictionary { + NSDictionary * dictionaryInput = nil; + NSDecimalNumber * outputRevenue = [SEGAppsFlyerIntegration extractRevenue:dictionaryInput withKey:@"key"]; + // XCTAssertTrue([outputRevenue isEqual:@(12.1)]); + XCTAssertNil(outputRevenue); +} + +- (void)testSEGAppsFlyerIntegration_extractRevenue_negativeFlow_missingKey { + NSDictionary * dictionaryInput = @{}; + NSDecimalNumber * outputRevenue = [SEGAppsFlyerIntegration extractRevenue:dictionaryInput withKey:@"key"]; + // XCTAssertTrue([outputRevenue isEqual:@(12.1)]); + XCTAssertNil(outputRevenue); +} + +- (void)testSEGAppsFlyerIntegration_extractRevenue_negativeFlow_stringNotNumber { + NSDictionary * dictionaryInput = @{@"key" : @"moris"}; + NSDecimalNumber * outputRevenue = [SEGAppsFlyerIntegration extractRevenue:dictionaryInput withKey:@"key"]; + XCTAssertTrue(isnan(outputRevenue.doubleValue)); +} + +- (void)testSEGAppsFlyerIntegration_extractRevenue_negativeFlow_keyNotExists { + NSDictionary * dictionaryInput = @{@"key" : @"moris"}; + NSDecimalNumber * outputRevenue = [SEGAppsFlyerIntegration extractRevenue:dictionaryInput withKey:@"key1"]; + XCTAssertNil(outputRevenue); +} + +// +//validateNil +// +- (void)testSEGAppsFlyerIntegration_validateNil_happyFlow_withString { + NSString * outputValidateNil = [SEGAppsFlyerIntegration validateNil:@"moris"]; + XCTAssertTrue([outputValidateNil isEqual:@"moris"]); +} + +- (void)testSEGAppsFlyerIntegration_validateNil_happyFlow_withNil { + NSString * outputValidateNil = [SEGAppsFlyerIntegration validateNil:nil]; + XCTAssertTrue([outputValidateNil isEqual:@""]); + outputValidateNil = [SEGAppsFlyerIntegration validateNil:[NSNull null]]; + XCTAssertTrue([outputValidateNil isEqual:@""]); +} + +- (void)testSEGAppsFlyerIntegration_validateNil_negativeFlow { + NSString * outputValidateNil = [SEGAppsFlyerIntegration validateNil:@(10.0)]; + XCTAssertTrue([outputValidateNil isEqual:@(10.0)]); +} + +// +// onConversionDataSuccess +// +//- (void)testSEGAppsFlyerIntegration_onConversionDataSuccess_happyflow{ +// [[NSUserDefaults standardUserDefaults] setPersistentDomain:[NSDictionary dictionary] forName:[[NSBundle mainBundle] bundleIdentifier]]; +// SEGAppsFlyerIntegration *integrationObject = [[SEGAppsFlyerIntegration alloc] initWithSettings:@{} withAnalytics:nil andDelegate:self]; +// [[integrationObject segDelegate] ] +// [integrationObject onConversionDataSuccess:@{}]; +//} + + +- (void)testPerformanceExample { + // This is an example of a performance test case. + [self measureBlock:^{ + // Put the code you want to measure the time of here. + }]; +} + +@end diff --git a/SegmentAppsFlyeriOSTests/SegmentAppsFlyeriOSTests-Bridging-Header.h b/SegmentAppsFlyeriOSTests/SegmentAppsFlyeriOSTests-Bridging-Header.h new file mode 100644 index 0000000..1b2cb5d --- /dev/null +++ b/SegmentAppsFlyeriOSTests/SegmentAppsFlyeriOSTests-Bridging-Header.h @@ -0,0 +1,4 @@ +// +// Use this file to import your target's public headers that you would like to expose to Swift. +// + diff --git a/SegmentAppsFlyeriOSTests/SegmentAppsFlyeriOSTests.swift b/SegmentAppsFlyeriOSTests/SegmentAppsFlyeriOSTests.swift new file mode 100644 index 0000000..e5d7602 --- /dev/null +++ b/SegmentAppsFlyeriOSTests/SegmentAppsFlyeriOSTests.swift @@ -0,0 +1,122 @@ +// +// SegmentAppsFlyeriOSTests.swift +// SegmentAppsFlyeriOSTests +// +// Created by Moris Gateno on 27/12/2022. +// Copyright © 2022 Andrii Hahan. All rights reserved. +// + +import XCTest +import SegmentAppsFlyeriOS + + + +final class SegmentAppsFlyeriOSTests: XCTestCase , SEGAppsFlyerLibDelegate, SEGAppsFlyerDeepLinkDelegate { + func onConversionDataSuccess(_ conversionInfo: [AnyHashable : Any]) { + print("onConversionDataSuccess") + } + + func onConversionDataFail(_ error: Error) { + print("onConversionDataFail") + } + + + override func setUpWithError() throws { + // Put setup code here. This method is called before the invocation of each test method in the class. + } + + override func tearDownWithError() throws { + // Put teardown code here. This method is called after the invocation of each test method in the class. + } + + // + //instance + // + func testSEGAppsFlyerIntegrationFactory_instance_happyFlow() throws { + let factoryObject = SEGAppsFlyerIntegrationFactory.instance() + XCTAssertNil(factoryObject?.delegate) + XCTAssertNil(factoryObject?.dlDelegate) + XCTAssertEqual(factoryObject?.manualMode,false) + } + + // + //createWithLaunchDelegate + // + func testSEGAppsFlyerIntegrationFactory_createWithLaunchDelegate_happyFlow() throws { + let factoryObject = SEGAppsFlyerIntegrationFactory.create(withLaunch:self) + XCTAssertNotNil(factoryObject?.delegate) + XCTAssertTrue(((factoryObject?.delegate.isEqual(self)) != nil)) + XCTAssertNil(factoryObject?.dlDelegate) + XCTAssertEqual(factoryObject?.manualMode,false) + } + + func testSEGAppsFlyerIntegrationFactory_createWithLaunchDelegate_nilFlow() throws { + let factoryObject = SEGAppsFlyerIntegrationFactory.create(withLaunch:nil) + XCTAssertNil(factoryObject?.delegate) + } + + // + //createWithLaunchDelegate andDeepLinkDelegate + // + + func testSEGAppsFlyerIntegrationFactory_createWithLaunchDelegateandDeepLinkDelegate_happyFlow() throws { + let factoryObject = SEGAppsFlyerIntegrationFactory.create(withLaunch: self, andDeepLinkDelegate: self) + XCTAssertNotNil(factoryObject?.delegate) + XCTAssertNotNil(factoryObject?.dlDelegate) + XCTAssertTrue(((factoryObject?.delegate.isEqual(self)) != nil)) + XCTAssertTrue(((factoryObject?.dlDelegate.isEqual(self)) != nil)) + XCTAssertEqual(factoryObject?.manualMode,false) + } + + func testSEGAppsFlyerIntegrationFactory_createWithLaunchDelegateandDeepLinkDelegate_nilFlow() throws { + let factoryObject = SEGAppsFlyerIntegrationFactory.create(withLaunch: nil, andDeepLinkDelegate: nil) + XCTAssertNil(factoryObject?.delegate) + XCTAssertNil(factoryObject?.dlDelegate) + } + + // + //createWithLaunchDelegate andManualMode + // + + func testSEGAppsFlyerIntegrationFactory_createWithLaunchDelegateandManualMode_happyFlow() throws { + var factoryObject = SEGAppsFlyerIntegrationFactory.create(withLaunch: self, andManualMode: true) + XCTAssertNotNil(factoryObject?.delegate) + XCTAssertNil(factoryObject?.dlDelegate) + XCTAssertTrue(((factoryObject?.delegate.isEqual(self)) != nil)) + XCTAssertEqual(factoryObject?.manualMode,true) + factoryObject = SEGAppsFlyerIntegrationFactory.create(withLaunch: self, andManualMode: false) + XCTAssertEqual(factoryObject?.manualMode,false) + } + + // + //createWithLaunchDelegate andDeepLinkDelegate andManualMode + // + func testSEGAppsFlyerIntegrationFactory_createWithLaunchDelegateandDeepLinkDelegateandManualMode_happyFlow() throws { + let factoryObject = SEGAppsFlyerIntegrationFactory.create(withLaunch: self, andDeepLinkDelegate: self, andManualMode: true) + XCTAssertNotNil(factoryObject?.delegate) + XCTAssertNotNil(factoryObject?.dlDelegate) + XCTAssertTrue(((factoryObject?.delegate.isEqual(self)) != nil)) + XCTAssertTrue(((factoryObject?.dlDelegate.isEqual(self)) != nil)) + XCTAssertEqual(factoryObject?.manualMode,true) + } + + // + //createWithSettings + // + func testSEGAppsFlyerIntegrationFactory_createWithSettings_happyFlow() throws { + let factoryObject = SEGAppsFlyerIntegrationFactory.create(withLaunch: self, andDeepLinkDelegate: self, andManualMode: true) + let integrationObject : SEGAppsFlyerIntegration = factoryObject?.create(withSettings: Dictionary(), for: Analytics()) as! SEGAppsFlyerIntegration + XCTAssertNotNil(integrationObject) + XCTAssertTrue(integrationObject.manualMode==true) + XCTAssertTrue(integrationObject.segDelegate.isEqual(self)) + XCTAssertTrue(integrationObject.segDLDelegate.isEqual(self)) + } + + func testPerformanceExample() throws { + // This is an example of a performance test case. + measure { + // Put the code you want to measure the time of here. + } + } + +} diff --git a/segment-appsflyer-ios.xcodeproj/project.pbxproj b/segment-appsflyer-ios.xcodeproj/project.pbxproj index 09040ae..d5c79d8 100644 --- a/segment-appsflyer-ios.xcodeproj/project.pbxproj +++ b/segment-appsflyer-ios.xcodeproj/project.pbxproj @@ -3,10 +3,12 @@ archiveVersion = 1; classes = { }; - objectVersion = 50; + objectVersion = 51; objects = { /* Begin PBXBuildFile section */ + 2A3CCD9C585BAFEE9F613B34 /* Pods_segment_appsflyer_ios.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 437DD4AF7134A231805D0B6A /* Pods_segment_appsflyer_ios.framework */; }; + 346AB37FAF5A3B97A508A009 /* Pods_SegmentAppsFlyeriOSTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 07C52ECF9F96ADBC1AD50CBE /* Pods_SegmentAppsFlyeriOSTests.framework */; }; 47A0A8F623D5CA7A00FE781F /* SEGAppsFlyerIntegration.m in Sources */ = {isa = PBXBuildFile; fileRef = 47A0A8F123D5CA7A00FE781F /* SEGAppsFlyerIntegration.m */; }; 47A0A8F723D5CA7A00FE781F /* SEGAppsFlyerIntegrationFactory.m in Sources */ = {isa = PBXBuildFile; fileRef = 47A0A8F223D5CA7A00FE781F /* SEGAppsFlyerIntegrationFactory.m */; }; 47A0A8F823D5CA7A00FE781F /* SegmentAppsFlyeriOS.h in Headers */ = {isa = PBXBuildFile; fileRef = 47A0A8F323D5CA7A00FE781F /* SegmentAppsFlyeriOS.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -14,9 +16,27 @@ 47A0A8FA23D5CA7A00FE781F /* SEGAppsFlyerIntegrationFactory.h in Headers */ = {isa = PBXBuildFile; fileRef = 47A0A8F523D5CA7A00FE781F /* SEGAppsFlyerIntegrationFactory.h */; settings = {ATTRIBUTES = (Public, ); }; }; 86F430F225B4369500BD66B9 /* AppsFlyerLib.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 47A0A8FD23D5CF8B00FE781F /* AppsFlyerLib.framework */; }; 86F430F525B4369600BD66B9 /* Segment.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 868810BD258FB606001F6545 /* Segment.framework */; }; + A5201335295B1A5B00B87090 /* SEGAppsFlyerIntegrationTests.m in Sources */ = {isa = PBXBuildFile; fileRef = A5201334295B1A5B00B87090 /* SEGAppsFlyerIntegrationTests.m */; }; + A52E9C84295B0478004EC3DF /* SegmentAppsFlyeriOSTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = A52E9C83295B0478004EC3DF /* SegmentAppsFlyeriOSTests.swift */; }; + A52E9C85295B0478004EC3DF /* SegmentAppsFlyeriOS.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 47A0A8DA23D5B13500FE781F /* SegmentAppsFlyeriOS.framework */; }; /* End PBXBuildFile section */ +/* Begin PBXContainerItemProxy section */ + A52E9C86295B0478004EC3DF /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 47A0A8D123D5B13500FE781F /* Project object */; + proxyType = 1; + remoteGlobalIDString = 47A0A8D923D5B13500FE781F; + remoteInfo = "segment-appsflyer-ios"; + }; +/* End PBXContainerItemProxy section */ + /* Begin PBXFileReference section */ + 07C52ECF9F96ADBC1AD50CBE /* Pods_SegmentAppsFlyeriOSTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_SegmentAppsFlyeriOSTests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 11D1EE0DB4918D94DDCA0894 /* Pods-SegmentAppsFlyeriOSTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-SegmentAppsFlyeriOSTests.release.xcconfig"; path = "Target Support Files/Pods-SegmentAppsFlyeriOSTests/Pods-SegmentAppsFlyeriOSTests.release.xcconfig"; sourceTree = ""; }; + 1548A28C2E5C46E858B31098 /* Pods-SegmentAppsFlyeriOSTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-SegmentAppsFlyeriOSTests.debug.xcconfig"; path = "Target Support Files/Pods-SegmentAppsFlyeriOSTests/Pods-SegmentAppsFlyeriOSTests.debug.xcconfig"; sourceTree = ""; }; + 383CE4C70EA898B25B26039C /* Pods-segment-appsflyer-ios.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-segment-appsflyer-ios.release.xcconfig"; path = "Target Support Files/Pods-segment-appsflyer-ios/Pods-segment-appsflyer-ios.release.xcconfig"; sourceTree = ""; }; + 437DD4AF7134A231805D0B6A /* Pods_segment_appsflyer_ios.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_segment_appsflyer_ios.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 47A0A8DA23D5B13500FE781F /* SegmentAppsFlyeriOS.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SegmentAppsFlyeriOS.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 47A0A8DE23D5B13500FE781F /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 47A0A8F123D5CA7A00FE781F /* SEGAppsFlyerIntegration.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SEGAppsFlyerIntegration.m; sourceTree = ""; }; @@ -28,6 +48,11 @@ 47A0A8FD23D5CF8B00FE781F /* AppsFlyerLib.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppsFlyerLib.framework; path = Carthage/Build/iOS/AppsFlyerLib.framework; sourceTree = ""; }; 86881093258F9113001F6545 /* segment_appsflyer_ios.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = segment_appsflyer_ios.framework; path = Carthage/Build/iOS/Static/segment_appsflyer_ios.framework; sourceTree = ""; }; 868810BD258FB606001F6545 /* Segment.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Segment.framework; path = Carthage/Build/iOS/Segment.framework; sourceTree = ""; }; + 99A7276F2E4C0F6453ECA910 /* Pods-segment-appsflyer-ios.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-segment-appsflyer-ios.debug.xcconfig"; path = "Target Support Files/Pods-segment-appsflyer-ios/Pods-segment-appsflyer-ios.debug.xcconfig"; sourceTree = ""; }; + A5201333295B1A5B00B87090 /* SegmentAppsFlyeriOSTests-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "SegmentAppsFlyeriOSTests-Bridging-Header.h"; sourceTree = ""; }; + A5201334295B1A5B00B87090 /* SEGAppsFlyerIntegrationTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SEGAppsFlyerIntegrationTests.m; sourceTree = ""; }; + A52E9C81295B0478004EC3DF /* SegmentAppsFlyeriOSTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = SegmentAppsFlyeriOSTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + A52E9C83295B0478004EC3DF /* SegmentAppsFlyeriOSTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SegmentAppsFlyeriOSTests.swift; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -37,6 +62,16 @@ files = ( 86F430F525B4369600BD66B9 /* Segment.framework in Frameworks */, 86F430F225B4369500BD66B9 /* AppsFlyerLib.framework in Frameworks */, + 2A3CCD9C585BAFEE9F613B34 /* Pods_segment_appsflyer_ios.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + A52E9C7E295B0478004EC3DF /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + A52E9C85295B0478004EC3DF /* SegmentAppsFlyeriOS.framework in Frameworks */, + 346AB37FAF5A3B97A508A009 /* Pods_SegmentAppsFlyeriOSTests.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -47,8 +82,10 @@ isa = PBXGroup; children = ( 47A0A8DC23D5B13500FE781F /* segment-appsflyer-ios */, + A52E9C82295B0478004EC3DF /* SegmentAppsFlyeriOSTests */, 47A0A8DB23D5B13500FE781F /* Products */, 47A0A8FB23D5CF8B00FE781F /* Frameworks */, + A7E5A8BDE3AE44B9A11797D8 /* Pods */, ); sourceTree = ""; }; @@ -56,6 +93,7 @@ isa = PBXGroup; children = ( 47A0A8DA23D5B13500FE781F /* SegmentAppsFlyeriOS.framework */, + A52E9C81295B0478004EC3DF /* SegmentAppsFlyeriOSTests.xctest */, ); name = Products; sourceTree = ""; @@ -88,10 +126,33 @@ 86881093258F9113001F6545 /* segment_appsflyer_ios.framework */, 47A0A8FC23D5CF8B00FE781F /* Analytics.framework */, 47A0A8FD23D5CF8B00FE781F /* AppsFlyerLib.framework */, + 07C52ECF9F96ADBC1AD50CBE /* Pods_SegmentAppsFlyeriOSTests.framework */, + 437DD4AF7134A231805D0B6A /* Pods_segment_appsflyer_ios.framework */, ); name = Frameworks; sourceTree = ""; }; + A52E9C82295B0478004EC3DF /* SegmentAppsFlyeriOSTests */ = { + isa = PBXGroup; + children = ( + A52E9C83295B0478004EC3DF /* SegmentAppsFlyeriOSTests.swift */, + A5201334295B1A5B00B87090 /* SEGAppsFlyerIntegrationTests.m */, + A5201333295B1A5B00B87090 /* SegmentAppsFlyeriOSTests-Bridging-Header.h */, + ); + path = SegmentAppsFlyeriOSTests; + sourceTree = ""; + }; + A7E5A8BDE3AE44B9A11797D8 /* Pods */ = { + isa = PBXGroup; + children = ( + 1548A28C2E5C46E858B31098 /* Pods-SegmentAppsFlyeriOSTests.debug.xcconfig */, + 11D1EE0DB4918D94DDCA0894 /* Pods-SegmentAppsFlyeriOSTests.release.xcconfig */, + 99A7276F2E4C0F6453ECA910 /* Pods-segment-appsflyer-ios.debug.xcconfig */, + 383CE4C70EA898B25B26039C /* Pods-segment-appsflyer-ios.release.xcconfig */, + ); + path = Pods; + sourceTree = ""; + }; /* End PBXGroup section */ /* Begin PBXHeadersBuildPhase section */ @@ -112,6 +173,7 @@ isa = PBXNativeTarget; buildConfigurationList = 47A0A8E223D5B13500FE781F /* Build configuration list for PBXNativeTarget "segment-appsflyer-ios" */; buildPhases = ( + C5EA81FA1F91B439A397062C /* [CP] Check Pods Manifest.lock */, 47A0A8D523D5B13500FE781F /* Headers */, 47A0A8D623D5B13500FE781F /* Sources */, 47A0A8D723D5B13500FE781F /* Frameworks */, @@ -126,18 +188,43 @@ productReference = 47A0A8DA23D5B13500FE781F /* SegmentAppsFlyeriOS.framework */; productType = "com.apple.product-type.framework"; }; + A52E9C80295B0478004EC3DF /* SegmentAppsFlyeriOSTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = A52E9C8A295B0478004EC3DF /* Build configuration list for PBXNativeTarget "SegmentAppsFlyeriOSTests" */; + buildPhases = ( + 3CDF7EA87A7C169A0A162476 /* [CP] Check Pods Manifest.lock */, + A52E9C7D295B0478004EC3DF /* Sources */, + A52E9C7E295B0478004EC3DF /* Frameworks */, + A52E9C7F295B0478004EC3DF /* Resources */, + E7E438810DBA7433C972DB6D /* [CP] Embed Pods Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + A52E9C87295B0478004EC3DF /* PBXTargetDependency */, + ); + name = SegmentAppsFlyeriOSTests; + productName = SegmentAppsFlyeriOSTests; + productReference = A52E9C81295B0478004EC3DF /* SegmentAppsFlyeriOSTests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ 47A0A8D123D5B13500FE781F /* Project object */ = { isa = PBXProject; attributes = { + LastSwiftUpdateCheck = 1410; LastUpgradeCheck = 1240; ORGANIZATIONNAME = "Andrii Hahan"; TargetAttributes = { 47A0A8D923D5B13500FE781F = { CreatedOnToolsVersion = 11.2; }; + A52E9C80295B0478004EC3DF = { + CreatedOnToolsVersion = 14.1; + LastSwiftMigration = 1410; + }; }; }; buildConfigurationList = 47A0A8D423D5B13500FE781F /* Build configuration list for PBXProject "segment-appsflyer-ios" */; @@ -154,6 +241,7 @@ projectRoot = ""; targets = ( 47A0A8D923D5B13500FE781F /* segment-appsflyer-ios */, + A52E9C80295B0478004EC3DF /* SegmentAppsFlyeriOSTests */, ); }; /* End PBXProject section */ @@ -166,8 +254,79 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + A52E9C7F295B0478004EC3DF /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXResourcesBuildPhase section */ +/* Begin PBXShellScriptBuildPhase section */ + 3CDF7EA87A7C169A0A162476 /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-SegmentAppsFlyeriOSTests-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; + C5EA81FA1F91B439A397062C /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-segment-appsflyer-ios-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; + E7E438810DBA7433C972DB6D /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-SegmentAppsFlyeriOSTests/Pods-SegmentAppsFlyeriOSTests-frameworks-${CONFIGURATION}-input-files.xcfilelist", + ); + name = "[CP] Embed Pods Frameworks"; + outputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-SegmentAppsFlyeriOSTests/Pods-SegmentAppsFlyeriOSTests-frameworks-${CONFIGURATION}-output-files.xcfilelist", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-SegmentAppsFlyeriOSTests/Pods-SegmentAppsFlyeriOSTests-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; +/* End PBXShellScriptBuildPhase section */ + /* Begin PBXSourcesBuildPhase section */ 47A0A8D623D5B13500FE781F /* Sources */ = { isa = PBXSourcesBuildPhase; @@ -178,8 +337,25 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + A52E9C7D295B0478004EC3DF /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + A52E9C84295B0478004EC3DF /* SegmentAppsFlyeriOSTests.swift in Sources */, + A5201335295B1A5B00B87090 /* SEGAppsFlyerIntegrationTests.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXSourcesBuildPhase section */ +/* Begin PBXTargetDependency section */ + A52E9C87295B0478004EC3DF /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 47A0A8D923D5B13500FE781F /* segment-appsflyer-ios */; + targetProxy = A52E9C86295B0478004EC3DF /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + /* Begin XCBuildConfiguration section */ 47A0A8E023D5B13500FE781F /* Debug */ = { isa = XCBuildConfiguration; @@ -302,6 +478,7 @@ }; 47A0A8E323D5B13500FE781F /* Debug */ = { isa = XCBuildConfiguration; + baseConfigurationReference = 99A7276F2E4C0F6453ECA910 /* Pods-segment-appsflyer-ios.debug.xcconfig */; buildSettings = { CODE_SIGN_IDENTITY = ""; "CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development"; @@ -335,6 +512,7 @@ }; 47A0A8E423D5B13500FE781F /* Release */ = { isa = XCBuildConfiguration; + baseConfigurationReference = 383CE4C70EA898B25B26039C /* Pods-segment-appsflyer-ios.release.xcconfig */; buildSettings = { CODE_SIGN_IDENTITY = ""; "CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development"; @@ -366,6 +544,62 @@ }; name = Release; }; + A52E9C88295B0478004EC3DF /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 1548A28C2E5C46E858B31098 /* Pods-SegmentAppsFlyeriOSTests.debug.xcconfig */; + buildSettings = { + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = 6UQAD4B3U2; + GENERATE_INFOPLIST_FILE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 16.1; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.MorisGateno.SegmentAppsFlyeriOSTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_EMIT_LOC_STRINGS = NO; + SWIFT_OBJC_BRIDGING_HEADER = "SegmentAppsFlyeriOSTests/SegmentAppsFlyeriOSTests-Bridging-Header.h"; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + A52E9C89295B0478004EC3DF /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 11D1EE0DB4918D94DDCA0894 /* Pods-SegmentAppsFlyeriOSTests.release.xcconfig */; + buildSettings = { + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = 6UQAD4B3U2; + GENERATE_INFOPLIST_FILE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 16.1; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.MorisGateno.SegmentAppsFlyeriOSTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_EMIT_LOC_STRINGS = NO; + SWIFT_OBJC_BRIDGING_HEADER = "SegmentAppsFlyeriOSTests/SegmentAppsFlyeriOSTests-Bridging-Header.h"; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ @@ -387,6 +621,15 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; + A52E9C8A295B0478004EC3DF /* Build configuration list for PBXNativeTarget "SegmentAppsFlyeriOSTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + A52E9C88295B0478004EC3DF /* Debug */, + A52E9C89295B0478004EC3DF /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; /* End XCConfigurationList section */ }; rootObject = 47A0A8D123D5B13500FE781F /* Project object */; diff --git a/segment-appsflyer-ios.xcodeproj/xcshareddata/xcschemes/SegmentAppsFlyeriOSTests.xcscheme b/segment-appsflyer-ios.xcodeproj/xcshareddata/xcschemes/SegmentAppsFlyeriOSTests.xcscheme new file mode 100644 index 0000000..cd9ad5c --- /dev/null +++ b/segment-appsflyer-ios.xcodeproj/xcshareddata/xcschemes/SegmentAppsFlyeriOSTests.xcscheme @@ -0,0 +1,53 @@ + + + + + + + + + + + + + + + + + + + + + From 96461da34fd2c59d146f37a55c60a587617137a7 Mon Sep 17 00:00:00 2001 From: Moris Gateno Date: Tue, 3 Jan 2023 17:05:20 +0200 Subject: [PATCH 02/18] added tests and added mocking for the appsflyerLib shared function --- .../SEGAppsFlyerIntegrationTests.m | 165 ++++++++++++++++-- .../Classes/SEGAppsFlyerIntegration.m | 7 +- 2 files changed, 161 insertions(+), 11 deletions(-) diff --git a/SegmentAppsFlyeriOSTests/SEGAppsFlyerIntegrationTests.m b/SegmentAppsFlyeriOSTests/SEGAppsFlyerIntegrationTests.m index a9b2e32..e23de69 100644 --- a/SegmentAppsFlyeriOSTests/SEGAppsFlyerIntegrationTests.m +++ b/SegmentAppsFlyeriOSTests/SEGAppsFlyerIntegrationTests.m @@ -17,6 +17,7 @@ - (void)track:(SEGTrackPayload *)payload; - (void)onConversionDataSuccess:(nonnull NSDictionary *)conversionInfo; - (instancetype)initWithSettings:(NSDictionary *)settings withAppsflyer:(AppsFlyerLib *)aAppsflyer; +(NSString *) validateNil: (NSString *) value; +- (AppsFlyerLib *)appsflyerLib; @end @interface AppsFlyerLib() @@ -72,7 +73,11 @@ - (void)testSEGAppsFlyerIntegration_initWithSettings_nilFlow_noDevKey{ NSDictionary * dictionaryInput = @{@"appleAppID" : @"appID", @"trackAttributionData" : @"123", }; - SEGAppsFlyerIntegration *integrationObject = [[SEGAppsFlyerIntegration alloc] initWithSettings:dictionaryInput withAnalytics:nil]; + AppsFlyerLib * appsFlyerObject = [AppsFlyerLib new]; + SEGAppsFlyerIntegration * SEGAppsFlyerIntegrationObject = [SEGAppsFlyerIntegration new]; + id SEGAppsFlyerIntegrationMock = OCMPartialMock(SEGAppsFlyerIntegrationObject); + OCMStub([SEGAppsFlyerIntegrationMock appsflyerLib]).andReturn(appsFlyerObject); + SEGAppsFlyerIntegration * integrationObject = [SEGAppsFlyerIntegrationMock initWithSettings:dictionaryInput withAnalytics:nil]; AppsFlyerLib *appsflyerObject = [integrationObject appsflyer]; XCTAssertNotNil(appsflyerObject); XCTAssertTrue([[appsflyerObject appsFlyerDevKey] isEqual:@""]); @@ -82,7 +87,12 @@ - (void)testSEGAppsFlyerIntegration_initWithSettings_nilFlow_noAppleID{ NSDictionary * dictionaryInput = @{@"appsFlyerDevKey" : @"devKey", @"trackAttributionData" : @"123", }; - SEGAppsFlyerIntegration *integrationObject = [[SEGAppsFlyerIntegration alloc] initWithSettings:dictionaryInput withAnalytics:nil]; + AppsFlyerLib * appsFlyerObject = [AppsFlyerLib new]; + SEGAppsFlyerIntegration * SEGAppsFlyerIntegrationObject = [SEGAppsFlyerIntegration new]; + id SEGAppsFlyerIntegrationMock = OCMPartialMock(SEGAppsFlyerIntegrationObject); + OCMStub([SEGAppsFlyerIntegrationMock appsflyerLib]).andReturn(appsFlyerObject); + + SEGAppsFlyerIntegration *integrationObject = [SEGAppsFlyerIntegrationMock initWithSettings:dictionaryInput withAnalytics:nil]; AppsFlyerLib *appsflyerObject = [integrationObject appsflyer]; XCTAssertNotNil(appsflyerObject); XCTAssertTrue([[appsflyerObject appleAppID] isEqual:@""]); @@ -92,7 +102,12 @@ -(void)testSEGAppsFlyerIntegration_initWithSettings_nilFlow_noTrackingAttributio NSDictionary * dictionaryInput = @{@"appsFlyerDevKey" : @"devKey", @"appleAppID" : @"appID" }; - SEGAppsFlyerIntegration *integrationObject = [[SEGAppsFlyerIntegration alloc] initWithSettings:dictionaryInput withAnalytics:nil]; + AppsFlyerLib * appsFlyerObject = [AppsFlyerLib new]; + SEGAppsFlyerIntegration * SEGAppsFlyerIntegrationObject = [SEGAppsFlyerIntegration new]; + id SEGAppsFlyerIntegrationMock = OCMPartialMock(SEGAppsFlyerIntegrationObject); + OCMStub([SEGAppsFlyerIntegrationMock appsflyerLib]).andReturn(appsFlyerObject); + + SEGAppsFlyerIntegration *integrationObject = [SEGAppsFlyerIntegrationMock initWithSettings:dictionaryInput withAnalytics:nil]; AppsFlyerLib *appsflyerObject = [integrationObject appsflyer]; XCTAssertNotNil(appsflyerObject); XCTAssertNil([appsflyerObject delegate]); @@ -198,7 +213,11 @@ -(void)testSEGAppsFlyerIntegration_identify_nilFlow{ @"appleAppID" : @"appID", @"trackAttributionData" : @"123", }; - SEGAppsFlyerIntegration *integrationObject = [[SEGAppsFlyerIntegration alloc] initWithSettings:settings withAnalytics:nil]; + AppsFlyerLib * appsFlyerObject = [AppsFlyerLib new]; + SEGAppsFlyerIntegration * SEGAppsFlyerIntegrationObject = [SEGAppsFlyerIntegration new]; + id SEGAppsFlyerIntegrationMock = OCMPartialMock(SEGAppsFlyerIntegrationObject); + OCMStub([SEGAppsFlyerIntegrationMock appsflyerLib]).andReturn(appsFlyerObject); + SEGAppsFlyerIntegration *integrationObject = [SEGAppsFlyerIntegrationMock initWithSettings:settings withAnalytics:nil]; NSMutableDictionary * traits = nil; SEGIdentifyPayload * payload = [[SEGIdentifyPayload alloc] initWithUserId:nil anonymousId:nil traits:traits context:nil integrations:nil]; [integrationObject identify:payload]; @@ -230,6 +249,7 @@ - (void)testSEGAppsFlyerIntegration_track_happyFlow_withCurrencyAndRevenue{ NSMutableDictionary * dictionary = @{@"revenue" : @"10.1", @"currency" : @"ILS"}; SEGTrackPayload * payload = [[SEGTrackPayload alloc] initWithEvent:@"testEvent" properties: dictionary context:@{} integrations:@{}]; [integrationObject track:payload]; + [appsFlyerMock stopMocking]; } -(void)testSEGAppsFlyerIntegration_track_nilFlow{ @@ -245,6 +265,7 @@ -(void)testSEGAppsFlyerIntegration_track_nilFlow{ [integrationObject setAppsflyer: appsFlyerMock]; SEGTrackPayload * payload = [[SEGTrackPayload alloc] initWithEvent:nil properties: nil context:@{} integrations:@{}]; [integrationObject track:payload]; + [appsFlyerMock stopMocking]; } -(void)testSEGAppsFlyerIntegration_track_negativeFlow_numberAsKeyWhenWhileLogEventExpectsString{ @@ -262,6 +283,7 @@ -(void)testSEGAppsFlyerIntegration_track_negativeFlow_numberAsKeyWhenWhileLogEve NSMutableDictionary * dictionary = @{@(10):@(11)}; SEGTrackPayload * payload = [[SEGTrackPayload alloc] initWithEvent:nil properties: dictionary context:@{} integrations:@{}]; [integrationObject track:payload]; + [appsFlyerMock stopMocking]; } // @@ -369,12 +391,135 @@ - (void)testSEGAppsFlyerIntegration_validateNil_negativeFlow { // // onConversionDataSuccess // -//- (void)testSEGAppsFlyerIntegration_onConversionDataSuccess_happyflow{ -// [[NSUserDefaults standardUserDefaults] setPersistentDomain:[NSDictionary dictionary] forName:[[NSBundle mainBundle] bundleIdentifier]]; -// SEGAppsFlyerIntegration *integrationObject = [[SEGAppsFlyerIntegration alloc] initWithSettings:@{} withAnalytics:nil andDelegate:self]; -// [[integrationObject segDelegate] ] -// [integrationObject onConversionDataSuccess:@{}]; -//} +- (void)onConversionDataSuccess:(NSDictionary *)conversionInfo{ + +} + +- (void)testSEGAppsFlyerIntegration_onConversionDataSuccess_happyflow{ + NSDictionary * dictionaryInputToAnalytics = @{@"campaign":@{@"ad_group":@"appsflyer", + @"name":@"gateno", + @"source":@"moris"}, + @"provider":@"AppsFlyer" + }; + NSDictionary * dictionaryInputAsParmeter = @{@"media_source":@"moris", + @"campaign":@"gateno", + @"adgroup":@"appsflyer" + }; + id SEGAnalyticsMock = OCMClassMock([SEGAnalytics class]); + id SEGAppsFlyerIntegrationTestsMock = OCMClassMock([SEGAppsFlyerIntegrationTests class]); + OCMStub([SEGAppsFlyerIntegrationTestsMock onConversionDataSuccess:[OCMArg checkWithBlock:^BOOL(id obj) { + XCTAssertTrue([dictionaryInputAsParmeter isEqualToDictionary:obj]); + return YES; + }]]); + OCMStub([SEGAnalyticsMock track:[OCMArg checkWithBlock:^BOOL(id obj) { + XCTAssertTrue([obj isEqual:@"Install Attributed"]); + return YES; + }] properties:[OCMArg checkWithBlock:^BOOL(id obj) { + XCTAssertTrue([obj isEqualToDictionary:dictionaryInputToAnalytics]); + return YES; + }]]); + + NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; + [userDefaults setBool:NO forKey:@"AF_Install_Attr_Sent"]; + SEGAppsFlyerIntegration *integrationObject = [[SEGAppsFlyerIntegration alloc] initWithSettings:@{} withAnalytics:SEGAnalyticsMock andDelegate:SEGAppsFlyerIntegrationTestsMock]; + + [integrationObject onConversionDataSuccess:dictionaryInputAsParmeter]; + XCTAssertTrue([userDefaults boolForKey:@"AF_Install_Attr_Sent"]); + + [SEGAnalyticsMock stopMocking]; + [SEGAppsFlyerIntegrationTestsMock stopMocking]; +} + +- (void)testSEGAppsFlyerIntegration_onConversionDataSuccess_negativeflow{ + NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; + SEGAnalytics * SEGAnalyticsObject = [SEGAnalytics new]; + id SEGAnalyticsMock = OCMPartialMock(SEGAnalyticsObject); + id SEGAppsFlyerIntegrationMock = OCMPartialMock(self); + OCMReject([SEGAppsFlyerIntegrationMock onConversionDataSuccess:[OCMArg any]]); + OCMReject([SEGAnalyticsMock track:[OCMArg any] properties:[OCMArg any]]); + [userDefaults setBool:YES forKey:@"AF_Install_Attr_Sent"]; + + SEGAppsFlyerIntegration *integrationObject = [[SEGAppsFlyerIntegration alloc] initWithSettings:@{} withAnalytics:SEGAnalyticsMock andDelegate:SEGAppsFlyerIntegrationMock]; + + [integrationObject onConversionDataSuccess:@{}]; + + [SEGAnalyticsMock verify]; + [SEGAppsFlyerIntegrationMock verify]; + [SEGAnalyticsMock stopMocking]; + [SEGAppsFlyerIntegrationMock stopMocking]; +} + +// +// onConversionDataFail +// +- (void)onConversionDataFail:(NSError *)error{ + +} +- (void)testSEGAppsFlyerIntegration_onConversionDataFail_happyflow{ + NSError * error = [NSError new]; + id SEGAppsFlyerIntegrationTestsMock = OCMClassMock([SEGAppsFlyerIntegrationTests class]); + OCMStub([SEGAppsFlyerIntegrationTestsMock onConversionDataFail:[OCMArg checkWithBlock:^BOOL(id obj) { + XCTAssertTrue([obj isEqual:error]); + }]]); + + SEGAppsFlyerIntegration *integrationObject = [[SEGAppsFlyerIntegration alloc] initWithSettings:@{} withAnalytics:nil andDelegate:SEGAppsFlyerIntegrationTestsMock]; + [integrationObject onConversionDataFail:error]; + [SEGAppsFlyerIntegrationTestsMock stopMocking]; +} + +// +// onConversionDataFail +// +- (void)onAppOpenAttribution:(NSDictionary *)attributionData{ + +} +- (void)testSEGAppsFlyerIntegration_onAppOpenAttribution_happyflow{ + NSDictionary * attributionData = @{@"key":@"value"}; + id SEGAppsFlyerIntegrationTestsMock = OCMClassMock([SEGAppsFlyerIntegrationTests class]); + OCMStub([SEGAppsFlyerIntegrationTestsMock onAppOpenAttribution:[OCMArg checkWithBlock:^BOOL(id obj) { + XCTAssertTrue([obj isEqualToDictionary:attributionData]); + }]]); + + SEGAppsFlyerIntegration *integrationObject = [[SEGAppsFlyerIntegration alloc] initWithSettings:@{} withAnalytics:nil andDelegate:SEGAppsFlyerIntegrationTestsMock]; + [integrationObject onAppOpenAttribution:attributionData]; + [SEGAppsFlyerIntegrationTestsMock stopMocking]; +} + +// +// onConversionDataFail +// +- (void)onAppOpenAttributionFailure:(NSError *)error{ + +} +- (void)testSEGAppsFlyerIntegration_onAppOpenAttributionFailure_happyflow{ + NSError * error = [NSError new]; + id SEGAppsFlyerIntegrationTestsMock = OCMClassMock([SEGAppsFlyerIntegrationTests class]); + OCMStub([SEGAppsFlyerIntegrationTestsMock onAppOpenAttribution:[OCMArg checkWithBlock:^BOOL(id obj) { + XCTAssertTrue([obj isEqual:error]); + }]]); + + SEGAppsFlyerIntegration *integrationObject = [[SEGAppsFlyerIntegration alloc] initWithSettings:@{} withAnalytics:nil andDelegate:SEGAppsFlyerIntegrationTestsMock]; + [integrationObject onAppOpenAttribution:error]; + [SEGAppsFlyerIntegrationTestsMock stopMocking]; +} + +// +// onConversionDataFail +// +- (void)didResolveDeepLink:(AppsFlyerDeepLinkResult *_Nonnull)result{ + +} +- (void)testSEGAppsFlyerIntegration_didResolveDeepLink_happyflow{ + AppsFlyerDeepLinkResult * result = [AppsFlyerDeepLinkResult alloc]; + id SEGAppsFlyerIntegrationTestsMock = OCMClassMock([SEGAppsFlyerIntegrationTests class]); + OCMStub([SEGAppsFlyerIntegrationTestsMock onAppOpenAttribution:[OCMArg checkWithBlock:^BOOL(id obj) { + XCTAssertTrue([obj isEqual:result]); + }]]); + + SEGAppsFlyerIntegration *integrationObject = [[SEGAppsFlyerIntegration alloc] initWithSettings:@{} withAnalytics:nil andDelegate:SEGAppsFlyerIntegrationTestsMock]; + [integrationObject onAppOpenAttribution:result]; + [SEGAppsFlyerIntegrationTestsMock stopMocking]; +} - (void)testPerformanceExample { diff --git a/segment-appsflyer-ios/Classes/SEGAppsFlyerIntegration.m b/segment-appsflyer-ios/Classes/SEGAppsFlyerIntegration.m index fffc61a..b399091 100644 --- a/segment-appsflyer-ios/Classes/SEGAppsFlyerIntegration.m +++ b/segment-appsflyer-ios/Classes/SEGAppsFlyerIntegration.m @@ -18,7 +18,7 @@ - (instancetype)initWithSettings:(NSDictionary *)settings withAnalytics:(SEGAnal NSString *afDevKey = [self.settings objectForKey:@"appsFlyerDevKey"]; NSString *appleAppId = [self.settings objectForKey:@"appleAppID"]; - self.appsflyer = [AppsFlyerLib shared]; + self.appsflyer = [self appsflyerLib]; [self.appsflyer setAppsFlyerDevKey:afDevKey]; [self.appsflyer setAppleAppID:appleAppId]; //self.appsflyer.isDebug = true; @@ -43,6 +43,11 @@ - (instancetype)initWithSettings:(NSDictionary *)settings withAnalytics:(SEGAnal return self; } +// Added for testabillity +- (AppsFlyerLib *)appsflyerLib { + return [AppsFlyerLib shared]; +} + - (instancetype)initWithSettings:(NSDictionary *)settings withAnalytics:(SEGAnalytics *)analytics From 77479a8305c5ac46914c83d7c587191a1feb539e Mon Sep 17 00:00:00 2001 From: Moris Gateno Date: Sun, 8 Jan 2023 13:47:27 +0200 Subject: [PATCH 03/18] added tests workflows and scheme --- .github/workflows/test.yml | 19 +++++++++++++++++++ .../xcschemes/segment-appsflyer-ios.xcscheme | 10 ++++++++++ 2 files changed, 29 insertions(+) create mode 100644 .github/workflows/test.yml diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 0000000..dbdbc8c --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,19 @@ +name: CI - Tests +on: + push: + branches-ignore: + - 'main' + - 'releases/**' +jobs: + Tests: + runs-on: macos-12 + steps: + - uses: actions/checkout@v2 + - uses: maxim-lobanov/setup-xcode@v1 + with: + xcode-version: latest-stable + - name: CocoaPod Install + run: cd testing-actions-moris-framework2 + pod install + - name: Test + run: xcodebuild test -scheme segment-appsflyer-ios -workspace segment-appsflyer-ios.xcworkspace -destination 'platform=iOS Simulator,name=iPhone 13' | xcpretty && exit ${PIPESTATUS[0]} \ No newline at end of file diff --git a/segment-appsflyer-ios.xcodeproj/xcshareddata/xcschemes/segment-appsflyer-ios.xcscheme b/segment-appsflyer-ios.xcodeproj/xcshareddata/xcschemes/segment-appsflyer-ios.xcscheme index d0d9d17..ff482ac 100644 --- a/segment-appsflyer-ios.xcodeproj/xcshareddata/xcschemes/segment-appsflyer-ios.xcscheme +++ b/segment-appsflyer-ios.xcodeproj/xcshareddata/xcschemes/segment-appsflyer-ios.xcscheme @@ -28,6 +28,16 @@ selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" shouldUseLaunchSchemeArgsEnv = "YES"> + + + + Date: Sun, 8 Jan 2023 13:52:03 +0200 Subject: [PATCH 04/18] updated yml file --- .github/workflows/test.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index dbdbc8c..68452b0 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -13,7 +13,6 @@ jobs: with: xcode-version: latest-stable - name: CocoaPod Install - run: cd testing-actions-moris-framework2 - pod install + run: pod install - name: Test run: xcodebuild test -scheme segment-appsflyer-ios -workspace segment-appsflyer-ios.xcworkspace -destination 'platform=iOS Simulator,name=iPhone 13' | xcpretty && exit ${PIPESTATUS[0]} \ No newline at end of file From 8ad88c6d0d5fbbc21dd932f897415de6018c267f Mon Sep 17 00:00:00 2001 From: Moris Gateno Date: Sun, 8 Jan 2023 14:04:44 +0200 Subject: [PATCH 05/18] file naming change --- ...ts.swift => SEGAppsFlyerIntegrationFactoryTests.swift} | 0 segment-appsflyer-ios.xcodeproj/project.pbxproj | 8 ++++---- 2 files changed, 4 insertions(+), 4 deletions(-) rename SegmentAppsFlyeriOSTests/{SegmentAppsFlyeriOSTests.swift => SEGAppsFlyerIntegrationFactoryTests.swift} (100%) diff --git a/SegmentAppsFlyeriOSTests/SegmentAppsFlyeriOSTests.swift b/SegmentAppsFlyeriOSTests/SEGAppsFlyerIntegrationFactoryTests.swift similarity index 100% rename from SegmentAppsFlyeriOSTests/SegmentAppsFlyeriOSTests.swift rename to SegmentAppsFlyeriOSTests/SEGAppsFlyerIntegrationFactoryTests.swift diff --git a/segment-appsflyer-ios.xcodeproj/project.pbxproj b/segment-appsflyer-ios.xcodeproj/project.pbxproj index d5c79d8..434869f 100644 --- a/segment-appsflyer-ios.xcodeproj/project.pbxproj +++ b/segment-appsflyer-ios.xcodeproj/project.pbxproj @@ -17,7 +17,7 @@ 86F430F225B4369500BD66B9 /* AppsFlyerLib.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 47A0A8FD23D5CF8B00FE781F /* AppsFlyerLib.framework */; }; 86F430F525B4369600BD66B9 /* Segment.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 868810BD258FB606001F6545 /* Segment.framework */; }; A5201335295B1A5B00B87090 /* SEGAppsFlyerIntegrationTests.m in Sources */ = {isa = PBXBuildFile; fileRef = A5201334295B1A5B00B87090 /* SEGAppsFlyerIntegrationTests.m */; }; - A52E9C84295B0478004EC3DF /* SegmentAppsFlyeriOSTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = A52E9C83295B0478004EC3DF /* SegmentAppsFlyeriOSTests.swift */; }; + A52E9C84295B0478004EC3DF /* SEGAppsFlyerIntegrationFactoryTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = A52E9C83295B0478004EC3DF /* SEGAppsFlyerIntegrationFactoryTests.swift */; }; A52E9C85295B0478004EC3DF /* SegmentAppsFlyeriOS.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 47A0A8DA23D5B13500FE781F /* SegmentAppsFlyeriOS.framework */; }; /* End PBXBuildFile section */ @@ -52,7 +52,7 @@ A5201333295B1A5B00B87090 /* SegmentAppsFlyeriOSTests-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "SegmentAppsFlyeriOSTests-Bridging-Header.h"; sourceTree = ""; }; A5201334295B1A5B00B87090 /* SEGAppsFlyerIntegrationTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SEGAppsFlyerIntegrationTests.m; sourceTree = ""; }; A52E9C81295B0478004EC3DF /* SegmentAppsFlyeriOSTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = SegmentAppsFlyeriOSTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; - A52E9C83295B0478004EC3DF /* SegmentAppsFlyeriOSTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SegmentAppsFlyeriOSTests.swift; sourceTree = ""; }; + A52E9C83295B0478004EC3DF /* SEGAppsFlyerIntegrationFactoryTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SEGAppsFlyerIntegrationFactoryTests.swift; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -135,7 +135,7 @@ A52E9C82295B0478004EC3DF /* SegmentAppsFlyeriOSTests */ = { isa = PBXGroup; children = ( - A52E9C83295B0478004EC3DF /* SegmentAppsFlyeriOSTests.swift */, + A52E9C83295B0478004EC3DF /* SEGAppsFlyerIntegrationFactoryTests.swift */, A5201334295B1A5B00B87090 /* SEGAppsFlyerIntegrationTests.m */, A5201333295B1A5B00B87090 /* SegmentAppsFlyeriOSTests-Bridging-Header.h */, ); @@ -341,7 +341,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - A52E9C84295B0478004EC3DF /* SegmentAppsFlyeriOSTests.swift in Sources */, + A52E9C84295B0478004EC3DF /* SEGAppsFlyerIntegrationFactoryTests.swift in Sources */, A5201335295B1A5B00B87090 /* SEGAppsFlyerIntegrationTests.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; From 6fd7f26d400dce9e956d6932bd232d054e69a520 Mon Sep 17 00:00:00 2001 From: morisgateno-appsflyer <121490279+morisgateno-appsflyer@users.noreply.github.com> Date: Sun, 8 Jan 2023 14:22:04 +0200 Subject: [PATCH 06/18] Updated ReadME - added badge to CI-Tests --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 6fd787e..ead1b29 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ [![Version](https://img.shields.io/cocoapods/v/segment-appsflyer-ios.svg?style=flat)](http://cocoapods.org/pods/segment-appsflyer-ios) [![Carthage compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](https://github.com/Carthage/Carthage) - +[![CI - Tests](https://github.com/AppsFlyerSDK/segment-appsflyer-ios/actions/workflows/test.yml/badge.svg?branch=dev%2FDELIVRY-17805%2Funit-tests&event=push)](https://github.com/AppsFlyerSDK/segment-appsflyer-ios/actions/workflows/test.yml) ---------- 🛠 In order for us to provide optimal support, we would kindly ask you to submit any issues to support@appsflyer.com From 613d4cbd11812e7ef566d243a4603502174ddcfe Mon Sep 17 00:00:00 2001 From: Moris Gateno Date: Sun, 8 Jan 2023 15:03:20 +0200 Subject: [PATCH 07/18] added responseToSupportIssue.yml --- .github/workflows/responseToSupportIssue.yml | 29 ++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 .github/workflows/responseToSupportIssue.yml diff --git a/.github/workflows/responseToSupportIssue.yml b/.github/workflows/responseToSupportIssue.yml new file mode 100644 index 0000000..59dc23d --- /dev/null +++ b/.github/workflows/responseToSupportIssue.yml @@ -0,0 +1,29 @@ +# This workflow creates new comment from template to an issue +# if it was labled as 'support' + +name: Add comment +on: + issues: + types: + - labeled +jobs: + add-comment: + if: github.event.label.name == 'support' + runs-on: ubuntu-latest + permissions: + issues: write + steps: + - name: Add comment + uses: peter-evans/create-or-update-comment@a35cf36e5301d70b76f316e867e7788a55a31dae + with: + issue-number: ${{ github.event.issue.number }} + body: | + 👋 Hi @${{ github.event.issue.user.login }} and Thank you for reaching out to us. + In order for us to provide optimal support, please submit a ticket to our support team at support@appsflyer.com. + When submitting the ticket, please specify: + - ✅ your AppsFlyer sign-up (account) email + - ✅ app ID + - ✅ production steps + - ✅ logs + - ✅ code snippets + - ✅ and any additional relevant information. \ No newline at end of file From 88fd60fe8f90926b6d9c2f52da35a0f32adf93d0 Mon Sep 17 00:00:00 2001 From: Moris Gateno Date: Tue, 17 Jan 2023 11:09:06 +0200 Subject: [PATCH 08/18] README changes --- README.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index ead1b29..06bce30 100644 --- a/README.md +++ b/README.md @@ -93,7 +93,7 @@ First of all, you must provide values for AppsFlyer Dev Key, Apple App ID (iTune Open `AppDelegate.h` and add: -``` +```objective-c #import "SEGAppsFlyerIntegrationFactory.h" ``` @@ -156,7 +156,7 @@ In `AppDelegate.m` ➜ `applicationDidBecomeActive`: 3. Open `AppDelegate.swift` and add: ```swift -import Analytics +import Segment import AppsFlyerLib ``` @@ -220,7 +220,7 @@ In identify call ```traits``` dictionary ```setCustomerUserID``` and ```currenc In order to get Conversion Data you need to: 1. Add `SEGAppsFlyerLibDelegate` protocol to your AppDelegate.h (or other) class -``` +```objective-c #import #import "SEGAppsFlyerIntegrationFactory.h" @@ -229,7 +229,7 @@ In identify call ```traits``` dictionary ```setCustomerUserID``` and ```currenc 2. Pass AppDelegate (or other) class when configuring Segment Analytics with AppsFlyer. Change line `[config use:[SEGAppsFlyerIntegrationFactory instance]];` to `[config use:[SEGAppsFlyerIntegrationFactory createWithLaunchDelegate:self]];` 3. In the class passed to the method above (AppDelegate.m by default) implement methods of the `SEGAppsFlyerLibDelegate` protocol. See sample code below: -``` +```objective-c #import "AppDelegate.h" @interface AppDelegate () @@ -291,7 +291,7 @@ In identify call ```traits``` dictionary ```setCustomerUserID``` and ```currenc 2. Pass AppDelegate (or other) class when configuring Segment Analytics with AppsFlyer. If you use sample code from above, change line `config.use(factoryNoDelegate)` to `config.use(factoryWithDelegate)` 3. Implement methods of the protocol in the class, passed as a delegate. See sample code below where AppDelegate is used for that: - ``` + ```swift class AppDelegate: UIResponder, UIApplicationDelegate, SEGAppsFlyerLibDelegate { var window: UIWindow? @@ -340,13 +340,13 @@ In order to use Unified Deep linking you need to: 1. Add `SEGAppsFlyerDeepLinkDelegate` protocol to your AppDelegate (or other) class 2. Pass AppDelegate (or other) class when configuring Segment Analytics with AppsFlyer. From the sample code above, change factoryWithDelegate to : - ``` + ```swift let factoryWithDelegate: SEGAppsFlyerIntegrationFactory = SEGAppsFlyerIntegrationFactory.create(withLaunch: self, andDeepLinkDelegate: self) ``` 3. Implement methods of the protocol in the class, passed as a delegate. See sample code below where AppDelegate is used for that: -``` +```swift extension AppDelegate: SEGAppsFlyerDeepLinkDelegate { func didResolveDeepLink(_ result: DeepLinkResult) { print(result) @@ -359,7 +359,7 @@ extension AppDelegate: SEGAppsFlyerDeepLinkDelegate { ## Install Attributed event If you are working with networks that don't allow passing user level data to 3rd parties, you will need to apply code to filter out these networks before calling -``` +```objective-c // [self.analytics track:@"Install Attributed" properties:[properties copy]]; ``` From fca418f480f37a7e9443c3271e33c7434fc55ca3 Mon Sep 17 00:00:00 2001 From: Moris Gateno Date: Tue, 17 Jan 2023 12:32:06 +0200 Subject: [PATCH 09/18] more changes to README --- README.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 06bce30..145dae4 100644 --- a/README.md +++ b/README.md @@ -118,14 +118,13 @@ In `AppDelegate.m` ➜ `didFinishLaunchingWithOptions`: // SEGAppsFlyerIntegrationFactory* factoryWithDelegate = [SEGAppsFlyerIntegrationFactory createWithLaunchDelegate:self andManualMode:YES]; - SEGAnalyticsConfiguration *config = [SEGAnalyticsConfiguration configurationWithWriteKey:@"WYsuyFINOKZuQyQAGn5JQoCgIdhOI146"]; + SEGAnalyticsConfiguration *config = [SEGAnalyticsConfiguration configurationWithWriteKey:@"SEGMENT_KEY"]; [config use:factoryNoDelegate]; // [config use:factoryWithDelegate]; // use this if you want to get conversion data in the app. Read more in the integration guide config.enableAdvertisingTracking = YES; //OPTIONAL config.trackApplicationLifecycleEvents = YES; //OPTIONAL config.trackDeepLinks = YES; //OPTIONAL config.trackPushNotifications = YES; //OPTIONAL - config.trackAttributionData = YES; //OPTIONAL [SEGAnalytics debug:YES]; //OPTIONAL [SEGAnalytics setupWithConfiguration:config]; ``` @@ -158,6 +157,7 @@ In `AppDelegate.m` ➜ `applicationDidBecomeActive`: ```swift import Segment import AppsFlyerLib +import segment_appsflyer_ios ``` 4. In `didFinishLaunchingWithOptions` add: @@ -188,7 +188,6 @@ import AppsFlyerLib config.trackApplicationLifecycleEvents = true //OPTIONAL config.trackDeepLinks = true //OPTIONAL config.trackPushNotifications = true //OPTIONAL - config.trackAttributionData = true //OPTIONAL Analytics.debug(false) Analytics.setup(with: config) From 473347a7b4d02feca3c1e4e62be80f4f486fa3bd Mon Sep 17 00:00:00 2001 From: Moris Gateno Date: Tue, 17 Jan 2023 12:36:16 +0200 Subject: [PATCH 10/18] some minor changes in example apps --- examples/ObjcPodsSample/ObjcPodsSample/AppDelegate.m | 2 +- examples/SwiftPodsSample/SwiftPodsSample/AppDelegate.swift | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/ObjcPodsSample/ObjcPodsSample/AppDelegate.m b/examples/ObjcPodsSample/ObjcPodsSample/AppDelegate.m index e89983f..b3046f8 100644 --- a/examples/ObjcPodsSample/ObjcPodsSample/AppDelegate.m +++ b/examples/ObjcPodsSample/ObjcPodsSample/AppDelegate.m @@ -35,7 +35,7 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:( // SEGAppsFlyerIntegrationFactory* factoryNoDelegate = [SEGAppsFlyerIntegrationFactory instance]; SEGAppsFlyerIntegrationFactory* factoryWithDelegate = [SEGAppsFlyerIntegrationFactory createWithLaunchDelegate:self]; - SEGAnalyticsConfiguration *config = [SEGAnalyticsConfiguration configurationWithWriteKey:@"WYsuyFINOKZuQyQAGn5JQoCgIdhOI146"]; + SEGAnalyticsConfiguration *config = [SEGAnalyticsConfiguration configurationWithWriteKey:@"SEGMENT_KEY"]; // [config use:factoryNoDelegate]; [config use:factoryWithDelegate]; // use this if you want to get conversion data in the app. Read more in the integration guide config.enableAdvertisingTracking = YES; //OPTIONAL diff --git a/examples/SwiftPodsSample/SwiftPodsSample/AppDelegate.swift b/examples/SwiftPodsSample/SwiftPodsSample/AppDelegate.swift index 3d1c3b0..f6baab7 100644 --- a/examples/SwiftPodsSample/SwiftPodsSample/AppDelegate.swift +++ b/examples/SwiftPodsSample/SwiftPodsSample/AppDelegate.swift @@ -18,7 +18,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate { // For AppsFLyer debug logs uncomment the line below AppsFlyerLib.shared().isDebug = true - AppsFlyerLib.shared().waitForATTUserAuthorization(timeoutInterval: 60) +// AppsFlyerLib.shared().waitForATTUserAuthorization(timeoutInterval: 60) /* Based on your needs you can either pass a delegate to process deferred and direct deeplinking callbacks or disregard them. From 01eda0149be6d23b1780f0e34d6c63a69cf3c5f3 Mon Sep 17 00:00:00 2001 From: Moris Gateno Date: Tue, 17 Jan 2023 15:37:08 +0200 Subject: [PATCH 11/18] changes done in integration to make it null-persistent --- .../Classes/SEGAppsFlyerIntegration.m | 22 ++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/segment-appsflyer-ios/Classes/SEGAppsFlyerIntegration.m b/segment-appsflyer-ios/Classes/SEGAppsFlyerIntegration.m index b399091..e808540 100644 --- a/segment-appsflyer-ios/Classes/SEGAppsFlyerIntegration.m +++ b/segment-appsflyer-ios/Classes/SEGAppsFlyerIntegration.m @@ -15,13 +15,29 @@ @implementation SEGAppsFlyerIntegration - (instancetype)initWithSettings:(NSDictionary *)settings withAnalytics:(SEGAnalytics *)analytics { if (self = [super init]) { self.settings = settings; - NSString *afDevKey = [self.settings objectForKey:@"appsFlyerDevKey"]; - NSString *appleAppId = [self.settings objectForKey:@"appleAppID"]; + if((!self.settings) || [self.settings isEqual:[NSNull null]]){ + self.settings = @{}.mutableCopy; + } + NSString *afDevKey; + id valueForKey_appsFlyerDevKey = [self.settings objectForKey:@"appsFlyerDevKey"]; + if(valueForKey_appsFlyerDevKey){ + afDevKey = [NSString stringWithFormat:@"%@",valueForKey_appsFlyerDevKey]; + } + else{ + afDevKey = @""; + } + NSString *appleAppId; + id valueForKey_appleAppID = [self.settings objectForKey:@"appleAppID"]; + if(valueForKey_appleAppID){ + appleAppId= [NSString stringWithFormat:@"%@", valueForKey_appleAppID]; + } + else{ + appleAppId = @""; + } self.appsflyer = [self appsflyerLib]; [self.appsflyer setAppsFlyerDevKey:afDevKey]; [self.appsflyer setAppleAppID:appleAppId]; - //self.appsflyer.isDebug = true; self.analytics = analytics; if ([self logAttributionData]) { From 84b9368eac73be3b99d1e03c4c33007562674ccf Mon Sep 17 00:00:00 2001 From: Moris Gateno Date: Tue, 17 Jan 2023 15:44:05 +0200 Subject: [PATCH 12/18] added test to unit tests --- .../SEGAppsFlyerIntegrationTests.m | 49 ++++++++++++++----- 1 file changed, 37 insertions(+), 12 deletions(-) diff --git a/SegmentAppsFlyeriOSTests/SEGAppsFlyerIntegrationTests.m b/SegmentAppsFlyeriOSTests/SEGAppsFlyerIntegrationTests.m index e23de69..792a28b 100644 --- a/SegmentAppsFlyeriOSTests/SEGAppsFlyerIntegrationTests.m +++ b/SegmentAppsFlyeriOSTests/SEGAppsFlyerIntegrationTests.m @@ -113,18 +113,43 @@ -(void)testSEGAppsFlyerIntegration_initWithSettings_nilFlow_noTrackingAttributio XCTAssertNil([appsflyerObject delegate]); } -//this test doesn't go through because [self.appsflyer setAppsFlyerDevKey:afDevKey]; -//does not accept number value. - need to check in this function the type of devkey and apple id before setting them. -//- (void)testSEGAppsFlyerIntegration_initWithSettings_negativeFlow_devKeyIsANumber{ -// NSDictionary * dictionaryInput = @{@"appsFlyerDevKey" : @(123), -// @"appleAppID" : @"appID", -// @"trackAttributionData" : @"123" -// }; -// SEGAppsFlyerIntegration *integrationObject = [[SEGAppsFlyerIntegration alloc] initWithSettings:dictionaryInput withAnalytics:nil]; -// AppsFlyerLib *appsflyerObject = [integrationObject appsflyer]; -// XCTAssertNotNil(appsflyerObject); -// XCTAssertNil([appsflyerObject delegate]); -//} +-(void)testSEGAppsFlyerIntegration_initWithSettings_nilFlow_nilSettings{ + AppsFlyerLib * appsFlyerObject = OCMClassMock([AppsFlyerLib class]); + SEGAppsFlyerIntegration * SEGAppsFlyerIntegrationObject = [SEGAppsFlyerIntegration new]; + id SEGAppsFlyerIntegrationMock = OCMPartialMock(SEGAppsFlyerIntegrationObject); + OCMStub([SEGAppsFlyerIntegrationMock appsflyerLib]).andReturn(appsFlyerObject); + + NSDictionary * dictionaryInput = [NSNull null]; + SEGAppsFlyerIntegration *integrationObject = [SEGAppsFlyerIntegrationObject initWithSettings:dictionaryInput withAnalytics:nil]; + AppsFlyerLib *appsflyerObject = [integrationObject appsflyer]; + XCTAssertNotNil(appsflyerObject); + XCTAssertNil([appsflyerObject delegate]); + + dictionaryInput = nil; + integrationObject = [SEGAppsFlyerIntegrationObject initWithSettings:dictionaryInput withAnalytics:nil]; + appsflyerObject = [integrationObject appsflyer]; + XCTAssertNotNil(appsflyerObject); + XCTAssertNil([appsflyerObject delegate]); +} + + +- (void)testSEGAppsFlyerIntegration_initWithSettings_negativeFlow_devKeyIsANumber{ + NSDictionary * dictionaryInput = @{@"appsFlyerDevKey" : @(123), + @"appleAppID" : @"appID", + @"trackAttributionData" : @"123" + }; + + AppsFlyerLib * appsFlyerObject = [AppsFlyerLib new];; + SEGAppsFlyerIntegration * SEGAppsFlyerIntegrationObject = [SEGAppsFlyerIntegration new]; + id SEGAppsFlyerIntegrationMock = OCMPartialMock(SEGAppsFlyerIntegrationObject); + OCMStub([SEGAppsFlyerIntegrationMock appsflyerLib]).andReturn(appsFlyerObject); + + SEGAppsFlyerIntegration *integrationObject = [SEGAppsFlyerIntegrationMock initWithSettings:dictionaryInput withAnalytics:nil]; + AppsFlyerLib *appsflyerObject = [integrationObject appsflyer]; + XCTAssertNotNil(appsflyerObject); + XCTAssertNotNil([appsflyerObject delegate]); +} + // //initWithSettings andDelegate From 972094ba24bd4c725ba4e6a20006facdf627e105 Mon Sep 17 00:00:00 2001 From: Moris Gateno Date: Wed, 18 Jan 2023 14:28:15 +0200 Subject: [PATCH 13/18] removed the if clause. --- segment-appsflyer-ios/Classes/SEGAppsFlyerIntegration.m | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/segment-appsflyer-ios/Classes/SEGAppsFlyerIntegration.m b/segment-appsflyer-ios/Classes/SEGAppsFlyerIntegration.m index e808540..b2c387e 100644 --- a/segment-appsflyer-ios/Classes/SEGAppsFlyerIntegration.m +++ b/segment-appsflyer-ios/Classes/SEGAppsFlyerIntegration.m @@ -15,9 +15,7 @@ @implementation SEGAppsFlyerIntegration - (instancetype)initWithSettings:(NSDictionary *)settings withAnalytics:(SEGAnalytics *)analytics { if (self = [super init]) { self.settings = settings; - if((!self.settings) || [self.settings isEqual:[NSNull null]]){ - self.settings = @{}.mutableCopy; - } + NSString *afDevKey; id valueForKey_appsFlyerDevKey = [self.settings objectForKey:@"appsFlyerDevKey"]; if(valueForKey_appsFlyerDevKey){ From 50f710b256a7f85ee0b752cf82ad166f2044dcb8 Mon Sep 17 00:00:00 2001 From: Moris Gateno Date: Tue, 17 Jan 2023 15:44:05 +0200 Subject: [PATCH 14/18] added test to unit tests --- .../SEGAppsFlyerIntegrationTests.m | 49 ++++++++++++++----- 1 file changed, 37 insertions(+), 12 deletions(-) diff --git a/SegmentAppsFlyeriOSTests/SEGAppsFlyerIntegrationTests.m b/SegmentAppsFlyeriOSTests/SEGAppsFlyerIntegrationTests.m index e23de69..792a28b 100644 --- a/SegmentAppsFlyeriOSTests/SEGAppsFlyerIntegrationTests.m +++ b/SegmentAppsFlyeriOSTests/SEGAppsFlyerIntegrationTests.m @@ -113,18 +113,43 @@ -(void)testSEGAppsFlyerIntegration_initWithSettings_nilFlow_noTrackingAttributio XCTAssertNil([appsflyerObject delegate]); } -//this test doesn't go through because [self.appsflyer setAppsFlyerDevKey:afDevKey]; -//does not accept number value. - need to check in this function the type of devkey and apple id before setting them. -//- (void)testSEGAppsFlyerIntegration_initWithSettings_negativeFlow_devKeyIsANumber{ -// NSDictionary * dictionaryInput = @{@"appsFlyerDevKey" : @(123), -// @"appleAppID" : @"appID", -// @"trackAttributionData" : @"123" -// }; -// SEGAppsFlyerIntegration *integrationObject = [[SEGAppsFlyerIntegration alloc] initWithSettings:dictionaryInput withAnalytics:nil]; -// AppsFlyerLib *appsflyerObject = [integrationObject appsflyer]; -// XCTAssertNotNil(appsflyerObject); -// XCTAssertNil([appsflyerObject delegate]); -//} +-(void)testSEGAppsFlyerIntegration_initWithSettings_nilFlow_nilSettings{ + AppsFlyerLib * appsFlyerObject = OCMClassMock([AppsFlyerLib class]); + SEGAppsFlyerIntegration * SEGAppsFlyerIntegrationObject = [SEGAppsFlyerIntegration new]; + id SEGAppsFlyerIntegrationMock = OCMPartialMock(SEGAppsFlyerIntegrationObject); + OCMStub([SEGAppsFlyerIntegrationMock appsflyerLib]).andReturn(appsFlyerObject); + + NSDictionary * dictionaryInput = [NSNull null]; + SEGAppsFlyerIntegration *integrationObject = [SEGAppsFlyerIntegrationObject initWithSettings:dictionaryInput withAnalytics:nil]; + AppsFlyerLib *appsflyerObject = [integrationObject appsflyer]; + XCTAssertNotNil(appsflyerObject); + XCTAssertNil([appsflyerObject delegate]); + + dictionaryInput = nil; + integrationObject = [SEGAppsFlyerIntegrationObject initWithSettings:dictionaryInput withAnalytics:nil]; + appsflyerObject = [integrationObject appsflyer]; + XCTAssertNotNil(appsflyerObject); + XCTAssertNil([appsflyerObject delegate]); +} + + +- (void)testSEGAppsFlyerIntegration_initWithSettings_negativeFlow_devKeyIsANumber{ + NSDictionary * dictionaryInput = @{@"appsFlyerDevKey" : @(123), + @"appleAppID" : @"appID", + @"trackAttributionData" : @"123" + }; + + AppsFlyerLib * appsFlyerObject = [AppsFlyerLib new];; + SEGAppsFlyerIntegration * SEGAppsFlyerIntegrationObject = [SEGAppsFlyerIntegration new]; + id SEGAppsFlyerIntegrationMock = OCMPartialMock(SEGAppsFlyerIntegrationObject); + OCMStub([SEGAppsFlyerIntegrationMock appsflyerLib]).andReturn(appsFlyerObject); + + SEGAppsFlyerIntegration *integrationObject = [SEGAppsFlyerIntegrationMock initWithSettings:dictionaryInput withAnalytics:nil]; + AppsFlyerLib *appsflyerObject = [integrationObject appsflyer]; + XCTAssertNotNil(appsflyerObject); + XCTAssertNotNil([appsflyerObject delegate]); +} + // //initWithSettings andDelegate From 8819f59d4015ddcb12d5e08f498c7bd466e449f6 Mon Sep 17 00:00:00 2001 From: Moris Gateno Date: Wed, 18 Jan 2023 14:42:55 +0200 Subject: [PATCH 15/18] added tests initWithSettings_nilFlow_nilSettings initWithSettings_negativeFlow_devKeyIsANumber --- SegmentAppsFlyeriOSTests/SEGAppsFlyerIntegrationTests.m | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/SegmentAppsFlyeriOSTests/SEGAppsFlyerIntegrationTests.m b/SegmentAppsFlyeriOSTests/SEGAppsFlyerIntegrationTests.m index 792a28b..1b5a8d5 100644 --- a/SegmentAppsFlyeriOSTests/SEGAppsFlyerIntegrationTests.m +++ b/SegmentAppsFlyeriOSTests/SEGAppsFlyerIntegrationTests.m @@ -119,17 +119,11 @@ -(void)testSEGAppsFlyerIntegration_initWithSettings_nilFlow_nilSettings{ id SEGAppsFlyerIntegrationMock = OCMPartialMock(SEGAppsFlyerIntegrationObject); OCMStub([SEGAppsFlyerIntegrationMock appsflyerLib]).andReturn(appsFlyerObject); - NSDictionary * dictionaryInput = [NSNull null]; + NSDictionary * dictionaryInput = nil; SEGAppsFlyerIntegration *integrationObject = [SEGAppsFlyerIntegrationObject initWithSettings:dictionaryInput withAnalytics:nil]; AppsFlyerLib *appsflyerObject = [integrationObject appsflyer]; XCTAssertNotNil(appsflyerObject); XCTAssertNil([appsflyerObject delegate]); - - dictionaryInput = nil; - integrationObject = [SEGAppsFlyerIntegrationObject initWithSettings:dictionaryInput withAnalytics:nil]; - appsflyerObject = [integrationObject appsflyer]; - XCTAssertNotNil(appsflyerObject); - XCTAssertNil([appsflyerObject delegate]); } From 00ad5fbbf71f1daaa1268929a0edd1d1bfab818a Mon Sep 17 00:00:00 2001 From: Moris Gateno Date: Sun, 29 Jan 2023 12:28:16 +0200 Subject: [PATCH 16/18] small changes in the readme and example obj-c commenting waitForATTUserAuthorization call. --- README.md | 4 ++-- examples/ObjcPodsSample/ObjcPodsSample/AppDelegate.m | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 145dae4..cea2fca 100644 --- a/README.md +++ b/README.md @@ -104,7 +104,7 @@ In `AppDelegate.m` ➜ `didFinishLaunchingWithOptions`: // For ApsFlyer debug logs [AppsFlyerLib shared].isDebug = YES; - [[AppsFlyerLib shared] waitForATTUserAuthorizationWithTimeoutInterval:60]; +// [[AppsFlyerLib shared] waitForATTUserAuthorizationWithTimeoutInterval:60]; /* Based on your needs you can either pass a delegate to process deferred and direct deeplinking callbacks or disregard them. @@ -164,7 +164,7 @@ import segment_appsflyer_ios ```swift // For AppsFLyer debug logs uncomment the line below // AppsFlyerLib.shared().isDebug = true - AppsFlyerLib.shared().waitForATTUserAuthorization(withTimeoutInterval: 60) +// AppsFlyerLib.shared().waitForATTUserAuthorization(withTimeoutInterval: 60) /* Based on your needs you can either pass a delegate to process deferred diff --git a/examples/ObjcPodsSample/ObjcPodsSample/AppDelegate.m b/examples/ObjcPodsSample/ObjcPodsSample/AppDelegate.m index b3046f8..8fb3c7b 100644 --- a/examples/ObjcPodsSample/ObjcPodsSample/AppDelegate.m +++ b/examples/ObjcPodsSample/ObjcPodsSample/AppDelegate.m @@ -26,7 +26,7 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:( // For ApsFlyer debug logs [AppsFlyerLib shared].isDebug = YES; - [[AppsFlyerLib shared] waitForATTUserAuthorizationWithTimeoutInterval:60]; +// [[AppsFlyerLib shared] waitForATTUserAuthorizationWithTimeoutInterval:60]; /* Based on your needs you can either pass a delegate to process deferred and direct deeplinking callbacks or disregard them. From f68c62e4b84a6ebf4d57d448c77aa367bb472340 Mon Sep 17 00:00:00 2001 From: Moris Gateno Date: Mon, 6 Feb 2023 17:05:13 +0200 Subject: [PATCH 17/18] versions updated. need to update only Carthage. And then test. --- Cartfile | 2 +- Cartfile.resolved | 4 ++-- Package.resolved | 4 ++-- Package.swift | 2 +- examples/SwiftPodsSample/Podfile | 2 +- segment-appsflyer-ios.podspec | 8 ++++---- 6 files changed, 11 insertions(+), 11 deletions(-) diff --git a/Cartfile b/Cartfile index f0c6a2e..905cf34 100644 --- a/Cartfile +++ b/Cartfile @@ -1,2 +1,2 @@ -binary "https://raw.githubusercontent.com/AppsFlyerSDK/AppsFlyerFramework/master/Carthage/appsflyer-ios.json" +binary "https://raw.githubusercontent.com/AppsFlyerSDK/AppsFlyerFramework/master/Carthage/appsflyer-ios.json" == 6.9.1 github "segmentio/analytics-ios" \ No newline at end of file diff --git a/Cartfile.resolved b/Cartfile.resolved index 23d3c00..f0b2e3a 100644 --- a/Cartfile.resolved +++ b/Cartfile.resolved @@ -1,2 +1,2 @@ -binary "https://raw.githubusercontent.com/AppsFlyerSDK/AppsFlyerFramework/master/Carthage/appsflyer-ios.json" "6.8.1" -github "segmentio/analytics-ios" "4.1.6" +binary "https://raw.githubusercontent.com/AppsFlyerSDK/AppsFlyerFramework/master/Carthage/appsflyer-ios.json" "6.9.1" +github "segmentio/analytics-ios" "4.1.8" diff --git a/Package.resolved b/Package.resolved index dbdbcde..88f6aba 100644 --- a/Package.resolved +++ b/Package.resolved @@ -15,8 +15,8 @@ "repositoryURL": "https://github.com/AppsFlyerSDK/AppsFlyerFramework.git", "state": { "branch": null, - "revision": "d1349c8fdd18a80a776298e4c5c3526e22feff78", - "version": "6.8.1" + "revision": "7a3cd712a77b30e487e53102b101c5e9ff96a95e", + "version": "6.9.1" } } ] diff --git a/Package.swift b/Package.swift index afeb282..a7f9040 100644 --- a/Package.swift +++ b/Package.swift @@ -17,7 +17,7 @@ let package = Package( dependencies: [ // Dependencies declare other packages that this package depends on. .package(name: "Segment", url: "https://github.com/segmentio/analytics-ios.git" , from: "4.0.0"), - .package(name: "AppsFlyerLib" , url: "https://github.com/AppsFlyerSDK/AppsFlyerFramework.git", from: "6.8.1"), + .package(name: "AppsFlyerLib" , url: "https://github.com/AppsFlyerSDK/AppsFlyerFramework.git", .exact("6.9.1")), ], targets: [ // Targets are the basic building blocks of a package. A target can define a module or a test suite. diff --git a/examples/SwiftPodsSample/Podfile b/examples/SwiftPodsSample/Podfile index dd4f6ab..230f983 100644 --- a/examples/SwiftPodsSample/Podfile +++ b/examples/SwiftPodsSample/Podfile @@ -6,6 +6,6 @@ target 'SwiftPodsSample' do use_frameworks! # Pods for SwiftPodsSample - pod 'segment-appsflyer-ios', '~> 6.8.1' + pod 'segment-appsflyer-ios', '6.9.1' end diff --git a/segment-appsflyer-ios.podspec b/segment-appsflyer-ios.podspec index 25e7ed4..8b069e9 100644 --- a/segment-appsflyer-ios.podspec +++ b/segment-appsflyer-ios.podspec @@ -22,14 +22,14 @@ Pod::Spec.new do |s| s.default_subspecs = 'Main' s.subspec 'Main' do |ss| - ss.ios.dependency 'AppsFlyerFramework','~> 6.8.1' - ss.tvos.dependency 'AppsFlyerFramework', '~> 6.8.1' + ss.ios.dependency 'AppsFlyerFramework','6.9.1' + ss.tvos.dependency 'AppsFlyerFramework', '6.9.1' ss.source_files = 'segment-appsflyer-ios/Classes/**/*' end s.subspec 'Strict' do |ss| - ss.ios.dependency 'AppsFlyerFramework/Strict', '~> 6.8.1' - ss.tvos.dependency 'AppsFlyerFramework/Strict', '~> 6.8.1' + ss.ios.dependency 'AppsFlyerFramework/Strict', '6.9.1' + ss.tvos.dependency 'AppsFlyerFramework/Strict', '6.9.1' ss.source_files = 'segment-appsflyer-ios/Classes/**/*' end end From 2d5ef03c5d4009979e887575092124fa3066ce43 Mon Sep 17 00:00:00 2001 From: Moris Gateno Date: Tue, 7 Feb 2023 15:53:49 +0200 Subject: [PATCH 18/18] final changes to repo before release --- Cartfile | 2 +- README.md | 8 ++++---- examples/ObjcPodsSample/Podfile | 2 +- segment-appsflyer-ios.podspec | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Cartfile b/Cartfile index 905cf34..9bb6e65 100644 --- a/Cartfile +++ b/Cartfile @@ -1,2 +1,2 @@ binary "https://raw.githubusercontent.com/AppsFlyerSDK/AppsFlyerFramework/master/Carthage/appsflyer-ios.json" == 6.9.1 -github "segmentio/analytics-ios" \ No newline at end of file +github "segmentio/analytics-ios" diff --git a/README.md b/README.md index cea2fca..7d574ae 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ # AppsFlyer integration for Segment. -## This is a Segment wrapper for AppsFlyer SDK that is built with iOS SDK v6.8.1. +## This is a Segment wrapper for AppsFlyer SDK that is built with iOS SDK v6.9.1. [![Version](https://img.shields.io/cocoapods/v/segment-appsflyer-ios.svg?style=flat)](http://cocoapods.org/pods/segment-appsflyer-ios) [![Carthage compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](https://github.com/Carthage/Carthage) @@ -48,12 +48,12 @@ To install the segment-appsflyer-ios integration: **Production** version: ```ruby -pod 'segment-appsflyer-ios', '6.8.1' +pod 'segment-appsflyer-ios', '6.9.1' ``` **Strict mode SDK** version: ```ruby -pod 'segment-appsflyer-ios/Strict', '6.8.1' +pod 'segment-appsflyer-ios/Strict', '6.9.1' ``` Use the strict mode SDK to completely remove IDFA collection functionality and AdSupport framework dependencies (for example, when developing apps for kids). @@ -65,7 +65,7 @@ Use the strict mode SDK to completely remove IDFA collection functionality and A **Production** version: ```ogdl -github "AppsFlyerSDK/segment-appsflyer-ios" "6.8.1" +github "AppsFlyerSDK/segment-appsflyer-ios" "6.9.1" ``` diff --git a/examples/ObjcPodsSample/Podfile b/examples/ObjcPodsSample/Podfile index fba002e..3900a2d 100644 --- a/examples/ObjcPodsSample/Podfile +++ b/examples/ObjcPodsSample/Podfile @@ -6,5 +6,5 @@ target 'ObjcPodsSample' do use_frameworks! # Pods for ObjcPodsSample - pod 'segment-appsflyer-ios', '~> 6.8.1' + pod 'segment-appsflyer-ios', '6.9.1' end diff --git a/segment-appsflyer-ios.podspec b/segment-appsflyer-ios.podspec index 8b069e9..4b4fa12 100644 --- a/segment-appsflyer-ios.podspec +++ b/segment-appsflyer-ios.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = "segment-appsflyer-ios" - s.version = "6.8.1" + s.version = "6.9.1" s.summary = "AppsFlyer Integration for Segment's analytics-ios library." s.description = <<-DESC