Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

feat(ios): Added support for App Open Ad type #353

Merged
merged 3 commits into from Jun 2, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
9 changes: 9 additions & 0 deletions apidoc/Admob.yml
Expand Up @@ -112,6 +112,13 @@ properties:
summary: Used when creating a <Modules.Admob.View> to determine ad type of rewarded video
permission: read-only
platforms: [iphone, ipad]

- name: AD_TYPE_APP_OPEN
type: Number
summary: Used when creating a <Modules.Admob.View> to determine ad type of app open
permission: read-only
platforms: [iphone, ipad]
hansemannn marked this conversation as resolved.
Show resolved Hide resolved
since: "6.2.0"

- name: AD_SIZE_BANNER
type: Number
Expand Down Expand Up @@ -361,6 +368,8 @@ methods:
type: void
summary: Disables automated in app purchase (IAP) reporting. Must be called before any IAP transaction is initiated. IAP reporting is used to track IAP ad conversions. Do not disable reporting if you use IAP ads.
platforms: [iphone, ipad]
deleted:
since: "6.2.0"

- name: getAndroidAdId
returns:
Expand Down
74 changes: 48 additions & 26 deletions apidoc/View.yml
Expand Up @@ -135,23 +135,31 @@ events:
properties:
- name: adUnitId
type: String
summary: Id for the add
- name: isReady
type: Boolean
summary: Whether the ad is ready. Populated only for interstitial ads
optional: true
summary: Id for the ad

- name: didFailToReceiveAd
summary: Sent when an ad request failed. Normally this is because no network connection was available or no ads were available (i.e. no fill).
platforms: [iphone, ipad]
properties:
- name: adUnitId
type: String
summary: add id that failed to load
summary: ad id that failed to load
- name: error
type: String
summary: error message

- name: didFailToShowAd
summary: Sent when App Open Ad failed to show.
platforms: [iphone, ipad]
properties:
- name: adUnitId
type: String
summary: ad id that failed to show
- name: error
type: String
summary: error message
since: 6.2.0

- name: willPresentScreen
summary: Sent just before presenting the user a full screen view, such as a browser, in response to clicking on an ad. Use this opportunity to stop animations, time sensitive interactions, etc.
description: |
Expand All @@ -163,47 +171,31 @@ events:
properties:
- name: adUnitId
type: String
summary: Id for the add
- name: isReady
type: Boolean
summary: Whether the ad is ready. Populated only for interstitial ads
optional: true
summary: Id for the ad

- name: willDismissScreen
summary: Sent just before dismissing a full screen view.
platforms: [iphone, ipad]
properties:
- name: adUnitId
type: String
summary: Id for the add
- name: isReady
type: Boolean
summary: Whether the ad is ready. Populated only for interstitial ads
optional: true
summary: Id for the ad

- name: didDismissScreen
summary: Sent just after dismissing a full screen view. Use this opportunity to restart anything you may have stopped as part of `willPresentScreen`.
platforms: [iphone, ipad]
properties:
- name: adUnitId
type: String
summary: Id for the add
- name: isReady
type: Boolean
summary: Whether the ad is ready. Populated only for interstitial ads
optional: true
summary: Id for the ad

- name: willLeaveApplication
summary: Sent just before the application will background or terminate because the user clicked on an ad that will launch another application (such as the App Store).
platforms: [iphone, ipad]
properties:
- name: adUnitId
type: String
summary: Id for the add
- name: isReady
type: Boolean
summary: Whether the ad is ready. Populated only for interstitial ads
optional: true
summary: Id for the ad

- name: didReceiveInAppPurchase
summary: Called when the user clicks on the buy button of an in-app purchase ad.
Expand All @@ -218,6 +210,36 @@ events:
deprecated:
since: "2.2.0"

- name: didRecordClick
summary: Called when the user clicks on the ad.
platforms: [iphone, ipad]
properties:
- name: adUnitId
type: String
summary: Id for the ad
since: "6.2.0"

- name: didRecordImpression
summary: Called when an ad is impressed
platforms: [iphone, ipad]
properties:
- name: adUnitId
type: String
summary: Id for the ad
since: "6.2.0"

- name: didRewardUser
summary: Fired when the reward based video ad has rewarded the user.
platforms: [iphone, ipad]
properties:
- name: type
type: String
summary: Type of the reward.
- name: amount
type: Number
summary: Amount rewarded to the user.
since: "6.2.0"

- name: ad_received
summary: Fired when ad is loaded
platforms: [android]
Expand Down
2 changes: 0 additions & 2 deletions ios/Classes/TiAdmobModule.h
Expand Up @@ -11,8 +11,6 @@

- (void)disableSDKCrashReporting:(id)unused;

- (void)disableAutomatedInAppPurchaseReporting:(id)unused; // REMOVED

- (void)requestConsentInfoUpdateWithParameters:(id)args;

- (void)loadForm:(id)args;
Expand Down
65 changes: 59 additions & 6 deletions ios/Classes/TiAdmobModule.m
Expand Up @@ -37,16 +37,65 @@ - (NSString *)moduleId

#pragma mark Public API's

