SDK DocumentationRecipesAnnouncementsSupport Forum
AndroidiOSAnnouncementsSupport Forum

Basic Integration

iOS Classic - Basic Integration

πŸ“

You are viewing the V3 docs. (For the V2 docs, go here.)

βœ…

While reading the documentation, take a look at our Sample App.

Initialize Taboola

πŸ“˜

The initialization steps in this section are the same for Classic and Web integrations.

In your AppDelegate class, create a TBLPublisherInfo object and initialize Taboola:

#import <TaboolaSDK/TaboolaSDK.h>

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // Immediately after application launch...
  
    // Initialize a TBLPublisherInfo instance with your unique 'publisherName':
    TBLPublisherInfo *publisherInfo = [[TBLPublisherInfo alloc]initWithPublisherName:@"<publisherName>"];

    // Initialize Taboola for your application:
    [Taboola initWithPublisherInfo:publisherInfo];
  
    // (Optional) Set *global* feature flags:
    [Taboola setGlobalExtraProperties:@{@"<feature flag key>":@"<value>"}];

    // (Optional) Set the desired log level: 
    [Taboola setLogLevel:LogLevelDebug];
    
    return YES;
}
import TaboolaSDK

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
    // Immediately after application launch...
  
    // Initialize a TBLPublisherInfo instance with your unique 'publisherName' (aka 'Publisher ID'):
    let publisherInfo = TBLPublisherInfo.init(publisherName: "<publisherName>")
    
    // Initialize Taboola for your application:
    Taboola.initWith(publisherInfo)
    
    // (Optional) Set *global* feature flags:
    Taboola.setGlobalExtraProperties(["<feature flag key>":"<value>"])
   
    // (Optional) Set the desired log level:
    Taboola.setLogLevel(LogLevel.debug)
    
    return true
}

πŸ“˜

publisherName

publisherName (aka Publisher ID) is a unique, alphabetic String. It might contain dashes - e.g. "<<publisherID>>" - but not spaces.

To obtain your Publisher ID, contact your Taboola Account Manager.

🚧

AppDelegate

Initialize Taboola in your AppDelegate class - or as early as possible within the app.

πŸ“˜

Logging

(Optional) To set the desired log level, use the setLogLevel method.

For more detail, see: Setters.

Build Taboola content instances

Flow 1: Build Taboola content instances via code

πŸ“˜

Best Practice

  • Flow 1 (thisΒ flow) is typically preferred - especially when using UICollectionView or UITableView.
  • However, if you are using the Storyboard to build the view, consider using Flow 2 (below).

🚧

Guidelines

  1. For each page (screen), initialize a TBLClassicPage instance.
  2. For each Widget or Feed on that page, use the TBLClassicPage instance to build a TBLClassicUnit instance.
  3. Make sure to assign a unique placement name to each TBLClassicUnit instance on that page (screen).

Load all Taboola content within the main UI thread.

In your Controller class, perform the following steps:

  1. Initialize a TBLClassicPage instance:
#import <TaboolaSDK/TaboolaSDK.h>
  
// In your ViewController:
  
@property (nonatomic, strong) TBLClassicPage *classicPage;

- (void)viewDidLoad {
    
    // Step 1 (this step):
    _classicPage = 
    [[TBLClassicPage alloc]initWithPageType:<pageType> pageUrl:<pageUrl> delegate:self scrollView:<yourScrollView>];

}
import TaboolaSDK

// In your ViewController:

var classicPage: TBLClassicPage? // Page

override func viewDidLoad() {

    // Step 1 (this step):
    classicPage = 
    TBLClassicPage.init(pageType: <pageType>, pageUrl: <pageUrl>, delegate: self, scrollView: <yourScrollView>)
  
}

πŸ“˜

Params

  • pageType - The page type, as provided by Taboola - e.g. "article".
  • pageUrl - A fully-qualified, public URL, with the same content as the current screen.
    • e.g. "https://www.example.com/articles?id=123"
  • delegate - A class instance that listens for Taboola SDK Events (i.e. implements theΒ TBLClassicPageDelegateΒ protocol).
  • scrollView - The scroll view in which you will embed the Taboola content instance(s).
    • e.g. _collectionView, _tableView, _scrollView (Objective C)
    • e.g. self.collectionView, self.tableView, self.scrollView (Swift)

🚧

Each ViewController must have its own instance of TBLClassicPage.

🚧

To maintain a smooth user experience, fetch Taboola content as soon as the view has loaded - i.e. in the viewDidLoad method.

