App Mediation - iOS

Freestar Ads Mediation OBJC iOS

Overview

Change Log

Freestar provides an effective ad mediation solution. The Freestar mediation method is universal auction, not the traditional waterfall. Universal auction is more sophisticated than waterfall and provides, by far, the best eCPM. This document describes how to integrate the Freestar SDK into your native iOS app quickly and easily. This repo is a fully integrated iOS sample app. Feel free to clone it, install the appropriate Cocoapods, open with Xcode and run it on a device.

Note: You can remotely toggle on/off any of the following ad providers as you see fit using our web dashboard. All applicable providers are enabled by default.

The current version of the Freestar SDK is 5.11.0.

Ad ProviderSDK VersionAd Unit Types
AdColony4.7.2Fullscreen Interstitial & Rewarded
AppLovin11.0.0Fullscreen Interstitial & Rewarded, Banner 320x50
AppLovinMax11.0.0Fullscreen Interstitial & Rewarded, Banner 300x250, Banner 320x50
Criteo4.3.1Fullscreen Interstitial & Rewarded, Banner 300x250, Banner 320x50
Admob9.2.0Fullscreen Interstitial & Rewarded, Banner 300x250, Banner 320x50, Native
Google Ads Manager9.2.0Fullscreen Interstitial & Rewarded, Banner 300x250, Banner 320x50, Native
MoPub (deprecated)5.18.2Fullscreen Interstitial & Rewarded, Banner 300x250, Banner 320x50, Native
Tapjoy12.8.0Fullscreen Rewarded
Unity Ads4.1.0Fullscreen Interstitial & Rewarded
Vungle6.10.6Fullscreen Interstitial & Rewarded
Google IMA3.13.0Preroll
Nimbus1.10.5Fullscreen Interstitial & Rewarded, Banner 300x250, Banner 320x50
TAM (Amazon Publisher Services)4.3.0Fullscreen Interstitial & Rewarded, Banner 300x250, Banner 320x50
Pangle3.7.0.8Fullscreen Interstitial & Rewarded, Banner 300x250, Banner 320x50, Native
Hyprmx6.0.0Fullscreen Interstitial & Rewarded, Banner 300x250, Banner 320x50
Yahoo1.14.2Fullscreen Interstitial, Banner 300x250, Banner 320x50

Project Setup

Your Podfile should have the following:

# Uncomment the next line to define a global platform for your project
platform :ios, '10.0' # minimum ios version

target 'FreestarOBJCSample' do # app name
  # Uncomment the next line if you're using Swift or would like to use dynamic frameworks
  # use_frameworks!
  pod 'FreestarAds', '~> 5.0' # required

  # Only specify the partners for which you want to run ads

  # M1 compatible
  pod "FreestarAds-AdColony", "~> 4.7"
  pod "FreestarAds-Tapjoy", "~> 12.8"
  pod "FreestarAds-Criteo", "~> 4.3"
  pod "FreestarAds-AppLovin", "~> 11.0"
  pod "FreestarAds-AppLovinMax", "~> 11.0"
  pod "FreestarAds-TAM", "~> 4.3"
  pod "FreestarAds-Hyprmx", "~> 6.0"
  pod "FreestarAds-Yahoo", "~> 1.14"
  pod 'FreestarAds-Googleadmob', '~> 9.2'
  pod 'FreestarAds-Googleadmob/Facebook', '~> 9.2'
  pod 'FreestarAds-GAM', '~> 9.2'
  pod 'FreestarAds-GAM/Facebook', '~> 9.2'
  pod "FreestarAds-Unity", "~> 4.1"
  
  # Not M1 compatible pods
  pod "FreestarAds-Vungle", "~> 6.10"
  pod "FreestarAds-Nimbus", "~> 1.10"
  pod "FreestarAds-Google", "~> 3.13"
  pod "FreestarAds-Pangle", "~> 3.7"
end

Once the podfile is setup, enter the Xcode project's base directory in the terminal and run pod install. Then open the generated .xcworkspace project with Xcode.

Info.plist

Some ad networks require adding special parameters in the app's Info.plist file. Below are the partner-specific Info.plist requirements.

Google Ad Manager
<key>GADIsAdManagerApp</key>
<true/>
Google Admob
<key>GADApplicationIdentifier</key>
<string>{YOUR_ADMOB_KEY}</string>
AppLovin
<key>AppLovinSdkKey</key>
<string>{YOUR_APPLOVIN_KEY}</string>
AdColony
<key>NSCalendarsUsageDescription</key>
<string>Adding events</string>
<key>NSPhotoLibraryUsageDescription</key>
<string>Taking selfies</string>
<key>NSCameraUsageDescription</key>
<string>Taking selfies</string>
<key>NSMotionUsageDescription </key>
<string>Interactive ad controls</string>

In the above entry, you should change the reasons to be appropriate for your app.

Logging

You can enable detailed logging from the SDK to inspect the ad mediation process in detail via an app's console. This is done by setting a flag in the Info.plist file:

<key>FSTR_LOGGING_ENABLE</key>
<true />

Once this change is made, rebuild the app to see the logs.

❗⚠Warning: For both performance and security reasons, it is not advisable to have detailed logging in production apps. Remove the flag in the Info.plist before submitting to the App Store.

Using the Freestar SDK

To interface with the Freestar ad mediation, have the following at the top of the code file where you want to make use of the SDK:

@import FreestarAds;

GDPR Support

Freestar is GDPR-ready and supports the IAB Standards for GDPR compliance.

Use the following simple api in conjunction with your existing Consent Management Provider. If you do not have a CMP solution, that’s ok, too! Our mediation sdk will detect if the user is in the EU and automatically apply GDPR actions to the ad request. So, by default, you do not have to do any extra work to use our sdk in a GDPR-compliant fashion.

// Save GDPR consent string
[[Freestar privacySettings] subjectToGDPR:gdprApplies withConsent:gdprConsentString];

Initialize Freestar

Freestar must be initialized in the application:didFinishLaunchingWithOptions: of your AppDelegate (or at another time as close as possible to the app launch). This gives the prefetch mechanism time work and thus, makes ad fill more likely when a request is made.

static NSString* const FREESTAR_APP_KEY = @"P8RIA3";

@implementation AppDelegate


- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // Override point for customization after application launch.
    [Freestar initWithAppKey:FREESTAR_APP_KEY];

    //more initialization code

    return YES;
}
Note: if you would like to see ads from TAM (Amazon Publisher Services), make sure your `AppDelegate` implements the `window` property from `UIApplicationDelegate` protocol:

@property(nullable, nonatomic) UIWindow* window;

Interstitial Ad

Implement the FreestarInterstitialDelegate protocol in one of your classes:

-(void)freestarInterstitialLoaded:(FreestarInterstitialAd *)ad {}
-(void)freestarInterstitialFailed:(FreestarInterstitialAd *)ad because:(FreestarNoAdReason)reason {}
-(void)freestarInterstitialShown:(FreestarInterstitialAd *)ad {}
-(void)freestarInterstitialClicked:(FreestarInterstitialAd *)ad {}
-(void)freestarInterstitialClosed:(FreestarInterstitialAd *)ad {}

This allows your app to listen to ad events and act appropriately. You will pass an instance of this object to the Freestar SDK when loading interstitial ad. In the current sample app, the class implementing this protocol is the ViewController, and the implementation is located in ViewController+FreestarAds.m

//self is the object that implements FreestarInterstitialDelegate
self.interstitial = [[FreestarInterstitialAd alloc] initWithDelegate:self];

//You can load associated to a placement as follows, or pass in
//nil for the default placement
[interstitial loadPlacement:@"interstitial_p1"];
If you plan to use more than one placement in your app, please adhere to the placement naming convention as follows:

"my_placement_name_pN", where N is the number of your placement.

For example, let us assume you are using 2 interstitial ad placements in your game or app. The first placement would be the default placement; simply do not specify a placement name by calling the loadPlacement: method with nil as the argument. The second placement would be, for example, "my_search_screen_p1". The ending "p1" tells the SDK to use the second placement you created in our web dashboard for the interstitial ad unit.

This placement format is the same for all the other ad units, such as rewarded ads and banner ads.

When the interstitial ad is ready, the freestarInterstitialLoaded: callback will occur.

-(void)freestarInterstitialLoaded:(FreestarInterstitialAd *)ad {
  //self in this case should be an instance of UIViewController
  [ad showFrom:self];  //You can display the ad now OR show it later; your choice.
}

There are other callbacks that will occur in other events, such as in the rare event where a load ad request does not result in a fill. Please see the ViewController+FreestarAds.m on this sample for those details.

❗⚠Warning: Attempting to load a new ad from the freestarInterstitialFailed:because: method is strongly discouraged. If you must load an ad from freestarInterstitialFailed:because:, limit ad load retries to avoid continuous failed ad requests in situations such as limited network connectivity.
The clicked callback is no longer reported for Googleadmob or GAM ads. This also applies to banner ads as well as interstitial.

Custom Targeting

Freestar Ads allows for custom targeting parameters that will be sent on to our Google Ads Manager adapter.

[interstitial addCustomTargeting:@"key1" as:@"value1"]; //optional
[interstitial addCustomTargeting:@"key2" as:@"value2"]; //optional
Note: the addCustomTargeting:as: method works in the same manner on rewarded, banner and preroll ads.

Banner Ad

Freestar supports 300x250 and 320x50 banner ad formats and allows you to control the refresh intervals remotely.

    smallBanner = [[FreestarBannerAd alloc] initWithDelegate:self     
      andSize:FreestarBanner320x50];
    [smallBanner loadPlacement:nil]; //or pass in specific placement

When the banner ad is ready, the freestarBannerLoaded: callback will occur.

-(void)freestarBannerLoaded:(FreestarBannerAd *)ad {
  NSLog(@"banner ad as been loaded: %@", ad);
}

If you insert the banner ad into the view hierarchy at this point, the ad will display automatically.

Banner ads can also be specified in Interface Builder layout and will be automatically loaded. If you do this, however, you will need to set the size and delegate properties on the ad object before calling loadPlacement:

The 320x50 ad size a standard for iPhones, on iPads, the corresponding banner ad size is 728x90. By default, a banner ad created with FreestarBanner320x50 as the size parameter will be rendered as a 320x50 ad on iPhones, and as a 728x90 ad on iPads. If you want to always render the ad as 320x50, regardless of device, you should set the fixedSize flag on the ad object:

smallBanner = [[FreestarBannerAd alloc] initWithDelegate:self andSize:FreestarBanner320x50];
smallBanner.fixedSize = YES;
[smallBanner loadPlacement:nil]; //or pass in specific placement

This will always show the in 320x50 size, no matter what device your app is running on.

Rewarded Ad

A common myth regarding Rewarded Ads is publishers are required to give something to the user. But, that's not true. You can simply tell the user they must watch the ad in order to be able to proceed to the next level or proceed to content.

Implement the FreestarRewardedDelegate protocol in one of your classes:

-(void)freestarRewardedLoaded:(FreestarRewardedAd *)ad {}
-(void)freestarRewardedFailed:(FreestarRewardedAd *)ad because:(FreestarNoAdReason)reason {}
-(void)freestarRewardedShown:(FreestarRewardedAd *)ad {}
-(void)freestarRewardedClosed:(FreestarRewardedAd *)ad {}
-(void)freestarRewardedFailedToStart:(FreestarRewardedAd *)ad because:(FreestarNoAdReason)reason {}
-(void)freestarRewardedAd:(FreestarRewardedAd *)ad received:(NSString *)rewardName amount:(NSInteger)rewardAmount {}

This allows your app to listen to ad events and act appropriately. You will pass an instance of this object to the Freestar SDK when loading rewarded ad. In the current sample app, the class implementing this protocol is the ViewController, and the implementation is located in ViewController+FreestarAds.m

//this may be overriden in the ad portal
FreestarReward *rew = [FreestarReward blankReward];
rew.rewardName = @"Coins";
rew.rewardAmount = 1000;
rew.userID = @"CoolGuy";
rew.secretKey = @"Bx34da3yn";

        //Note: If you want to use server-to-server rewarded callbacks, the Freestar team will provide
        //      you with a secret key and only that will work.
        //      However, if you want to use client-side only rewarded callbacks, then you can supply
        //      your own "secretKey" or null.

//self is the object that implements FreestarRewardedDelegate
self.rewarded = [[FreestarRewardedAd alloc] initWithDelegate:self
  andReward:rew];
[rewarded loadPlacement:@"rewarded_p1"]; //or pass in nil for default

When the rewarded ad is ready, the freestarRewardedLoaded: callback will occur.

-(void)freestarRewardedLoaded:(FreestarRewardedAd *)ad {
  //self in this case should be an instance of UIViewController
  [ad showFrom:self];  //You can display the ad now OR show it later; your choice.
}

When the user has fully watched the rewarded ad (or when the given ad partner determines sufficient watch time for the reward), the following callback will occur:

-(void)freestarRewardedAd:(FreestarRewardedAd*)ad received:(NSString *)rewardName {} amount:(NSInteger)rewardAmount {
  //allow user to proceed to app content or next level in app/game
  //can use the name/amount to show change in UI
}

When the user has closed the rewarded ad, the following callback will occur:

-(void)freestarRewardedClosed {}
If the user does not watch the rewarded ad thru to completion, freestarRewardedAd:received:amount: will not occur. However, the freestarRewardedClosed will always occur when the rewarded ad is dismissed regardless if the user watched the entire rewarded ad or not.
❗⚠ Please assume that ads will expire in about 1 hour after the loaded callback. Meaning, you may cache an ad in your app or game, but must be displayed with the allotted hour.

Native Ad

Medium and Small Native ADs

ad images

Freestar supports the Native Ad unit. Native ads are well suited for content-based or feed-based apps because developers can actually customize the ad layout to better match their user experience.

Get Started

        @import FreestarAds;
        ...

        self.nativeAd = [[FreestarNativeAd alloc] initWithDelegate:self andSize:FreestarNativeSmall]; //or FreestarNativeMedium
        [self.nativeAd loadPlacement:nil];
        //Note: you may pass in a "placement" parameter in loadPlacement but it requires prior remote staff setup
        

Assuming you implemented the FreestarNativeAdDelegate protocol:

- (void)freestarNativeClosed;
- (void)freestarNativeFailed:(nonnull FreestarNativeAd *)ad because:(FreestarNoAdReason)reason;
- (void)freestarNativeLoaded:(nonnull FreestarNativeAd *)ad;
- (void)freestarNativeShown:(nonnull FreestarNativeAd *)ad;

and set the delegate object on nativeAd, when the native ad is ready, the freestarNativeLoaded: callback will occur.

- (void)freestarNativeLoaded:(nonnull FreestarNativeAd *)ad {
    self.nativeAd.center = self.view.center; //choose the position of your ad within your app view 
    [self.view addSubview:self.nativeAd]
}

Another Way

Another way to display native ads is to put FreestarNativeAd directly into your Interface Builder layout by placing a view where you want and assigning its class to be FreestarNativeAd.

NOTE: If you choose this route, then you do not need any code in Objective-C or Swift since the ad will automatically be fetched and displayed. Also, if you need to set targeting parameters in the AdRequest, then please use the programmatic approach (above) and do not put the native ad in the layout. However, to receive the delegate callbacks listed above, you will need to assign the delegate object to the ad from the XIB once it is loaded.

Native Templates

Freestar supports two native ad templates: small and medium

By default, you are not required to modify the native ad templates. However, if you want to modify, keep reading...

Modify Small and/or Medium Templates

If you wish to modify the templates, get a copy here.

