1 2 3 4 |
VMaxAdView *adView = [[VMaxAdView alloc] initWithAdspotID:"<YOUR_ADSPOT_ID>" viewController:self withAdUXType:kVMaxAdUX_Native]; adView.delegate = self; |
1 2 3 4 5 |
var adView : VMaxAdView! = VMaxAdView(adspotID: "<YOUR_ADSPOT_ID>", viewController: self, withAdUXType: VMaxAdUX.Native) adView.delegate = self; |
Then one must request an ad via cacheAd as follows:
1 2 |
[adView cacheAd]; |
1 2 |
adView.cacheAd() |
Complete invocation code
1 2 3 4 5 6 7 8 9 10 11 12 |
VMaxAdView *adView = [[VMaxAdView alloc] initWithAdspotID:"<YOUR_ADSPOT_ID>" viewController:self withAdUXType:kVMaxAdUX_Native]; adView.delegate = self; // for a custom admob native ad size, set VMaxAdSettings as follows VMaxAdSettings *adSettings = [[VMaxAdSettings alloc] init]; adSettings.admobNativeExpressAdSize = CGSizeMake(300, 300); adView.adSettings = adSettings; // cache an ad [adView cacheAd]; |
1 2 3 4 5 6 7 |
var adView : VMaxAdView! = VMaxAdView(adspotID: "<YOUR_ADSPOT_ID>", viewController: self, withAdUXType: VMaxAdUX.Native) adView.delegate = self adView.cacheAd() |
On caching success, the following callback is invoked using which, further customisation is possible as illustrated below:
From 3.6.0
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 |
- (void)onAdReady:(VMaxAdView *)theAdView { NSLog(@"onAdReady"); } Inside this callback, one can obtain the VMaxNativeAd object as follows: - (void)onAdReady:(VMaxAdView *)theAdView { NSLog(@"onAdReady"); VMaxNativeAd *nativeAd = [theAdView getNativeAd]; // check ad partner if ([nativeAd.nativeAdPartner caseInsensitiveCompare:@"Facebook"] == NSOrderedSame) { // Ad partner is Facebook, render native ad layout using custom view for Facebook using VMaxNativeAd elements if(nativeAd.imageIcon != nil) { // set icon image in custom ad view __weak CustomAdDisplayController *weakSelf = self; [self.nativeAd.imageIcon loadImageAsyncWithBlock:^(UIImage *image) { if (image) { [weakSelf.customAdView.iconImageView setImage:image]; } }]; } if(nativeAd.getTitle != nil) // set title in custom ad view self.customAdView.titleLabel.text = nativeAd.getTitle; if(nativeAd.getCtaText != nil) // set cta button title in custom ad view [self.customAdView.ctaButton setTitle:nativeAd.getCtaText forState:UIControlStateNormal]; // Facebook ad choices view is automatically added by the Facebook native adapter on the top right of custom ad view. Leave sufficient space for the same depending on expanded state set to YES/NO for the ad choices view // setup other elements as needed & implement delegates (is a must) } else if ([nativeAd.nativeAdPartner caseInsensitiveCompare:@"AdMob"] == NSOrderedSame) { // Ad partner is AdMob, render native ad using custom layout for AdMob using VMaxNativeAd elements if(nativeAd.getTitle != nil) self.customAdView.adTitleLabel.text = nativeAd.getTitle; if(nativeAd.getDesc != nil) self.customAdView.adDescLabel.text = nativeAd.getDesc; if(nativeAd.getCtaText != nil) [self.customAdView.ctaButton setTitle:nativeAd.getCtaText forState:UIControlStateNormal]; // AdMob ad choice icon is automatically added by the AdMob native adapter on the top right of custom ad view. Leave sufficient space for the same; about 15x15px // setup other elements as needed & implement delegates (is a must) } else { // Other ad partner, render native ad using custom layout for AdMob using VMaxNativeAd elements if(nativeAd.getTitle != nil) self.customAdView.adTitleLabel.text = nativeAd.getTitle; if(self.nativeAd.getDesc != nil) self.customAdView.adDescLabel.text = nativeAd.getDesc; if(nativeAd.getCtaText != nil) [self.customAdView.ctaButton setTitle:nativeAd.getCtaText forState:UIControlStateNormal]; // add 'ad attribution' manually self.customAdView.adAttributionLabel.text = @"Ad"; self.customAdView.adAttributionLabel.hidden = NO; // setup other elements as needed & implement delegates (is a must) } // register views of the customAdView to receive touch events & for impression firing (is a must) [nativeAd registerViewForInteraction:adView view:self.customAdView listOfViews:self.customAdView.subviews]; } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 |
func onAdReady(theAdView: VMaxAdView!) { print("onAdReady") let nativeAd:VMaxNativeAd = theAdView.getNativeAd() print(nativeAd) if nativeAd.nativeAdPartner == "Facebook" { // This is Facebook native Ad. So render the native ad using custom layout // for Facebook using VMaxNativeAd elements. // Get the Image Icon. if nativeAd.imageIcon != nil { nativeAd.imageIcon.loadImageAsyncWithBlock({ (let image:UIImage!) -> Void in if image != nil { self.customAdView.iconImageView.image = image } }) } // Get the FB Ad Title. if nativeAd.title != nil { self.customAdView.titleLabel.text = nativeAd.title } // Get CTA Button Title. if nativeAd.ctaText != nil { self.customAdView.ctaButton.setTitle(nativeAd.ctaText, forState: UIControlState.Normal) } // Facebook ad choices view is automatically added by the Facebook native adapter on the // top right of custom ad view. Leave sufficient space for the same depending on expanded // state set to YES/NO for the ad choices view // Setup other elements provided in VMaxNativeAd markup as per your needs. } else if nativeAd.nativeAdPartner == "AdMob" { // Ad partner is AdMob, render native ad using custom layout for AdMob using // VMaxNativeAd elements if nativeAd.title != nil { self.customAdView.adTitleLabel.text = nativeAd.title } if nativeAd.desc != nil { self.customAdView.adDescLabel.text = nativeAd.desc; } if nativeAd.ctaText != nil { self.customAdView.ctaButton.setTitle(nativeAd.ctaText, forState: UIControlState.Normal) } // AdMob ad choice icon is automatically added by the AdMob native adapter on the // top right of custom ad view. Leave sufficient space for the same; about 15x15px. // setup other elements as needed & implement delegates (is a must) } else { // Other ad partner, render native ad using custom layout for AdMob using // VMaxNativeAd elements if nativeAd.title != nil { self.customAdView.adTitleLabel.text = nativeAd.title } if nativeAd.desc != nil { self.customAdView.adDescLabel.text = nativeAd.desc; } if nativeAd.ctaText != nil { self.customAdView.ctaButton.setTitle(nativeAd.ctaText, forState: UIControlState.Normal) } // add 'ad attribution' manually self.customAdView.adAttributionLabel.text = "Ad"; self.customAdView.adAttributionLabel.hidden = false; // setup other elements as needed & implement delegates (is a must) } } |
Before 3.6.0
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 |
- (void)adViewDidCacheAd:(VMaxAdView *)theAdView { NSLog(@"adViewDidCacheAd"); } Inside this callback, one can obtain the VMaxNativeAd object as follows: - (void)adViewDidCacheAd:(VMaxAdView *)theAdView { NSLog(@"adViewDidCacheAd"); VMaxNativeAd *nativeAd = [theAdView getNativeAd]; // check ad partner if ([nativeAd.nativeAdPartner caseInsensitiveCompare:@"Facebook"] == NSOrderedSame) { // Ad partner is Facebook, render native ad layout using custom view for Facebook using VMaxNativeAd elements if(nativeAd.imageIcon != nil) { // set icon image in custom ad view __weak CustomAdDisplayController *weakSelf = self; [self.nativeAd.imageIcon loadImageAsyncWithBlock:^(UIImage *image) { if (image) { [weakSelf.customAdView.iconImageView setImage:image]; } }]; } if(nativeAd.getTitle != nil) // set title in custom ad view self.customAdView.titleLabel.text = nativeAd.getTitle; if(nativeAd.getCtaText != nil) // set cta button title in custom ad view [self.customAdView.ctaButton setTitle:nativeAd.getCtaText forState:UIControlStateNormal]; // Facebook ad choices view is automatically added by the Facebook native adapter on the top right of custom ad view. Leave sufficient space for the same depending on expanded state set to YES/NO for the ad choices view // setup other elements as needed & implement delegates (is a must) } else if ([nativeAd.nativeAdPartner caseInsensitiveCompare:@"AdMob"] == NSOrderedSame) { // Ad partner is AdMob, render native ad using custom layout for AdMob using VMaxNativeAd elements if(nativeAd.getTitle != nil) self.customAdView.adTitleLabel.text = nativeAd.getTitle; if(nativeAd.getDesc != nil) self.customAdView.adDescLabel.text = nativeAd.getDesc; if(nativeAd.getCtaText != nil) [self.customAdView.ctaButton setTitle:nativeAd.getCtaText forState:UIControlStateNormal]; // AdMob ad choice icon is automatically added by the AdMob native adapter on the top right of custom ad view. Leave sufficient space for the same; about 15x15px // setup other elements as needed & implement delegates (is a must) } else { // Other ad partner, render native ad using custom layout for AdMob using VMaxNativeAd elements if(nativeAd.getTitle != nil) self.customAdView.adTitleLabel.text = nativeAd.getTitle; if(self.nativeAd.getDesc != nil) self.customAdView.adDescLabel.text = nativeAd.getDesc; if(nativeAd.getCtaText != nil) [self.customAdView.ctaButton setTitle:nativeAd.getCtaText forState:UIControlStateNormal]; // add 'ad attribution' manually self.customAdView.adAttributionLabel.text = @"Ad"; self.customAdView.adAttributionLabel.hidden = NO; // setup other elements as needed & implement delegates (is a must) } // register views of the customAdView to receive touch events & for impression firing (is a must) [nativeAd registerViewForInteraction:adView view:self.customAdView listOfViews:self.customAdView.subviews]; } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 |
func adViewDidCacheAd(theAdView: VMaxAdView!) { print("adViewDidCacheAd") let nativeAd:VMaxNativeAd = theAdView.getNativeAd() print(nativeAd) if nativeAd.nativeAdPartner == "Facebook" { // This is Facebook native Ad. So render the native ad using custom layout // for Facebook using VMaxNativeAd elements. // Get the Image Icon. if nativeAd.imageIcon != nil { nativeAd.imageIcon.loadImageAsyncWithBlock({ (let image:UIImage!) -> Void in if image != nil { self.customAdView.iconImageView.image = image } }) } // Get the FB Ad Title. if nativeAd.title != nil { self.customAdView.titleLabel.text = nativeAd.title } // Get CTA Button Title. if nativeAd.ctaText != nil { self.customAdView.ctaButton.setTitle(nativeAd.ctaText, forState: UIControlState.Normal) } // Facebook ad choices view is automatically added by the Facebook native adapter on the // top right of custom ad view. Leave sufficient space for the same depending on expanded // state set to YES/NO for the ad choices view // Setup other elements provided in VMaxNativeAd markup as per your needs. } else if nativeAd.nativeAdPartner == "AdMob" { // Ad partner is AdMob, render native ad using custom layout for AdMob using // VMaxNativeAd elements if nativeAd.title != nil { self.customAdView.adTitleLabel.text = nativeAd.title } if nativeAd.desc != nil { self.customAdView.adDescLabel.text = nativeAd.desc; } if nativeAd.ctaText != nil { self.customAdView.ctaButton.setTitle(nativeAd.ctaText, forState: UIControlState.Normal) } // AdMob ad choice icon is automatically added by the AdMob native adapter on the // top right of custom ad view. Leave sufficient space for the same; about 15x15px. // setup other elements as needed & implement delegates (is a must) } else { // Other ad partner, render native ad using custom layout for AdMob using // VMaxNativeAd elements if nativeAd.title != nil { self.customAdView.adTitleLabel.text = nativeAd.title } if nativeAd.desc != nil { self.customAdView.adDescLabel.text = nativeAd.desc; } if nativeAd.ctaText != nil { self.customAdView.ctaButton.setTitle(nativeAd.ctaText, forState: UIControlState.Normal) } // add 'ad attribution' manually self.customAdView.adAttributionLabel.text = "Ad"; self.customAdView.adAttributionLabel.hidden = false; // setup other elements as needed & implement delegates (is a must) } } |
Using the VMaxNativeAd object, developers can further use the VMaxNativeAd elements to create custom native ads depending on their availability. The elements are further tabled in detail below.
Native Ad Display Precedence
It is recommended to display the key ‘central’ native ad elements by following the precedence as follows:
- Video ~ Recommended. If native ad contains vastVideoTag (via getVastVideoTag)
- Media View ~ if native ad partner is Facebook & native ad contains ‘view’ (via getView)
- Main Image ~ if native ad partner contains imageMain (via getImageMain)
- Medium Image ~ if native ad partner contains imageMedium (via getImageMedium)
- Description ~ if native ad partner contains description (via getDesc)
This allows for an immersive ad experience for the end user by ensuring display of native ad content based on the native ad element(s) availability, thus ensuring maximum visibility.
Native Ad Elements
Parameter | Recommended | Description |
nativeAd.getTitle | Yes | the title property of the ad |
nativeAd.getCtaText | Yes | the call to action title property of the ad |
nativeAd.getDesc | Yes | the description property of the ad |
nativeAd.getView | Yes | the view property of the ad; a dynamic view that is capable of displaying image or video e.g: media view in case of facebook |
nativeAd.getImageIcon | Yes | the VMaxAdImage object created in response to the native ad containing an icon image |
nativeAd.getImageIcon.image | the image property of the icon object | |
nativeAd.getImageIcon.url | the url of the image property of the icon object | |
nativeAd.getImageIcon.width | the width of the image property of the icon object | |
nativeAd.getImageIcon.height | the height of the image property of the icon object | |
nativeAd.getImageMain | Yes | the VMaxAdImage object created in response to the native ad containing a main image |
nativeAd.getImageMain.image | ||
nativeAd.getImageMain.url | ||
nativeAd.getImageMain.width | ||
nativeAd.getImageMedium | the VMaxAdImage object created in response to the native ad containing a medium image | |
nativeAd.getImageMedium.image | ||
nativeAd.getImageMedium.url | ||
nativeAd.getImageMedium.width | ||
nativeAd.getImageMedium.height | ||
nativeAd.getImageMain.height | ||
nativeAd.getImageBanner | the VMaxAdImage object created in response to the native ad containing a banner image | |
nativeAd.getImageBanner.image | ||
nativeAd.getImageBanner.url | ||
nativeAd.getImageBanner.width | ||
nativeAd.getImageBanner.height | ||
nativeAd.getImageTile | the VMaxAdImage object created in response to the native ad containing a tile image | |
nativeAd.getImageTile.image | ||
nativeAd.getImageTile.url | ||
nativeAd.getImageTile.width | ||
nativeAd.getImageTile.height | ||
nativeAd.getRating | the rating property of the ad | |
nativeAd.getSalePrice | the sale price property of the ad | |
nativeAd.getPrice | the price property of the ad | |
nativeAd.getSponsored | the sponsored property of the ad | |
nativeAd.getLikes | the likes property of the ad | |
nativeAd.getPhone | the phone property of the ad | |
nativeAd.getAddress | the address property of the ad | |
nativeAd.getDesc2 | the description property of the ad | |
nativeAd.getDisplayUrl | the display url property of the ad | |
nativeAd.getDownloadss | the downloads property of the ad | |
nativeAd.getNativeAdPartner | the descriptive native ad partner name e.g: Facebook, AdMob, etc | |
nativeAd.getNativeAdType | the type of the native ad e.g: Infeed, ContentStream, AppInstall, ContentAd etc | |
nativeAd.getLink | the link property of the ad | |
nativeAd.getVastVideoTag | the vast video xml markup property of the ad | |
nativeAd.getObjective | the objective property of the ad |
Additional notes for InMobi Native Ads
From InMobi version 6.0.0 (supported from VMAX iOS SDK v3.5.16), InMobi returns a ‘screenshots’ element on their dashboard as shown in the accompanying image.
1 2 3 4 5 6 |
screenshots = { aspectRatio = “1.91”; height = 313; url = “http://xyz.jpeg”; width = 600; }; |
- If you select an image with aspectRatio ‘1.91’, this is mapped to the ‘imageMain’ element of the Native Ad object. Thus, requesting for imageMedium will result in a nil value.
- If you select an image with aspectRatio ‘1’, this is mapped to the ‘imageMedium’ & ‘imageTile’ elements of the Native Ad object. Thus, requesting for imageMain will result in a nil value.
As a best practice, you should always check if the requested element is nil or not and for non-nil, use the native ad element in rendering your custom native ad layout.
Ad Network Policies
In addition, you need to adhere to the policies shared by AdMob and Facebook here:
- https://support.google.com/admob/answer/6240618
- https://support.google.com/admob/answer/6240809
- https://developers.facebook.com/docs/audience-network/guidelines/native-ads
If using any ad network other that AdMob or Facebook, be sure to include an Ad symbol so that app users can identify that it’s an ad. The below example shows a test ad from VMAX having an icon, large image, title, CTA button and the ad attribution symbol in the top right. The AdChoice icon is also used by some programmatic partners so if you are not using the helper library to render the ad, you should keep an empty space of 15px by 15px at the top right of your ad and ensure that the AdChoice icon is displayed along with the URL sent to you in the ad response.