(However, if you are using a UIPageViewController, see the Fetching content callout below.)

  1. Create Unit (TBLClassicUnit) instances for the Page that you initialized:
#import <TaboolaSDK/TaboolaSDK.h>
  
// In your ViewController:
  
@property (nonatomic, strong) TBLClassicPage *classicPage;
@property (nonatomic, strong) TBLClassicUnit *widgetUnit;
@property (nonatomic, strong) TBLClassicUnit *feedUnit;

- (void)viewDidLoad {

    // Step 1:
    _classicPage = [[TBLClassicPage alloc]initWithPageType:<pageType> pageUrl:<pageUrl> delegate:self scrollView:<yourScrollView>];
    
    // Step 2 (this step):
    _widgetUnit = [classicPage createUnitWithPlacementName:<placement1> mode:<mode1>]
    // (Apply optional setters here, if needed...)
    
    // Step 2 (this step):
    _feedUnit = [classicPage createUnitWithPlacementName:<placement2> mode:<mode2>]
    // (Apply optional setters here, if needed...)

}
import TaboolaSDK

// In your ViewController:

var classicPage: TBLClassicPage? // Page
var widgetUnit: TBLClassicUnit? // Widget
var feedUnit: TBLClassicUnit? // Feed

override func viewDidLoad() {
  
    // Step 1:
    classicPage = TBLClassicPage.init(pageType: <pageType>, pageUrl: <pageUrl>, delegate: self, scrollView: <yourScrollView>)
    
    // Step 2 (this step):
    widgetUnit = classicPage?.createUnit(withPlacementName: <placement1>, mode: <mode1>)
    // (Apply optional setters here, if needed...)

    // Step 2 (this step):
    feedUnit = classicPage?.createUnit(withPlacementName: <placement2>, mode: <mode2>)
    // (Apply optional setters here, if needed...)
  
}

πŸ“˜

Params

  • placementName - The placement name, as provided by Taboola - e.g. "Feed without video".
  • mode - The UI Mode ID of the placement, as provided by Taboola - e.g. "thumbs-feed-01".

🚧

placementName

If a given page contains multiple TBLClassicUnit instances, then each instance must be assigned a unique Placement Name.

  1. Fetch Taboola content for each Unit that you built:
#import <TaboolaSDK/TaboolaSDK.h>

@property (nonatomic, strong) TBLClassicPage *classicPage;
@property (nonatomic, strong) TBLClassicUnit *widgetUnit;
@property (nonatomic, strong) TBLClassicUnit *feedUnit;

- (void)viewDidLoad {

    // Step 1:
    _classicPage = [[TBLClassicPage alloc]initWithPageType:<pageType> pageUrl:<pageUrl> delegate:self scrollView:<yourScrollView>];
    
    // Step 2:
    _widgetUnit = [classicPage createUnitWithPlacementName:<placement1> mode:<mode>];
    // (Apply optional setters here, if needed...)
    
    // Step 3 (this step):
    [_widgetUnit fetchContent];
    
    // Step 2:
    _feedUnit = [classicPage createUnitWithPlacementName:<placement2> mode:<mode>];
    // (Apply optional setters here, if needed...)
      
    // Step 3 (this step):
    [_feedUnit fetchContent];
}
import TaboolaSDK

var classicPage: TBLClassicPage? // Page
var widgetUnit: TBLClassicUnit? // Widget
var feedUnit: TBLClassicUnit? // Feed

override func viewDidLoad() {
  
    // Step 1:
    classicPage = TBLClassicPage.init(pageType: <pageType>, pageUrl: <pageUrl>, delegate: self, scrollView: <yourScrollView>)
    
    // Step 2:
    widgetUnit = classicPage?.createUnit(withPlacementName: <placement1>, mode: <mode>)
    // (Apply optional setters here, if needed...)
  
    // Step 3 (this step):
    widgetUnit?.fetchContent()

    // Step 2:
    feedUnit = classicPage?.createUnit(withPlacementName: <placement2>, mode: <mode>)
    // (Apply optional setters here, if needed...)
  
    // Step 3 (this step):
    feedUnit?.fetchContent()
}

🚧

Fetching content

  1. To maintain a smooth user experience, fetch Taboola content as soon as the view has loaded - i.e. in the viewDidLoad method.
  2. Do not cache Taboola content. Fetch new content each time the app opens, or the relevant screen is created.

🚧