- (void)disableSDKCrashReporting:(id)unused
{
[GADMobileAds.sharedInstance disableSDKCrashReporting];

// Check if the TC string last updated date was more than 13 months ago
// https://developers.google.com/admob/ios/privacy/gdpr#troubleshooting
/**
* This function checks the date of last consent, which is base64-encoded in digits 1..7 of a string that is stored
* in userDefaults under the key "IABTCF_TCString".
*
* If this date is older than 365 days, the entry with that key will be removed from userDefaults. With the IABTCF
* configuration now being invalid, the CMP should re-display the consent dialog the next time it is instantiated.
*
* This should avoid errors of any used ad solution, which is supposed to consider consent older than 13 months "outdated".
*
* Inspired by @bocops code: https://github.com/bocops/UMP-workarounds/blob/main/detect_outdated_consent/android/java/detect_outdated_consent.java
*/
- (void)deleteTCStringIfOutdated {
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];

// IABTCF string is stored in userDefaults
NSString *tcString = [userDefaults stringForKey:@"IABTCF_TCString"] ?: @"";

// Check if the TCF string is empty
if (tcString.length > 0) {

// base64 alphabet used to store data in IABTCF string
NSString *base64 = @"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";

// Date is stored in digits 1..7 of the IABTCF string
NSString *dateSubstring = [tcString substringWithRange:NSMakeRange(1, 6)];

// Interpret date substring as base64-encoded integer value
long timestamp = 0;
for (int i = 0; i < dateSubstring.length; i++) {
unichar c = [dateSubstring characterAtIndex:i];

NSInteger value = [base64 rangeOfString:[NSString stringWithFormat:@"%C", c]].location;
timestamp = timestamp * 64 + value;
}

// Timestamp is given is deci-seconds, convert to milliseconds
timestamp *= 100;

// Compare with current timestamp to get age in days
long daysAgo = (long)(([[NSDate date] timeIntervalSince1970] * 1000) - timestamp) / (1000 * 60 * 60 * 24);
NSLog(@"[DEBUG] Ti.AdMob: TC string last updated date was %ld days ago", daysAgo);
// Delete TC string if age is over a year
if (daysAgo > 365) {
[userDefaults removeObjectForKey:@"IABTCF_TCString"];
[userDefaults synchronize];
NSLog(@"[DEBUG] Ti.AdMob: TC string removed");
}
} else {
NSLog(@"[DEBUG] The TCF string does not exist or is empty.");
}
}

- (void)disableAutomatedInAppPurchaseReporting:(id)unused
- (void)disableSDKCrashReporting:(id)unused
{
DEPRECATED_REMOVED(@"Admob.disableAutomatedInAppPurchaseReporting", @"4.0.0", @"4.0.0 (removed by Google)");
[GADMobileAds.sharedInstance disableSDKCrashReporting];
}

- (void)requestConsentInfoUpdateWithParameters:(id)args
{
ENSURE_SINGLE_ARG(args, NSDictionary);
Expand All @@ -66,6 +115,9 @@ - (void)requestConsentInfoUpdateWithParameters:(id)args
// Set tag for under age of consent. Here NO means users are not under age.
parameters.tagForUnderAgeOfConsent = [TiUtils boolValue:@"tagForUnderAgeOfConsent" properties:args def:NO];;

// The TCF string may be outdated, so proceed with removal if needed.
[self deleteTCStringIfOutdated];

// Request an update to the consent information.
[[UMPConsentInformation sharedInstance] requestConsentInfoUpdateWithParameters:parameters
completionHandler:^(NSError *_Nullable error) {
Expand Down Expand Up @@ -367,5 +419,6 @@ - (void)setInMobi_updateGDPRConsent:(id)updateGDPRConsent
MAKE_SYSTEM_PROP(AD_TYPE_BANNER, TiAdmobAdTypeBanner);
MAKE_SYSTEM_PROP(AD_TYPE_INTERSTITIAL, TiAdmobAdTypeInterstitial);
MAKE_SYSTEM_PROP(AD_TYPE_REWARDED_VIDEO, TiAdmobAdTypeRewardedVideo);
MAKE_SYSTEM_PROP(AD_TYPE_APP_OPEN, TiAdmobAdTypeAppOpen);

@end
24 changes: 0 additions & 24 deletions ios/Classes/TiAdmobModuleAssets.m

This file was deleted.

3 changes: 2 additions & 1 deletion ios/Classes/TiAdmobTypes.h
Expand Up @@ -10,5 +10,6 @@
typedef NS_ENUM(NSUInteger, TiAdmobAdType){
TiAdmobAdTypeBanner = 0,
TiAdmobAdTypeInterstitial,
TiAdmobAdTypeRewardedVideo
TiAdmobAdTypeRewardedVideo,
TiAdmobAdTypeAppOpen
};
5 changes: 5 additions & 0 deletions ios/Classes/TiAdmobView.h
Expand Up @@ -12,6 +12,7 @@
GADBannerView *bannerView;
GADRewardedAd *rewardedAd;
GADInterstitialAd *interstitialAd;
GADAppOpenAd *appOpenAd;

NSString *adUnitId;
}
Expand All @@ -22,6 +23,10 @@

- (void)showRewardedVideo;

- (void)requestAppOpenAd;

- (void)showAppOpenAd;

- (void)setAdUnitId_:(id)value;

- (void)setKeywords_:(id)value;
Expand Down