Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Native Ad to Objective C #5

Open
wants to merge 25 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ iOs/Swift/Pods/
UserInterfaceState.xcuserstate
xcschememanagement.plist
PodFile.lock
*.DS_Store

#Xamarin
Xamarin/DemoApp_Android/DemoApp_Android/bin/*
Expand Down
166 changes: 140 additions & 26 deletions iOS/Objective C/IronSourceDemoApp/Base.lproj/Main.storyboard

Large diffs are not rendered by default.

4 changes: 4 additions & 0 deletions iOS/Objective C/IronSourceDemoApp/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>GADNativeAdValidatorEnabled</key>
<false/>
<key>GADApplicationIdentifier</key>
<string>ca-app-pub-8308482712547653~4726171084</string>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleExecutable</key>
Expand Down
171 changes: 171 additions & 0 deletions iOS/Objective C/IronSourceDemoApp/LevelPlayNativeAdView.xib

Large diffs are not rendered by default.

29 changes: 29 additions & 0 deletions iOS/Objective C/IronSourceDemoApp/NativeAdView.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
//
// NativeAdView.h
// IronSourceDemoApp
//
// Created by Luga Wang on 9/15/23.
// Copyright © 2023 supersonic. All rights reserved.
//

#import <UIKit/UIKit.h>
#import <IronSource/IronSource.h>

@class NativeAdView;
@protocol NativeAdViewDelegate <NSObject>
- (void)nativeAdViewDeleteButtonTapped:(NativeAdView *)adView;
@end

@interface NativeAdView : UIView

@property (nonatomic, weak) id<NativeAdViewDelegate> delegate;

@property (nonatomic, strong) ISNativeAdView *isNativeAdView;
@property (nonatomic, strong) LevelPlayNativeAd *levelPlayNativeAd;
- (void)loadNativeAdLayout: (LevelPlayNativeAd *)nativeAd;

@property (nonatomic, strong) UILabel *adBadge;
@property (nonatomic, strong) UIButton *deleteButton;
@property (nonatomic, strong) UIView *topView;

@end
98 changes: 98 additions & 0 deletions iOS/Objective C/IronSourceDemoApp/NativeAdView.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
//
// NativeAdView.m
// IronSourceDemoApp
//
// Created by Luga Wang on 9/15/23.
// Copyright © 2023 supersonic. All rights reserved.
//

#import "NativeAdView.h"

@implementation NativeAdView

- (instancetype)init {
self = [super init];
if (self) {
UINib *nib = [UINib nibWithNibName:@"LevelPlayNativeAdView" bundle:[NSBundle mainBundle]];
NSArray *nibContents = [nib instantiateWithOwner:nil options:nil];
_isNativeAdView = (ISNativeAdView *)[nibContents firstObject];
[self configDeleteButton];

// Avoid conflicts of constraints
self.translatesAutoresizingMaskIntoConstraints = NO;
_isNativeAdView.translatesAutoresizingMaskIntoConstraints = NO;
}
return self;
}

// This adding a customized delete button to the NativeAdView that removes the native ad from the table view and call the destory API.
- (void) configDeleteButton {
_deleteButton = [UIButton buttonWithType:UIButtonTypeCustom];
_deleteButton.showsTouchWhenHighlighted = YES;
[_deleteButton setTitle:@"x" forState:UIControlStateNormal];
_deleteButton.backgroundColor = [UIColor lightGrayColor];
_deleteButton.layer.cornerRadius = 15;
[_deleteButton addTarget:self action:@selector(deleteButtonTapped:) forControlEvents:UIControlEventTouchUpInside];
_deleteButton.translatesAutoresizingMaskIntoConstraints = NO;

[_isNativeAdView addSubview:_deleteButton];
[NSLayoutConstraint activateConstraints:@[
maozel marked this conversation as resolved.
Show resolved Hide resolved
[_deleteButton.widthAnchor constraintEqualToConstant:30],
[_deleteButton.heightAnchor constraintEqualToConstant:30],
[_deleteButton.topAnchor constraintEqualToAnchor:_isNativeAdView.topAnchor],
[_deleteButton.trailingAnchor constraintEqualToAnchor:_isNativeAdView.trailingAnchor],
]];
}

// This was triggered after a successful load of a native ad.
- (void)loadNativeAdLayout:(LevelPlayNativeAd *)nativeAd {
_levelPlayNativeAd = nativeAd;

if (_levelPlayNativeAd.icon.image) {
_isNativeAdView.adAppIcon.image = _levelPlayNativeAd.icon.image;
} else {
[_isNativeAdView.adAppIcon removeFromSuperview];
}

if (_levelPlayNativeAd.title) {
_isNativeAdView.adTitleView.text = _levelPlayNativeAd.title;
}

if (_levelPlayNativeAd.advertiser) {
LugaWUnity marked this conversation as resolved.
Show resolved Hide resolved
_isNativeAdView.adAdvertiserView.text = _levelPlayNativeAd.advertiser;
}

if (_levelPlayNativeAd.body) {
LugaWUnity marked this conversation as resolved.
Show resolved Hide resolved
_isNativeAdView.adBodyView.text = _levelPlayNativeAd.body;
}

if (_levelPlayNativeAd.callToAction) {
[_isNativeAdView.adCallToActionView setTitle:_levelPlayNativeAd.callToAction forState:UIControlStateNormal];
_isNativeAdView.adCallToActionView.userInteractionEnabled = NO;
}

[_isNativeAdView registerNativeAdViews:_levelPlayNativeAd];

// Bring the delete button to the front of the layer
[_isNativeAdView bringSubviewToFront:_deleteButton];

[self addSubview:_isNativeAdView];
// Constraints between self and _isNativeAdView
[NSLayoutConstraint activateConstraints:@[
[_isNativeAdView.widthAnchor constraintEqualToAnchor:self.widthAnchor],
[self.heightAnchor constraintEqualToAnchor:_isNativeAdView.heightAnchor],
[_isNativeAdView.centerXAnchor constraintEqualToAnchor:self.centerXAnchor],
]];
}

// Remove the native ad from the table view.
- (void)deleteButtonTapped:(UIButton *)sender {
// Check if the delegate responds to the delete button tap selector
if ([self.delegate respondsToSelector:@selector(nativeAdViewDeleteButtonTapped:)]) {
// Call the delegate method
[self.delegate nativeAdViewDeleteButtonTapped:self];
}
}


@end
17 changes: 17 additions & 0 deletions iOS/Objective C/IronSourceDemoApp/NativeAdViewController.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
//
// NativeAdViewController.h
// IronSourceDemoApp
//
// Created by Luga Wang on 9/15/23.
// Copyright © 2023 supersonic. All rights reserved.
//

#import <UIKit/UIKit.h>

NS_ASSUME_NONNULL_BEGIN

@interface NativeAdViewController : UIViewController

@end

NS_ASSUME_NONNULL_END
175 changes: 175 additions & 0 deletions iOS/Objective C/IronSourceDemoApp/NativeAdViewController.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
//
// NativeAdViewController.m
// IronSourceDemoApp
//
// Created by Luga Wang on 9/15/23.
// Copyright © 2023 supersonic. All rights reserved.
//

#import "NativeAdViewController.h"
#import "NativeAdView.h"
#import <IronSource/IronSource.h>

@interface NativeAdViewController () <LevelPlayNativeAdDelegate, UITableViewDelegate, UITableViewDataSource, NativeAdViewDelegate>

@property (weak, nonatomic) IBOutlet UITableView *tableView;
@property (weak, nonatomic) IBOutlet UIButton *loadNAButton;

// This is an array of pairs of <LevelPlayNativeAd, NativeAdView>.
@property (nonatomic, strong) NSMutableArray<NSArray *> *nativeAdList;
// This is an array of <NativeAdView> that will be used as the data source of the UITableView.
@property (nonatomic, strong) NSMutableArray *tableViewData;

@end

@implementation NativeAdViewController

- (instancetype)initWithCoder:(NSCoder *)aDecoder {
self = [super initWithCoder:aDecoder];
if (self) {
_nativeAdList = [NSMutableArray array];
_tableViewData = [NSMutableArray array];
}
return self;
}

- (void)viewDidLoad {
[super viewDidLoad];

// add a border to the loadNAButton
_loadNAButton.layer.cornerRadius = 17.0f;
_loadNAButton.layer.masksToBounds = YES;
_loadNAButton.layer.borderWidth = 3.5f;
_loadNAButton.layer.borderColor = [[UIColor grayColor] CGColor];
}


- (IBAction)loadNAButtonTapped:(id)sender {
// This will build and try to load a Native Ad; then store the [adObject, adView] pair to the list self.nativeAdList

LevelPlayNativeAd *nativeAd = [[[[LevelPlayNativeAdBuilder new] withViewController:self] withPlacementName:@""] withDelegate:self].build;

if (nativeAd) {
[nativeAd loadAd];

NativeAdView *newView = [[NativeAdView alloc] init];
newView.delegate = self;
[self.nativeAdList addObject:@[nativeAd, newView]];
nativeAd = nil;
newView = nil;
}
}

- (void)nativeAdViewDeleteButtonTapped:(NativeAdView *)currentAdView {
// Find the corresponding NativeAdView and remove it
NSInteger index = -1;
for (NSInteger i = 0; i < self.nativeAdList.count; i++) {
NSArray *pair = self.nativeAdList[i];
if ([pair.lastObject isEqual:currentAdView]) {
index = i;
break;
}
}

if (index != -1) {
NSArray *pair = self.nativeAdList[index];
LevelPlayNativeAd *nativeAd = pair[0];
NativeAdView *adView = pair[1];

[nativeAd destroyAd];

NSIndexPath *indexPath = [NSIndexPath indexPathForRow:index inSection:0];
[self.tableViewData removeObject:adView];
[self.tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];

// make sure remove the object from the list to prevent leak
[self.nativeAdList removeObject:pair];
nativeAd = nil;
adView = nil;
}
}

#pragma mark - LevelPlayNativeAdDelegate Functions

// ISNativeAdLoadDelegate

// This method gets invoked after a failed attempt to load Native Ad.
// If it does happen, check out 'error' for more information and consult our
// Knowledge center.
- (void)didFailToLoad:(nonnull LevelPlayNativeAd *)nativeAd withError:(nonnull NSError *)error {
NSLog(@"%s",__PRETTY_FUNCTION__);
}

// This method gets invoked after a native ad was loaded.
// Then the information will be passed to the NativeAdView and added to your data source.
- (void)didLoad:(nonnull LevelPlayNativeAd *)nativeAd withAdInfo:(nonnull ISAdInfo *)adInfo {
NSLog(@"%s",__PRETTY_FUNCTION__);

// Find the index of the pair from self.nativeAdList based on the current loaded ad object.
NSInteger index = -1;
for (NSInteger i = 0; i < self.nativeAdList.count; i++) {
NSArray *pair = self.nativeAdList[i];
if ([pair.firstObject isEqual:nativeAd]) {
index = i;
break;
}
}

// Get the [adObject, adView] pair from the index and load the associated UIView.
if (index != -1) {
NSArray *pair = self.nativeAdList[index];
NativeAdView *adView = pair[1];

[adView loadNativeAdLayout:nativeAd];

NSIndexPath *indexPath = [NSIndexPath indexPathForRow:index inSection:0];
[self.tableViewData addObject:adView]; // Add the adView to your data source.
adView = nil;
[self.tableView insertRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];

// Scroll to the newly added cell
NSIndexPath *latestIndexPath = [NSIndexPath indexPathForRow:self.tableViewData.count - 1 inSection:0];
[self.tableView scrollToRowAtIndexPath:latestIndexPath atScrollPosition:UITableViewScrollPositionBottom animated:YES];
}
}

// ISNativeAdInteractionDelegate

// This method gets invoked after a native ad has been clicked
- (void)didClick:(nonnull LevelPlayNativeAd *)nativeAd withAdInfo:(nonnull ISAdInfo *)adInfo {
NSLog(@"%s",__PRETTY_FUNCTION__);
}

// This method gets invoked after a native ad impression has been recorded
- (void)didRecordImpression:(nonnull LevelPlayNativeAd *)nativeAd withAdInfo:(nonnull ISAdInfo *)adInfo {
maozel marked this conversation as resolved.
Show resolved Hide resolved
NSLog(@"%s",__PRETTY_FUNCTION__);
}

#pragma mark - UI TableView Delegate Functions
- (nonnull UITableViewCell *)tableView:(nonnull UITableView *)tableView cellForRowAtIndexPath:(nonnull NSIndexPath *)indexPath {
id cellData = _tableViewData[indexPath.row];
LugaWUnity marked this conversation as resolved.
Show resolved Hide resolved
if ([cellData isKindOfClass:[NativeAdView class]]) {
// Return the NativeAdView as a cell.
NativeAdView *adView = (NativeAdView *)cellData;
UITableViewCell *adCell = [[UITableViewCell alloc] init];
[adCell.contentView addSubview:adView];

[NSLayoutConstraint activateConstraints:@[
[adView.widthAnchor constraintEqualToAnchor:adCell.contentView.widthAnchor constant:0],
[adView.centerXAnchor constraintEqualToAnchor:adCell.contentView.centerXAnchor constant:0],

[adCell.contentView.heightAnchor constraintEqualToAnchor:adView.heightAnchor constant:0],
[adView.centerYAnchor constraintEqualToAnchor:adCell.contentView.centerYAnchor constant:0],
]];
adView = nil;
return adCell;
}
cellData = nil;
return nil;
}

- (NSInteger)tableView:(nonnull UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return _tableViewData.count;
}

@end
Loading