Get the Freestar-Native-Medium-Custom.xib and Freestar-Native-Small-Custom.xib files and add them to your App bundle with Xcode. You may edit them with Interface Builder to better meet your needs. However, when you modify either of the .xib files, please do not remove any elements, rename any IBOutlets, or change the tag property on any element in the hierarchy. To drop back to using the default Freestar templates, simply remove the custom files from your app bundle.

Sample Project

All of this and more, such as Preroll Ads can be seen in the sample ViewController+FreestarAds.m:

https://github.com/freestarcapital/SDK_documentation_iOS/blob/master/FreestarOBJCSample/FreestarOBJCSample/ViewController+FreestarAds.m

Important iOS 14 Changes

One thing you must do as a publisher is set the Facebook setAdvertiserTrackingEnabled flag appropriately, since Facebook is one of our partners. Here is the official document from Facebook. Generally speaking, one typical you could approach this is if the user has granted the app permission to track them at the OS level, then you would set this flag to true. By default, the flag will be false, meaning that Facebook will not serve any ads. We leave this implementation detail to you in order to give you, the app publisher, more control.

GDPR Update

We are releasing a major update to the Freestar SDK later this week that will require publishers to utilize a GDPR TCF 2.0 compliant CMP in order to render ads to users in a GDPR affected country. If the publisher is not utilizing a GDPR TCF 2.0 compliant CMP once upgraded to this SDK version, then ads will not serve to users in a GDPR affected country.

We put together a comprehensive list of FAQs below to help break down how the changes may impact your business. If you have additional questions, please reach out to your dedicated Account Manager and we will be happy to help on a case by case basis.

What is the new SDK version?

4.0.0 for iOS and Android

How do I become GDPR compliant?

In order to be able to serve ads to your users who reside in any EU country, you will need to implement an IAB TCF 2.0 CMP service.

The CMP service is essentially a personal data and privacy form that must be presented to users to collect their consent or dissent. This form can be presented as often as you like throughout the session of your game or app, as you may require your users to see ads. The most typical setup would be for the first visit to an App with an option to edit your preferences through some other call to action.

What if I already have a CMP implemented?

If you already have a CMP implemented, you will need to add Publisher First, Inc. (Freestar’s official legal entity) as a vendor, as well as each of our partners listed here if not already included.

You will need to retrigger the consent form for GDPR affected users once Freestar and additional vendors are added to the vendor list.

If the list of vendors has already been included, no additional effort is required.

How does the Freestar SDK work with a CMP?

Freestar SDK will automatically detect the user's CMP response and act accordingly. More specifically, if the user consents, then Freestar SDK will be allowed to serve ads. If the user dissents, then Freestar SDK will not show ads.

What if I choose not to implement a CMP?

If a CMP is not implemented at all, then Freestar SDK will not show ads to users who reside in a GDPR affected country.

What do I need to do once I choose a CMP?

After you have chosen a CMP Service provider, during configuration and setup of your CMP, you will need to include a list of supported vendors. We recommend that you select ‘Include All Vendors’ rather than choosing specific vendors, as your list of vendors may change over time.

If you choose to add vendors to your list manually, you will need to include Publisher First, Inc. (Freestar’s official legal entity) as a vendor as well as Freestar’s list of supported vendors here.

Does Great Britain still observe GDPR requirements despite leaving the E.U.?

Yes, it does still apply. In anticipation of Brexit, a new domestic data privacy law called the UK-GDPR took effect on 1/31/20. The UK-GDPR is almost word for word completely identical to the EU’s GDPR.

CMP Recommendations:

Consent Manager - https://www.consentmanager.net/ App Consent - https://sfbx.io/en/produits/

Here is a list of IAB approved CMP Service providers you can implement in your game or app: https://iabeurope.eu/cmp-list/

Testing

