From e5ec8d8b7ece7e149a3b553a081b4cc0bf687f88 Mon Sep 17 00:00:00 2001 From: Kowshickkarthick Subramanian Date: Tue, 16 Feb 2021 15:29:47 +0000 Subject: [PATCH 1/5] Merge pull request #680 in MOBILE-SDK/app_mobile-sdk-ios from MS-4658_Native_ViewabilityIssue to develop Squashed commit of the following: commit e0fbcbd70aa7065692749749f3646ad7c1bb1008 Author: Akash.Verma Date: Thu Feb 4 14:05:18 2021 +0530 Code updated as per comments commit efd69c6e38b7e8072b3f49dd64eac4a1e41c7d06 Author: Akash.Verma Date: Wed Feb 3 18:37:06 2021 +0530 ANNativeAdRequestDelegate added for samples --- .../NativeAd/NativeAdViewController.m | 40 ++++++++++++++++++- .../NativeAd/NativeAdViewController.swift | 39 +++++++++++++++++- 2 files changed, 77 insertions(+), 2 deletions(-) diff --git a/examples/ObjectiveC/SimpleIntegration/SimpleIntegrationObjC/NativeAd/NativeAdViewController.m b/examples/ObjectiveC/SimpleIntegration/SimpleIntegrationObjC/NativeAd/NativeAdViewController.m index e66a5709e..c6cb40031 100644 --- a/examples/ObjectiveC/SimpleIntegration/SimpleIntegrationObjC/NativeAd/NativeAdViewController.m +++ b/examples/ObjectiveC/SimpleIntegration/SimpleIntegrationObjC/NativeAd/NativeAdViewController.m @@ -32,7 +32,7 @@ - (void)viewDidLoad { [ANLogManager setANLogLevel:ANLogLevelAll]; self.nativeAdRequest= [[ANNativeAdRequest alloc] init]; - self.nativeAdRequest.placementId = @"19212468"; + self.nativeAdRequest.placementId = @"17058950"; self.nativeAdRequest.gender = ANGenderMale; self.nativeAdRequest.shouldLoadIconImage = YES; self.nativeAdRequest.shouldLoadMainImage = YES; @@ -70,5 +70,43 @@ - (void)adRequest:(nonnull ANNativeAdRequest *)request didFailToLoadWithError:(n NSLog(@"Ad request Failed With Error"); } +#pragma mark - ANNativeAdDelegate + +- (void)adDidLogImpression:(id)ad { + NSLog(@"%@", NSStringFromSelector(_cmd)); +} + +- (void)adWillExpire:(id)ad { + NSLog(@"%@", NSStringFromSelector(_cmd)); +} + +- (void)adDidExpire:(id)ad { + NSLog(@"%@", NSStringFromSelector(_cmd)); +} + +- (void)adWasClicked:(id)ad { + NSLog(@"%@", NSStringFromSelector(_cmd)); +} + +- (void)adWillPresent:(id)ad { + NSLog(@"%@", NSStringFromSelector(_cmd)); +} + +- (void)adDidPresent:(id)ad { + NSLog(@"%@", NSStringFromSelector(_cmd)); +} + +- (void)adWillClose:(id)ad { + NSLog(@"%@", NSStringFromSelector(_cmd)); +} + +- (void)adDidClose:(id)ad { + NSLog(@"%@", NSStringFromSelector(_cmd)); +} + +- (void)adWillLeaveApplication:(id)ad { + NSLog(@"%@", NSStringFromSelector(_cmd)); +} + @end diff --git a/examples/Swift/SimpleIntegration/SimpleIntegrationSwift/NativeAd/NativeAdViewController.swift b/examples/Swift/SimpleIntegration/SimpleIntegrationSwift/NativeAd/NativeAdViewController.swift index f9e01f6e2..90f7c7804 100644 --- a/examples/Swift/SimpleIntegration/SimpleIntegrationSwift/NativeAd/NativeAdViewController.swift +++ b/examples/Swift/SimpleIntegration/SimpleIntegrationSwift/NativeAd/NativeAdViewController.swift @@ -32,7 +32,7 @@ class NativeAdViewController: UIViewController , ANNativeAdRequestDelegate , ANN // Do any additional setup after loading the view. nativeAdRequest = ANNativeAdRequest() - nativeAdRequest!.placementId = "1281482" + nativeAdRequest!.placementId = "17058950" nativeAdRequest!.shouldLoadIconImage = true nativeAdRequest!.shouldLoadMainImage = true nativeAdRequest!.delegate = self @@ -64,5 +64,42 @@ class NativeAdViewController: UIViewController , ANNativeAdRequestDelegate , ANN func adRequest(_ request: ANNativeAdRequest, didFailToLoadWithError error: Error, with adResponseInfo: ANAdResponseInfo?) { print("Ad request Failed With Error") } + + // MARK: - ANNativeAdDelegate + func adDidLogImpression(_ response: Any) { + print("adDidLogImpression") + } + + func adWillExpire(_ response: Any) { + print("adWillExpire") + } + + func adDidExpire(_ response: Any) { + print("adDidExpire") + } + + func adWasClicked(_ response: Any) { + print("adWasClicked") + } + + func adWillPresent(_ response: Any) { + print("adWillPresent") + } + + func adDidPresent(_ response: Any) { + print("adDidPresent") + } + + func adWillClose(_ response: Any) { + print("adWillClose") + } + + func adDidClose(_ response: Any) { + print("adDidClose") + } + + func adWillLeaveApplication(_ response: Any) { + print("adWillLeaveApplication") + } } From e6b1d0c49e4e80991b40c4a542842c7f5e36d589 Mon Sep 17 00:00:00 2001 From: Kowshickkarthick Subramanian Date: Fri, 19 Feb 2021 00:24:41 +0000 Subject: [PATCH 2/5] Merge pull request #683 in MOBILE-SDK/app_mobile-sdk-ios from MS-4659-NetID-Changes to develop Squashed commit of the following: commit dfc5839d1a0f7002d1fdac342c38066ffb6cb19d Author: ksubramanian Date: Thu Feb 18 17:25:13 2021 -0500 Updated to include ANExternalUserId.h commit 2b49ccc59a13465226ca75dc75e41ede96435775 Author: ksubramanian Date: Thu Feb 18 09:38:13 2021 -0500 Updated inline code comments commit a28a49f2362963c0b6be9844b8b6dfd9acc246d8 Author: ksubramanian Date: Wed Feb 17 17:27:42 2021 -0500 Updated as per review comments commit 7da0bf1c69fb3ee1e3d5470b5c53183905188b0a Author: ksubramanian Date: Wed Feb 17 17:19:46 2021 -0500 Updated NSSet to NSDictionary commit 429d1ad4dd7e84269769b9e517f9dbd266893dfd Author: ksubramanian Date: Wed Feb 17 12:18:14 2021 -0500 Code Refactor commit 301d9c8a6260a2b097e67c4ad87e51e52febb277 Author: ksubramanian Date: Wed Feb 17 10:50:09 2021 -0500 Updated unit tests commit 8a5cc95835f89ad710b3a88105c225686adae343 Author: ksubramanian Date: Wed Feb 17 01:44:20 2021 -0500 Updated unit tests commit c66b69c1f980f6787cf60f6c3c8a4b073dd0bd3b Author: ksubramanian Date: Wed Feb 17 01:39:01 2021 -0500 Code Cleanup and added comments commit ac3f3bf9242cd9bd76965c9f540e305d777a655f Author: ksubramanian Date: Wed Feb 17 01:25:02 2021 -0500 Updted Placements ids commit 96039ee43e91f9e23983f3c4b08aec729f8f807a Author: ksubramanian Date: Wed Feb 17 01:20:21 2021 -0500 Added Unit Tests commit 72ae2e596cb8a916f3ec099cf0e1cfff6a1b735f Author: ksubramanian Date: Tue Feb 16 17:09:31 2021 -0500 First Try --- .../BannerAd/BannerAdViewController.swift | 2 +- .../InterstitialAdViewController.swift | 2 +- .../MultiAdViewController.swift | 8 +- .../VideoAd/VideoAdViewController.swift | 2 +- sdk/AppNexusNativeSDK/AppNexusNativeSDK.h | 2 + sdk/AppNexusSDK.xcodeproj/project.pbxproj | 12 ++ sdk/AppNexusSDK/AppNexusSDK.h | 4 + sdk/sourcefiles/ANAdConstants.h | 7 + sdk/sourcefiles/ANAdProtocol.h | 2 +- sdk/sourcefiles/ANExternalUserId.h | 47 ++++++ sdk/sourcefiles/ANSDKSettings.h | 14 ++ sdk/sourcefiles/ANTargetingParameters.h | 2 +- sdk/sourcefiles/internal/ANExternalUserId.m | 34 +++++ .../internal/ANUniversalTagRequestBuilder.m | 62 +++++++- ...niversalTagRequestBuilderFunctionalTests.m | 136 +++++++++++++++++- .../UnitTestApp.xcodeproj/project.pbxproj | 6 + 16 files changed, 327 insertions(+), 15 deletions(-) create mode 100644 sdk/sourcefiles/ANExternalUserId.h create mode 100644 sdk/sourcefiles/internal/ANExternalUserId.m diff --git a/examples/Swift/SimpleIntegration/SimpleIntegrationSwift/BannerAd/BannerAdViewController.swift b/examples/Swift/SimpleIntegration/SimpleIntegrationSwift/BannerAd/BannerAdViewController.swift index ee4008f82..7cc033b73 100644 --- a/examples/Swift/SimpleIntegration/SimpleIntegrationSwift/BannerAd/BannerAdViewController.swift +++ b/examples/Swift/SimpleIntegration/SimpleIntegrationSwift/BannerAd/BannerAdViewController.swift @@ -27,7 +27,7 @@ class BannerAdViewController: UIViewController , ANBannerAdViewDelegate{ let adWidth: Int = 300 let adHeight: Int = 250 - let adID = "1281482" + let adID = "17058950" // We want to center our ad on the screen. let screenRect: CGRect = UIScreen.main.bounds diff --git a/examples/Swift/SimpleIntegration/SimpleIntegrationSwift/InterstitialAd/InterstitialAdViewController.swift b/examples/Swift/SimpleIntegration/SimpleIntegrationSwift/InterstitialAd/InterstitialAdViewController.swift index b87c31732..b9735affc 100644 --- a/examples/Swift/SimpleIntegration/SimpleIntegrationSwift/InterstitialAd/InterstitialAdViewController.swift +++ b/examples/Swift/SimpleIntegration/SimpleIntegrationSwift/InterstitialAd/InterstitialAdViewController.swift @@ -24,7 +24,7 @@ class InterstitialAdViewController: UIViewController , ANInterstitialAdDelegate super.viewDidLoad() self.title = "Interstitial Ad" - interstitialAd = ANInterstitialAd(placementId: "1281482") + interstitialAd = ANInterstitialAd(placementId: "17058950") interstitialAd!.delegate = self interstitialAd!.clickThroughAction = ANClickThroughAction.openSDKBrowser interstitialAd!.load() diff --git a/examples/Swift/SimpleIntegration/SimpleIntegrationSwift/MultiAdRequest/MultiAdViewController.swift b/examples/Swift/SimpleIntegration/SimpleIntegrationSwift/MultiAdRequest/MultiAdViewController.swift index e66d4803b..c3d5efe5f 100644 --- a/examples/Swift/SimpleIntegration/SimpleIntegrationSwift/MultiAdRequest/MultiAdViewController.swift +++ b/examples/Swift/SimpleIntegration/SimpleIntegrationSwift/MultiAdRequest/MultiAdViewController.swift @@ -63,7 +63,7 @@ class MultiAdViewController: UITableViewController , ANMultiAdRequestDelegate , // Create InstreamVideo Ad Object func createVideoAd(adView : UIView) -> ANInstreamVideoAd { - videoAd = ANInstreamVideoAd(placementId: "17982237") + videoAd = ANInstreamVideoAd(placementId: "17058950") videoAd.loadDelegate = self return videoAd } @@ -71,7 +71,7 @@ class MultiAdViewController: UITableViewController , ANMultiAdRequestDelegate , // Create Interstitial Ad Object func createInterstitialAd() -> ANInterstitialAd{ - interstitialAd = ANInterstitialAd(placementId: "17982237") + interstitialAd = ANInterstitialAd(placementId: "17058950") interstitialAd!.delegate = self return interstitialAd! } @@ -79,7 +79,7 @@ class MultiAdViewController: UITableViewController , ANMultiAdRequestDelegate , // Create Native Ad Object func createNativeAd() -> ANNativeAdRequest{ nativeAdRequest = ANNativeAdRequest() - nativeAdRequest!.placementId = "17982237" + nativeAdRequest!.placementId = "17058950" nativeAdRequest!.shouldLoadIconImage = true nativeAdRequest!.shouldLoadMainImage = true nativeAdRequest!.delegate = self @@ -92,7 +92,7 @@ class MultiAdViewController: UITableViewController , ANMultiAdRequestDelegate , let rect = CGRect(origin: CGPoint(x: 0,y :0), size: CGSize(width: self.bannerAdView.frame.size.width , height: self.bannerAdView.frame.size.height)) // Make a banner ad view. - self.bannerAd = ANBannerAdView(frame: rect, placementId: "17982237", adSize: size) + self.bannerAd = ANBannerAdView(frame: rect, placementId: "17058950", adSize: size) self.bannerAd!.rootViewController = self self.bannerAd!.delegate = self self.bannerAd!.shouldResizeAdToFitContainer = true diff --git a/examples/Swift/SimpleIntegration/SimpleIntegrationSwift/VideoAd/VideoAdViewController.swift b/examples/Swift/SimpleIntegration/SimpleIntegrationSwift/VideoAd/VideoAdViewController.swift index d2b65282b..9c8a159e3 100644 --- a/examples/Swift/SimpleIntegration/SimpleIntegrationSwift/VideoAd/VideoAdViewController.swift +++ b/examples/Swift/SimpleIntegration/SimpleIntegrationSwift/VideoAd/VideoAdViewController.swift @@ -43,7 +43,7 @@ class VideoAdViewController: UIViewController , ANInstreamVideoAdLoadDelegate, A } setupContentPlayer() - videoAd = ANInstreamVideoAd(placementId: "1281482") + videoAd = ANInstreamVideoAd(placementId: "17058950") videoAd?.load(with: self) videoAd?.clickThroughAction = ANClickThroughAction.openSDKBrowser diff --git a/sdk/AppNexusNativeSDK/AppNexusNativeSDK.h b/sdk/AppNexusNativeSDK/AppNexusNativeSDK.h index d5c6070ce..32bc74be7 100644 --- a/sdk/AppNexusNativeSDK/AppNexusNativeSDK.h +++ b/sdk/AppNexusNativeSDK/AppNexusNativeSDK.h @@ -49,3 +49,5 @@ FOUNDATION_EXPORT const unsigned char AppNexusNativeSDKVersionString[]; #import + +#import diff --git a/sdk/AppNexusSDK.xcodeproj/project.pbxproj b/sdk/AppNexusSDK.xcodeproj/project.pbxproj index 1363f2c82..a85cfb926 100644 --- a/sdk/AppNexusSDK.xcodeproj/project.pbxproj +++ b/sdk/AppNexusSDK.xcodeproj/project.pbxproj @@ -17,6 +17,10 @@ 0099B484228CA0F6004E80AB /* UIView+ANCategory.m in Sources */ = {isa = PBXBuildFile; fileRef = ECE4EA9B194B768A0069D934 /* UIView+ANCategory.m */; }; 0099B485228CA18C004E80AB /* NSTimer+ANCategory.h in Headers */ = {isa = PBXBuildFile; fileRef = ECE4EA98194B768A0069D934 /* NSTimer+ANCategory.h */; settings = {ATTRIBUTES = (Private, ); }; }; 0099B486228CA191004E80AB /* NSTimer+ANCategory.m in Sources */ = {isa = PBXBuildFile; fileRef = ECE4EA99194B768A0069D934 /* NSTimer+ANCategory.m */; }; + 00C4919325DF043100609E49 /* ANExternalUserId.h in Headers */ = {isa = PBXBuildFile; fileRef = 00C4919225DF043100609E49 /* ANExternalUserId.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 00C4919425DF043100609E49 /* ANExternalUserId.h in Headers */ = {isa = PBXBuildFile; fileRef = 00C4919225DF043100609E49 /* ANExternalUserId.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 00C491C325DF15AB00609E49 /* ANExternalUserId.m in Sources */ = {isa = PBXBuildFile; fileRef = 00C491C025DF15AB00609E49 /* ANExternalUserId.m */; }; + 00C491C425DF15AB00609E49 /* ANExternalUserId.m in Sources */ = {isa = PBXBuildFile; fileRef = 00C491C025DF15AB00609E49 /* ANExternalUserId.m */; }; 00D6B04820D1BC9B007A3439 /* ANOMIDImplementation.h in Headers */ = {isa = PBXBuildFile; fileRef = 00D6B04720D1BC9B007A3439 /* ANOMIDImplementation.h */; }; 00D6B04B20D1BCAF007A3439 /* ANOMIDImplementation.m in Sources */ = {isa = PBXBuildFile; fileRef = 00D6B04920D1BCAF007A3439 /* ANOMIDImplementation.m */; }; 0E02F07024336D570073A226 /* ANCSRNativeAdResponse.m in Sources */ = {isa = PBXBuildFile; fileRef = 0E3E3E62241FB73500823D66 /* ANCSRNativeAdResponse.m */; }; @@ -370,6 +374,8 @@ 0035C5AF1F44971100915E97 /* ANSSMMediationAdViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ANSSMMediationAdViewController.m; sourceTree = ""; }; 006F6B992295F70E003D2DF0 /* ANAdFetcherBase.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ANAdFetcherBase.m; sourceTree = ""; }; 006F6B9D2295F72A003D2DF0 /* ANAdFetcherBase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ANAdFetcherBase.h; sourceTree = ""; }; + 00C4919225DF043100609E49 /* ANExternalUserId.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ANExternalUserId.h; sourceTree = ""; }; + 00C491C025DF15AB00609E49 /* ANExternalUserId.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ANExternalUserId.m; sourceTree = ""; }; 00D6B04720D1BC9B007A3439 /* ANOMIDImplementation.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ANOMIDImplementation.h; sourceTree = ""; }; 00D6B04920D1BCAF007A3439 /* ANOMIDImplementation.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ANOMIDImplementation.m; sourceTree = ""; }; 0E0C5E5B2437E2EC0030B813 /* ANCSRAd.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ANCSRAd.m; sourceTree = ""; }; @@ -682,6 +688,7 @@ ECE4EA8E194B768A0069D934 /* ANAdView.h */, ECE4EA8F194B768A0069D934 /* ANBannerAdView.h */, ECE4EA90194B768A0069D934 /* ANCustomAdapter.h */, + 00C4919225DF043100609E49 /* ANExternalUserId.h */, 0E35D4A92088F652000A6C27 /* ANGDPRSettings.h */, 609732B31E42E7910061EC0A /* ANInstreamVideoAd.h */, ECE4EA91194B768A0069D934 /* ANInterstitialAd.h */, @@ -895,6 +902,7 @@ 60D39E1422570FE20029F741 /* ANVideoPlayerSettings.m */, 60183FD222933E9500CFDE33 /* ANWebView.h */, 60183FD322933E9500CFDE33 /* ANWebView.m */, + 00C491C025DF15AB00609E49 /* ANExternalUserId.m */, ); path = internal; sourceTree = ""; @@ -1107,6 +1115,7 @@ 609732D71E42E9860061EC0A /* ANVideoAdProcessor.h in Headers */, 60D39E2922679E480029F741 /* ANVideoPlayerSettings+ANCategory.h in Headers */, 60D39E1522570FE20029F741 /* ANVideoPlayerSettings.h in Headers */, + 00C4919325DF043100609E49 /* ANExternalUserId.h in Headers */, 60183FD52293482700CFDE33 /* ANWebView.h in Headers */, 0ECF336622D79A62007DB185 /* AppNexusSDK.h in Headers */, 609732B01E42E73D0061EC0A /* NSDictionary+ANCategory.h in Headers */, @@ -1179,6 +1188,7 @@ F52F82EB2293362600F4578C /* NSObject+ANCategory.h in Headers */, F52F82EE2293367A00F4578C /* NSString+ANCategory.h in Headers */, 0099B485228CA18C004E80AB /* NSTimer+ANCategory.h in Headers */, + 00C4919425DF043100609E49 /* ANExternalUserId.h in Headers */, 0099B483228CA0EB004E80AB /* UIView+ANCategory.h in Headers */, F5731B4B228C8D050012B134 /* UIView+ANNativeAdCategory.h in Headers */, ); @@ -1355,6 +1365,7 @@ 0E0C5E5C2437E2EC0030B813 /* ANCSRAd.m in Sources */, 0E92D3B52420D06A00209580 /* ANCSRNativeAdController.m in Sources */, 0E3E3E64241FB73500823D66 /* ANCSRNativeAdResponse.m in Sources */, + 00C491C325DF15AB00609E49 /* ANExternalUserId.m in Sources */, 0ED85345208A94F200A5FFA0 /* ANGDPRSettings.m in Sources */, 8A9AEDF61A1BF99D00C58BDA /* ANGlobal.m in Sources */, 60165D262464823E00E8E07C /* ANHTTPNetworkSession.m in Sources */, @@ -1438,6 +1449,7 @@ F5731B6C228C8E430012B134 /* ANGDPRSettings.m in Sources */, F5731B71228C8FD20012B134 /* ANGlobal.m in Sources */, 60165D272464823E00E8E07C /* ANHTTPNetworkSession.m in Sources */, + 00C491C425DF15AB00609E49 /* ANExternalUserId.m in Sources */, F5731B73228C900B0012B134 /* ANLocation.m in Sources */, F5731B77228C902D0012B134 /* ANLogging.m in Sources */, F5731B76228C902A0012B134 /* ANLogManager.m in Sources */, diff --git a/sdk/AppNexusSDK/AppNexusSDK.h b/sdk/AppNexusSDK/AppNexusSDK.h index 371a87866..12b60686a 100644 --- a/sdk/AppNexusSDK/AppNexusSDK.h +++ b/sdk/AppNexusSDK/AppNexusSDK.h @@ -48,3 +48,7 @@ FOUNDATION_EXPORT const unsigned char AppNexusSDKVersionString[]; #import #import +#import + + + diff --git a/sdk/sourcefiles/ANAdConstants.h b/sdk/sourcefiles/ANAdConstants.h index 78e8bebeb..fe603c71a 100644 --- a/sdk/sourcefiles/ANAdConstants.h +++ b/sdk/sourcefiles/ANAdConstants.h @@ -58,3 +58,10 @@ typedef NS_ENUM(NSUInteger, ANVideoOrientation) { ANLandscape, ANSquare }; + + + + + + + diff --git a/sdk/sourcefiles/ANAdProtocol.h b/sdk/sourcefiles/ANAdProtocol.h index c8d12d991..1dea72cad 100644 --- a/sdk/sourcefiles/ANAdProtocol.h +++ b/sdk/sourcefiles/ANAdProtocol.h @@ -69,7 +69,7 @@ /** Specifies a string that corresponds to an external user ID for user */ -@property (nonatomic, readwrite, strong, nullable) NSString *externalUid; +@property (nonatomic, readwrite, strong, nullable) NSString *externalUid DEPRECATED_MSG_ATTRIBUTE("Use ANSDKSettings.publisherUserId instead."); /** diff --git a/sdk/sourcefiles/ANExternalUserId.h b/sdk/sourcefiles/ANExternalUserId.h new file mode 100644 index 000000000..75f5f8b39 --- /dev/null +++ b/sdk/sourcefiles/ANExternalUserId.h @@ -0,0 +1,47 @@ +/* Copyright 2021 APPNEXUS INC + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + */ + +#import +/* + * Supported Third Party ID Sources + * */ +typedef NS_ENUM(NSUInteger, ANExternalUserIdSource) { + ANExternalUserIdSourceLiveRamp, + ANExternalUserIdSourceNetId, + ANExternalUserIdSourceCriteo, + ANExternalUserIdSourceTheTradeDesk +}; + + + +/** + Defines the User Id Object from an External Thrid Party Source + */ +@interface ANExternalUserId : NSObject + +/** + Source of the External User Id + */ +@property (nonatomic, readwrite) ANExternalUserIdSource source; + +/** + The User Id String + */ +@property (nonatomic, readwrite, strong, nonnull) NSString *userId; + + +- (nullable instancetype)initWithSource:(ANExternalUserIdSource)source userId:(nonnull NSString *)userId; + +@end diff --git a/sdk/sourcefiles/ANSDKSettings.h b/sdk/sourcefiles/ANSDKSettings.h index 9c82dccf9..45f18848d 100644 --- a/sdk/sourcefiles/ANSDKSettings.h +++ b/sdk/sourcefiles/ANSDKSettings.h @@ -16,6 +16,8 @@ #import +#import "ANExternalUserId.h" + @interface ANSDKSettings : NSObject @@ -95,4 +97,16 @@ An AppNexus disableIDFAUsage is a boolean value which exclude the IDFA field in */ @property (nonatomic, readwrite) BOOL disableIDFAUsage; + +/** + Specifies a string that corresponds to the Publishers User ID for current application user. +*/ +@property (nonatomic, readwrite, strong, nullable) NSString *publisherUserId; + + +/** + A Dictionary containing objects that hold External UserId parameters. + */ +@property (nonatomic, readwrite, strong, nullable) NSArray *externalUserIdArray; + @end diff --git a/sdk/sourcefiles/ANTargetingParameters.h b/sdk/sourcefiles/ANTargetingParameters.h index 049a14c52..c1a6116f4 100644 --- a/sdk/sourcefiles/ANTargetingParameters.h +++ b/sdk/sourcefiles/ANTargetingParameters.h @@ -31,7 +31,7 @@ @property (nonatomic, readwrite, strong, nullable) NSString *age; @property (nonatomic, readwrite, assign) ANGender gender; -@property (nonatomic, readwrite, strong, nullable) NSString *externalUid; +@property (nonatomic, readwrite, strong, nullable) NSString *externalUid DEPRECATED_MSG_ATTRIBUTE("No Alternatives"); /** location may be nil if not specified by app. */ diff --git a/sdk/sourcefiles/internal/ANExternalUserId.m b/sdk/sourcefiles/internal/ANExternalUserId.m new file mode 100644 index 000000000..b593dcb31 --- /dev/null +++ b/sdk/sourcefiles/internal/ANExternalUserId.m @@ -0,0 +1,34 @@ +/* Copyright 2021 APPNEXUS INC + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + */ + +#import "ANExternalUserId.h" + +@implementation ANExternalUserId + +@synthesize source = __source; +@synthesize userId = __userId; + +- (nullable instancetype)initWithSource:(ANExternalUserIdSource)source userId:(NSString *)userId{ + self = [super init]; + + if (self != nil) { + self.source = source; + self.userId = userId; + } + + return self; +} + +@end diff --git a/sdk/sourcefiles/internal/ANUniversalTagRequestBuilder.m b/sdk/sourcefiles/internal/ANUniversalTagRequestBuilder.m index ce2bb8062..e5ce719d8 100644 --- a/sdk/sourcefiles/internal/ANUniversalTagRequestBuilder.m +++ b/sdk/sourcefiles/internal/ANUniversalTagRequestBuilder.m @@ -231,6 +231,13 @@ - (NSDictionary *)requestBody requestDict[@"user"] = user; } + // Set EUID node, EUID - Third party id solutions + // + NSArray *> *externalUserIds = [self externalUserIds]; + if (externalUserIds) { + requestDict[@"eids"] = externalUserIds; + } + NSDictionary *device = [self device]; if (device) { requestDict[@"device"] = device; @@ -565,12 +572,15 @@ -(void)getAdFramework:(NSMutableDictionary *)tag{ // - NSString *externalUid = [self.adFetcherDelegate externalUid]; - if (externalUid) { - userDict[@"external_uid"] = externalUid; + NSString *publisherUserId = [[ANSDKSettings sharedInstance] publisherUserId]; + + // Use publisherFirstPartyID if it is present. External Id in ANAdProtocol is deprecated. + if (publisherUserId) { + userDict[@"external_uid"] = publisherUserId; + }else if ([self.adFetcherDelegate externalUid]) { + userDict[@"external_uid"] = [self.adFetcherDelegate externalUid]; } - // return [userDict copy]; } @@ -774,6 +784,50 @@ -(void)getAdFramework:(NSMutableDictionary *)tag{ } + +- (NSArray *> *)externalUserIds +{ + NSArray *externalUserIdArray = [ANSDKSettings.sharedInstance externalUserIdArray]; + + if ([externalUserIdArray count] <= 0) { return nil; } + // + NSMutableArray *> *transformedeuidArray = [[NSMutableArray *> alloc] init]; + + for (ANExternalUserId *externaluserId in externalUserIdArray) + { + switch (externaluserId.source) { + case ANExternalUserIdSourceLiveRamp: + [transformedeuidArray addObject:@{ + @"source" : @"liveramp.com", + @"id" : externaluserId.userId + } ]; + break; + case ANExternalUserIdSourceCriteo: + [transformedeuidArray addObject:@{ + @"source" : @"criteo.com", + @"id" : externaluserId.userId + } ]; + break; + case ANExternalUserIdSourceNetId: + [transformedeuidArray addObject:@{ + @"source" : @"netid.de", + @"id" : externaluserId.userId + } ]; + break; + case ANExternalUserIdSourceTheTradeDesk: + [transformedeuidArray addObject:@{ + @"source" : @"adserver.org", + @"id" : externaluserId.userId, + @"rti_partner" : @"TDID" + } ]; + break; + } + } + // + return [transformedeuidArray copy]; +} + + - (NSDictionary *)sdk { return @{ @"source" : @"ansdk", diff --git a/tests/UnitTestApp/FunctionalTests/ANUniversalTagRequestBuilderFunctionalTests.m b/tests/UnitTestApp/FunctionalTests/ANUniversalTagRequestBuilderFunctionalTests.m index 1b2661363..ed0f27f16 100644 --- a/tests/UnitTestApp/FunctionalTests/ANUniversalTagRequestBuilderFunctionalTests.m +++ b/tests/UnitTestApp/FunctionalTests/ANUniversalTagRequestBuilderFunctionalTests.m @@ -24,6 +24,7 @@ #import "ANGDPRSettings.h" #import "ANUSPrivacySettings.h" #import "ANOMIDImplementation.h" +#import "ANExternalUserId.h" static NSString *const kTestUUID = @"0000-000-000-00"; @@ -60,6 +61,8 @@ - (void)tearDown { [[ANSDKSettings sharedInstance] setAuctionTimeout:0]; ANSDKSettings.sharedInstance.geoOverrideCountryCode = nil; ANSDKSettings.sharedInstance.geoOverrideZipCode = nil; + ANSDKSettings.sharedInstance.publisherUserId = nil; + ANSDKSettings.sharedInstance.externalUserIdArray = nil; for (UIView *additionalView in [[ANGlobal getKeyWindow].rootViewController.view subviews]){ [additionalView removeFromSuperview]; @@ -667,8 +670,6 @@ - (void)testUTRequestForEmptyZipCodeAndEmptyCountryCode [self waitForExpectationsWithTimeout:UTMODULETESTS_TIMEOUT handler:nil]; } - - - (void)testUTRequestForOMIDSignalEnableBannerAd { [self setUpOMIDTestCaseForAd:@[ @(ANAllowedMediaTypeBanner) ] andEnableOMID:YES]; @@ -845,4 +846,135 @@ -(void)OMIDSignalDisableAssert:(NSDictionary *)jsonObject andMediaType:(NSArray< } + + +- (void)testUTRequestPublisherUserIDS +{ + + ANSDKSettings.sharedInstance.publisherUserId = @"foobar-publisherfirstpartyid"; // This value should be seen in UT Request body + TestANUniversalFetcher *adFetcher = [[TestANUniversalFetcher alloc] initWithPlacementId:placementID]; + + //publisherFirstPartyID should be used instead of externalUid. + // If both publisherFirstPartyID and externalUid are set, publisherFirstPartyID will override externalUID + adFetcher.externalUid = @"AppNexus"; // This value should not be seen in UT Request body. + + NSURLRequest *request = [ANUniversalTagRequestBuilder buildRequestWithAdFetcherDelegate:adFetcher.delegate]; + XCTestExpectation *expectation = [self expectationWithDescription:[NSString stringWithFormat:@"%s", __PRETTY_FUNCTION__]]; + + + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), + ^{ + NSError *error; + + id jsonObject = [NSJSONSerialization JSONObjectWithData:request.HTTPBody + options:kNilOptions + error:&error]; + TESTTRACEM(@"jsonObject=%@", jsonObject); + XCTAssertNil(error); + XCTAssertNotNil(jsonObject); + XCTAssertTrue([jsonObject isKindOfClass:[NSDictionary class]]); + NSDictionary *jsonDict = (NSDictionary *)jsonObject; + NSDictionary *userDict = jsonDict[@"user"]; + XCTAssertNotNil(userDict); + + NSString *puhlisherUserId = userDict[@"external_uid"]; + XCTAssertNotNil(puhlisherUserId); + XCTAssertEqualObjects(puhlisherUserId, @"foobar-publisherfirstpartyid"); + + [expectation fulfill]; + }); + + [self waitForExpectationsWithTimeout:UTMODULETESTS_TIMEOUT handler:nil]; + +} + +- (void)testUTRequestExternalUserIds +{ +// ANSDKSettings.sharedInstance.externalUserIds=@{ +// ANExternalUserIdNetId : @"999888777", +// ANExternalUserIdLiveRamp : @"AjfowMv4ZHZQJFM8TpiUnYEyA81Vdgg", +// ANExternalUserIdTheTradeDesk : @"00000111-91b1-49b2-ae37-17a8173dc36f", +// ANExternalUserIdCriteo : @"_fl7bV96WjZsbiUyQnJlQ3g4ckh5a1N" +// }; + + NSMutableArray *tempExternalUserIdArray = [[NSMutableArray alloc] init]; + + ANExternalUserId *netIdUser = [ANExternalUserId alloc]; + netIdUser.source = ANExternalUserIdSourceNetId; + netIdUser.userId = @"999888777"; + + ANExternalUserId *tradeDeskUser = [ANExternalUserId alloc]; + tradeDeskUser.source = ANExternalUserIdSourceTheTradeDesk; + tradeDeskUser.userId = @"00000111-91b1-49b2-ae37-17a8173dc36f"; + + [tempExternalUserIdArray addObject:[[ANExternalUserId alloc] initWithSource:ANExternalUserIdSourceCriteo userId:@"_fl7bV96WjZsbiUyQnJlQ3g4ckh5a1N"]]; + [tempExternalUserIdArray addObject:[[ANExternalUserId alloc] initWithSource:ANExternalUserIdSourceLiveRamp userId:@"AjfowMv4ZHZQJFM8TpiUnYEyA81Vdgg" ]]; + + [tempExternalUserIdArray addObject:netIdUser]; + [tempExternalUserIdArray addObject:tradeDeskUser]; + + ANSDKSettings.sharedInstance.externalUserIdArray = tempExternalUserIdArray; + + + TestANUniversalFetcher *adFetcher = [[TestANUniversalFetcher alloc] initWithPlacementId:placementID]; + NSURLRequest *request = [ANUniversalTagRequestBuilder buildRequestWithAdFetcherDelegate:adFetcher.delegate]; + + XCTestExpectation *netIDExpectation = [self expectationWithDescription:[NSString stringWithFormat:@"%s", __PRETTY_FUNCTION__]]; + XCTestExpectation *liveRampExpectation = [self expectationWithDescription:[NSString stringWithFormat:@"%s", __PRETTY_FUNCTION__]]; + XCTestExpectation *tradeDeskExpectation = [self expectationWithDescription:[NSString stringWithFormat:@"%s", __PRETTY_FUNCTION__]]; + XCTestExpectation *criteoExpectation = [self expectationWithDescription:[NSString stringWithFormat:@"%s", __PRETTY_FUNCTION__]]; + + + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), + ^{ + NSError *error; + + id jsonObject = [NSJSONSerialization JSONObjectWithData:request.HTTPBody + options:kNilOptions + error:&error]; + TESTTRACEM(@"jsonObject=%@", jsonObject); + XCTAssertNil(error); + XCTAssertNotNil(jsonObject); + XCTAssertTrue([jsonObject isKindOfClass:[NSDictionary class]]); + NSDictionary *jsonDict = (NSDictionary *)jsonObject; + NSArray *eidsArray = jsonDict[@"eids"]; + NSDictionary *eidDictionary = jsonDict[@"eids"]; + XCTAssertEqual(eidDictionary.count, 4 ); + + NSUInteger count = [eidsArray count]; + for (NSUInteger index = 0; index < count ; index++) { + TESTTRACEM(@"source==============%@", eidsArray[index][@"source"]); + if([eidsArray[index][@"source"] isEqualToString: @"criteo.com"]){ + XCTAssertEqualObjects(eidsArray[index][@"source"], @"criteo.com"); + XCTAssertEqualObjects(eidsArray[index][@"id"], @"_fl7bV96WjZsbiUyQnJlQ3g4ckh5a1N"); + [criteoExpectation fulfill]; + } + + if([eidsArray[index][@"source"] isEqualToString: @"netid.de"]){ + XCTAssertEqualObjects(eidsArray[index][@"source"], @"netid.de"); + XCTAssertEqualObjects(eidsArray[index][@"id"], @"999888777"); + [netIDExpectation fulfill]; + } + + if([eidsArray[index][@"source"] isEqualToString: @"liveramp.com"]){ + XCTAssertEqualObjects(eidsArray[index][@"source"], @"liveramp.com"); + XCTAssertEqualObjects(eidsArray[index][@"id"], @"AjfowMv4ZHZQJFM8TpiUnYEyA81Vdgg"); + [liveRampExpectation fulfill]; + } + + if([eidsArray[index][@"source"] isEqualToString: @"adserver.org"]){ + XCTAssertEqualObjects(eidsArray[index][@"source"], @"adserver.org"); + XCTAssertEqualObjects(eidsArray[index][@"id"], @"00000111-91b1-49b2-ae37-17a8173dc36f"); + XCTAssertEqualObjects(eidsArray[index][@"rti_partner"], @"TDID"); + [tradeDeskExpectation fulfill]; + } + } + }); + + [self waitForExpectationsWithTimeout:UTMODULETESTS_TIMEOUT handler:nil]; + +} + + + @end diff --git a/tests/UnitTestApp/UnitTestApp.xcodeproj/project.pbxproj b/tests/UnitTestApp/UnitTestApp.xcodeproj/project.pbxproj index 4cf0b11e0..bf7bd8a5c 100644 --- a/tests/UnitTestApp/UnitTestApp.xcodeproj/project.pbxproj +++ b/tests/UnitTestApp/UnitTestApp.xcodeproj/project.pbxproj @@ -11,6 +11,8 @@ 00436C1B24A45F2C00C42D73 /* ANJAMCustomKeywordsResponse.json in Resources */ = {isa = PBXBuildFile; fileRef = 00436C1724A45F1C00C42D73 /* ANJAMCustomKeywordsResponse.json */; }; 004833BF24A39D6400BFF7A6 /* ANHTTPStubbingManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 0E8C970C21FF32EB005D1F0E /* ANHTTPStubbingManager.m */; }; 004833E824A3CF7300BFF7A6 /* ANHTTPStubURLProtocol.m in Sources */ = {isa = PBXBuildFile; fileRef = 0E8C970E21FF32EB005D1F0E /* ANHTTPStubURLProtocol.m */; }; + 00B5CB6E25DCC4FD003D1EFD /* FBAudienceNetwork.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FC871DA125BB038F003144BC /* FBAudienceNetwork.framework */; }; + 00B5CB6F25DCC4FD003D1EFD /* FBAudienceNetwork.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = FC871DA125BB038F003144BC /* FBAudienceNetwork.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 0E061F1E23D1F37F000F0E1E /* testLoadTwoMARInstancesSimultaneously.json in Resources */ = {isa = PBXBuildFile; fileRef = 0E061F1C23D1F37F000F0E1E /* testLoadTwoMARInstancesSimultaneously.json */; }; 0E14222122F99B9A006C597A /* ANResourceValidationTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 0E14221F22F99B9A006C597A /* ANResourceValidationTestCase.m */; }; 0E14222322F99BA8006C597A /* ANResourceValidationTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 0E14222222F99BA8006C597A /* ANResourceValidationTestCase.m */; }; @@ -615,6 +617,7 @@ dstSubfolderSpec = 10; files = ( 0E6B7E4922D8DE49005D069E /* AppNexusSDK.framework in Embed Frameworks */, + 00B5CB6F25DCC4FD003D1EFD /* FBAudienceNetwork.framework in Embed Frameworks */, ); name = "Embed Frameworks"; runOnlyForDeploymentPostprocessing = 0; @@ -1157,6 +1160,7 @@ 0ED159F92236B82900D56022 /* GLKit.framework in Frameworks */, FC4C72E324FF02B800379108 /* GoogleMobileAds.framework in Frameworks */, 0ED159E52236B54900D56022 /* JavaScriptCore.framework in Frameworks */, + 00B5CB6E25DCC4FD003D1EFD /* FBAudienceNetwork.framework in Frameworks */, 0ED159E72236B55400D56022 /* libc++.tbd in Frameworks */, 0ED159E92236B55B00D56022 /* libsqlite3.tbd in Frameworks */, 0ED159EB2236B56100D56022 /* libxml2.tbd in Frameworks */, @@ -3160,6 +3164,7 @@ ONLY_ACTIVE_ARCH = YES; OTHER_LDFLAGS = "-ObjC"; SDKROOT = iphoneos; + VALIDATE_WORKSPACE = YES; }; name = Debug; }; @@ -3219,6 +3224,7 @@ SDKROOT = iphoneos; SWIFT_COMPILATION_MODE = wholemodule; VALIDATE_PRODUCT = YES; + VALIDATE_WORKSPACE = YES; }; name = Release; }; From 3d896d1a9da3f9ac4feb014b4a92e2dca7df1c4d Mon Sep 17 00:00:00 2001 From: Kowshickkarthick Subramanian Date: Fri, 19 Feb 2021 19:22:52 +0000 Subject: [PATCH 3/5] Merge pull request #685 in MOBILE-SDK/app_mobile-sdk-ios from MS-4671-LimitForANJAMRefreshFrequency to develop Squashed commit of the following: commit 5b230d56cd8e0b6fb6c8d5a331aa844e862f9049 Author: ksubramanian Date: Fri Feb 19 13:04:24 2021 -0500 Added Warn log commit d09b536a32472c8dea3b7f82a927156d3c7f22ed Author: ksubramanian Date: Fri Feb 19 11:53:49 2021 -0500 Codechagnes --- sdk/sourcefiles/internal/ANANJAMImplementation.m | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/sdk/sourcefiles/internal/ANANJAMImplementation.m b/sdk/sourcefiles/internal/ANANJAMImplementation.m index 191479166..9c58eab55 100644 --- a/sdk/sourcefiles/internal/ANANJAMImplementation.m +++ b/sdk/sourcefiles/internal/ANANJAMImplementation.m @@ -19,6 +19,10 @@ #import "ANLogging.h" #import "NSString+ANCategory.h" +// Minimum MARID refresh interval set via ANJAM in Seconds. +// +#define kANMinimumMRAIDRefreshFrequencyInSeconds 0.1 + NSString *const kANCallMayDeepLink = @"MayDeepLink"; NSString *const kANCallDeepLink = @"DeepLink"; NSString *const kANCallExternalBrowser = @"ExternalBrowser"; @@ -174,7 +178,15 @@ + (void)callGetCustomKeywords:(ANAdWebViewController *)controller query:(NSDicti + (void)callSetMraidRefreshFrequency:(ANAdWebViewController *)controller query:(NSDictionary *)query { NSString *milliseconds = [query valueForKey:@"ms"]; - controller.checkViewableTimeInterval = [milliseconds doubleValue] / 1000; + double refreshFrequencyinSeconds = [milliseconds doubleValue] / 1000; + if (refreshFrequencyinSeconds < kANMinimumMRAIDRefreshFrequencyInSeconds) + { + controller.checkViewableTimeInterval = kANMinimumMRAIDRefreshFrequencyInSeconds; + ANLogWarn(@"setMraidRefreshFrequency called with value %f, setMraidRefreshFrequency set to minimum allowed value %f.", + refreshFrequencyinSeconds, kANMinimumMRAIDRefreshFrequencyInSeconds ); + } else { + controller.checkViewableTimeInterval = refreshFrequencyinSeconds; + } } // Send the result back to JS From fc9de8059d1ef7a7be839457214de3c858524d3b Mon Sep 17 00:00:00 2001 From: Abhishek Sharma Date: Tue, 23 Feb 2021 13:15:38 +0000 Subject: [PATCH 4/5] ATTrackingManager Support Squashed commit of the following: commit 76db2867aef7e8a24e37a19cc6dfe0a893275566 Author: abhisheksharma Date: Tue Feb 23 12:59:55 2021 +0530 updated value of limit_ad_tracking commit c433e1df656dbeb60ad82283b926490febf74dde Author: abhisheksharma Date: Sat Feb 20 03:58:33 2021 +0530 Fixed Unit testcase commit c4b537f945de8dbf8cf6ac9857703df5f2d077c6 Author: abhisheksharma Date: Sat Feb 20 02:23:47 2021 +0530 Updated Unit testcase commit 2eba4037616895a38a877836e97bf125c1f15d43 Author: abhisheksharma Date: Sat Feb 20 02:10:15 2021 +0530 updated table commit 3af21cbd0579d0ae5ad2bb3c7f4bda3a54961216 Author: abhisheksharma Date: Sat Feb 20 01:35:23 2021 +0530 Updated Unit Test commit 398f18bbde4b189ac0ada3dddbccedf33c51ae26 Author: abhisheksharma Date: Sat Feb 20 00:59:35 2021 +0530 Added iOS 14 change --- sdk/sourcefiles/internal/ANGlobal.m | 18 ++ .../internal/ANUniversalTagRequestBuilder.m | 20 +- ...niversalTagRequestBuilderFunctionalTests.m | 110 +++++++--- .../ANCSRUniversalTagRequestBuilderTests.m | 70 ++++-- tests/UnitTestApp/UnitTestApp/AppDelegate.m | 31 +++ tests/UnitTestApp/UnitTestApp/Info.plist | 6 +- .../ANUniversalTagRequestBuilderTests.m | 204 +++++++++++++----- 7 files changed, 347 insertions(+), 112 deletions(-) diff --git a/sdk/sourcefiles/internal/ANGlobal.m b/sdk/sourcefiles/internal/ANGlobal.m index 99987967f..0e7a10cab 100644 --- a/sdk/sourcefiles/internal/ANGlobal.m +++ b/sdk/sourcefiles/internal/ANGlobal.m @@ -22,6 +22,9 @@ #import "ANHTTPNetworkSession.h" #import "ANOMIDImplementation.h" #import "ANGDPRSettings.h" +#if __has_include() + #import +#endif NSString * __nonnull const ANInternalDelgateTagKeyPrimarySize = @"ANInternalDelgateTagKeyPrimarySize"; NSString * __nonnull const ANInternalDelegateTagKeySizes = @"ANInternalDelegateTagKeySizes"; @@ -49,6 +52,11 @@ return @(systemInfo.machine); } + +/* +True : Advertising Tracking Enabled +False : Advertising Tracking Disabled, Restricted or NotDetermined + */ BOOL ANAdvertisingTrackingEnabled() { // If a user does turn this off, use the unique identifier *only* for the following: // - Frequency capping @@ -56,6 +64,16 @@ BOOL ANAdvertisingTrackingEnabled() { // - Estimating number of unique users // - Security and fraud detection // - Debugging + + if (@available(iOS 14, *)) { +#if __has_include() + if ([ATTrackingManager trackingAuthorizationStatus] == ATTrackingManagerAuthorizationStatusAuthorized ){ + return YES; + }else { + return NO; + } +#endif + } return [ASIdentifierManager sharedManager].isAdvertisingTrackingEnabled; } diff --git a/sdk/sourcefiles/internal/ANUniversalTagRequestBuilder.m b/sdk/sourcefiles/internal/ANUniversalTagRequestBuilder.m index e5ce719d8..dad1f939d 100644 --- a/sdk/sourcefiles/internal/ANUniversalTagRequestBuilder.m +++ b/sdk/sourcefiles/internal/ANUniversalTagRequestBuilder.m @@ -234,7 +234,7 @@ - (NSDictionary *)requestBody // Set EUID node, EUID - Third party id solutions // NSArray *> *externalUserIds = [self externalUserIds]; - if (externalUserIds) { + if (externalUserIds && ANAdvertisingTrackingEnabled()) { requestDict[@"eids"] = externalUserIds; } @@ -570,10 +570,8 @@ -(void)getAdFramework:(NSMutableDictionary *)tag{ userDict[@"language"] = language; } - // NSString *publisherUserId = [[ANSDKSettings sharedInstance] publisherUserId]; - // Use publisherFirstPartyID if it is present. External Id in ANAdProtocol is deprecated. if (publisherUserId) { userDict[@"external_uid"] = publisherUserId; @@ -581,7 +579,6 @@ -(void)getAdFramework:(NSMutableDictionary *)tag{ userDict[@"external_uid"] = [self.adFetcherDelegate externalUid]; } - // return [userDict copy]; } @@ -648,17 +645,8 @@ -(void)getAdFramework:(NSMutableDictionary *)tag{ deviceDict[@"connectiontype"] = @(connectionType); - // - if (@available(iOS 14, *)) { -#if __has_include() - if ([ATTrackingManager trackingAuthorizationStatus] == ATTrackingManagerAuthorizationStatusAuthorized){ - deviceDict[@"limit_ad_tracking"] = [NSNumber numberWithBool:false]; - }else if ([ATTrackingManager trackingAuthorizationStatus] == ATTrackingManagerAuthorizationStatusDenied){ - deviceDict[@"limit_ad_tracking"] = [NSNumber numberWithBool:true]; - } -#endif - }else{ - deviceDict[@"limit_ad_tracking"] = [NSNumber numberWithBool:!ANAdvertisingTrackingEnabled()]; + if(ANAdvertisingTrackingEnabled()){ + deviceDict[@"limit_ad_tracking"] = [NSNumber numberWithBool:NO]; } NSDictionary *deviceId = [self deviceId]; @@ -720,7 +708,7 @@ -(void)getAdFramework:(NSMutableDictionary *)tag{ - (NSDictionary *)deviceId { - if([ANGDPRSettings canAccessDeviceData]){ + if([ANGDPRSettings canAccessDeviceData] && ANAdvertisingTrackingEnabled()){ return [self fetchAdvertisingIdentifier]; } diff --git a/tests/UnitTestApp/FunctionalTests/ANUniversalTagRequestBuilderFunctionalTests.m b/tests/UnitTestApp/FunctionalTests/ANUniversalTagRequestBuilderFunctionalTests.m index ed0f27f16..c6f5be0f8 100644 --- a/tests/UnitTestApp/FunctionalTests/ANUniversalTagRequestBuilderFunctionalTests.m +++ b/tests/UnitTestApp/FunctionalTests/ANUniversalTagRequestBuilderFunctionalTests.m @@ -25,7 +25,9 @@ #import "ANUSPrivacySettings.h" #import "ANOMIDImplementation.h" #import "ANExternalUserId.h" - +#if __has_include() + #import +#endif static NSString *const kTestUUID = @"0000-000-000-00"; static NSTimeInterval UTMODULETESTS_TIMEOUT = 20.0; @@ -939,36 +941,84 @@ - (void)testUTRequestExternalUserIds NSDictionary *jsonDict = (NSDictionary *)jsonObject; NSArray *eidsArray = jsonDict[@"eids"]; NSDictionary *eidDictionary = jsonDict[@"eids"]; - XCTAssertEqual(eidDictionary.count, 4 ); - NSUInteger count = [eidsArray count]; - for (NSUInteger index = 0; index < count ; index++) { - TESTTRACEM(@"source==============%@", eidsArray[index][@"source"]); - if([eidsArray[index][@"source"] isEqualToString: @"criteo.com"]){ - XCTAssertEqualObjects(eidsArray[index][@"source"], @"criteo.com"); - XCTAssertEqualObjects(eidsArray[index][@"id"], @"_fl7bV96WjZsbiUyQnJlQ3g4ckh5a1N"); - [criteoExpectation fulfill]; - } - - if([eidsArray[index][@"source"] isEqualToString: @"netid.de"]){ - XCTAssertEqualObjects(eidsArray[index][@"source"], @"netid.de"); - XCTAssertEqualObjects(eidsArray[index][@"id"], @"999888777"); - [netIDExpectation fulfill]; - } - - if([eidsArray[index][@"source"] isEqualToString: @"liveramp.com"]){ - XCTAssertEqualObjects(eidsArray[index][@"source"], @"liveramp.com"); - XCTAssertEqualObjects(eidsArray[index][@"id"], @"AjfowMv4ZHZQJFM8TpiUnYEyA81Vdgg"); - [liveRampExpectation fulfill]; - } - - if([eidsArray[index][@"source"] isEqualToString: @"adserver.org"]){ - XCTAssertEqualObjects(eidsArray[index][@"source"], @"adserver.org"); - XCTAssertEqualObjects(eidsArray[index][@"id"], @"00000111-91b1-49b2-ae37-17a8173dc36f"); - XCTAssertEqualObjects(eidsArray[index][@"rti_partner"], @"TDID"); - [tradeDeskExpectation fulfill]; - } - } + if (@available(iOS 14, *)) { + #if __has_include() + if ([ATTrackingManager trackingAuthorizationStatus] == ATTrackingManagerAuthorizationStatusAuthorized){ + XCTAssertEqual(eidDictionary.count, 4 ); + + NSUInteger count = [eidsArray count]; + for (NSUInteger index = 0; index < count ; index++) { + TESTTRACEM(@"source==============%@", eidsArray[index][@"source"]); + if([eidsArray[index][@"source"] isEqualToString: @"criteo.com"]){ + XCTAssertEqualObjects(eidsArray[index][@"source"], @"criteo.com"); + XCTAssertEqualObjects(eidsArray[index][@"id"], @"_fl7bV96WjZsbiUyQnJlQ3g4ckh5a1N"); + [criteoExpectation fulfill]; + } + + if([eidsArray[index][@"source"] isEqualToString: @"netid.de"]){ + XCTAssertEqualObjects(eidsArray[index][@"source"], @"netid.de"); + XCTAssertEqualObjects(eidsArray[index][@"id"], @"999888777"); + [netIDExpectation fulfill]; + } + + if([eidsArray[index][@"source"] isEqualToString: @"liveramp.com"]){ + XCTAssertEqualObjects(eidsArray[index][@"source"], @"liveramp.com"); + XCTAssertEqualObjects(eidsArray[index][@"id"], @"AjfowMv4ZHZQJFM8TpiUnYEyA81Vdgg"); + [liveRampExpectation fulfill]; + } + + if([eidsArray[index][@"source"] isEqualToString: @"adserver.org"]){ + XCTAssertEqualObjects(eidsArray[index][@"source"], @"adserver.org"); + XCTAssertEqualObjects(eidsArray[index][@"id"], @"00000111-91b1-49b2-ae37-17a8173dc36f"); + XCTAssertEqualObjects(eidsArray[index][@"rti_partner"], @"TDID"); + [tradeDeskExpectation fulfill]; + } + } + }else { + + XCTAssertNil(eidDictionary ); + [tradeDeskExpectation fulfill]; + [criteoExpectation fulfill]; + [netIDExpectation fulfill]; + [liveRampExpectation fulfill]; + + } + #endif + }else{ + XCTAssertEqual(eidDictionary.count, 4 ); + + NSUInteger count = [eidsArray count]; + for (NSUInteger index = 0; index < count ; index++) { + TESTTRACEM(@"source==============%@", eidsArray[index][@"source"]); + if([eidsArray[index][@"source"] isEqualToString: @"criteo.com"]){ + XCTAssertEqualObjects(eidsArray[index][@"source"], @"criteo.com"); + XCTAssertEqualObjects(eidsArray[index][@"id"], @"_fl7bV96WjZsbiUyQnJlQ3g4ckh5a1N"); + [criteoExpectation fulfill]; + } + + if([eidsArray[index][@"source"] isEqualToString: @"netid.de"]){ + XCTAssertEqualObjects(eidsArray[index][@"source"], @"netid.de"); + XCTAssertEqualObjects(eidsArray[index][@"id"], @"999888777"); + [netIDExpectation fulfill]; + } + + if([eidsArray[index][@"source"] isEqualToString: @"liveramp.com"]){ + XCTAssertEqualObjects(eidsArray[index][@"source"], @"liveramp.com"); + XCTAssertEqualObjects(eidsArray[index][@"id"], @"AjfowMv4ZHZQJFM8TpiUnYEyA81Vdgg"); + [liveRampExpectation fulfill]; + } + + if([eidsArray[index][@"source"] isEqualToString: @"adserver.org"]){ + XCTAssertEqualObjects(eidsArray[index][@"source"], @"adserver.org"); + XCTAssertEqualObjects(eidsArray[index][@"id"], @"00000111-91b1-49b2-ae37-17a8173dc36f"); + XCTAssertEqualObjects(eidsArray[index][@"rti_partner"], @"TDID"); + [tradeDeskExpectation fulfill]; + } + } + } + + }); [self waitForExpectationsWithTimeout:UTMODULETESTS_TIMEOUT handler:nil]; diff --git a/tests/UnitTestApp/FunctionalTests/CSR/ANCSRUniversalTagRequestBuilderTests.m b/tests/UnitTestApp/FunctionalTests/CSR/ANCSRUniversalTagRequestBuilderTests.m index 7f020e586..714abe3ea 100644 --- a/tests/UnitTestApp/FunctionalTests/CSR/ANCSRUniversalTagRequestBuilderTests.m +++ b/tests/UnitTestApp/FunctionalTests/CSR/ANCSRUniversalTagRequestBuilderTests.m @@ -28,7 +28,9 @@ #import "NSURLRequest+HTTPBodyTesting.h" #import "ANNativeAdResponse+PrivateMethods.h" #import "ANNativeAdResponse+ANTest.h" - +#if __has_include() + #import +#endif static NSTimeInterval UTMODULETESTS_TIMEOUT = 20.0; static NSString *PlacementID = @"9924001"; @@ -77,7 +79,7 @@ - (void)setUp { self.nativeRequest = [[ANNativeAdRequest alloc] init]; - self.nativeRequest.delegate = self; + self.nativeRequest.delegate = self; [SDKValidationURLProtocol setDelegate:self]; @@ -277,19 +279,57 @@ - (void)testUTRequestForCSR break; } - NSNumber *lmt = device[@"limit_ad_tracking"]; - XCTAssertNotNil(lmt); - XCTAssertEqual([lmt boolValue], ANAdvertisingTrackingEnabled() ? NO : YES); - // get the objective c type of the NSNumber for limit_ad_tracking - // "c" is the BOOL type that is returned from NSNumber objCType for BOOL value - const char *boolType = "c"; - XCTAssertEqual(strcmp([lmt objCType], boolType), 0); - - // Device Id Start - NSDictionary *deviceId = device[@"device_id"]; - XCTAssertNotNil(deviceId); - NSString *idfa = deviceId[@"idfa"]; - XCTAssertNotNil(idfa); + + + + if (@available(iOS 14, *)) { + #if __has_include() + if ([ATTrackingManager trackingAuthorizationStatus] == ATTrackingManagerAuthorizationStatusAuthorized){ + + NSNumber *lmt = device[@"limit_ad_tracking"]; + + XCTAssertEqual([lmt boolValue], ANAdvertisingTrackingEnabled() ? NO : YES); + // get the objective c type of the NSNumber for limit_ad_tracking + // "c" is the BOOL type that is returned from NSNumber objCType for BOOL value + //const char *boolType = "c"; + //XCTAssertEqual(strcmp([lmt objCType], boolType), 0); + + // Device Id Start + NSDictionary *deviceId = device[@"device_id"]; + XCTAssertNotNil(deviceId); + NSString *idfa = deviceId[@"idfa"]; + XCTAssertNotNil(idfa); + }else{ + + NSNumber *lmt = device[@"limit_ad_tracking"]; + XCTAssertNil(lmt); + // get the objective c type of the NSNumber for limit_ad_tracking + // "c" is the BOOL type that is returned from NSNumber objCType for BOOL value + //const char *boolType = "c"; + //XCTAssertEqual(strcmp([lmt objCType], boolType), 0); + // Device Id Start + NSDictionary *deviceId = device[@"device_id"]; + XCTAssertNil(deviceId); + } + #endif + }else{ + NSNumber *lmt = device[@"limit_ad_tracking"]; + + XCTAssertEqual([lmt boolValue], ANAdvertisingTrackingEnabled() ? NO : YES); + // get the objective c type of the NSNumber for limit_ad_tracking + // "c" is the BOOL type that is returned from NSNumber objCType for BOOL value + //const char *boolType = "c"; + //XCTAssertEqual(strcmp([lmt objCType], boolType), 0); + + // Device Id Start + NSDictionary *deviceId = device[@"device_id"]; + XCTAssertNotNil(deviceId); + NSString *idfa = deviceId[@"idfa"]; + XCTAssertNotNil(idfa); + } + + + XCTAssertNil(error); XCTAssertNotNil(jsonObject); diff --git a/tests/UnitTestApp/UnitTestApp/AppDelegate.m b/tests/UnitTestApp/UnitTestApp/AppDelegate.m index 132461d38..da8086607 100644 --- a/tests/UnitTestApp/UnitTestApp/AppDelegate.m +++ b/tests/UnitTestApp/UnitTestApp/AppDelegate.m @@ -18,6 +18,9 @@ #import "ANHTTPStubbingManager.h" #import "ANTestGlobal.h" #import "ANGlobal.h" +#if __has_include() + #import +#endif @interface AppDelegate () @@ -33,11 +36,39 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:( [[ANHTTPStubbingManager sharedStubbingManager] enable]; [ANHTTPStubbingManager sharedStubbingManager].ignoreUnstubbedRequests = YES; + if (@available(iOS 14, *)) { + [self requestTrackingAuthorization]; + } + // Override point for customization after application launch. return YES; } +- (void)requestTrackingAuthorization{ + // Checking the OS version before calling the Tracking Consent dialog, it's available only in iOS 14 and above + if (@available(iOS 14, *)) { +#if __has_include() + [ATTrackingManager requestTrackingAuthorizationWithCompletionHandler:^(ATTrackingManagerAuthorizationStatus authStatus) { + switch (authStatus) { + case ATTrackingManagerAuthorizationStatusNotDetermined: + NSLog(@"Tracking Authorization Status==NotDetermined"); + break; + case ATTrackingManagerAuthorizationStatusRestricted: + NSLog(@"Tracking Authorization Status==Restricted"); + break; + case ATTrackingManagerAuthorizationStatusDenied: + NSLog(@"Tracking Authorization Status==Denied"); + break; + case ATTrackingManagerAuthorizationStatusAuthorized: + NSLog(@"Tracking Authorization Status==Authorized"); + break; + } + }]; +#endif + } +} + #if __IPHONE_9_0 - (UIInterfaceOrientationMask)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window { #else diff --git a/tests/UnitTestApp/UnitTestApp/Info.plist b/tests/UnitTestApp/UnitTestApp/Info.plist index 68ffb6bde..17682c03a 100644 --- a/tests/UnitTestApp/UnitTestApp/Info.plist +++ b/tests/UnitTestApp/UnitTestApp/Info.plist @@ -18,6 +18,8 @@ 1.0 CFBundleVersion 1 + GADIsAdManagerApp + LSRequiresIPhoneOS NSAppTransportSecurity @@ -27,6 +29,8 @@ NSLocationWhenInUseUsageDescription AppNexus and/or the SDKs mediated by AppNexus would like to access your location information. + NSUserTrackingUsageDescription + Your data will be used to deliver personalised ads to you UILaunchStoryboardName LaunchScreen UIMainStoryboardFile @@ -49,7 +53,5 @@ UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight - GADIsAdManagerApp - diff --git a/tests/UnitTestApp/UnitTests/ANUniversalTagRequestBuilderTests.m b/tests/UnitTestApp/UnitTests/ANUniversalTagRequestBuilderTests.m index 5a1bae27d..aff02750f 100644 --- a/tests/UnitTestApp/UnitTests/ANUniversalTagRequestBuilderTests.m +++ b/tests/UnitTestApp/UnitTests/ANUniversalTagRequestBuilderTests.m @@ -22,7 +22,9 @@ #import "ANReachability.h" #import "TestANUniversalFetcher.h" #import "ANGDPRSettings.h" - +#if __has_include() + #import +#endif static NSString *const kTestUUID = @"0000-000-000-00"; static NSTimeInterval UTMODULETESTS_TIMEOUT = 20.0; @@ -119,10 +121,6 @@ - (void)testUTRequest NSNumber *gender = user[@"gender"]; XCTAssertNotNil(gender); - // externalUid - NSString *externalUid = user[@"external_uid"]; - XCTAssertNotNil(externalUid); - XCTAssertEqualObjects(externalUid, @"AppNexus"); NSString * deviceLanguage = [[NSLocale preferredLanguages] firstObject]; NSString *language = user[@"language"]; XCTAssertEqualObjects(language, deviceLanguage); @@ -156,20 +154,45 @@ - (void)testUTRequest break; } - NSNumber *lmt = device[@"limit_ad_tracking"]; - XCTAssertNotNil(lmt); - XCTAssertEqual([lmt boolValue], ANAdvertisingTrackingEnabled() ? NO : YES); - // get the objective c type of the NSNumber for limit_ad_tracking - // "c" is the BOOL type that is returned from NSNumber objCType for BOOL value -// const char *boolType = "c"; -// XCTAssertEqual(strcmp([lmt objCType], boolType), 0); - - // Device Id Start - NSDictionary *deviceId = device[@"device_id"]; - XCTAssertNotNil(deviceId); - NSString *idfa = deviceId[@"idfa"]; - XCTAssertNotNil(idfa); - XCTAssertEqualObjects(idfa, @"00000000-0000-0000-0000-000000000000"); + + if (@available(iOS 14, *)) { + #if __has_include() + if ([ATTrackingManager trackingAuthorizationStatus] == ATTrackingManagerAuthorizationStatusAuthorized){ + NSNumber *lmt = device[@"limit_ad_tracking"]; + XCTAssertNotNil(lmt); + XCTAssertEqual([lmt boolValue], NO); + + // Device Id Start + NSDictionary *deviceId = device[@"device_id"]; + XCTAssertNotNil(deviceId); + NSString *idfa = deviceId[@"idfa"]; + XCTAssertNotNil(idfa); + XCTAssertEqualObjects(idfa, @"00000000-0000-0000-0000-000000000000"); + + }else { + + NSNumber *lmt = device[@"limit_ad_tracking"]; + XCTAssertNil(lmt); + NSDictionary *deviceId = device[@"device_id"]; + XCTAssertNil(deviceId); + } + #endif + }else{ + + + NSNumber *lmt = device[@"limit_ad_tracking"]; + XCTAssertNotNil(lmt); + XCTAssertEqual([lmt boolValue], ANAdvertisingTrackingEnabled() ? NO : YES); + + // get the objective c type of the NSNumber for limit_ad_tracking + + // Device Id Start + NSDictionary *deviceId = device[@"device_id"]; + XCTAssertNotNil(deviceId); + NSString *idfa = deviceId[@"idfa"]; + XCTAssertNotNil(idfa); + } + // [expectation fulfill]; @@ -215,12 +238,31 @@ - (void)testUTRequestWithPurpose1AndConsentSetTrue XCTAssertNotNil(device); XCTAssertNil(keywords); // no keywords passed unless set in the targeting + + if (@available(iOS 14, *)) { +#if __has_include() + if ([ATTrackingManager trackingAuthorizationStatus] == ATTrackingManagerAuthorizationStatusAuthorized){ + + NSDictionary *deviceId = device[@"device_id"]; + XCTAssertNotNil(deviceId); + NSString *idfa = deviceId[@"idfa"]; + XCTAssertEqualObjects(idfa, @"00000000-0000-0000-0000-000000000000"); + + + }else{ + NSDictionary *deviceId = device[@"device_id"]; + XCTAssertNil(deviceId); + } + #endif + }else{ + // Device Id Start + NSDictionary *deviceId = device[@"device_id"]; + XCTAssertNotNil(deviceId); + NSString *idfa = deviceId[@"idfa"]; + XCTAssertNotNil(idfa); + + } - // Device Id Start - NSDictionary *deviceId = device[@"device_id"]; - XCTAssertNotNil(deviceId); - NSString *idfa = deviceId[@"idfa"]; - XCTAssertEqualObjects(idfa, @"00000000-0000-0000-0000-000000000000"); // [expectation fulfill]; @@ -267,12 +309,32 @@ - (void)testUTRequestWithPurpose1SetTrueAndConsentSetFalse XCTAssertNil(keywords); // no keywords passed unless set in the targeting - // Device Id Start - NSDictionary *deviceId = device[@"device_id"]; - XCTAssertNotNil(deviceId); - NSString *idfa = deviceId[@"idfa"]; - XCTAssertEqualObjects(idfa, @"00000000-0000-0000-0000-000000000000"); - + + + if (@available(iOS 14, *)) { +#if __has_include() + if ([ATTrackingManager trackingAuthorizationStatus] == ATTrackingManagerAuthorizationStatusAuthorized){ + // Device Id Start + NSDictionary *deviceId = device[@"device_id"]; + XCTAssertNotNil(deviceId); + NSString *idfa = deviceId[@"idfa"]; + XCTAssertEqualObjects(idfa, @"00000000-0000-0000-0000-000000000000"); + + + }else{ + NSDictionary *deviceId = device[@"device_id"]; + XCTAssertNil(deviceId); + } + #endif + }else{ + // Device Id Start + NSDictionary *deviceId = device[@"device_id"]; + XCTAssertNotNil(deviceId); + NSString *idfa = deviceId[@"idfa"]; + XCTAssertNotNil(idfa); + } + + // [expectation fulfill]; }); @@ -415,14 +477,29 @@ - (void)testUTRequestWithoutPurpose1ConsentFalse XCTAssertNotNil(device); XCTAssertNil(keywords); // no keywords passed unless set in the targeting - - // Device Id Start - NSDictionary *deviceId = device[@"device_id"]; - XCTAssertNotNil(deviceId); - NSString *idfa = deviceId[@"idfa"]; - XCTAssertNotNil(idfa); - XCTAssertEqualObjects(idfa, @"00000000-0000-0000-0000-000000000000"); - + + if (@available(iOS 14, *)) { +#if __has_include() + if ([ATTrackingManager trackingAuthorizationStatus] == ATTrackingManagerAuthorizationStatusAuthorized){ + // Device Id Start + NSDictionary *deviceId = device[@"device_id"]; + XCTAssertNotNil(deviceId); + NSString *idfa = deviceId[@"idfa"]; + XCTAssertNotNil(idfa); + XCTAssertEqualObjects(idfa, @"00000000-0000-0000-0000-000000000000"); + }else{ + NSDictionary *deviceId = device[@"device_id"]; + XCTAssertNil(deviceId); + } +#endif + }else{ + // Device Id Start + NSDictionary *deviceId = device[@"device_id"]; + XCTAssertNotNil(deviceId); + NSString *idfa = deviceId[@"idfa"]; + XCTAssertNotNil(idfa); + } + // [expectation fulfill]; }); @@ -462,12 +539,6 @@ - (void)testUTRequestForDuration XCTAssertEqual(tags.count, 1); NSDictionary *tag = [tags firstObject]; - // externalUid - NSString *externalUid = user[@"external_uid"]; - XCTAssertNotNil(externalUid); - XCTAssertEqualObjects(externalUid, @"AppNexus"); - - NSDictionary *video = tag[@"video"]; XCTAssertNotNil(video); XCTAssertEqual(video.count, 2); @@ -538,7 +609,7 @@ - (void)testUTRequestWithOneCustomKeywordsValue } - (void)testUTRequestWithMultipleCustomKeywordsValues -{ +{ TestANUniversalFetcher *adFetcher = [[TestANUniversalFetcher alloc] initWithPlacementId:videoPlacementID]; [adFetcher addCustomKeywordWithKey:@"state" value:@"NY"]; @@ -679,8 +750,27 @@ - (void)testUTRequestDisableIDFAUsageDefault NSDictionary *device = jsonDict[@"device"]; XCTAssertNotNil(device); // Device Id Start - NSDictionary *deviceId = device[@"device_id"]; - XCTAssertNotNil(deviceId); + + + if (@available(iOS 14, *)) { +#if __has_include() + if ([ATTrackingManager trackingAuthorizationStatus] == ATTrackingManagerAuthorizationStatusAuthorized){ + // Device Id Start + NSDictionary *deviceId = device[@"device_id"]; + XCTAssertNotNil(deviceId); + + }else{ + NSDictionary *deviceId = device[@"device_id"]; + XCTAssertNil(deviceId); + } +#endif + }else{ + // Device Id Start + NSDictionary *deviceId = device[@"device_id"]; + XCTAssertNotNil(deviceId); + } + + [expectation fulfill]; }); @@ -763,8 +853,24 @@ - (void)testUTRequestDisableIDFAUsageSetToFalse NSDictionary *jsonDict = (NSDictionary *)jsonObject; NSDictionary *device = jsonDict[@"device"]; XCTAssertNotNil(device); - NSDictionary *deviceId = device[@"device_id"]; - XCTAssertNotNil(deviceId); + + if (@available(iOS 14, *)) { +#if __has_include() + if ([ATTrackingManager trackingAuthorizationStatus] == ATTrackingManagerAuthorizationStatusAuthorized){ + // Device Id Start + NSDictionary *deviceId = device[@"device_id"]; + XCTAssertNotNil(deviceId); + + }else{ + NSDictionary *deviceId = device[@"device_id"]; + XCTAssertNil(deviceId); + } +#endif + }else{ + // Device Id Start + NSDictionary *deviceId = device[@"device_id"]; + XCTAssertNotNil(deviceId); + } [expectation fulfill]; }); From d2f8dceb45b9d2ee4bedac3db187878afeb187df Mon Sep 17 00:00:00 2001 From: abhisheksharma Date: Tue, 23 Feb 2021 23:14:36 +0530 Subject: [PATCH 5/5] v7.10 --- AppNexusSDK.podspec | 2 +- RELEASE-NOTES.md | 9 +++++++++ sdk/AppNexusNativeSDK/SDK-Info.plist | 2 +- sdk/AppNexusSDK/SDK-Info.plist | 2 +- sdk/sourcefiles/internal/ANGlobal.h | 2 +- 5 files changed, 13 insertions(+), 4 deletions(-) diff --git a/AppNexusSDK.podspec b/AppNexusSDK.podspec index 8a53298d5..90a7575fc 100644 --- a/AppNexusSDK.podspec +++ b/AppNexusSDK.podspec @@ -1,7 +1,7 @@ Pod::Spec.new do |s| s.name = "AppNexusSDK" - s.version = "7.9" + s.version = "7.10" s.platform = :ios, "9.0" s.summary = "AppNexus iOS Mobile Advertising SDK" diff --git a/RELEASE-NOTES.md b/RELEASE-NOTES.md index f7cf409ea..17dd260e4 100644 --- a/RELEASE-NOTES.md +++ b/RELEASE-NOTES.md @@ -1,3 +1,12 @@ +## 7.10 +### New Feature ++ MS-4659, MS-4674 Added support for User Id from external sources(Criteo, NetID, LiverRamp, The Trade Desk) (https://wiki.xandr.com/x/7IW1Bg) ++ MS-4657 Changes to support AppTrackingTransparency (https://wiki.xandr.com/x/3Ie1Bg) +### Improvements/Bug Fixes ++ MS-4671 Added minimum threshold of 100ms for callSetMraidRefreshFrequency +### Deprecated API ++ externalUid property in ANAdProtocol has been deprecated, use publisherUserId in ANSDKSettings instead (https://wiki.xandr.com/x/7IW1Bg). + ## 7.9 ### New Feature + MS-4388 Support to disable passing device IDs in bid requests diff --git a/sdk/AppNexusNativeSDK/SDK-Info.plist b/sdk/AppNexusNativeSDK/SDK-Info.plist index 65d826aa2..7f5488338 100644 --- a/sdk/AppNexusNativeSDK/SDK-Info.plist +++ b/sdk/AppNexusNativeSDK/SDK-Info.plist @@ -15,7 +15,7 @@ CFBundlePackageType FMWK CFBundleShortVersionString - 7.9 + 7.10 CFBundleVersion $(CURRENT_PROJECT_VERSION) diff --git a/sdk/AppNexusSDK/SDK-Info.plist b/sdk/AppNexusSDK/SDK-Info.plist index 2a22ce697..1dfe1b686 100644 --- a/sdk/AppNexusSDK/SDK-Info.plist +++ b/sdk/AppNexusSDK/SDK-Info.plist @@ -15,7 +15,7 @@ CFBundlePackageType FMWK CFBundleShortVersionString - 7.9 + 7.10 CFBundleSignature ???? CFBundleVersion diff --git a/sdk/sourcefiles/internal/ANGlobal.h b/sdk/sourcefiles/internal/ANGlobal.h index 0a9e59fd0..2391f8079 100644 --- a/sdk/sourcefiles/internal/ANGlobal.h +++ b/sdk/sourcefiles/internal/ANGlobal.h @@ -26,7 +26,7 @@ #define AN_ERROR_TABLE @"errors" #define AN_DEFAULT_PLACEMENT_ID @"default_placement_id" -#define AN_SDK_VERSION @"7.9" +#define AN_SDK_VERSION @"7.10" #define APPNEXUS_BANNER_SIZE CGSizeMake(320, 50)