UIPageViewController

If you prefetch more than 1 page using UIPageViewController:

  1. Fetch Taboola content when the next page is visible to the user - i.e. in the viewWillAppear method.
  2. Fetch content once only (not every time the viewWillAppear method is fired).

πŸ‘

What's Next?

Now that your ViewController can fetch Taboola content, you are ready to manage the layout (see below).


Flow 2: Build Taboola content instances via the Storyboard

πŸ“˜

Best Practice

  • Flow 1 (above) is typically preferred - especially when using UICollectionView or UITableView.
  • However, if you are using the Storyboard to build the view, consider using Flow 2 (this flow).

🚧

Guidelines

  • For each page (screen), initialize a TBLClassicPage instance in the relevant Controller.
  • For each Widget or Feed on that page, add a TBLClassicUnit via the Storyboard (details provided below).
  • In your Controller, add the above TBLClassicUnit instances to the TBLClassicPage instance.
  1. In your Controller class, initialize a TBLClassicPage instance:
#import <TaboolaSDK/TaboolaSDK.h>
  
@property (nonatomic, strong) TBLClassicPage *classicPage;

- (void)viewDidLoad {
    
    // Step 1 (this step):
    _classicPage = [[TBLClassicPage alloc]initWithPageType:<pageType> pageUrl:<pageUrl> delegate:self scrollView:<yourScrollView>];

}
import TaboolaSDK

var classicPage: TBLClassicPage? // Page

override func viewDidLoad() {

    // Step 1 (this step):
    classicPage = TBLClassicPage.init(pageType: <pageType>, pageUrl: <pageUrl>, delegate: self, scrollView: <yourScrollView>)
  
}

πŸ“˜

Params

  • pageType - The page type, as provided by Taboola - e.g. "article".
  • pageUrl - A fully-qualified, public URL, with the same content as this screen:
    • e.g. "https://www.example.com/articles?id=123"
  • delegate - A class instance that listens for Taboola SDK Events (i.e. implements theΒ TBLClassicPageDelegateΒ protocol).
  • scrollView - The scroll view in which you will embed the Taboola content instance(s).
    • e.g. _collectionView, _tableView, _scrollView (Objective C)
    • e.g. self.collectionView, self.tableView, self.scrollView (Swift)

🚧

Each ViewController must have its own instance of TBLClassicPage.

🚧

To maintain a smooth user experience, fetch Taboola content as soon as the view has loaded - i.e. in the viewDidLoad method.

(However, if you are using a UIPageViewController, see the Fetching content callout below.)

  1. In the Storyboard, add a View component.
Document Layout (Example)
  1. In the Identity Inspector, change the View’s class from UIView (default) to TBLClassicUnit:
Identity Inspector
  1. In your Controller class, connect the Storyboard element to your Controller property:
@property (nonatomic, weak) IBOutlet TBLClassicUnit *widgetUnit;
@property (nonatomic, weak) IBOutlet TBLClassicUnit *feedUnit;
@IBOutlet weak var widgetUnit: TBLClassicUnit!
@IBOutlet weak var feedUnit: TBLClassicUnit!
  1. In your Controller class, add the Taboola Unit to the Page:
[classicPage addUnit:_widgetUnit placementName:<placement1> mode:<mode1>];
[classicPage addUnit:_feedUnit placementName:<placement2> mode:<mode2>];
classicPage?.add(widgetUnit, placementName: <placement1>, mode: <mode1>)
classicPage?.add(feedUnit, placementName: <placement2>, mode: <mode2>)

πŸ“˜

Params

  • unit - The TBLClassicUnit instance that you created above.
  • placementName - The placement name, as provided by Taboola - e.g. "Feed without video".
  • mode - The UI Mode ID of the placement, as provided by Taboola - e.g. "thumbs-feed-01".

🚧

placementName

If a given page contains multiple TBLClassicUnit instances, then each instance must be assigned a unique Placement Name.

  1. In your Controller class, fetch Taboola content for each Unit that you added:
- (void)viewDidLoad {

    // Step 1:
    _classicPage = [[TBLClassicPage alloc]initWithPageType:<pageType> pageUrl:<pageUrl> delegate:self scrollView:<yourScrollView>];
    
    // Step 5:
    [_classicPage addUnit:_widgetUnit placementName:<placementName> mode:<mode>];
    // (Apply optional setters here, if needed...)
    
    // Step 6 (this step):
    [_widgetUnit fetchContent];
    
    // Step 5:
    [_classicPage addUnit:_feedUnit placementName:<placementName> mode:<mode>];
    // (Apply optional setters here, if needed...)  
      
    // Step 6 (this step):
    [_feedUnit fetchContent];
}
override func viewDidLoad() {
  
    // Step 1:
    classicPage = TBLClassicPage.init(pageType: <pageType>, pageUrl: <pageUrl>, delegate: self, scrollView: <yourScrollView>)
    
    if let widgetUnit = widgetUnit {
        
        // Step 5:
        classicPage?.add(widgetUnit, placementName: <placement1>, mode: <mode1>)
        // (Apply optional setters here, if needed...)
      
        // Step 6 (this step):
        widgetUnit.fetchContent()
    }
    
    if let feedUnit = feedUnit {
        
        // Step 5:
        classicPage?.add(feedUnit, placementName: <placement2>, mode: <mode2>)
        // (Apply optional setters here, if needed...)
      
        // Step 6 (this step):
        feedUnit.fetchContent()
    }
  
}

🚧

Fetching content

  1. To maintain a smooth user experience, fetch Taboola content as soon as the view has loaded - i.e. in the viewDidLoad method.
  2. Do not cache Taboola content. Fetch new content each time the app opens, or the relevant screen is created.

🚧

UIPageViewController

If you prefetch more than 1 page using UIPageViewController:

  1. Fetch Taboola content when the next page is visible to the user - i.e. in the viewWillAppear method.
  2. Fetch content once only (not every time the viewWillAppear method is fired).

Manage the layout

We recommend using Taboola SDK to manage the cell. The following code fragment illustrates the overall concept.

// In your UICollectionViewDelegate and UICollectionViewDatasource implemenation:

// sizeForItemAtIndexPath
// Note: 'withUIInsets' determines the *margin* around the Unit.
-(CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
   
   // Widget size...
    return [_widgetUnit collectionView:collectionView layout:collectionViewLayout sizeForItemAtIndexPath:indexPath withUIInsets:UIEdgeInsetsMake(10, 10, 10, 10)];
    
    // Feed size...
    return [_feedUnit  collectionView:collectionView layout:collectionViewLayout sizeForItemAtIndexPath:indexPath withUIInsets:UIEdgeInsetsMake(10, 10, 10, 10)];
   
}

// cellForItemAtIndexPath
// Note: 'withBackground' sets the *color* of the Unit.
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {

    // Widget...
    return [_widgetUnit collectionView:collectionView cellForItemAtIndexPath:indexPath withBackground:nil];

    // Feed...
    return [_feedUnit collectionView:collectionView cellForItemAtIndexPath:indexPath withBackground:nil];
    
}
// In your UICollectionViewDelegate and UICollectionViewDatasource implemenation:

// sizeForItemAt
// Note: 'withUIInsets' determines the *margin* around the Unit.
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
  
    // Widget size
    if let widgetUnit = widgetUnit {
        return widgetUnit.collectionView(collectionView, layout: collectionView.collectionViewLayout, sizeForItemAt: indexPath, withUIInsets: UIEdgeInsets(top: 10, left:10, bottom: 10, right: 10))
    }
    
    // Feed size
    if let widgetUnit = widgetUnit {
        return feedUnit.collectionView(collectionView, layout: collectionView.collectionViewLayout, sizeForItemAt: indexPath, withUIInsets: UIEdgeInsets(top: 10, left: 10, bottom: 10, right: 10))
    }

}

// cellForItemAt
// Note: 'withBackground' sets the *color* of the Unit.
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {

    // Widget cell
    if let widgetUnit = widgetUnit {
        return widgetUnit.collectionView(collectionView, cellForItemAt: indexPath, withBackground: nil)
    }

    // Feed cell
    if let feedUnit = feedUnit {
        return feedUnit.collectionView(collectionView, cellForItemAt: indexPath, withBackground: nil)
    }
       
}
// In your UITableViewDelegate and UITableViewDatasource implemenation:

// heightForRowAtIndexPath
// Note: 'withUIInsets' determines the *margin* around the Unit.
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {

    // Widget height...
    return [__widgetUnit tableView:tableView heightForRowAtIndexPath:indexPath withUIInsets:UIEdgeInsetsMake(10, 10, 10, 10)];

    // Feed height...
    return [_feedUnit tableView:tableView heightForRowAtIndexPath:indexPath withUIInsets:UIEdgeInsetsMake(10, 10, 10, 10)];
    
}