For iOS, please use our iOS test key 91784edd-3492-4111-8742-f71bd3803dd3 (we have a different key for Android, so don't use for both iOS and Android) for all your iOS testing runs and enable test mode.

Turn on test mode:

FSTR_TEST_ADS
    

You will usually get 100% fill on all ad units.

It is not recommended to use your production key for testing runs as that is strictly prohibited by our partners and bad things may happen to us on the business side of things.
Do not forget to uninstall and re-install your app when changing keys on your device.

When you are satisfied with your testing, please make a release build with your production key, and turn test mode off. Publish to store.

SKAdNetwork IDs

iOS 14 changed the way advertising works on iOS devices. Ad effectiveness tracking requires the usage of SKAdNetwork APIs. To enable this, SKAdNetwork keys should be included in your app's Info.plist file.

Please see our list: https://github.com/freestarcapital/SDK_documentation_iOS/wiki/iOS-14-SKAdNetwork-IDs

M1 Macs

Currently, we do not support the building of our SDK on M1 macs. This will be addressed in an upcoming release.

Xcode 12 related cocoapods build errors

Recently, in Xcode 12.2, Apple made some breaking changes in Xcode related to build settings. By default, arm64 architecture is now added to ARCHS_STANDARD. In addition, they have removed support for VALID_ARCHS setting from Xcode. Apple also added, in Xcode 12, a new build setting called Excluded Architectures. The reason Apple added arm64 is to support simulator on M1 Mac hardware. However this causes build issues running simulator on Intel Macs. As a result, publishers running Xcode on Intel Macs will need to make usage of the EXCLUDED_ARCHS build setting, for simulator testing, to exclude the arm64 simulator. So, if your Xcode build is failing with arm64 simulator errors in the log, such as:

building for iOS Simulator, but linking in object file built for iOS, file for architecture arm64

then, it is suggested to use this cocoapods post install hook in your Podfile:

  post_install do |installer|
      installer.pods_project.build_configurations.each do |config|
          config.build_settings["EXCLUDED_ARCHS[sdk=iphonesimulator*]"] = "arm64"
      end
  end

This is a temporary fix and should address the issue of build failures resulting from Xcode attempting to build (arm64) simulator on Intel Macs. As of our latest SDK release, we do this automatically in the podspec via xcconfigs, however not every SDK vendor has adopted this workaround. This post install hook is only needed if you are running Xcode 12 on Intel hardware and wanting to run simulator, and you have a cocoapods dependency that is not Xcode 12 / arm64 compliant.

Firebase Dependency

If your app integrated the Firebase SDK, reference the Firebase version compatible with current release 7.0

pod 'Firebase/Core', '~> 7.0'

For further reference:
https://github.com/CocoaPods/CocoaPods/issues/10104
https://stackoverflow.com/questions/63607158/xcode-12-building-for-ios-simulator-but-linking-in-object-file-built-for-ios/63955114#63955114

Yahoo Demand Partner Configuration

If Yahoo is being added as a demand partner in your Podfile, then it is required to add an entry into your Info.plist. See example below:

<key>VerizonAdsSourceAppId</key>
<string>Replace_this_with_your_App's_App_Store_ID</string>

GAM and Googleadmob OB adapters

If you would like to make usage of Google Open Bidding (OB) adapters for FreestarAds, please contact your account manager (AM) for further instructions. We do not advise including OB adapters into your project without first consulting with your AM.

Freestar Ads Mediation Xamarin iOS

Freestar Ads Mediation provides support for Xamarin iOS in C# by providing the necessary NuGet package.

Change Log

Supported Ad Partners

Note: The supported list for Xamarin may differ from our Native iOS

Ad ProviderSDK VersionAd Unit Types
AdColony4.1.4Fullscreen Interstitial & Rewarded
Amazon3.0.0Fullscreen Interstitial, Banner 300x250, Banner 320x50
AppLovin6.11.5Fullscreen Interstitial & Rewarded, Banner 320x50
Criteo3.4.2Fullscreen Interstitial, Banner 300x250, Banner 320x50
Admob7.53.1Fullscreen Interstitial & Rewarded, Banner 300x250, Banner 320x50
Google Ads Manager7.53.1Fullscreen Interstitial & Rewarded, Banner 300x250, Banner 320x50
Unity Ads3.4.2Fullscreen Interstitial & Rewarded, Banner 320x50

Getting Started

Start displaying Freestar Ads in your Xamarin app today by following the simple steps below.

Requirements

• Before we begin, you must have a working Xamarin app running on an iOS device. This document will not show how to create a Xamarin app for iOS as that would be beyond the scope of Freestar Ads Mediation.

• Your Xamarin app must target Xamarin.iOS 9.0 or higher.

NuGet Dependencies

In Visual Studio, INSTALL the following NuGet packages:

NuGet Package NameVersion
Xamarin.Essentials1.3.1
xam.ios.freestar_ads3.2.5

Info.plist

Some ad networks require adding special parameters in the app's Info.plist file. Below are the partner-specific Info.plist requirements.

Google Ad Manager
<key>GADIsAdManagerApp</key>
<true/>
Google Admob
<key>GADApplicationIdentifier</key>
<string>{YOUR_ADMOB_KEY}</string>
AppLovin
<key>AppLovinSdkKey</key>
<string>{YOUR_APPLOVIN_KEY}</string>
AdColony
<key>NSCalendarsUsageDescription</key>
<string>Adding events</string>
<key>NSPhotoLibraryUsageDescription</key>
<string>Taking selfies</string>
<key>NSCameraUsageDescription</key>
<string>Taking selfies</string>
<key>NSMotionUsageDescription </key>
<string>Interactive ad controls</string>

In the above entry, you should change the reasons to be appropriate for your app.

Logging

You can enable detailed logging from the SDK to inspect the ad mediation process in detail via an app's console. This is done by setting a flag in the Info.plist file:

<key>CHP_LOGGING_ENABLE</key>
<string>true</string>

Once this change is made, rebuild the app to see the logs.

❗⚠Warning: For both performance and security reasons, it is not advisable to have detailed logging in production apps. Remove the flag in the Info.plist before submitting to the App Store.

Using the Freestar SDK

Note: Any Xamarin class calling Freestar code will need the following directive: using FreestarAds;

Freestar Initialization

In the FinishedLaunching of your starting AppDelegate:

Freestar.InitWithAdUnitID("P8RIA3"); //use our test key

Interstitial Ads

How to display full screen Interstitial ads:

First, implement the IFreestarInterstitialDelegate interface.

Note: How to implement an interface in C# is beyond the scope of this document.
FreestarInterstitialAd interstitialAd = new FreestarInterstitialAd([YOUR IFreestarInterstitialDelegate]);
interstitialAd.LoadPlacement(null);  //Note: you may pass a "placement" string instead.
If you plan to use more than one placement in your app, please adhere to the placement naming convention as follows:

"my_placement_name_pN", where N is the number of your placement.

For example, let us assume you are using 2 interstitial ad placements in your game or app. The first placement would be the default placement; simply do not specify a placement name by calling the loadPlacement method with null as the argument. The second placement would be, for example, "my_search_screen_p1". The ending "p1" tells the SDK to use the second placement you created in our web dashboard for the interstitial ad unit.

This placement format is the same for all the other ad units, such as rewarded ads and banner ads.

When you receive FreestarInterstitialLoaded from your IFreestarInterstitialDelegate, you may show the ad:

interstitialAd.ShowFrom([YOUR App's current top ViewController]);

Rewarded Ads

How to display full screen Rewarded ads:

First, implement the IFreestarRewardedDelegate interface.

Note: How to implement an interface in C# is beyond the scope of this document.

Choose the reward name and amount, and pass it to the created ad:

FreestarReward rwd = FreestarReward.BlankReward();
rwd.RewardAmount = 100;
rwd.RewardName = "gems";
FreestarRewardedAd rewardedAd = new FreestarRewardedAd(YOUR IFreestarRewardedDelegate], rwd);

rewardedAd.LoadPlacement(null);  //Note: you may pass a "placement" string instead.

When you receive FreestarRewardedLoaded from your IFreestarRewardedDelegate, you may show the ad:

rewardedAd.ShowFrom([YOUR App's current top ViewController]);

Banner Ads

How to display Banner ads:

FreestarBannerAd bannerAd = new FreestarBannerAd(
          [YOUR IFreestarBannerAdDelegate],
          FreestarBannerAdSize.FreestarBanner320x50);
//For MREC size, use FreestarBannerAdSize.FreestarBanner300x250
bannerAd.LoadPlacement(null); //Note: you may pass a "placement" string instead.

Next, you will receive FreestarBannerLoaded of your IFreestarBannerAdDelegate. Here is an example implementation:

public void IFreestarBannerAdDelegate.FreestarBannerLoaded(FreestarBannerAd ad)
{
    ad.Center = new CGPoint(
          YOUR_AdContainer.Frame.Width / 2,
          YOUR_AdContainer.Frame.Height / 2);
    YOUR_AdContainer.AddSubview(ad);
}

Sample Reference App

Finally, we have a Sample Reference Xamarin iOS app. Please use for reference purposes only as the Visual Studio project might not build or compile on your local machine.

Important iOS 14 Changes

One thing you must do as a publisher is set the Facebook setAdvertiserTrackingEnabled flag appropriately, since Facebook is one of our partners. Here is the official document from Facebook. Generally speaking, one typical you could approach this is if the user has granted the app permission to track them at the OS level, then you would set this flag to true. By default, the flag will be false, meaning that Facebook will not serve any ads. We leave this implementation detail to you in order to give you, the app publisher, more control.

GDPR Update

We are releasing a major update to the Freestar SDK later this week that will require publishers to utilize a GDPR TCF 2.0 compliant CMP in order to render ads to users in a GDPR affected country. If the publisher is not utilizing a GDPR TCF 2.0 compliant CMP once upgraded to this SDK version, then ads will not serve to users in a GDPR affected country.

We put together a comprehensive list of FAQs below to help break down how the changes may impact your business. If you have additional questions, please reach out to your dedicated Account Manager and we will be happy to help on a case by case basis.

What is the new SDK version?

4.0.0 for iOS and Android

How do I become GDPR compliant?

In order to be able to serve ads to your users who reside in any EU country, you will need to implement an IAB TCF 2.0 CMP service.

The CMP service is essentially a personal data and privacy form that must be presented to users to collect their consent or dissent. This form can be presented as often as you like throughout the session of your game or app, as you may require your users to see ads. The most typical setup would be for the first visit to an App with an option to edit your preferences through some other call to action.

What if I already have a CMP implemented?

If you already have a CMP implemented, you will need to add Publisher First, Inc. (Freestar’s official legal entity) as a vendor, as well as each of our partners listed here if not already included.

You will need to retrigger the consent form for GDPR affected users once Freestar and additional vendors are added to the vendor list.

If the list of vendors has already been included, no additional effort is required.

How does the Freestar SDK work with a CMP?

Freestar SDK will automatically detect the user's CMP response and act accordingly. More specifically, if the user consents, then Freestar SDK will be allowed to serve ads. If the user dissents, then Freestar SDK will not show ads.

What if I choose not to implement a CMP?

If a CMP is not implemented at all, then Freestar SDK will not show ads to users who reside in a GDPR affected country.

What do I need to do once I choose a CMP?

After you have chosen a CMP Service provider, during configuration and setup of your CMP, you will need to include a list of supported vendors. We recommend that you select ‘Include All Vendors’ rather than choosing specific vendors, as your list of vendors may change over time.

If you choose to add vendors to your list manually, you will need to include Publisher First, Inc. (Freestar’s official legal entity) as a vendor as well as Freestar’s list of supported vendors here.

Does Great Britain still observe GDPR requirements despite leaving the E.U.?

Yes, it does still apply. In anticipation of Brexit, a new domestic data privacy law called the UK-GDPR took effect on 1/31/20. The UK-GDPR is almost word for word completely identical to the EU’s GDPR.

CMP Recommendations:

Consent Manager - https://www.consentmanager.net/ App Consent - https://sfbx.io/en/produits/

Here is a list of IAB approved CMP Service providers you can implement in your game or app: https://iabeurope.eu/cmp-list/

Testing

For iOS, please use our iOS test key 91784edd-3492-4111-8742-f71bd3803dd3 (we have a different key for Android, so don't use for both iOS and Android) for all your iOS testing runs and enable test mode.

Turn on test mode:

FSTR_TEST_ADS
    

You will usually get 100% fill on all ad units.

It is not recommended to use your production key for testing runs as that is strictly prohibited by our partners and bad things may happen to us on the business side of things.
Do not forget to uninstall and re-install your app when changing keys on your device.

When you are satisfied with your testing, please make a release build with your production key, and turn test mode off. Publish to store.

SKAdNetwork IDs

iOS 14 changed the way advertising works on iOS devices. Ad effectiveness tracking requires the usage of SKAdNetwork APIs. To enable this, SKAdNetwork keys should be included in your app's Info.plist file.

Please see our list: https://github.com/freestarcapital/SDK_documentation_iOS/wiki/iOS-14-SKAdNetwork-IDs

M1 Macs

Currently, we do not support the building of our SDK on M1 macs. This will be addressed in an upcoming release.

Xcode 12 related cocoapods build errors

Recently, in Xcode 12.2, Apple made some breaking changes in Xcode related to build settings. By default, arm64 architecture is now added to ARCHS_STANDARD. In addition, they have removed support for VALID_ARCHS setting from Xcode. Apple also added, in Xcode 12, a new build setting called Excluded Architectures. The reason Apple added arm64 is to support simulator on M1 Mac hardware. However this causes build issues running simulator on Intel Macs. As a result, publishers running Xcode on Intel Macs will need to make usage of the EXCLUDED_ARCHS build setting, for simulator testing, to exclude the arm64 simulator. So, if your Xcode build is failing with arm64 simulator errors in the log, such as:

building for iOS Simulator, but linking in object file built for iOS, file for architecture arm64

then, it is suggested to use this cocoapods post install hook in your Podfile:

  post_install do |installer|
      installer.pods_project.build_configurations.each do |config|
          config.build_settings["EXCLUDED_ARCHS[sdk=iphonesimulator*]"] = "arm64"
      end
  end

This is a temporary fix and should address the issue of build failures resulting from Xcode attempting to build (arm64) simulator on Intel Macs. As of our latest SDK release, we do this automatically in the podspec via xcconfigs, however not every SDK vendor has adopted this workaround. This post install hook is only needed if you are running Xcode 12 on Intel hardware and wanting to run simulator, and you have a cocoapods dependency that is not Xcode 12 / arm64 compliant.

Firebase Dependency

If your app integrated the Firebase SDK, reference the Firebase version compatible with current release 7.0

pod 'Firebase/Core', '~> 7.0'

For further reference:
https://github.com/CocoaPods/CocoaPods/issues/10104
https://stackoverflow.com/questions/63607158/xcode-12-building-for-ios-simulator-but-linking-in-object-file-built-for-ios/63955114#63955114

Yahoo Demand Partner Configuration

If Yahoo is being added as a demand partner in your Podfile, then it is required to add an entry into your Info.plist. See example below:

<key>VerizonAdsSourceAppId</key>
<string>Replace_this_with_your_App's_App_Store_ID</string>

GAM and Googleadmob OB adapters

If you would like to make usage of Google Open Bidding (OB) adapters for FreestarAds, please contact your account manager (AM) for further instructions. We do not advise including OB adapters into your project without first consulting with your AM.

Freestar Ads Mediation Swift iOS

Overview

Change Log

Freestar provides an effective ad mediation solution. The Freestar mediation method is universal auction, not the traditional waterfall. Universal auction is more sophisticated than waterfall and provides, by far, the best eCPM. This document describes how to integrate the Freestar SDK into your Swift iOS app quickly and easily. This repo is a fully integrated Swift iOS sample app. Feel free to clone it, install the appropriate Cocoapods, open with Xcode and run it on a device.

Note: You can remotely toggle on/off any of the following ad providers as you see fit using our web dashboard. All applicable providers are enabled by default.

The current version of the Freestar SDK is 5.11.0.

Ad ProviderSDK VersionAd Unit Types
AdColony4.7.2Fullscreen Interstitial & Rewarded
AppLovin11.0.0Fullscreen Interstitial & Rewarded, Banner 320x50
AppLovinMax11.0.0Fullscreen Interstitial & Rewarded, Banner 300x250, Banner 320x50
Criteo4.3.1Fullscreen Interstitial & Rewarded, Banner 300x250, Banner 320x50
Admob9.2.0Fullscreen Interstitial & Rewarded, Banner 300x250, Banner 320x50, Native
Google Ads Manager9.2.0Fullscreen Interstitial & Rewarded, Banner 300x250, Banner 320x50, Native
MoPub (deprecated)5.18.2Fullscreen Interstitial & Rewarded, Banner 300x250, Banner 320x50, Native
Tapjoy12.8.0Fullscreen Rewarded
Unity Ads4.1.0Fullscreen Interstitial & Rewarded
Vungle6.10.3Fullscreen Interstitial & Rewarded
Google IMA3.13.0Preroll
Nimbus1.10.5Fullscreen Interstitial & Rewarded, Banner 300x250, Banner 320x50
TAM (Amazon Publisher Services)4.3.0Fullscreen Interstitial & Rewarded, Banner 300x250, Banner 320x50
Pangle3.7.0.8Fullscreen Interstitial & Rewarded, Banner 300x250, Banner 320x50, Native
Hyprmx6.0.0Fullscreen Interstitial & Rewarded, Banner 300x250, Banner 320x50
Yahoo1.14.2Fullscreen Interstitial, Banner 300x250, Banner 320x50

Project Setup

Your Podfile should have the following:

# Uncomment the next line to define a global platform for your project
platform :ios, '10.0' # minimum ios version

target 'FreestarSwiftSample' do # app name
  # Uncomment the next line if you're using Swift or would like to use dynamic frameworks
  # use_frameworks!
  pod 'FreestarAds', '~> 5.0' # required

  # Only specify the partners for which you want to run ads

  # M1 compatible
  pod "FreestarAds-AdColony", "~> 4.7"
  pod "FreestarAds-Tapjoy", "~> 12.8"
  pod "FreestarAds-Criteo", "~> 4.3"
  pod "FreestarAds-AppLovin", "~> 11.0"
  pod "FreestarAds-AppLovinMax", "~> 11.0"
  pod "FreestarAds-TAM", "~> 4.3"
  pod "FreestarAds-Hyprmx", "~> 6.0"
  pod "FreestarAds-Yahoo", "~> 1.14"
  pod 'FreestarAds-Googleadmob', '~> 9.2'
  pod 'FreestarAds-Googleadmob/Facebook', '~> 9.2'
  pod 'FreestarAds-GAM', '~> 9.2'
  pod 'FreestarAds-GAM/Facebook', '~> 9.2'
  pod "FreestarAds-Unity", "~> 4.1"
  
  # Not M1 compatible pods
  pod "FreestarAds-Vungle", "~> 6.10"
  pod "FreestarAds-Nimbus", "~> 1.10"
  pod "FreestarAds-Google", "~> 3.13"
  pod "FreestarAds-Pangle", "~> 3.7"
end

Once the podfile is setup, enter the Xcode project's base directory in the terminal and run pod install. Then open the generated .xcworkspace project with Xcode.

Info.plist

Some ad networks require adding special parameters in the app's Info.plist file. Below are the partner-specific Info.plist requirements.

Google Ad Manager
<key>GADIsAdManagerApp</key>
<true/>
Google Admob
<key>GADApplicationIdentifier</key>
<string>{YOUR_ADMOB_KEY}</string>
AppLovin
<key>AppLovinSdkKey</key>
<string>{YOUR_APPLOVIN_KEY}</string>
AdColony
<key>NSCalendarsUsageDescription</key>
<string>Adding events</string>
<key>NSPhotoLibraryUsageDescription</key>
<string>Taking selfies</string>
<key>NSCameraUsageDescription</key>
<string>Taking selfies</string>
<key>NSMotionUsageDescription </key>
<string>Interactive ad controls</string>

In the above entry, you should change the reasons to be appropriate for your app.

Logging

You can enable detailed logging from the SDK to inspect the ad mediation process in detail via an app's console. This is done by setting a flag in the Info.plist file:

<key>FSTR_LOGGING_ENABLE</key>
<true />

Once this change is made, rebuild the app to see the logs.

❗⚠Warning: For both performance and security reasons, it is not advisable to have detailed logging in production apps. Remove the flag in the Info.plist before submitting to the App Store.

Using the Freestar SDK

To interface with the Freestar ad mediation, have the following at the top of the code file where you want to make use of the SDK:

import FreestarAds

GDPR Support

Freestar is GDPR-ready and supports the IAB Standards for GDPR compliance.

Use the following simple api in conjunction with your existing Consent Management Provider. If you do not have a CMP solution, that’s ok, too! Our mediation sdk will detect if the user is in the EU and automatically apply GDPR actions to the ad request. So, by default, you do not have to do any extra work to use our sdk in a GDPR-compliant fashion.

// Save GDPR consent string
Freestar.privacySettings().subject(
  toGDPR: gdprApplies,
  withConsent: gdprConsentString)

Initialize Freestar

Freestar must be initialized in the application(_:didFinishLaunchingWithOptions:) of your AppDelegate (or at another time as close as possible to the app launch). This gives the prefetch mechanism time work and thus, makes ad fill more likely when a request is made.

class AppDelegate: UIResponder, UIApplicationDelegate {
  static let FREESTAR_APP_KEY = "P8RIA3"

  func application(_ application: UIApplication,
    didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        // Override point for customization after application launch.

        Freestar.initWithAppKey(AppDelegate.FREESTAR_APP_KEY)
        //more initialization code

        return true
    }
}
Note: if you would like to see ads from TAM (Amazon Publisher Services), make sure your `AppDelegate` implements the `window` property from `UIApplicationDelegate` protocol:

var window : UIWindow? = UIWindow(frame: UIScreen.main.bounds)

The window parameter must be a var declaration with type UIWindow?

Interstitial Ad

Implement the FreestarInterstitialDelegate protocol in one of your classes:

func freestarInterstitialLoaded:(_ ad: FreestarInterstitialAd) {}
func freestarInterstitialFailed:(_ ad: FreestarInterstitialAd because reason: FreestarNoAdReason) {}
func freestarInterstitialShown:(_ ad: FreestarInterstitialAd) {}
func freestarInterstitialClicked:(_ ad: FreestarInterstitialAd) {}
func freestarInterstitialClosed:(_ ad: FreestarInterstitialAd) {}

This allows your app to listen to ad events and act appropriately. You will pass an instance of this object to the Freestar SDK when loading interstitial ad. In the current sample app, the class implementing this protocol is the FullscreenAdViewController, and the implementation is located in FullscreenAdViewController.swift

The actual implementation resides in an extension to the FullscreenAdViewController class

//self is the object that implements FreestarInterstitialDelegate
self.interstitialAd = FreestarInterstitialAd(delegate: self)

//You can load associated to a placement as follows, or pass in
//nil for the default placement
self.interstitialAd?.loadPlacement("interstitial_p1")
If you plan to use more than one placement in your app, please adhere to the placement naming convention as follows:

"my_placement_name_pN", where N is the number of your placement.

For example, let us assume you are using 2 interstitial ad placements in your game or app. The first placement would be the default placement; simply do not specify a placement name by calling the loadPlacement() method with nil as the argument. The second placement would be, for example, "my_search_screen_p1". The ending "p1" tells the SDK to use the second placement you created in our web dashboard for the interstitial ad unit.

This placement format is the same for all the other ad units, such as rewarded ads and banner ads.

When the interstitial ad is ready, the freestarInterstitialLoaded() callback will occur.

func freestarInterstitialLoaded(_ ad: FreestarInterstitialAd){
  //self in this case should be an instance of UIViewController
  ad.showFrom(self)  //You can display the ad now OR show it later; your choice.
}

There are other callbacks that will occur in other events, such as in the rare event where a load ad request does not result in a fill. Please see the FullscreenAdViewController.swift on this sample for those details.

❗⚠Warning: Attempting to load a new ad from the freestarInterstitialFailed(because:) method is strongly discouraged. If you must load an ad from freestarInterstitialFailed:because:, limit ad load retries to avoid continuous failed ad requests in situations such as limited network connectivity.
The clicked callback is no longer reported for Googleadmob or GAM ads. This also applies to banner ads as well as interstitial.

Custom Targeting

Freestar Ads allows for custom targeting parameters that will be sent on to our Google Ads Manager adapter.

interstitial.addCustomTargeting("key1" as:"value1") //optional
interstitial.addCustomTargeting("key2" as:"value2") //optional
Note: the addCustomTargeting(:as) method works in the same manner on rewarded, banner and preroll ads.

Banner Ad

FreeStar supports 300x250 and 320x50 banner ad formats and allows you to control the refresh intervals remotely.

    smallBanner = FreestarBannerAd(delegate: self, andSize: .banner320x50)
    smallBanner.loadPlacement(nil) //nil is the 'default' placement or pass in specific placement e.g. "inview_p1"
                                  

When the banner ad is ready, the freestarBannerLoaded() callback will occur.

func freestarBannerLoaded:(_ ad: FreestarBannerAd) {
  NSLog(@"banner ad as been loaded: %@", ad);
}

If you insert the banner ad into the view hierarchy at this point, the ad will display automatically.

Banner ads can also be specified in Interface Builder layout and will be automatically loaded. If you do this, however, you will need to set the size and delegate properties on the ad object before calling loadPlacement()

The 320x50 ad size a standard for iPhones, on iPads, the corresponding banner ad size is 728x90. By default, a banner ad created with .banner320x50 as the size parameter will be rendered as a 320x50 ad on iPhones, and as a 728x90 ad on iPads. If you want to always render the ad as 320x50, regardless of device, you should set the fixedSize flag on the ad object:

smallBanner = FreestarBannerAd(delegate: self, andSize: .banner320x50)
smallBanner.fixedSize = true;
smallBanner.loadPlacement(nil) //or pass in specific placement

This will always show the in 320x50 size, no matter what device your app is running on.

Adaptive Banner (320x50 only)

Adaptive banner is a feature that allows for the option to serve dynamic banner sizes, i.e. a fullscreen width and a variable height. This presentation can give users an improved UX because of the fact that it is a fullscreen width format. Normal small banners are fixed at 320px in width, while adaptive banner can often times be 390px or more.
Note: To properly support adaptive banner, it is likely that the current project autolayout will need to be modified. Please see below examples.

Enable Adaptive Banner in AppDelegate
Freestar.setAdaptiveBannerEnabledIfAvailable(true)
Freestar.initWithAppKey('FREESTAR_API_KEY')
Calculate and Set the adaptiveBannerWidth Property (Optional)

Note: This property defaults to fullscreen width based on orientation

    banner.adaptiveBannerWidth = calculateAdaptiveViewWidth()
    banner.translatesAutoresizingMaskIntoConstraints = false  // autolayout is the preferred approach
    func calculateAdaptiveViewWidth() -> CGFloat {
        let frame = { () -> CGRect in
          // Here safe area is taken into account, hence the view frame is used
          // after the view has been laid out.
          if #available(iOS 11.0, *) {
            return view.frame.inset(by: view.safeAreaInsets)
          } else {
            return view.frame
          }
        }()
        return frame.size.width
    }
Autolayout Using Constraints

Since adaptive banner is a flexible width and/or height format, it may be required to change your current layout to support dynamic size. This is just one example of how this can be achieved, but is by no means, the only approach.

    func freestarBannerLoaded(_ ad: FreestarBannerAd) {
        container?.addSubview(ad) // add banner to container
                
        ad.centerXAnchor.constraint(equalTo: container!.centerXAnchor).isActive = true  // horizontal center
        ad.centerYAnchor.constraint(equalTo: container!.centerYAnchor).isActive = true  // vertical center 
        if (ad.isAdaptive) {  // check if current banner is adaptive
            // set adaptive width (but also ensure, using autolayout, there is sufficient height available for up to 90x)
            ad.widthAnchor.constraint(equalToConstant: calculateAdaptiveViewWidth()).isActive = true
        } else {
            // non-adaptive so set fixed width
            ad.widthAnchor.constraint(equalToConstant: ad.frame.width).isActive = true
            ad.heightAnchor.constraint(equalToConstant: ad.frame.height).isActive = true
        }
    }       

Rewarded Ad

A common myth regarding Rewarded Ads is publishers are required to give something to the user. But, that's not true. You can simply tell the user they must watch the ad in order to be able to proceed to the next level or proceed to content.

Implement the FreestarRewardedDelegate protocol in one of your classes:

func freestarRewardedLoaded(_ ad: FreestarRewardedAd) {}
func freestarRewardedFailed(_ ad: FreestarRewardedAd, because reason: FreestarNoAdReason) {}
func freestarRewardedShown(_ ad: FreestarRewardedAd) {}
func freestarRewardedClosed(_ ad: FreestarRewardedAd) {}
func freestarRewardedFailedToStart(_ ad: FreestarRewardedAd, because reason: FreestarNoAdReason) {}
func freestarRewardedAd(_ ad: FreestarRewardedAd, received rewardName: String, amount rewardAmount: Int) {}

This allows your app to listen to ad events and act appropriately. You will pass an instance of this object to the Freestar SDK when loading rewarded ad. In the current sample app, the class implementing this protocol is the FullscreenAdViewController, and the implementation is located in FullscreenAdViewController.swift

//this may be overriden in the ad portal
let rew = FreestarReward.blank()
rew.rewardName = "Coins"
rew.rewardAmount = 1000
rew.userID = "CoolGuy"
rew.secretKey = "Bx34da3yn"

        //Note: If you want to use server-to-server rewarded callbacks, the Freestar team will provide
        //      you with a secret key and only that will work.
        //      However, if you want to use client-side only rewarded callbacks, then you can supply
        //      your own "secretKey" or null.

self.rewardedAd = FreestarRewardedAd(delegate: self, andReward: rew)
self.rewardedAd?.loadPlacement("rewarded_p1") //or pass in nil for default

When the rewarded ad is ready, the freestarRewardedLoaded() callback will occur.

func freestarRewardedLoaded:(_ ad: FreestarRewardedAd) {
  //self in this case should be an instance of UIViewController
  ad.showFrom(self) //You can display the ad now OR show it later; your choice.
}

When the user has fully watched the rewarded ad (or when the given ad partner determines sufficient watch time for the reward), the following callback will occur:

func freestarRewardedAd(_ ad: FreestarRewardedAd, received rewardName: String, amount rewardAmount: Int) {
  //allow user to proceed to app content or next level in app/game
  //can use the name/amount to show change in UI
}

When the user has closed the rewarded ad, the following callback will occur:

func freestarRewardedClosed(_ ad: FreestarRewardedAd) {}
If the user does not watch the rewarded ad thru to completion, freestarRewardedAd(received:amount:) will not occur. However, the freestarRewardedClosed() will always occur when the rewarded ad is dismissed regardless if the user watched the entire rewarded ad or not.
❗⚠ Please assume that ads will expire in about 1 hour after the loaded callback. Meaning, you may cache an ad in your app or game, but must be displayed with the allotted hour.

Native Ad

Medium and Small Native ADs

ad images

Freestar supports the Native Ad unit. Native ads are well suited for content-based or feed-based apps because developers can actually customize the ad layout to better match their user experience.

Get Started

        import FreestarAds
        ...

        self.nativeAd = FreestarNativeAd(delegate: self, andSize: .medium) //or .small
        self.nativeAd.loadPlacement(nil);
        //Note: you may pass in a "placement" parameter in loadPlacement but it requires prior remote staff setup
        

Assuming you implemented the FreestarNativeAdDelegate protocol:

func freestarNativeClosed(_ ad: FreestarNativeAd)
func freestarNativeFailed(_ ad: FreestarNativeAd, because reason: FreestarNoAdReason)
func freestarNativeLoaded(_ ad: FreestarNativeAd)
func freestarNativeShown(_ ad: FreestarNativeAd)
func freestarNativeClicked(_ ad: FreestarNativeAd)

and set the delegate object on nativeAd, when the native ad is ready, the freestarNativeLoaded callback will occur.

func freestarNativeLoaded(_ ad: FreestarNativeAd) {
    self.nativeAd.center = self.view.center //choose the position of your ad within your app view 
    self.view.addSubview(self.nativeAd)
}

Another Way

Another way to display native ads is to put FreestarNativeAd directly into your Interface Builder layout by placing a view where you want and assigning its class to be FreestarNativeAd.

NOTE: If you choose this route, then you do not need any code in Objective-C or Swift since the ad will automatically be fetched and displayed. Also, if you need to set targeting parameters in the AdRequest, then please use the programmatic approach (above) and do not put the native ad in the layout. However, to receive the delegate callbacks listed above, you will need to assign the delegate object to the ad from the XIB once it is loaded.

Native Templates

Freestar supports two native ad templates: small and medium

By default, you are not required to modify the native ad templates. However, if you want to modify, keep reading...

Modify Small and/or Medium Templates

If you wish to modify the templates, get a copy here.

Get the Freestar-Native-Medium-Custom.xib and Freestar-Native-Small-Custom.xib files and add them to your App bundle with Xcode. You may edit them with Interface Builder to better meet your needs. However, when you modify either of the .xib files, please do not remove any elements, rename any IBOutlets, or change the tag property on any element in the hierarchy. To drop back to using the default Freestar templates, simply remove the custom files from your app bundle.

App Open Ad

To enable App Open Ad(s), please add this code after SDK initialization and UI window setup.

Freestar.requestAppOpenAds(withPlacement: "interstitial_p1", waitScreen: true) { placement, event, error in }

Sample Project

All of this and more, such as Preroll Ads can be seen in the sample FreestarSwiftSample:

https://github.com/freestarcapital/SDK_documentation_iOS/blob/master/FreestarSwiftSample/FreestarSwiftSample

Important iOS 14 Changes

One thing you must do as a publisher is set the Facebook setAdvertiserTrackingEnabled flag appropriately, since Facebook is one of our partners. Here is the official document from Facebook. Generally speaking, one typical you could approach this is if the user has granted the app permission to track them at the OS level, then you would set this flag to true. By default, the flag will be false, meaning that Facebook will not serve any ads. We leave this implementation detail to you in order to give you, the app publisher, more control.

GDPR Update

We are releasing a major update to the Freestar SDK later this week that will require publishers to utilize a GDPR TCF 2.0 compliant CMP in order to render ads to users in a GDPR affected country. If the publisher is not utilizing a GDPR TCF 2.0 compliant CMP once upgraded to this SDK version, then ads will not serve to users in a GDPR affected country.

We put together a comprehensive list of FAQs below to help break down how the changes may impact your business. If you have additional questions, please reach out to your dedicated Account Manager and we will be happy to help on a case by case basis.

What is the new SDK version?

4.0.0 for iOS and Android

How do I become GDPR compliant?

In order to be able to serve ads to your users who reside in any EU country, you will need to implement an IAB TCF 2.0 CMP service.

The CMP service is essentially a personal data and privacy form that must be presented to users to collect their consent or dissent. This form can be presented as often as you like throughout the session of your game or app, as you may require your users to see ads. The most typical setup would be for the first visit to an App with an option to edit your preferences through some other call to action.

What if I already have a CMP implemented?

If you already have a CMP implemented, you will need to add Publisher First, Inc. (Freestar’s official legal entity) as a vendor, as well as each of our partners listed here if not already included.

You will need to retrigger the consent form for GDPR affected users once Freestar and additional vendors are added to the vendor list.

If the list of vendors has already been included, no additional effort is required.

How does the Freestar SDK work with a CMP?

Freestar SDK will automatically detect the user's CMP response and act accordingly. More specifically, if the user consents, then Freestar SDK will be allowed to serve ads. If the user dissents, then Freestar SDK will not show ads.

What if I choose not to implement a CMP?

If a CMP is not implemented at all, then Freestar SDK will not show ads to users who reside in a GDPR affected country.

What do I need to do once I choose a CMP?

After you have chosen a CMP Service provider, during configuration and setup of your CMP, you will need to include a list of supported vendors. We recommend that you select ‘Include All Vendors’ rather than choosing specific vendors, as your list of vendors may change over time.

If you choose to add vendors to your list manually, you will need to include Publisher First, Inc. (Freestar’s official legal entity) as a vendor as well as Freestar’s list of supported vendors here.

Does Great Britain still observe GDPR requirements despite leaving the E.U.?

Yes, it does still apply. In anticipation of Brexit, a new domestic data privacy law called the UK-GDPR took effect on 1/31/20. The UK-GDPR is almost word for word completely identical to the EU’s GDPR.

CMP Recommendations:

Consent Manager - https://www.consentmanager.net/ App Consent - https://sfbx.io/en/produits/

Here is a list of IAB approved CMP Service providers you can implement in your game or app: https://iabeurope.eu/cmp-list/

Testing

For iOS, please use our iOS test key 91784edd-3492-4111-8742-f71bd3803dd3 (we have a different key for Android, so don't use for both iOS and Android) for all your iOS testing runs and enable test mode.

Turn on test mode:

FSTR_TEST_ADS
    

You will usually get 100% fill on all ad units.

It is not recommended to use your production key for testing runs as that is strictly prohibited by our partners and bad things may happen to us on the business side of things.
Do not forget to uninstall and re-install your app when changing keys on your device.

When you are satisfied with your testing, please make a release build with your production key, and turn test mode off. Publish to store.

SKAdNetwork IDs

iOS 14 changed the way advertising works on iOS devices. Ad effectiveness tracking requires the usage of SKAdNetwork APIs. To enable this, SKAdNetwork keys should be included in your app's Info.plist file.

Please see our list: https://github.com/freestarcapital/SDK_documentation_iOS/wiki/iOS-14-SKAdNetwork-IDs

M1 Macs

Currently, we do not support the building of our SDK on M1 macs. This will be addressed in an upcoming release.

Xcode 12 related cocoapods build errors

Recently, in Xcode 12.2, Apple made some breaking changes in Xcode related to build settings. By default, arm64 architecture is now added to ARCHS_STANDARD. In addition, they have removed support for VALID_ARCHS setting from Xcode. Apple also added, in Xcode 12, a new build setting called Excluded Architectures. The reason Apple added arm64 is to support simulator on M1 Mac hardware. However this causes build issues running simulator on Intel Macs. As a result, publishers running Xcode on Intel Macs will need to make usage of the EXCLUDED_ARCHS build setting, for simulator testing, to exclude the arm64 simulator. So, if your Xcode build is failing with arm64 simulator errors in the log, such as:

building for iOS Simulator, but linking in object file built for iOS, file for architecture arm64

then, it is suggested to use this cocoapods post install hook in your Podfile:

  post_install do |installer|
      installer.pods_project.build_configurations.each do |config|
          config.build_settings["EXCLUDED_ARCHS[sdk=iphonesimulator*]"] = "arm64"
      end
  end

This is a temporary fix and should address the issue of build failures resulting from Xcode attempting to build (arm64) simulator on Intel Macs. As of our latest SDK release, we do this automatically in the podspec via xcconfigs, however not every SDK vendor has adopted this workaround. This post install hook is only needed if you are running Xcode 12 on Intel hardware and wanting to run simulator, and you have a cocoapods dependency that is not Xcode 12 / arm64 compliant.

Firebase Dependency

If your app integrated the Firebase SDK, reference the Firebase version compatible with current release 7.0

pod 'Firebase/Core', '~> 7.0'

For further reference:
https://github.com/CocoaPods/CocoaPods/issues/10104
https://stackoverflow.com/questions/63607158/xcode-12-building-for-ios-simulator-but-linking-in-object-file-built-for-ios/63955114#63955114

Yahoo Demand Partner Configuration

If Yahoo is being added as a demand partner in your Podfile, then it is required to add an entry into your Info.plist. See example below:

<key>VerizonAdsSourceAppId</key>
<string>Replace_this_with_your_App's_App_Store_ID</string>

GAM and Googleadmob OB adapters

If you would like to make usage of Google Open Bidding (OB) adapters for FreestarAds, please contact your account manager (AM) for further instructions. We do not advise including OB adapters into your project without first consulting with your AM.

Freestar Ads Mediation ReactNative iOS

Overview

Change Log

Freestar provides an effective ad mediation solution. The Freestar mediation method is universal auction, not the traditional waterfall. Universal auction is more sophisticated than waterfall and provides, by far, the best eCPM. This document describes how to integrate the Freestar SDK into your ReactNative iOS app quickly and easily. This repo is a fully integrated ReactNative iOS sample app. Feel free to clone it, install the appropriate Cocoapods, launch ReactNative and run it on a device.

Note: You can remotely toggle on/off any of the following ad providers as you see fit using our web dashboard. All applicable providers are enabled by default.

See SDK Version and Supported Demand Source Partner Versions

Project Setup

The ReactNative environment generates an Xcode project on creation, including a companion Pods project to install appropriate dependencies via Cocoapods. To integrate the Freestar SDK, install the ReactNative plugin from npm:

npm install --save @freestar/freestar-plugin-react-native

NOTE: if you already have the plugin installed, you should update it:

npm update --save @freestar/freestar-plugin-react-native

Then edit the Podfile:

  1. ReactNative generates a project with the minimum iOS target version of 9.0. FreestarAds mimum requirement is 10.0, and the Podfile needs to reflect that:

platform :ios, '10.0' # minimum ios version

  1. You need to specify the partners for which you want to run ads via Freestar mediation. Append them to the React-generated Podfile:
  pod 'FreestarAds-AdColony', '~> 5.0'
  pod 'FreestarAds-AppLovin', '~> 5.0'
  pod 'FreestarAds-Googleadmob', '~> 6.0'
  pod 'FreestarAds-Tapjoy', '~> 5.0'
  pod 'FreestarAds-Unity', '~> 6.0'
  pod 'FreestarAds-Vungle', '~> 5.0'
  pod 'FreestarAds-Criteo', '~> 3.0'
  pod 'FreestarAds-GAM', '~> 5.0'
  pod 'FreestarAds-Mopub', '~> 5.0' # (deprecated)
  pod 'FreestarAds-Nimbus', '~> 3.0'
  pod 'FreestarAds-TAM', '~> 2.0'
  pod 'FreestarAds-Pangle', '~> 1.0'

Rerun pod install in the ios directory of the ReactNative project. Then open the generated .xcworkspace project with Xcode.

Info.plist

Some ad networks require adding special parameters in the app's Info.plist file. Below are the partner-specific Info.plist requirements.

Google Ad Manager
<key>GADIsAdManagerApp</key>
<true/>

Google Admob
<key>GADApplicationIdentifier</key>
<string>{YOUR_ADMOB_KEY}</string>

AppLovin
<key>AppLovinSdkKey</key>
<string>{YOUR_APPLOVIN_KEY}</string>

AdColony
<key>NSCalendarsUsageDescription</key>
<string>Adding events</string>
<key>NSPhotoLibraryUsageDescription</key>
<string>Taking selfies</string>
<key>NSCameraUsageDescription</key>
<string>Taking selfies</string>
<key>NSMotionUsageDescription </key>
<string>Interactive ad controls</string>

In the above entry, you should change the reasons to be appropriate for your app.

Logging

You can enable detailed logging from the SDK to inspect the ad mediation process in detail via an app's console. This is done by setting a flag in the Info.plist file:

<key>CHP_LOGGING_ENABLE</key>
<string>true</string>

Once this change is made, rebuild the app to see the logs.

❗⚠Warning: For both performance and security reasons, it is not advisable to have detailed logging in production apps. Remove the flag in the Info.plist before submitting to the App Store.

Using the Freestar SDK

To interface with the Freestar ad mediation, have the following at the top of the code file where you want to make use of the SDK:

import FreestarReactBridge from 'freestar-plugin-react';

import FreestarReactBridge from "@freestar/freestar-plugin-react-native";

GDPR Support

Freestar is GDPR-ready and supports the IAB Standards for GDPR compliance.

Use the following simple api in conjunction with your existing Consent Management Provider. If you do not have a CMP solution, that’s ok, too! Our mediation sdk will detect if the user is in the EU and automatically apply GDPR actions to the ad request. So, by default, you do not have to do any extra work to use our sdk in a GDPR-compliant fashion.

// Save GDPR consent string
FreestarReactBridge.subjectToGDPR( 
    gdprApplies,      //boolean
    gdprConsentString //string
);

Initialize Freestar

Freestar must be initialized as close as possible to the app launch. This gives the prefetch mechanism time work and thus, makes ad fill more likely when a request is made.

export default function App(props) {
    let FREESTAR_API_KEY = "P8RIA3";
    FreestarReactBridge. initWithAdUnitID(FREESTAR_API_KEY);

    //more initialization code

    return (
        //overall react UI
    );
}

Interstitial Ad

Provide the SDK with the callback function for events related to interstitial ads:

FreestarReactBridge.subscribeToInterstitialCallbacks((eventName) => {
    if(eventName === "onInterstitialLoaded") {
        // ad can now be shown
    } else if (eventName === "onInterstitialClicked") {
        // ad clicked
    } else if (eventName === "onInterstitialShown") {
        // ad shown
    } else if (eventName === "onInterstitialFailed") {
        // no ad available
    } else if (eventName === "onInterstitialDismissed") {
        //ad has closed, resume the app
    } else {
       console.log("unknown event");
    }
  });

This allows your app to listen to ad events and act appropriately. In the current sample app, this is implemented in the FullscreenAds() function of the App.js file.

To receive any callbacks, you will need to load the ad:

//You can load associated to a placement as follows, or pass in
// the empty string for the default placement
FreestarReactBridge.loadInterstitialAd("interstitial_p1");
If you plan to use more than one placement in your app, please adhere to the placement naming convention as follows:

"my_placement_name_pN", where N is the number of your placement.

For example, let us assume you are using 2 interstitial ad placements in your game or app. The first placement would be the default placement; simply do not specify a placement name by calling the loadInterstitialAd() method with "" as the argument. The second placement would be, for example, "my_search_screen_p1". The ending "p1" tells the SDK to use the second placement you created in our web dashboard for the interstitial ad unit.

This placement format is the same for all the other ad units, such as rewarded ads and banner ads.

When the interstitial ad is ready, the "onInterstitialLoaded callback event will arrive.

FreestarReactBridge.subscribeToInterstitialCallbacks((eventName) => {
    if(eventName === "onInterstitialLoaded") {
        // ad can now be shown
        //You can display the ad now OR show it later; your choice.
        FreestarReactBridge.showInterstitialAd();
    }
    //other events
}

There are other callbacks that will occur in other events, such as in the rare event where a load ad request does not result in a fill. Please see the App.js on this sample for those details.

❗⚠Warning: Attempting to load a new ad from the "onInterstitialFailed" callback event is strongly discouraged. If you must load an ad from "onInterstitialFailed" callback, limit ad load retries to avoid continuous failed ad requests in situations such as limited network connectivity.

Banner Ad

FreeStar supports 300x250 (MREC) and 320x50 (BANNER) banner ad formats and allows you to control the refresh intervals remotely. You can use ReactNative to place the ads in appropriate locations in your app.

To do so, first, import the banner ad objects from the plugin:

import BannerAd from '@freestar/freestar-plugin-react-native/BannerAd';
import MrecBannerAd from '@freestar/freestar-plugin-react-native/MrecBannerAd';
import MrecBannerAd2 from '@freestar/freestar-plugin-react-native/MrecBannerAd2';

MrecBannerAd comes in separate classes to enable displaying the MREC-size ad in different contexts without them overriding each other -- a reload of an ad in one banner does not affect the others. There are 4 built-in options: MrecBannerAdMrecBannerAd2MrecBannerAd3 and MrecBannerAd4, with identical behavior. The same setup applies to the Small and Medium native ad units (see below): 4 distinct options for each.

Then setup the ad:

    <BannerAd
        style={{width: 320, height: 50}}
        requestOptions={{ size:'BANNER' }}
        onBannerAdLoaded={bannerLoaded}
        onBannerAdFailedToLoad={bannerFailed}
      />

And for MREC:

<View style={{ flexDirection: 'row', paddingTop: 10}}>
  <BannerAd
      style={{width: 300, height: 250}}
      requestOptions={
        {
            size:'MREC',
            isCoppaEnabled: false,
            targetingParams: {
                  'someparam1': 'somevalue1',
                  'someparam2': 'somevalue2',
                  'someparam3': 'somevalue3',
            },
            testDeviceIds: ['deviceId1','deviceId2', 'deviceId3']
        }
      }
      onBannerAdLoaded={bannerLoaded}
      onBannerAdFailedToLoad={bannerFailed}
  />
</View>
      
  <View style={{ flexDirection: 'row', paddingTop: 10}}>
  <BannerAd2
    style={{width: 300, height: 250}}
    requestOptions={{}}
    onBannerAdLoaded={bannerLoaded}
    onBannerAdFailedToLoad={bannerFailed}
  />
</View>

The bannerLoaded and bannerFailed should be functions implemented by you to handle the corresponding events. The ad will load automatically after being inserted into the view hierarchy, and display when it is ready.

Note: the requestOptions parameter is required. If your app has no additional parameters to pass in, add requestOptions={{}} to the banner ad element.

Custom Targeting

Freestar Ads allows for custom targeting parameters that will be sent on to our Google Ads Manager adapter.

<BannerAd
         style={{width: 300, height: 250}}
         requestOptions={
            {
               size:'MREC',
               targetingParams: {
                     'someparam1': 'somevalue1',
                     'someparam2': 'somevalue2',
                     'someparam3': 'somevalue3'
               }
            }
         }
         onBannerAdLoaded={bannerLoaded}
        onBannerAdFailedToLoad={bannerFailed}
        />

Rewarded Ad

A common myth regarding Rewarded Ads is publishers are required to give something to the user. But, that's not true. You can simply tell the user they must watch the ad in order to be able to proceed to the next level or proceed to content.

Provide the SDK with the callback function for events related to rewarded ads:

FreestarReactBridge.subscribeToRewardCallbacks((eventName, rewardName = '', rewardAmount = 0) => {
    if (eventName === "onRewardedFailed") {
      // no ad available
    } else if (eventName === "onRewardedDismissed") {
      // ad closed
    } else if(eventName === "onRewardedLoaded") {
      // ad ready
    } else if (eventName === "onRewardedCompleted") {
      // received reward
      console.log("reward ad completed: awarded " + rewardAmount + ' ' + rewardName);
    } else if (eventName === "onRewardedShown") {

    } else if (eventName === "onRewardedShowFailed") {
      // couldn't display ad
    } else {
       console.log("unknown event");
    }
  });

This allows your app to listen to ad events and act appropriately. In the current sample app, this is implemented in the FullscreenAds() function of the App.js file.

To receive any callbacks, you will need to load the ad:

//You can load associated to a placement as follows, or pass in
// the empty string for the default placement
FreestarReactBridge.loadRewardAd("rewarded_p1");

When the rewarded ad is ready, the "onRewardedLoaded callback event will arrive.

FreestarReactBridge.subscribeToRewardCallbacks((eventName, rewardName = '', rewardAmount = 0) => {
    if(eventName === "onRewardedLoaded") {
      // ad can now be shown
      //You can display the ad now OR show it later; your choice.
      FreestarReactBridge.showRewardAd(
          "Coins",   //reward name
          50,        //reward amount
          "myuserId",//user id 
          "12345678" //secret key
      );
    }
    //other callback events
});

When the user has fully watched the rewarded ad (or when the given ad partner determines sufficient watch time for the reward), the onRewardedCompleted callback event will arrive.

When the user has closed the rewarded ad, the onRewardedDismissed callback event will arrive.

If the user does not watch the rewarded ad thru to completion, onRewardedCompleted callback event will not arrive, but the onRewardedDismissed event always arrive when the rewarded ad is dismissed regardless if the user watched the entire rewarded ad or not.
❗⚠ Please assume that ads will expire in about 1 hour after the loaded callback. Meaning, you may cache an ad in your app or game, but must be displayed with the allotted hour.

Native Ads

Organizationally, native ads work similar to banner ads, but permit customization of how ad data is displayed. They are only supported by the following partners:

  • Mopub (deprecated)
  • Googleadmob
  • GAM

To display native ads in a ReactNative app, first import the native ad objects from the plugin:

import SmallNativeAd from '@freestar/freestar-plugin-react-native/SmallNativeAd';
import MediumNativeAd2 from '@freestar/freestar-plugin-react-native/MediumNativeAd';

And then add them to the app at the appropriate location:

<View style={{ flexDirection: 'row', paddingTop: 30}}>
  <MediumNativeAd
      style={{width: 300, height: 250}}
      requestOptions={
        {
            targetingParams: {
                  'someparam1': 'somevalue1',
                  'someparam2': 'somevalue2',
                  'someparam3': 'somevalue3',
            },
            testDeviceIds: ['deviceId1','deviceId2', 'deviceId3']
        }
      }
      onNativeAdLoaded={nativeLoaded}
      onNativeAdFailedToLoad={nativeFailed}
  />
  </View>
  
  <View style={{ flexDirection: 'row', paddingTop: 10}}>
  <SmallNativeAd
    style={{width: 320, height: 50}}
    requestOptions={{}}
    onNativeAdLoaded={nativeLoaded}
    onNativeAdFailedToLoad={nativeFailed}
  />
</View>

Just like with banners, the nativeLoaded and nativeFailed should be functions implemented by you to handle the corresponding events, and the requestOptions parameter is required. If your app has no additional parameters to pass in, add requestOptions={{}} to the native ad element.

Sample Project

All of this and more, can be seen in the sample FreestarReactNativeSample:

https://github.com/freestarcapital/SDK_documentation_iOS/blob/master/FreestarReactNativeSample

Important iOS 14 Changes

One thing you must do as a publisher is set the Facebook setAdvertiserTrackingEnabled flag appropriately, since Facebook is one of our partners. Here is the official document from Facebook. Generally speaking, one typical you could approach this is if the user has granted the app permission to track them at the OS level, then you would set this flag to true. By default, the flag will be false, meaning that Facebook will not serve any ads. We leave this implementation detail to you in order to give you, the app publisher, more control.

GDPR Update

We are releasing a major update to the Freestar SDK later this week that will require publishers to utilize a GDPR TCF 2.0 compliant CMP in order to render ads to users in a GDPR affected country. If the publisher is not utilizing a GDPR TCF 2.0 compliant CMP once upgraded to this SDK version, then ads will not serve to users in a GDPR affected country.

We put together a comprehensive list of FAQs below to help break down how the changes may impact your business. If you have additional questions, please reach out to your dedicated Account Manager and we will be happy to help on a case by case basis.

What is the new SDK version?

4.0.0 for iOS and Android

How do I become GDPR compliant?

In order to be able to serve ads to your users who reside in any EU country, you will need to implement an IAB TCF 2.0 CMP service.

The CMP service is essentially a personal data and privacy form that must be presented to users to collect their consent or dissent. This form can be presented as often as you like throughout the session of your game or app, as you may require your users to see ads. The most typical setup would be for the first visit to an App with an option to edit your preferences through some other call to action.

What if I already have a CMP implemented?

If you already have a CMP implemented, you will need to add Publisher First, Inc. (Freestar’s official legal entity) as a vendor, as well as each of our partners listed here if not already included.

You will need to retrigger the consent form for GDPR affected users once Freestar and additional vendors are added to the vendor list.

If the list of vendors has already been included, no additional effort is required.

How does the Freestar SDK work with a CMP?

Freestar SDK will automatically detect the user's CMP response and act accordingly. More specifically, if the user consents, then Freestar SDK will be allowed to serve ads. If the user dissents, then Freestar SDK will not show ads.

What if I choose not to implement a CMP?

If a CMP is not implemented at all, then Freestar SDK will not show ads to users who reside in a GDPR affected country.

What do I need to do once I choose a CMP?

After you have chosen a CMP Service provider, during configuration and setup of your CMP, you will need to include a list of supported vendors. We recommend that you select ‘Include All Vendors’ rather than choosing specific vendors, as your list of vendors may change over time.

If you choose to add vendors to your list manually, you will need to include Publisher First, Inc. (Freestar’s official legal entity) as a vendor as well as Freestar’s list of supported vendors here.

Does Great Britain still observe GDPR requirements despite leaving the E.U.?

Yes, it does still apply. In anticipation of Brexit, a new domestic data privacy law called the UK-GDPR took effect on 1/31/20. The UK-GDPR is almost word for word completely identical to the EU’s GDPR.

CMP Recommendations:

Consent Manager - https://www.consentmanager.net/ App Consent - https://sfbx.io/en/produits/

Here is a list of IAB approved CMP Service providers you can implement in your game or app: https://iabeurope.eu/cmp-list/

Testing

For iOS, please use our iOS test key 91784edd-3492-4111-8742-f71bd3803dd3 (we have a different key for Android, so don't use for both iOS and Android) for all your iOS testing runs and enable test mode.

Turn on test mode:

FSTR_TEST_ADS
    

You will usually get 100% fill on all ad units.

It is not recommended to use your production key for testing runs as that is strictly prohibited by our partners and bad things may happen to us on the business side of things.
Do not forget to uninstall and re-install your app when changing keys on your device.

When you are satisfied with your testing, please make a release build with your production key, and turn test mode off. Publish to store.

SKAdNetwork IDs

iOS 14 changed the way advertising works on iOS devices. Ad effectiveness tracking requires the usage of SKAdNetwork APIs. To enable this, SKAdNetwork keys should be included in your app's Info.plist file.

Please see our list: https://github.com/freestarcapital/SDK_documentation_iOS/wiki/iOS-14-SKAdNetwork-IDs

M1 Macs

Currently, we do not support the building of our SDK on M1 macs. This will be addressed in an upcoming release.

Xcode 12 related cocoapods build errors

Recently, in Xcode 12.2, Apple made some breaking changes in Xcode related to build settings. By default, arm64 architecture is now added to ARCHS_STANDARD. In addition, they have removed support for VALID_ARCHS setting from Xcode. Apple also added, in Xcode 12, a new build setting called Excluded Architectures. The reason Apple added arm64 is to support simulator on M1 Mac hardware. However this causes build issues running simulator on Intel Macs. As a result, publishers running Xcode on Intel Macs will need to make usage of the EXCLUDED_ARCHS build setting, for simulator testing, to exclude the arm64 simulator. So, if your Xcode build is failing with arm64 simulator errors in the log, such as:

building for iOS Simulator, but linking in object file built for iOS, file for architecture arm64

then, it is suggested to use this cocoapods post install hook in your Podfile:

  post_install do |installer|
      installer.pods_project.build_configurations.each do |config|
          config.build_settings["EXCLUDED_ARCHS[sdk=iphonesimulator*]"] = "arm64"
      end
  end

This is a temporary fix and should address the issue of build failures resulting from Xcode attempting to build (arm64) simulator on Intel Macs. As of our latest SDK release, we do this automatically in the podspec via xcconfigs, however not every SDK vendor has adopted this workaround. This post install hook is only needed if you are running Xcode 12 on Intel hardware and wanting to run simulator, and you have a cocoapods dependency that is not Xcode 12 / arm64 compliant.

Firebase Dependency

If your app integrated the Firebase SDK, reference the Firebase version compatible with current release 7.0

pod 'Firebase/Core', '~> 7.0'

For further reference:
https://github.com/CocoaPods/CocoaPods/issues/10104
https://stackoverflow.com/questions/63607158/xcode-12-building-for-ios-simulator-but-linking-in-object-file-built-for-ios/63955114#63955114

Yahoo Demand Partner Configuration

If Yahoo is being added as a demand partner in your Podfile, then it is required to add an entry into your Info.plist. See example below:

<key>VerizonAdsSourceAppId</key>
<string>Replace_this_with_your_App's_App_Store_ID</string>

GAM and Googleadmob OB adapters

If you would like to make usage of Google Open Bidding (OB) adapters for FreestarAds, please contact your account manager (AM) for further instructions. We do not advise including OB adapters into your project without first consulting with your AM.

Freestar Ads Mediation Unity iOS

Freestar Ads Mediation - Unity Integration Guide for iOS

Supported Ad Partners

Note: The supported list for Unity may differ from our Native iOS

Ad ProviderSDK VersionAd Unit Types
AdColony4.7.2Fullscreen Interstitial & Rewarded
AppLovin11.0.0Fullscreen Interstitial & Rewarded, Banner 320x50
AppLovinMax11.0.0Fullscreen Interstitial & Rewarded, Banner 300x250, Banner 320x50
Criteo4.3.1Fullscreen Interstitial & Rewarded, Banner 300x250, Banner 320x50
Admob9.2.0Fullscreen Interstitial & Rewarded, Banner 300x250, Banner 320x50, Native
Google Ads Manager9.2.0Fullscreen Interstitial & Rewarded, Banner 300x250, Banner 320x50, Native
MoPub (deprecated)5.18.2Fullscreen Interstitial & Rewarded, Banner 300x250, Banner 320x50, Native
Tapjoy12.8.0Fullscreen Rewarded
Unity Ads4.1.0Fullscreen Interstitial & Rewarded
Vungle6.10.6Fullscreen Interstitial & Rewarded
Google IMA3.13.0Preroll
Nimbus1.10.5Fullscreen Interstitial & Rewarded, Banner 300x250, Banner 320x50
TAM (Amazon Publisher Services)4.3.0Fullscreen Interstitial & Rewarded, Banner 300x250, Banner 320x50
Pangle3.7.0.8Fullscreen Interstitial & Rewarded, Banner 300x250, Banner 320x50, Native
Hyprmx6.0.0Fullscreen Interstitial & Rewarded, Banner 300x250, Banner 320x50
Yahoo1.14.2Fullscreen Interstitial, Banner 300x250, Banner 320x50

Getting Started

Start displaying Freestar Ads in your Unity game today by following the simple steps below.

Requirements

• Unity 2020 or newer

• Xcode 13 and iOS 11 or higher

Cocoapods

Begin

Please follow the instructions in order.

Make sure you switched to iOS:

Import FreestarMediation unitypackage

Unity Player Settings

Import FreestarMediation unitypackage

Other settings: Target minimum iOS version: 11.0

Other settings: Graphics API: Open GLES2

Other settings: Target SDK: Either Simulator SDK or Device SDK Unity iOS projects are generated for one or the other, but not both.

Import FreestarMediation unitypackage

Import FreestarMediation unitypackage

Import Custom Package

Download FreestarMediation.unitypackage

Next, we will import it into Unity as a Custom Package.

Import FreestarMediation unitypackage

Assets: Import Package: Custom Package

Import FreestarMediation unitypackage

Hit the Import button.

Additional Post Setup Steps

For certain project file type(s), it may be necessary to make manual changes to your Xcode project to make it build correctly.

  1. Add this line in the pod file and save it. Before saving you can exclude (by removing the pod dependencies) any mediation partners that you don’t want to integrate (Please contact your account manager for more details):
    Podfile:
    use_frameworks! :linkage => :static
    
  2. Run `pod install —-repo-update` to download and install the latest version.
  3. Open the `.xcworkspace` file by double clicking it.
  4. Go to:
    Pods → Target Support Files → Pods-UnityFramework → Pod-UnityFramework-resources.sh And delete below lines:
    install_resource "${BUILT_PRODUCTS_DIR}/FreestarAds/FreestarAds.framework/Freestar-Native-Medium.nib"
    install_resource "${BUILT_PRODUCTS_DIR}/FreestarAds/FreestarAds.framework/Freestar-Native-Small.nib"
    
    There could be more than one instance of these lines depending on the number of "$CONFIGURATION". Please make sure to delete these two lines from all configurations.
  5. Add `/usr/lib/swift` to your Run Search Paths Xcode build setting.
  6. Add and embed below shown frameworks.

  7. Go to -> Libraries -> com.unity.ads -> plugin -> iOS

    Select all files under this and deselect the ‘UnityFramework’ under target membership on right hand side.

Resolve iOS Dependencies

One of the files imported in the FreestarMediation package is the dependencies spec: Editor/FreestarMediationDependencies.xml. This will be used to generate the Podfile for the Xcode project. The relevant section is the following:

 <iosPods>
    <iosPod name="FreestarAds" version="~> 5.0"></iosPod>
    <iosPod name="FreestarAds-AdColony" version="~> 4.7"></iosPod>
    <iosPod name="FreestarAds-AppLovin" version="~> 11.0"></iosPod>
    <iosPod name="FreestarAds-AppLovinMax" version="~> 11.0"></iosPod>
    <iosPod name="FreestarAds-Tapjoy" version="~> 12.8"></iosPod>
    <iosPod name="FreestarAds-Googleadmob" version="~> 9.2"></iosPod>
    <iosPod name="FreestarAds-Googleadmob/Facebook" version="~> 9.2"></iosPod>
    <iosPod name="FreestarAds-GAM" version="~> 9.2"></iosPod>
    <iosPod name="FreestarAds-GAM/Facebook" version="~> 9.2"></iosPod>
    <iosPod name="FreestarAds-TAM" version="~> 4.3"></iosPod>
    <iosPod name="FreestarAds-Criteo" version="~> 4.3"></iosPod>
    <iosPod name="FreestarAds-Unity" version="~> 4.1"></iosPod>
    <iosPod name="FreestarAds-Vungle" version="~> 6.10"></iosPod>
    <iosPod name="FreestarAds-Pangle" version="~> 3.7"></iosPod>
  </iosPods>

You may wish to only include some ad partners. Remove or comment out the lines listing those you do not wish to use. However, the FreestarAds pod is required.

Freestar Initialization and Displaying Ads


Initialization

Within your Unity app, you need to initialize the Freestar SDK. After you imported the FreestarMediation package, you can use the C# code within by importing the Freestar namespace:

import Freestar;

Now you will be able to call methods in Freestar classes, the most important of which is the FreestarUnityBridge. You will need a Freestar API Key, and pass it to the initializer. For efficiency, it is best to do this as soon as possible within your app's lifecycle.

FreestarUnityBridge.initWithAPIKey(YOUR_API_KEY);

This will initialize the SDK and enable it to run ads. The Freestar Unity plugin supports two types of fullscreen ads: interstitial and rewarded, and banner ads in two sizes: 320x50 display points, and 300x250 display points.

Interstitial Ads

Interstitial ads take over the app, running in fullscreen, and allow return to the app upon completion. You can opt in to receive callbacks when key events occur in an ad's lifecycle, allowing you to make any changes necessary (such as pausing your game while the ad is playing). To do this, your Unity code needs to implement the FreestarInterstitialAdCallbackReceiver interface:

void onInterstitialAdLoaded(string placement);
void onInterstitialAdFailed(string placement);
void onInterstitialAdShown(string placement);
void onInterstitialAdClicked(string placement);
void onInterstitialAdDismissed(string placement);

And then pass in the object that implements this interface to FreestarUnityBridge:

FreestarUnityBridge.setInterstitialAdListener(this);

Finally, you request to load an ad:

FreestarUnityBridge.loadInterstitialAd (AD_PLACEMENT);

Note: there are additional detailes of what placements are and the format they need to be in our guide for native app integration. If you do not wish to use placements, simply pass in an empty string:

FreestarUnityBridge.loadInterstitialAd ("");

While implementing callbacks is optional, showing an ad before it's loaded will not work. The onInterstitialAdLoaded callback informs your unity code when the ad is ready. You can now make the following call:

FreestarUnityBridge.showInterstitialAd (AD_PLACEMENT);

Make sure the placement strings match, if you are using more than one placement. The ad will now take over the app, and make the appropriate callbacks; the onInterstitialAdDismissed is sent when the ad returns control back to the app.

Rewarded Ads

Rewarded ads behave like interstitial ads, but are augmented with an incentivization mechanism. Typically, the user is rewarded by in-app virtual currency upon completion of the ad. The currency and amount are under your control, and thus need to be passed to FreestarUnityBridge.

To do this, your Unity code needs to implement the FreestarRewardedAdCallbackReceiver interface:

void onRewardedAdLoaded(string placement);
void onRewardedAdFailed(string placement);
void onRewardedAdShown(string placement);
void onRewardedAdFinished(string placement);
void onRewardedAdDismissed(string placement);

And then pass in the object that implements this interface to FreestarUnityBridge:

FreestarUnityBridge.setRewardedAdListener(this);

Finally, you request to load an ad:

FreestarUnityBridge.loadRewardedAd (AD_PLACEMENT);

While implementing callbacks is optional, showing an ad before it's loaded will not work. The onRewardedAdLoaded callback informs your unity code when the ad is ready. You can now make the following call:

FreestarUnityBridge.showRewardedAd (
  AD_PLACEMENT, //use "" if you don't need multiple placements
  50,           //reward amount
  "Coins",      //reward name
  "Freestar1"   //User ID, use "" if not utilized
  "SECRET_KEY"  //An optional secret for greater security, use "" if not utilized
);

Make sure the placement strings match, if you are using more than one placement. The ad will now take over the app, and make the appropriate callbacks; the onRewardedAdDismissed is sent when the ad returns control back to the app.

The onRewardedAdFinished is called before the dismissed callback, and may be called when the ad is still playing. It is an indicator that the reward for the ad may now be given to the app user.

Banner Ads

Banner ads are displayed on top of the app, and only obscure it partially, rather than taking over the screen entirely. Freestar allows you to display either small (320x50) or medium (300x250) banners, and to choose to show them at the top, bottom, or middle of the device screen. You can also receive callbacks for key events in the ad's lifecycle.

To do this, your Unity code needs to implement the FreestarBannerAdCallbackReceiver interface:

void onBannerAdShowing(string placement, int adSize);
void onBannerAdClicked(string placement, int adSize);
void onBannerAdFailed(string placement, int adSize);

And then pass in the object that implements this interface to FreestarUnityBridge:

FreestarUnityBridge.setBannerAdListener(this);

Finally, you request the ad. There are no separate load and show calls:

FreestarUnityBridge.ShowBannerAd(
  "", //the placement string -- empty if you don't use multiple placements
  FreestarConstants.BANNER_AD_SIZE_320x50,  //banner size
  FreestarConstants.BANNER_AD_POSITION_TOP  //position
);

The ad will load and display automatically at the appropriate position. When you no longer need it, you can remove it:

FreestarUnityBridge.CloseBannerAd("",FreestarConstants.BANNER_AD_SIZE_320x50);

Make sure the placement string and size you pass in match.

Working sample

Take a look at the sample project and specifically its Main.cs class.

This working sample shows how to initialize, implement the ad listeners, and show fullscreen Interstitial, Rewarded, and banner ads. SampleScene.scene is also included.

Some publishers like to create a singleton class based on this sample. Utilize it as you see fit.

The generated project

After creating the app flow in Unity, you can have it generate an Xcode project: File->Build Settings will open the settings window, with a Build button. This will only work on a Mac that has Xcode and Cocoapods installed; you will be prompted for a save location, and Unity will create an Xcode project. Within the generated folder, make sure to open the .xcworkspace file. You will now have a generated Xcode project capable of building a working iOS app with Freestar Ads integrated.

However, there are several things to keep in mind. If, in the FreestarMediationDependencies.xml file (see above), you've asked to include either FreestarAds-Googleadmob or FreestarAds-GAM pods, you will need to modify the generated app's Info.plist file to include the following:

<key>GADApplicationIdentifier</key>
<string>{YOUR_ADMOB_KEY}</string>

The key is obtained from Google, without it, an app that integrates either of its Ad SDKs cannot run.

There are also potential build errors due to Unity-iOS compatibility issues, that depend on the version of Unity and Xcode involved. Two known ones are resolved as follows:

A Metal compatibility problem

Some version of Unity generate invalid Metal-related code; this produces a compilation error when attempting to build the app in the MetalHelper.mm file. The issue can be resolved by commenting out the following section:

#if PLATFORM_IOS || PLATFORM_TVOS
    if (@available(iOS 10.3, tvOS 10.2, *))
    {
        const int targetFPS = UnityGetTargetFPS(); assert(targetFPS > 0);
        [UnityCurrentMTLCommandBuffer() presentDrawable: surface->drawable afterMinimumDuration: 1.0 / targetFPS];
        return;
    }
#endif

There is a fallback outside the macro, so the removal of the code does not break the rest of the architecture.

An Unity 2018 problem

iOS apps generated with Unity 2018 will not build for the simulator in recent versions of Xcode. Builds for device work correctly.

A module header problem

Unity Xcode projects are generated with modules disabled, this means convenience headers in the style:

@import UIKit;

don't work. Some versions of the FreestarAds SDK include such a declaration in the FreestarPrerollAd.h header. Xcode will flag the compiler error, the solution is to open the header and replace the statement:

@import AVKit;

With the equivalent:

#import <AVKit/AVKit.h>

Now, the Xcode will build the app and you can run it on your device or simulator as if it was a native app.

Important iOS 14 Changes

One thing you must do as a publisher is set the Facebook setAdvertiserTrackingEnabled flag appropriately, since Facebook is one of our partners. Here is the official document from Facebook. Generally speaking, one typical you could approach this is if the user has granted the app permission to track them at the OS level, then you would set this flag to true. By default, the flag will be false, meaning that Facebook will not serve any ads. We leave this implementation detail to you in order to give you, the app publisher, more control.

GDPR Update

We are releasing a major update to the Freestar SDK later this week that will require publishers to utilize a GDPR TCF 2.0 compliant CMP in order to render ads to users in a GDPR affected country. If the publisher is not utilizing a GDPR TCF 2.0 compliant CMP once upgraded to this SDK version, then ads will not serve to users in a GDPR affected country.

We put together a comprehensive list of FAQs below to help break down how the changes may impact your business. If you have additional questions, please reach out to your dedicated Account Manager and we will be happy to help on a case by case basis.

What is the new SDK version?

4.0.0 for iOS and Android

How do I become GDPR compliant?

In order to be able to serve ads to your users who reside in any EU country, you will need to implement an IAB TCF 2.0 CMP service.

The CMP service is essentially a personal data and privacy form that must be presented to users to collect their consent or dissent. This form can be presented as often as you like throughout the session of your game or app, as you may require your users to see ads. The most typical setup would be for the first visit to an App with an option to edit your preferences through some other call to action.

What if I already have a CMP implemented?

If you already have a CMP implemented, you will need to add Publisher First, Inc. (Freestar’s official legal entity) as a vendor, as well as each of our partners listed here if not already included.

You will need to retrigger the consent form for GDPR affected users once Freestar and additional vendors are added to the vendor list.

If the list of vendors has already been included, no additional effort is required.

How does the Freestar SDK work with a CMP?

Freestar SDK will automatically detect the user's CMP response and act accordingly. More specifically, if the user consents, then Freestar SDK will be allowed to serve ads. If the user dissents, then Freestar SDK will not show ads.

What if I choose not to implement a CMP?

If a CMP is not implemented at all, then Freestar SDK will not show ads to users who reside in a GDPR affected country.

What do I need to do once I choose a CMP?

After you have chosen a CMP Service provider, during configuration and setup of your CMP, you will need to include a list of supported vendors. We recommend that you select ‘Include All Vendors’ rather than choosing specific vendors, as your list of vendors may change over time.

If you choose to add vendors to your list manually, you will need to include Publisher First, Inc. (Freestar’s official legal entity) as a vendor as well as Freestar’s list of supported vendors here.

Does Great Britain still observe GDPR requirements despite leaving the E.U.?

Yes, it does still apply. In anticipation of Brexit, a new domestic data privacy law called the UK-GDPR took effect on 1/31/20. The UK-GDPR is almost word for word completely identical to the EU’s GDPR.

CMP Recommendations:

Consent Manager - https://www.consentmanager.net/ App Consent - https://sfbx.io/en/produits/

Here is a list of IAB approved CMP Service providers you can implement in your game or app: https://iabeurope.eu/cmp-list/

Testing

For iOS, please use our iOS test key 91784edd-3492-4111-8742-f71bd3803dd3 (we have a different key for Android, so don't use for both iOS and Android) for all your iOS testing runs and enable test mode.

Turn on test mode:

FSTR_TEST_ADS
    

You will usually get 100% fill on all ad units.

It is not recommended to use your production key for testing runs as that is strictly prohibited by our partners and bad things may happen to us on the business side of things.
Do not forget to uninstall and re-install your app when changing keys on your device.

When you are satisfied with your testing, please make a release build with your production key, and turn test mode off. Publish to store.

SKAdNetwork IDs

iOS 14 changed the way advertising works on iOS devices. Ad effectiveness tracking requires the usage of SKAdNetwork APIs. To enable this, SKAdNetwork keys should be included in your app's Info.plist file.

Please see our list: https://github.com/freestarcapital/SDK_documentation_iOS/wiki/iOS-14-SKAdNetwork-IDs

M1 Macs

Currently, we do not support the building of our SDK on M1 macs. This will be addressed in an upcoming release.

Xcode 12 related cocoapods build errors

Recently, in Xcode 12.2, Apple made some breaking changes in Xcode related to build settings. By default, arm64 architecture is now added to ARCHS_STANDARD. In addition, they have removed support for VALID_ARCHS setting from Xcode. Apple also added, in Xcode 12, a new build setting called Excluded Architectures. The reason Apple added arm64 is to support simulator on M1 Mac hardware. However this causes build issues running simulator on Intel Macs. As a result, publishers running Xcode on Intel Macs will need to make usage of the EXCLUDED_ARCHS build setting, for simulator testing, to exclude the arm64 simulator. So, if your Xcode build is failing with arm64 simulator errors in the log, such as:

building for iOS Simulator, but linking in object file built for iOS, file for architecture arm64

then, it is suggested to use this cocoapods post install hook in your Podfile:

  post_install do |installer|
      installer.pods_project.build_configurations.each do |config|
          config.build_settings["EXCLUDED_ARCHS[sdk=iphonesimulator*]"] = "arm64"
      end
  end

This is a temporary fix and should address the issue of build failures resulting from Xcode attempting to build (arm64) simulator on Intel Macs. As of our latest SDK release, we do this automatically in the podspec via xcconfigs, however not every SDK vendor has adopted this workaround. This post install hook is only needed if you are running Xcode 12 on Intel hardware and wanting to run simulator, and you have a cocoapods dependency that is not Xcode 12 / arm64 compliant.

Firebase Dependency

If your app integrated the Firebase SDK, reference the Firebase version compatible with current release 7.0

pod 'Firebase/Core', '~> 7.0'

For further reference:
https://github.com/CocoaPods/CocoaPods/issues/10104
https://stackoverflow.com/questions/63607158/xcode-12-building-for-ios-simulator-but-linking-in-object-file-built-for-ios/63955114#63955114

Yahoo Demand Partner Configuration

If Yahoo is being added as a demand partner in your Podfile, then it is required to add an entry into your Info.plist. See example below:

<key>VerizonAdsSourceAppId</key>
<string>Replace_this_with_your_App's_App_Store_ID</string>

GAM and Googleadmob OB adapters

If you would like to make usage of Google Open Bidding (OB) adapters for FreestarAds, please contact your account manager (AM) for further instructions. We do not advise including OB adapters into your project without first consulting with your AM.

Freestar Ads Mediation Cordova iOS

Freestar Ads Mediation - Cordova Integration Guide for iOS

Supported Ad Partners

Note: The supported list for Cordova may differ from our Native iOS

Ad ProviderSDK VersionAd Unit Types
AdColony4.7.2Fullscreen Interstitial & Rewarded
AppLovin10.1.1Fullscreen Interstitial & Rewarded, Banner 300x250, Banner 320x50
Admob8.12.0Fullscreen Interstitial & Rewarded, Banner 300x250, Banner 320x50, Native
Google Ads Manager8.12.0Fullscreen Interstitial & Rewarded, Banner 300x250, Banner 320x50, Native
MoPub (deprecated)5.18.2Fullscreen Interstitial & Rewarded, Banner 300x250, Banner 320x50, Native
Tapjoy12.8.0Fullscreen Interstitial & Rewarded
Unity Ads3.7.2Fullscreen Interstitial & Rewarded, Banner 320x50
Vungle6.10.3Fullscreen Interstitial & Rewarded
TAM (Amazon Publisher Services)4.0.0Fullscreen Interstitial, Banner 300x250, Banner 320x50
Pangle3.7.0.8Fullscreen Interstitial & Rewarded, Banner 300x250, Banner 320x50, Native
Hyprmx6.0.0Fullscreen Interstitial & Rewarded, Banner 300x250, Banner 320x50

Getting Started

Apache Cordova is a metaplatform for developing mobile apps with Javascript. This document will instruct you how to deliver Freestar Ads in mobile apps built with Cordova. Start displaying Freestar Ads in your Cordova app today by following the simple steps below.

Requirements

• NPM 6 or newer

• Cordova 9 or newer

• iOS SDK with Xcode for iOS 10 or higher

Cocoapods

Begin

Please follow the instructions in order.

Go to your cordova app directory in a terminal and add the Freestar Cordova plugin:

$ cordova plugin add @freestar/cordova-plugin-freestar

If you do not wish to integrate every advertising partner, edit the following section of the node_modules/cordova-plugin-freestar/plugin.xml file so that only the partners you wish to include are listed:

<pods use-frameworks="true">
              <pod name="FreestarAds" spec="~> 5.3" />
              <pod name="FreestarAds-AdColony" spec="~> 5.1" />
              <pod name="FreestarAds-AppLovin" spec="~> 5.1" />
              <pod name="FreestarAds-Googleadmob" spec="~> 6.1" />
              <pod name="FreestarAds-Tapjoy" spec="~> 5.0" />
              <pod name="FreestarAds-Unity" spec="~> 6.0" />
              <pod name="FreestarAds-Vungle" spec="~> 5.2" />
              <pod name="FreestarAds-GAM" spec="~> 5.1" />
              <pod name="FreestarAds-TAM" spec="~> 2.2" />
              <pod name="FreestarAds-Pangle" spec="~> 1.1" />
              <pod name="FreestarAds-Hyprmx" spec="~> 1.0" />
              <pod name="FreestarAds-Mopub" spec="~> 5.1" /> (deprecated)
            </pods>

Freestar Ads require an API key to deliver ads. Once you obtain the key, make sure it is added to the app's Info.plist file in the generated iOS app. You can either edit the plist directly after the app is generated, or modify the Cordova app's config.xml file:

<platform name="ios">
  <edit-config target="com.freestar.ios.ads.API_KEY" file="*-Info.plist" mode="merge">
    <string>YOUR_API_KEY</string>
  </edit-config>
</platform>

If, in the list of partners describes above, you've asked to include either FreestarAds-Googleadmob or FreestarAds-GAM pods, you will also need to modify the generated app's Info.plist file to include Google's ad API key:

<edit-config target="GADApplicationIdentifier" file="*-Info.plist" mode="merge">
    <string>YOUR_ADMOB_KEY</string>
</edit-config>

Once all the changes are made, you can generate the iOS app from your cordova codebase:

$ cordova platform add ios

Opening the .xcworkspace file in the generated project with Xcode will allow you to run the app on the iOS simulator or device.

Displaying Ads

If the Freestar Cordova plugin was succesfully integrated, its apis will be accessible via the window.plugins.freestarPlugin object.

Interstitial Ads

Interstitial ads take over the app, running in fullscreen, and allow return to the app upon completion. You can opt in to receive callbacks when key events occur in an ad's lifecycle, allowing you to make any changes necessary (such as pausing your game while the ad is playing). To do this, your Cordova code needs to add event listeners to the corresponding ad events:

document.addEventListener('onInterstitialLoaded', onInterstitialLoaded, false);
document.addEventListener('onInterstitialFailed', onInterstitialFailed, false);
document.addEventListener('onInterstitialShown', onInterstitialShown, false);
document.addEventListener('onInterstitialClicked', onInterstitialClicked, false);
document.addEventListener('onInterstitialDismissed', onInterstitialDismissed, false);

Then, you request to load an ad:

window.plugins.freestarPlugin.loadInterstitialAd(AD_PLACEMENT);

Note: there are additional details of what placements are and the format they need to be in our guide for native app integration. If you do not wish to use placements, simply pass in null:

window.plugins.freestarPlugin.loadInterstitialAd(null);

While implementing callbacks is optional, showing an ad before it's loaded will not work. The onInterstitialAdLoaded callback informs your Cordova code when the ad is ready. You can now make the following call:

window.plugins.freestarPlugin.showInterstitialAd(AD_PLACEMENT);

Make sure the placement strings match, if you are using more than one placement. The easiest way to do this is to show the ad from within the onInterstitialAdLoaded callback you added as an event listener for that event:

function onInterstitialLoaded(data) {
    window.plugins.freestarPlugin.showInterstitialAd(data.placement);
}

The ad will now take over the app, and make the appropriate callbacks; the onInterstitialAdDismissed is sent when the ad returns control back to the app.

Rewarded Ads

Rewarded ads behave like interstitial ads, but are augmented with an incentivization mechanism. Typically, the user is rewarded by in-app virtual currency upon completion of the ad. The currency and amount are under your control, and thus need to be passed to window.plugins.freestarPlugin.

To do this, your Cordova code needs to add event listeners to the rewarded ad events:

document.addEventListener('onRewardedVideoLoaded', onRewardedVideoLoaded, false);
document.addEventListener('onRewardedVideoFailed', onRewardedVideoFailed, false);
document.addEventListener('onRewardedVideoShown', onRewardedVideoShown, false);
document.addEventListener('onRewardedVideoShownError', onRewardedVideoShownError, false);
document.addEventListener('onRewardedVideoCompleted', onRewardedVideoCompleted, false);
document.addEventListener('onRewardedVideoDismissed', onRewardedVideoDismissed, false);

And then request to load an ad:

window.plugins.freestarPlugin.loadRewardedAd(null);

While implementing callbacks is optional, showing an ad before it's loaded will not work. The onRewardedVideoLoaded callback informs your Cordova code when the ad is ready. You can now make the following call:

window.plugins.freestarPlugin.showRewardedAd(
  AD_PLACEMENT, 
  "MySecret1234", //secret key 
  "MyUserId",     //user id
  "Gold Coins",   //reward name
  "100"           //reward amount
  );

Make sure the placement strings match, if you are using more than one placement. The ad will now take over the app, and make the appropriate callbacks; the onRewardedVideoDismissed is sent when the ad returns control back to the app.

The onRewardedVideoCompleted is called before the dismissed callback, and may be called when the ad is still playing. It is an indicator that the reward for the ad may now be given to the app user.

Banner Ads

Banner ads are displayed on top of the app, and only obscure it partially, rather than taking over the screen entirely. Freestar allows you to display either small (320x50) or medium (300x250) banners, and to choose to show them at the top, bottom, or middle of the device screen. You can also receive callbacks for key events in the ad's lifecycle.

To do this, your Cordova code needs to add event listeners to the rewarded ad events:

document.addEventListener('onBannerAdFailed', onBannerAdFailed, false);
document.addEventListener('onBannerAdShown', onBannerAdShown, false);
document.addEventListener('onBannerAdClicked', onBannerAdClicked, false);
document.addEventListener('onBannerAdDismissed', onBannerAdDismissed, false);

And then request the ad. There are no separate load and show calls:

window.plugins.freestarPlugin.showBannerAd(
  null, //the placement string -- null if you don't use multiple placements
  window.plugins.freestarPlugin.BANNER_AD_SIZE_320x50, //banner size
  window.plugins.freestarPlugin.BANNER_AD_SIZE_320x50  //banner position
);

The ad will load and display automatically at the appropriate position. When you no longer need it, you can remove it:

window.plugins.freestarPlugin.closeBannerAd(null, window.plugins.freestarPlugin.BANNER_AD_SIZE_300x250);

Make sure the placement string and size you pass in match.

Working sample

Take a look at the sample project and specifically its www/index.js file.

This working sample shows how to initialize, implement the ad listeners, and show fullscreen Interstitial, Rewarded, and banner ads.

Important iOS 14 Changes

One thing you must do as a publisher is set the Facebook setAdvertiserTrackingEnabled flag appropriately, since Facebook is one of our partners. Here is the official document from Facebook. Generally speaking, one typical you could approach this is if the user has granted the app permission to track them at the OS level, then you would set this flag to true. By default, the flag will be false, meaning that Facebook will not serve any ads. We leave this implementation detail to you in order to give you, the app publisher, more control.

GDPR Update

We are releasing a major update to the Freestar SDK later this week that will require publishers to utilize a GDPR TCF 2.0 compliant CMP in order to render ads to users in a GDPR affected country. If the publisher is not utilizing a GDPR TCF 2.0 compliant CMP once upgraded to this SDK version, then ads will not serve to users in a GDPR affected country.

We put together a comprehensive list of FAQs below to help break down how the changes may impact your business. If you have additional questions, please reach out to your dedicated Account Manager and we will be happy to help on a case by case basis.

What is the new SDK version?

4.0.0 for iOS and Android

How do I become GDPR compliant?

In order to be able to serve ads to your users who reside in any EU country, you will need to implement an IAB TCF 2.0 CMP service.

The CMP service is essentially a personal data and privacy form that must be presented to users to collect their consent or dissent. This form can be presented as often as you like throughout the session of your game or app, as you may require your users to see ads. The most typical setup would be for the first visit to an App with an option to edit your preferences through some other call to action.

What if I already have a CMP implemented?

If you already have a CMP implemented, you will need to add Publisher First, Inc. (Freestar’s official legal entity) as a vendor, as well as each of our partners listed here if not already included.

You will need to retrigger the consent form for GDPR affected users once Freestar and additional vendors are added to the vendor list.

If the list of vendors has already been included, no additional effort is required.

How does the Freestar SDK work with a CMP?

Freestar SDK will automatically detect the user's CMP response and act accordingly. More specifically, if the user consents, then Freestar SDK will be allowed to serve ads. If the user dissents, then Freestar SDK will not show ads.

What if I choose not to implement a CMP?

If a CMP is not implemented at all, then Freestar SDK will not show ads to users who reside in a GDPR affected country.

What do I need to do once I choose a CMP?

After you have chosen a CMP Service provider, during configuration and setup of your CMP, you will need to include a list of supported vendors. We recommend that you select ‘Include All Vendors’ rather than choosing specific vendors, as your list of vendors may change over time.

If you choose to add vendors to your list manually, you will need to include Publisher First, Inc. (Freestar’s official legal entity) as a vendor as well as Freestar’s list of supported vendors here.

Does Great Britain still observe GDPR requirements despite leaving the E.U.?

Yes, it does still apply. In anticipation of Brexit, a new domestic data privacy law called the UK-GDPR took effect on 1/31/20. The UK-GDPR is almost word for word completely identical to the EU’s GDPR.

CMP Recommendations:

Consent Manager - https://www.consentmanager.net/ App Consent - https://sfbx.io/en/produits/

Here is a list of IAB approved CMP Service providers you can implement in your game or app: https://iabeurope.eu/cmp-list/

Testing

For iOS, please use our iOS test key 91784edd-3492-4111-8742-f71bd3803dd3 (we have a different key for Android, so don't use for both iOS and Android) for all your iOS testing runs and enable test mode.

Turn on test mode:

FSTR_TEST_ADS
    

You will usually get 100% fill on all ad units.

It is not recommended to use your production key for testing runs as that is strictly prohibited by our partners and bad things may happen to us on the business side of things.
Do not forget to uninstall and re-install your app when changing keys on your device.

When you are satisfied with your testing, please make a release build with your production key, and turn test mode off. Publish to store.

SKAdNetwork IDs

iOS 14 changed the way advertising works on iOS devices. Ad effectiveness tracking requires the usage of SKAdNetwork APIs. To enable this, SKAdNetwork keys should be included in your app's Info.plist file.

Please see our list: https://github.com/freestarcapital/SDK_documentation_iOS/wiki/iOS-14-SKAdNetwork-IDs

M1 Macs

Currently, we do not support the building of our SDK on M1 macs. This will be addressed in an upcoming release.

Xcode 12 related cocoapods build errors

Recently, in Xcode 12.2, Apple made some breaking changes in Xcode related to build settings. By default, arm64 architecture is now added to ARCHS_STANDARD. In addition, they have removed support for VALID_ARCHS setting from Xcode. Apple also added, in Xcode 12, a new build setting called Excluded Architectures. The reason Apple added arm64 is to support simulator on M1 Mac hardware. However this causes build issues running simulator on Intel Macs. As a result, publishers running Xcode on Intel Macs will need to make usage of the EXCLUDED_ARCHS build setting, for simulator testing, to exclude the arm64 simulator. So, if your Xcode build is failing with arm64 simulator errors in the log, such as:

building for iOS Simulator, but linking in object file built for iOS, file for architecture arm64

then, it is suggested to use this cocoapods post install hook in your Podfile:

  post_install do |installer|
      installer.pods_project.build_configurations.each do |config|
          config.build_settings["EXCLUDED_ARCHS[sdk=iphonesimulator*]"] = "arm64"
      end
  end

This is a temporary fix and should address the issue of build failures resulting from Xcode attempting to build (arm64) simulator on Intel Macs. As of our latest SDK release, we do this automatically in the podspec via xcconfigs, however not every SDK vendor has adopted this workaround. This post install hook is only needed if you are running Xcode 12 on Intel hardware and wanting to run simulator, and you have a cocoapods dependency that is not Xcode 12 / arm64 compliant.

Firebase Dependency

If your app integrated the Firebase SDK, reference the Firebase version compatible with current release 7.0

pod 'Firebase/Core', '~> 7.0'

For further reference:
https://github.com/CocoaPods/CocoaPods/issues/10104
https://stackoverflow.com/questions/63607158/xcode-12-building-for-ios-simulator-but-linking-in-object-file-built-for-ios/63955114#63955114

Yahoo Demand Partner Configuration

If Yahoo is being added as a demand partner in your Podfile, then it is required to add an entry into your Info.plist. See example below:

<key>VerizonAdsSourceAppId</key>
<string>Replace_this_with_your_App's_App_Store_ID</string>

GAM and Googleadmob OB adapters

If you would like to make usage of Google Open Bidding (OB) adapters for FreestarAds, please contact your account manager (AM) for further instructions. We do not advise including OB adapters into your project without first consulting with your AM.

Freestar Flutter Plugin

Welcome to the freestar_flutter_plugin wiki!

The latest version of our plugin can be found here.

Add Freestar Ads Mediation to your Flutter app. Supported on Android and iOS platforms.

Run our sample

A great way to become familiar with Freestar mediation is to run our sample app.

  1. If not already done so, install the Flutter development environment by Google!

  2. Connect an Android device to your computer. (Don't worry, the plugin also supports iOS!)

  3. Open command-shell or terminal window and:

git clone https://github.com/freestarcapital/freestar_flutter_plugin
cd freestar_flutter_plugin/example
flutter run

Getting Started

Follow these steps to integrate Freestar Flutter plugin (freestar_flutter_plugin) package into your Flutter app. The first step will be Dart setup. The Android and iOS sub-sections will follow.

Dart Setup

The following are essentially excerpts from our example main.dart Please take a look to see how easy it is to integrate Freestar mediation.

Initialize Freestar

import 'package:freestar_flutter_plugin/freestar_flutter_plugin.dart';

In your initState method, setup Freestar with the following test keys:

FreestarFlutterPlugin.enableLogging(true);        //set false for production
FreestarFlutterPlugin.enableTestMode(true);       //set false for production
FreestarFlutterPlugin.enablePartnerChooser(true); //set false for production

if (defaultTargetPlatform == TargetPlatform.android) {
  FreestarFlutterPlugin.init("XqjhRR"); //Android Test Key
} else if (defaultTargetPlatform == TargetPlatform.iOS) {
  FreestarFlutterPlugin.init("P8RIA3");  //iOS Test Key
}

Interstitial Ad (Fullscreen ad)

Make sure to implement the InterstitialAdListener interface. For example:

class _MyAppState extends State<MyApp>
    implements InterstitialAdListener

Declare/Instantiate InterstitialAd

InterstitialAd _interstitialAd = new InterstitialAd(); 

// Another way:
InterstitialAd _interstitialAd = InterstitialAd.from('optional-placement', myInterstitialAdListener); 

// Loading
_interstitialAd.interstitialAdListener = myInterstitialAdListener; //if not already set, do so before calling loadAd
_interstitialAd.placement = 'optional-placement';  //optional placement or simply omit if not needed

//optional targeting parameters
Map targetingParams = Map();
targetingParams["my-targeting-param1"] = "example value 1";
targetingParams["my-targeting-param2"] = "example value 2";
_interstitialAd.targetingParams = targetingParams; //optional targeting params or simply omit if not needed

_interstitialAd.loadAd();  //fetches highest-paying mediation partner ad-fill

When you receive the onInterstitialAdLoaded callback, the interstitial ad is ready to be shown:

_interstitialAd.showAd();  //Display fullscreen interstitial ad

Rewarded Ad (Fullscreen ad)

Make sure to implement the RewardedAdListener interface. For example:

class _MyAppState extends State<MyApp>
    implements RewardedAdListener

Declare/Instantiate RewardedAd

RewardedAd _rewardedAd = new RewardedAd(); 

// Another way:
RewardedAd _rewardedAd = RewardedAd.from('optional-placement', myRewardedAdListener); 

// Loading
_rewardedAd.rewardedAdListener = myRewardedAdListener; //if not already set, do so before calling loadAd
_rewardedAd.placement = 'optional-placement';  //optional placement or simply omit if not needed

//optional targeting parameters
Map targetingParams = Map();
targetingParams["my-targeting-param1"] = "example value 1";
targetingParams["my-targeting-param2"] = "example value 2";
_rewardedAd.targetingParams = targetingParams; //optional targeting params or simply omit if not needed

_rewardedAd.loadAd();  //fetches highest-paying mediation partner ad-fill

When you receive the onRewardedAdLoaded callback, the Rewarded ad is ready to be shown:


//secret - the secret string you want to secure your reward with
//userId - your user id string.  can use empty string ""
//rewardType - can be "Gold" or "Coins" or whatever your virtual currency may be!
//rewardAmount - whatever string amount your user will be rewarded with

_rewardedAd.showAd("my-secret-12345", "myUserId-12345", "V-Bucks", "100");  //Display fullscreen Rewarded ad

When 'onRewardedAdCompleted' is called, this indicates the user has completed viewing the fullscreen rewarded to the end.

Banner Ad

The following banner ad sizes are supported:

BannerAd.AD_SIZE_BANNER_320x50
BannerAd.AD_SIZE_MREC_300x250
BannerAd.AD_SIZE_LEADERBOARD_728x90   (for tablet devices)

Make sure to implement the BannerAdListener interface. For example:

class _MyAppState extends State<MyApp>
    implements BannerAdListener

Declare/Instantiate BannerAd

BannerAd _bannerAd = new BannerAd(); 

// Another way:
BannerAd _bannerAd = BannerAd.from('optional-placement', BannerAd.AD_SIZE_BANNER_320x50, myRewardedAdListener, false);

//The last parameter is `doAutoloadWhenCreated` (see below for reference)

Add BannerAd to your UI

Add the BannerAd to your Scaffold or UI hierarchy:

_bannerAd.bannerAdListener = myBannerAdListener;    //set listener, if not already set
_bannerAd.adSize = BannerAd.AD_SIZE_BANNER_320x50;  //set the banner ad size, if not already not
_bannerAd.doAutoloadWhenCreated = true;  //displays the banner ad as soon as UI is initialized and do not need to call bannerAd.loadAd

//Small banner ad example:
Container(width: 320.0,  //explicitly set the physical container size appropriately
          height: 50.0,
          child: _bannerAd)

//MREC banner ad example:
Container(width: 300.0,  //explicitly set the physical container size appropriately
          height: 250.0,
          child: _mrecBannerAd)

Banner ad also supports optional targeting parameters:

Map targetingParams = Map();
targetingParams["my-targeting-param1"] = "example value 1";
targetingParams["my-targeting-param2"] = "example value 2";
_bannerAd.targetingParams = targetingParams; //optional targeting params or simply omit if not needed

_bannerAd.loadAd();  //fetches highest-paying mediation partner ad-fill

When the a fill is received, the BannerAd will automatically display in the position where it was added to the UI and onBannerAdLoaded will be called.

Native Ad

Native Ads are supported. Out of the box, native ads support two general sizes:

NativeAd.NATIVE_TEMPLATE_SMALL    AND
NativeAd.NATIVE_TEMPLATE_MEDIUM

Make sure to implement the NativeAdListener interface. For example:

class _MyAppState extends State<MyApp>
    implements NativeAdListener

Declare/Instantiate NativeAd

NativeAd _nativeAd = new NativeAd(); 

// Another way:
NativeAd _nativeAd = NativeAd.from('optional-placement', NativeAd.NATIVE_TEMPLATE_SMALL, myNativeAdListener, false);

//The last parameter is `doAutoloadWhenCreated` (see below for reference)

Add NativeAd to your UI

Add the NativeAd to your Scaffold or UI hierarchy:

_nativeAd.nativeAdListener = myNativeAdListener;    //set listener, if not already set
_nativeAd.adSize = NativeAd.NATIVE_TEMPLATE_SMALL;  //set the native ad size, if not already not
_nativeAd.doAutoloadWhenCreated = true;  //displays the native ad as soon as UI is initialized and do not need to call nativeAd.loadAd

//Small template native ad example:
Container(width: window.physicalSize.width,  //fullscreen width
          height: 100.0,  //100.0 is the small native ad height
          child: _smallNativeAd)

//Medium template native ad example:
Container(width: window.physicalSize.width,  //fullscreen width
          height: 350.0,  //350.0 is the medium native ad height
          child: _mediumNativeAd)

Native ad also supports optional targeting parameters:

Map targetingParams = Map();
targetingParams["my-targeting-param1"] = "example value 1";
targetingParams["my-targeting-param2"] = "example value 2";
_nativeAd.targetingParams = targetingParams; //optional targeting params or simply omit if not needed

_nativeAd.loadAd();  //fetches highest-paying mediation partner ad-fill

When the a fill is received, the NativeAd will automatically display in the position where it was added to the UI and onNativeAdLoaded will be called.

Android Setup

Add this section to your app AndroidManifest.xml. More specifically, just the meta-data tags. Using our example, the path would be: freestar_flutter_plugin/example/android/app/src/main/AndroidManifest.xml

When done, you may run your Flutter app on a connected Android device!

Android Proguard

When creating a release version of your Android app, make sure to use our proguard-rules.pro from our flutter sample ads app.

Android plugin dependencies

See our plugin gradle dependencies here

iOS Setup

The flutter build ios command in the terminal will generate an Xcode project from your Flutter app. The generated folder (example/ios) in this repo will include:

  • An .xcworkspace file
  • An .xcproject file
  • {YOUR_APP_NAME} folder containing generated native code
  • Podfile file
  • Podfile.lock file
  • Pods folder

The last three relate to the CocoaPods system, used both by Flutter and by Freestar to manage iOS library dependencies. To complete the setup, you will need to edit the Podfile with the following changes:

  1. Specify the iOS version: platform :ios, '10.0'. This is the minimum supported version. Freestar supports iOS 10.0 and above.
  2. In the target '{YOUR_APP_NAME}' section, list the advertsing partners from which you would like to see ads:
  pod 'FreestarAds-AdColony', '~> 5.0'
  pod 'FreestarAds-AppLovin', '~> 5.0'
  pod 'FreestarAds-Googleadmob', '~> 6.0'
  pod 'FreestarAds-Tapjoy', '~> 5.0'
  pod 'FreestarAds-Unity', '~> 6.0'
  pod 'FreestarAds-Vungle', '~> 5.0'
  pod 'FreestarAds-Criteo', '~> 3.0'
  pod 'FreestarAds-GAM', '~> 5.0'
  pod 'FreestarAds-Mopub', '~> 5.0'
  pod 'FreestarAds-Nimbus', '~> 3.0'
  pod 'FreestarAds-TAM', '~> 2.0'
  pod 'FreestarAds-Pangle', '~> 1.0'
  pod 'FreestarAds-Hyprmx', '~> 1.0'



Once you made the changes, save the Podfile, enter the ios directory in the terminal, and re-run pod install. Then open the {YOUR_APP_NAME}.xcworkspace file with Xcode.

The generated project will include an Info.plist file. If, when editing your Podfile (see above), you included either FreestarAds-Googleadmob or FreestarAds-GAM in the partner list, you will need to add your Google Application Identifier (received from Google) to the Info.plist; the app will not function without this:

<key>GADApplicationIdentifier</key>
<string>ca-app-pub-3940256099942544~1458002511</string>

There are also two flags that you can add to the plist to aid in development. To see test ads:

<key>CHP_TEST_ADS</key>
<string>enable</string>

Test ads do not generate revenue, remove this flag before submitting the app to the App Store.

To generate detailed logging from the Freestar SDK:

<key>CHP_LOGGING_ENABLE</key>
<string>true</string>
❗⚠Warning: For both performance and security reasons, it is not advisable to have detailed logging in production apps. Remove the flag in the Info.plist before submitting to the App Store.

When done, you may run your Flutter app on a connected iOS device!

Summary

Integrating Freestar Flutter plugin to display ads in your Flutter app is easy. As mentioned, please see our example main.dart