Widget via Native
DEPRECATION NOTICE
On March 31, 2025, Taboola will sunset SDK 2.
Before then, please make sure to migrate to SDK 3 for iOS.
Step 1: Import Taboola SDK
For CocoaPods, import TaboolaSDK
into your bridging header.
#import <TaboolaSDK/TaboolaSDK.h>
import TaboolaSDK
For Carthage, import the framework:
#import <TaboolaFramework/TaboolaFramework.h>
import TaboolaFramework
Step 2: Initialize Taboola
Create a PublisherInfo
object and init Taboola
PublisherInfo *publisherInfo = [[PublisherInfo alloc]initWithPublisherId:@"publisherId"];
[Taboola initWithPublisherInfo:publisherInfo];
let publisherInfo = PublisherInfo.init(publisherId: "publisherId")
Taboola.initWith(publisherInfo)
publisherId
- Your publisher ID as provided to you by Taboola account manager
Step 3: Adding the TaboolaWidget
Using frames
TaboolaView* taboolaView = [[TaboolaView alloc] initWithFrame:<CGRect>];
let taboolaView = TaboolaView()
Using Constraints
Starting from iOS SDK 2.3.7, it is possible to create a taboolaView
using constraints
TaboolaView* taboolaView = [[TaboolaView alloc] init];
[taboolaView setConstraintsOn: YES];
let taboolaView = TaboolaView()
taboolaView.setConstraintsOn(true)
Step 4: Set the TaboolaView Object Properties
For your production properties, contact your account manager.
For testing properties, see further down in this page.
// An identification of a Taboola recommendation unit UI template (you might use different UI templates in different parts of the app, in which case you will need to get the applicable mode for each UI template)
taboolaView.mode = @"my-mode";
// An identification of your publisher account on the Taboola system
taboolaView.publisher = @"my-publisher";
// Sets the page type of the page on which the widget is displayed (one of article, photo, video, home, category, search) If you're not sure what is the right value, contact your account manager.
taboolaView.pageType = @"my-page-type";
// Sets the canonical URL for the page on which the widget is displayed
taboolaView.pageUrl = @"my-page-url";
//Sets the publisher internal ID for the page on which the widget is displayed
taboolaView.pageId = @"my-page-id";
// An identification of a specific placement in the app (you might place Taboola recommendation units in multiple placements in the app, in which case you should get applicable placement ids for each such placement)
taboolaView.placement = @"my-placement";
//The target type of the page on which the widget is displayed. If you're not sure what is the right value, contact your account manager.
taboolaView.targetType = @"my-target-type";
// An identification of a Taboola recommendation unit UI template (you might use different UI templates in different parts of the app, in which case you will need to get the applicable mode for each UI template)
taboolaView.mode = "my-mode"
// An identification of your publisher account on the Taboola system
taboolaView.publisher = "my-publisher"
// Sets the page type of the page on which the widget is displayed (one of article, photo, video, home, category, search) If you're not sure what is the right value, contact your account manager.
taboolaView.pageType = "my-page-type"
// Sets the canonical URL for the page on which the widget is displayed
taboolaView.pageUrl = "my-page-url"
//Sets the publisher internal ID for the page on which the widget is displayed
taboolaView.pageId = "my-page-id"
// An identification of a specific placement in the app (you might place Taboola recommendation units in multiple placements in the app, in which case you should get applicable placement ids for each such placement)
taboolaView.placement = "my-placement"
//The target type of the page on which the widget is displayed. If you're not sure what is the right value, contact your account manager.
taboolaView.targetType = "my-target-type"
publisher
- Your publisher id parameter as provided by your Taboola account managermode
- Your mode parameter as provided by your Taboola account managerplacement
- Your placement parameter as provided by your Taboola account managerpageUrl
- The full URL of a public web page which reflects the current screen's contentpageId
- An internal identification for the current screen's content. Pass this along the page URL to set the item ID as your internal IDpageType
- Your page type parameter as provided by your Taboola account managertargetType
- Your target type parameter as provided by your Taboola account manager
Step 5: Fetch content
To show the widget, call fetchContent
when the screen (view) loads
- (void)viewDidLoad{
[super viewDidLoad];
// Load taboolaView with testing values
taboolaView.delegate = self;
taboolaView.ownerViewController = self;
taboolaView.mode = @"alternating-widget-without-video-1-on-1";
taboolaView.publisher = @"sdk-tester";
taboolaView.pageType = @"home";
taboolaView.pageUrl = @"http://blog.taboola.com";
taboolaView.placement = @"Mid Article";
taboolaView.targetType = @"mix";
// Fill taboolaView with recommendations
[taboolaView fetchContent];
}
override func viewDidLoad() {
super.viewDidLoad()
// Load taboolaView with testing values
taboolaView.delegate = self
taboolaView.ownerViewController = self
taboolaView.mode = "alternating-widget-without-video-1-on-1"
taboolaView.publisher = "sdk-tester"
taboolaView.pageType = "article"
taboolaView.pageUrl = "http://blog.taboola.com"
taboolaView.placement = "Mid Article"
// Fill taboolaView with recommendations
taboolaView.fetchContent()
}
Important!
- To maintain good UX - please fetch content as soon as the screen loads and not when the user reaches the Taboola area on the screen
- When working with
UIPageViewController
, Please fetch the widget content only when the view is visible to the user- Make sure you load the
taboolaView
object only from the main UI thread
Step 6: Adjust the Widget height
Taboola Widget adjusts it height automatically. We highly recommend to use this option as the final height of the widget may dynamically change according to the different UI mode that is loaded in Taboola Backstage.
In order to adjust your app layout to these changes, set 'autoResizeHeight' to YES (This is the default) and listen to the height parameter within the didLoadPlacementNamed
delegate (See in Step 7)
Please keep in mind that the widget height can change throughout the app lifecycle after the first loading event - make sure you are listening to the didLoadPlacementNamed
for any height change.
If wish to adjust the size of Taboola Widget manually, you can do so by setting autoResizeHeight
to NO
.
Step 7: Additional Integration Information (Optional)
This section describes some optional points in the integration
Delegates
To receive client-side callbacks, the client can set a delegate for each widget. The following events are available:
didLoadPlacementNamed
- Triggered after the TaboolaView is successfully rendered; returns the placement name and the updated height valuedidFailToLoadPlacementNamed
- Triggered after the TaboolaView fails to render; returns the placement name and the error string value. Since iOS SDK 2.5.0, it is possible to get the detailed error strings by activating thedetailedErrorCodes
feature flag;NO_ITEMS
(no fill by Taboola),WRONG_PARAMS
(wrong "tb_mode" was used),RESPONSE_ERROR
,TIMEOUT
(connectivity issue),UNKNOWN_ERROR
, andINTERNAL_1
Example:
taboolaView.delegate = self;
[taboolaView setExtraProperties:@{@"detailedErrorCodes":@"true"}];
- (void)taboolaView:(UIView *)taboolaView didLoadPlacementNamed:(NSString *)placementName withHeight:(CGFloat)height;
- (void)taboolaView:(UIView *)taboolaView didFailToLoadPlacementNamed:(NSString *)placementName withErrorMessage:(NSString *)error;
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
taboolaView.delegate = self
taboolaView.setExtraProperties(["detailedErrorCodes": true])
}
}
extension ViewController: TaboolaViewDelegate {
func taboolaView(_ taboolaView: UIView!, didLoadPlacementNamed placementName: String!, withHeight height: CGFloat) {
print("Placement \(String(describing: placementName)) loaded successfully. height \(height)");
}
func taboolaView(_ taboolaView: UIView!, didFailToLoadPlacementNamed placementName: String!, withErrorMessage error: String!) {
print("Placement \(String(describing: placementName)) failed to load because: %@ \(String(describing: error))");
}
}
Intercepting Organic Recommendation Items Clicks
The SDK enables app developers to change the default behavior when a user clicks on an organic item. For example, you might want to create a click-through or to override the default way of opening the organic recommended article.
// To intercept recommendation clicks
- (BOOL)onItemClick:(NSString *)placementName withItemId:(NSString *)itemId withClickUrl:(NSString *)clickUrl isOrganic:(BOOL)organic {
NSLog(@"Start load request on first screen: %@ isOrganic? %@", clickUrl, organic ? @"YES":@"NO");
if (organic) {
NSLog(@"organic items should open as native app pages.");
}
return YES;
}
//Returns: YES if the taboolaView should handle the click; otherwise, NO. Default value is YES.
//NOTICE: As of version 1.5.1, clicks on non-organic items will be handled by
//Taboola SDK and the app will not be allowed to override the default click
//handler. "No" responses from taboolaViewItemClickHandler will only be
//honored for organic items.
func onItemClick(_ placementName: String!, withItemId itemId: String!, withClickUrl clickUrl: String!, isOrganic organic: Bool) -> Bool {
if organic {
print("itemId: \(String(describing: itemId))")
} else {
print("clickUrl: \(String(describing: clickUrl))")
}
return true
}
The method is called every time a user clicks a recommendation, immediately before triggering the default behavior. If recommendation clicks are not intercepted, they are presented by a Taboola powered in-app browser. It is also important to note that TaboolaView also fires notifications that can be caught by any object inside the app. This is in case you want to react to these notifications elsewhere in your code.
The app can intercept the click there, and returns a boolean value:
-
Returns NO - abort the default behavior (in which case the app displays the recommendation content on its own - e.g. using a custom in-app browser)
-
Returns YES - this enables the app to implement a click-through and continue with the default click handling behavior (which displays the clicked content with an in-app browser)
-
"organic" indicates whether the item clicked was an organic content recommendation or not. Best practice is to suppress the default behavior for organic items. Instead, open the relevant screen in your app which shows that piece of content.
-
Use "itemId" in organic clicks for deeplink
-
"clickUrl" is the URL with the redirect
Important!
In some cases the delegates parameters can be with null value. Please make sure to handle such a case in your code
Replacing the Default In-app Browser Icons
The file TaboolaViewResources.bundle
includes the default icons for the TaboolaView in-app browser. You can replace these icons by providing an alternative TaboolaViewResources.bundle
file which contains the following files:
- back_icon.png
- forward_icon.png
Using more than one Taboola asset on the same screen
It is possible to add more than one Taboola asset on the same screen. For example, placing two Taboola widgets on a feed style screen. When doing so it is important to avoid duplicate items on each asset
- Set the same
viewId
value for each taboolaWidget object before fetching content. TheviewId
value must be a string of digits. We recommend using the current epoch timestamp. In any case, theviewId
value can not exceed 19 digits. - Fetch the content for the second asset only after a response is received for the first asset. Please use the
didLoadPlacementNamed
to listen to render is done events
To do so, please make sure you do the following:
//sets the viewId to be a string of digits (current epoch timestamp)
int timestamp = [[NSDate date] timeIntervalSince1970];
String *viewId = [NSString stringWithFormat:@"%d",timestamp];
BOOL didLoadFeed = NO;
//fetching content for the first Taboola item -
//for example, mid article widget
_taboolaMidArticleWidget.viewID = viewId;
[_taboolaMidArticleWidget fetchContent];
(void) taboolaView:(UIView *)
taboolaView didLoadPlacementNamed:(NSString *)
placementName withHeight:(CGFloat) height
{
if (!_didLoadFeed)
{
_didLoadFeed = YES;
// We are loading the feed only when the widget finished loading- for dedup.
_taboolaFeed.viewID = viewId;
[_taboolaFeed fetchContent];
}
}
//sets the viewId to be a string of digits (current epoch timestamp)
lazy var viewId: String = {
let timestamp = Int(Date().timeIntervalSince1970)
return "\(timestamp)"
}()
var didLoadFeed = false
//fetching content for the first Taboola item -
//for example, mid article widget
taboolaMidArticleWidget.viewID = viewId
taboolaMidArticleWidget.fetchContent()
func taboolaView(_ taboolaView: UIView!, didLoadPlacementNamed placementName: String!, withHeight height: CGFloat) {
if !didLoadFeed
{ didLoadFeed = true // We are loading the feed only when the widget finished loading- for dedup.
taboolaFeed.viewID = viewId
taboolaFeed.fetchContent()
}
}
Step 8: Resetting Taboola When Closing the Screen
Do not forget to reset Taboola when leaving the current screen.
- (void)dealloc
{
[taboolaView reset];
}
deinit {
taboolaView.reset()
}
Step 9: Testing and Examples
You can find code examples on our Github repository.
You can use the following parameters for testing and development. Sponsored items are flagged with an "SC: " prefix in the title; organic items are flagged with an "OC: " prefix in the title
Parameters | Mid Article Widget | Below Article Widget |
---|---|---|
publisher | "sdk-tester-demo" | "sdk-tester-demo" |
placement | "Mid Article" | "Below Article" |
PageUrl | "https://blog.taboola.com" | "https://blog.taboola.com" |
PageType | "home" | "home" |
TargetType | "mix" | "mix" |
mode | "alternating-widget-without-video-1-on-1" | "alternating-widget-without-video-1x4" |
Step 10: Submit Build for QA
When you have finished the integration, contact your account manager and send a debuggable (TestFlight or other beta platform) version of your iOS project.
You're done!
Integration Support
Should you have any problems integrating the product, log a ticket with us by emailing your account manager. For a quick support you can also check our discussion forum
Updated 23 days ago