// cellForRowAtIndexPath
// Note: 'withBackground' sets the *color* of the Unit.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{

    // Widget...
    return [__widgetUnit tableView:tableView cellForRowAtIndexPath:indexPath withBackground:nil];

    // Feed...
    return [_feedUnit tableView:tableView cellForRowAtIndexPath:indexPath withBackground:nil];
    
}
// In your UITableViewDelegate and UITableViewDatasource implemenation:

// heightForRowAt
// Note: 'withUIInsets' determines the *margin* around the Unit.
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
    
    // Widget height
    if let widgetUnit = widgetUnit {
        return widgetUnit.tableView(tableView, heightForRowAt: indexPath, withUIInsets: UIEdgeInsets(top: 10, left: 10, bottom: 10, right: 10))
    }
    
    // Feed height
    if let feedUnit = feedUnit {
        return feedUnit.tableView(tableView, heightForRowAt: indexPath, withUIInsets: UIEdgeInsets(top: 10, left: 10, bottom: 10, right: 10))
    }
    
}

// cellForRowAt
// Note: 'withBackground' sets the *color* of the Unit.
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

    // Widget cell
    if let widgetUnit = widgetUnit {
        return widgetUnit.tableView(tableView, cellForRowAt: indexPath, withBackground: nil)
    }

    // Feed cell
    if let feedUnit = feedUnit {
        return feedUnit.tableView(tableView, cellForRowAt: indexPath, withBackground: nil)
    }
}

πŸ“˜

Tip

For each callback method provided by the layout (e.g. sizeForItemAtIndexPath), Taboola SDK provides a method with the same name (e.g. sizeForItemAtIndexPath) for managing the UI.

🚧

TableView

When using TableView, we recommend implementing the estimatedHeightForRowAtIndexPath delegate. This can prevent potential issues with scrolling through a Taboola Feed.


See: Troubleshooting > Feed jumps during scrolling

🚧

Best practice

We recommend using Taboola SDK to manage the cell (above). It simplifies development and reduces potential for error.

If you prefer to manage the cell yourself, see: Advanced Options > Publisher manages the cell.

The Click Event

Taboola Classic Integration provides a TBLClassicPageDelegate for event handling.

If desired, you can intercept the click event, and open organic content directly within your app:

- (BOOL)classicUnit:(UIView*)classicUnit didClickPlacementName:(NSString *)placementName itemId:(NSString *)itemId clickUrl:(NSString *)clickUrl isOrganic:(BOOL)organic {
    // Insert your code here...
    // Return 'NO' to handle the click event yourself - or 'YES' for Taboola to handle it.
    // Note: you can override the default behavior for *organic* content only.
    return YES;
}
func classicUnit(_ classicUnit: UIView!, didClickPlacementName placementName: String!, itemId: String!, clickUrl: String!, isOrganic organic: Bool) -> Bool {
    // Insert your code here...
    // Return 'false' if you are handling the click event yourself, or 'true' if you want Taboola SDK to handle the click event.
    // Note: you can override the default behavior for *organic* content only.
    return true;
}

🚧

You can override the default behavior for organic content only.

πŸ“˜

For more information, see Event Handling and didClickPlacementName.

Troubleshooting

Feed jumps during scrolling

Issue

Occasionally, the Taboola Feed may jump during scrolling. Sometimes, this can also result in the user not being able to scroll any further.

Resolution

To avoid the above issue, make sure that the following TableView delegate has been implemented:

- (CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath {
    return [self tableView:tableView heightForRowAtIndexPath:indexPath];
}
func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
        return self.tableView(tableView, heightForRowAt: indexPath)
}

Well Done!

You have completed the basic integration steps!

If everything is working smoothly, take a look at the What's Next section below.

πŸ™ˆ

Taboola content not rendering?

  1. Test with the same params as the sample app, and see if those work.
  2. Still stuck? Submit a question In our forum.

What's next?

  1. For handling clicks and other important events, see Event Handling.
  2. To use advanced options while working with the Taboola SDK, see Advanced Options.
  3. In order to provide personalized recommendations for impressions in the EU and California, make sure to implement GDPR & CCPA respectively.
  4. If you have not already done so, make sure to look at our sample app.
  5. Once you are complete, submit your text app to Taboola for verification - see: App Verification.

🚧

IMPORTANT

Prior to launch, you must provide Taboola with a test app for verification. Skipping this step may result in a significant loss of revenue.

See: App Verification