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' and 'appStoreId':
TBLPublisherInfo *publisherInfo = [[TBLPublisherInfo alloc] initWithPublisherName:@"<publisherName>" appStoreId:@(<appStoreId>)];
// 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' and 'appStoreId':
let publisherInfo = TBLPublisherInfo.init(publisherName: "<publisherName>", appStoreId: <appStoreId>)
// 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
}
Params
publisherName
- An alphanumeric string, provided by Taboola - e.g."<<publisherID>>"
.This field is also referred to as the Publisher ID.
appStoreId
- Your App Store ID, obtained via the App Store Connect dashboard.See below.
appStoreId
Your App Store ID - aka Apple ID or iTunes ID - is a unique, numeric identifier that allows Apple to distinguish your app from others.
Passing the
appStoreId
param allows for improved tracking and attribution and is strongly recommended.(Requires SDK
3.8.27
or higher)
Obtaining your App Store ID
- Log in to the App Store Connect dashboard.
- Under
My Apps
, select the relevant app.- Under
General
, selectApp Information
(left).- Copy your Apple ID (right).
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
orUITableView
.- However, if you are using the Storyboard to build the view, consider using Flow 2 (below).
Guidelines
- For each page (screen), initialize a
TBLClassicPage
instance.- For each Widget or Feed on that page, use the
TBLClassicPage
instance to build aTBLClassicUnit
instance.- 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:
- 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.)
- 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.
- 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
- To maintain a smooth user experience, fetch Taboola content as soon as the view has loaded - i.e. in the
viewDidLoad
method.- 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
:
- Fetch Taboola content when the next page is visible to the user - i.e. in the
viewWillAppear
method.- 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
orUITableView
.- 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 theTBLClassicPage
instance.
- 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.)
- In the Storyboard, add a View component.
Document Layout (Example) |
---|
- In the Identity Inspector, change the Viewβs class from
UIView
(default) toTBLClassicUnit
:
Identity Inspector |
---|
- 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!
- 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
- TheTBLClassicUnit
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.
- 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
- To maintain a smooth user experience, fetch Taboola content as soon as the view has loaded - i.e. in the
viewDidLoad
method.- 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
:
- Fetch Taboola content when the next page is visible to the user - i.e. in the
viewWillAppear
method.- 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 theestimatedHeightForRowAtIndexPath
delegate. This can prevent potential issues with scrolling through a Taboola Feed.
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?
- Test with the same params as the sample app, and see if those work.
- Still stuck? Submit a question In our forum.
What's next?
- For handling clicks and other important events, see Event Handling.
- To use advanced options while working with the Taboola SDK, see Advanced Options.
- In order to provide personalized recommendations for impressions in the EU and California, make sure to implement GDPR & CCPA respectively.
- If you have not already done so, make sure to look at our sample app.
- 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
Updated 6 months ago