Introduction
This guideline is relevant for our developers who use more than one widget for a single page on their Mobile app. It’s important to note that on Mobile apps there is no “real page”, so the meaning in this context is a “screen” or a “page” in which 2 widgets or more are shown to the user.
Guidelines:
-
Please make sure that you set the “index” variable on each request, i.e. the first request should be sent with idx=0, the second with idx=1 and so on.
-
The second call for “fetchRecommandations” should be executed from the callback (success or failure) of the first request. The reason we ask our developers to do this is as follows: the response of the first request contains a token from the server that should be sent together with the second request. This is all done “behind the scene” by the SDK, however in order for this to work the SDK has to wait for the response of the first call. Meaning, you, the developer, have to make sure this logic works well within your app.
Android Example
The code is from Journal sample app:
@Override
public void fragmentBecameVisible() {
if (! didGetRecommendations) {
fetchRecommendations(OBDemoWidgetID2);
}
}
private void fetchRecommendations(String widgetId) {
OBRequest request = new OBRequest();
request.setUrl(post.url);
request.setWidgetId(widgetId);
if (widgetId.equals(OBDemoWidgetID3)) {
request.setWidgetIndex(1);
}
// Default index is 0 so the first request will be according to guidelines.
Outbrain.fetchRecommendations(request, this);
}
@Override
public void onOutbrainRecommendationsSuccess(final OBRecommendationsResponse recommendations) {
String requestWidgetId = recommendations.getRequest().getWidgetJsId();
didGetRecommendations = true;
// Response from the first "fetch" call
if (requestWidgetId.equals(OBDemoWidgetID2)) {
// First set the result of the first call on the screen,
// we can't be sure the second response will be "success".
setRecommendationsForDrawer(recommendations);
fetchRecommendations(OBDemoWidgetID3);
}
// Response from the second "fetch" call
if (requestWidgetId.equals(OBDemoWidgetID3)) {
setRecommendationsForFooter(recommendations);
}
}
@Override
public void onOutbrainRecommendationsFailure(Exception ex) {
Log.e("OB", "failure = " + ex.getMessage());
ex.printStackTrace();
}
Please note the following:
-
The flow starts at fragmentBecameVisible() – there we fetch recommendations for OBDemoWidgetID2.
-
On the “success” callback we call the second widget OBDemoWidgetID3
-
In fetchRecommendations() for the second widget (OBDemoWidgetID3) we set idx=1
iOS Example
The code is from Journal sample app:
- (void)delayedContentLoad
{
self.textView.scrollsToTop = YES;
// If we've loaded outbrain data already, or we're currently loading
// then there's nothing else to do.
if(_outbrainLoaded || _loadingOutbrain) return;
self.textView.delegate = nil;
OBRequest * request = [OBRequest requestWithURL:self.post.url widgetID:OBDemoWidgetID2];
[Outbrain fetchRecommendationsForRequest:request withDelegate:self];
}
#pragma mark - OBResponseDelegate methods
- (void)outbrainDidReceiveResponseWithSuccess:(OBRecommendationResponse *)response
{
_outbrainLoaded = YES;
_loadingOutbrain = NO;
_adhesionDisabled = NO;
_adhesionLocked = NO;
// If there are no recommendations (shouldn't happen often). Then we
// just don't show anything
if(response.recommendations.count == 0)
{
// .... code for handling this situation
return;
}
// Adjust the webView contentInset so we can insert our view at the bottom
UIScrollView * sv = self.textView; // self.webView.scrollView; <!-- Maybe use this later
sv.delegate = self;
UIEdgeInsets insets = sv.contentInset;
insets.bottom = self.outbrainViewHeight;
sv.contentInset = insets;
// If "true" we received the response of the first "fetch" request
if (response.request.widgetIndex == 0) {
self.outbrainClassicView.recommendationResponse = response;
self.outbrainClassicView.frame = CGRectOffset(_outbrainClassicView.bounds, 0, sv.contentSize.height);
[sv addSubview:self.outbrainClassicView];
if(sv.contentOffset.y >= CGRectGetMinY(_outbrainClassicView.frame))
{
_adhesionDisabled = YES;
}
self.outbrainClassicView.alpha = 0.f;
[UIView animateWithDuration:.3f
animations:^{
self.outbrainClassicView.alpha = 1.f;
}];
OBRequest * secondRequest = [OBRequest requestWithURL:self.post.url
widgetID:OBDemoWidgetID2
widgetIndex:1];
[Outbrain fetchRecommendationsForRequest:secondRequest withDelegate:self];
}
else { // This is the response of the second "fetch" request
self.outbrainHoverView.recommendationResponse = response;
self.outbrainHoverView.frame = CGRectOffset(_outbrainHoverView.bounds, 0, CGRectGetMaxY(sv.bounds));
[sv addSubview:self.outbrainHoverView];
self.outbrainHoverView.alpha = 0.f;
}
}
- (void)outbrainResponseDidFail:(NSError *)response
{
UIAlertView * alert = [[UIAlertView alloc] initWithTitle:response.domain message:response.userInfo[NSLocalizedDescriptionKey] delegate:nil cancelButtonTitle:nil otherButtonTitles:@"OK", nil];
[alert show];
}
Please note the following:
-
The flow starts at delayedContentLoad() – there we fetch recommendations for OBDemoWidgetID2.
-
On the “success” callback we call the second widget OBDemoWidgetID3 (OBDemoWidgetID3) and we set idx=1