简体   繁体   English

iAd非页内广告的奇怪行为

[英]Strange Behaviour with iAd Interstitial

I am experiencing some weird behaviour in both ios7 and 8.. 我在ios7和8中都遇到了一些奇怪的行为。

What happens is sometimes the full screen is presented with an X(POTRAIT FUllSCREEN AD - my app is landscape only). 有时会发生全屏显示X(POTRAIT FUllSCREEN AD - 我的应用仅限横向)。 You click the X and you can go back to my menu fine. 你点击X,你可以回到我的菜单。

But sometimes an ad will show without an X(LANDSCAPE FUllSCREEN AD). 但有时广告会显示没有X(LANDSCAPE FUllSCREEN AD)。 If you wait DiDFinish delegate NEVER gets called. 如果你等待DiDFinish委托从未被调用。 So then I try clicking it to go away. 那么我试着点击它就消失了。 It then shows another ad with an X(LANDSCAPE FUllSCREEN AD). 然后它会显示另一个带有X的广告(LANDSCAPE FUllSCREEN AD)。 So i click the X. It then goes to another ad(LANDSCAPE FUllSCREEN AD) where DiDFinish gets called. 所以我点击X.然后转到另一个广告(LANDSCAPE FUllSCREEN AD),在那里DiDFinish iOS7 it'll just freeze on that 3rd ad shown. iOS7它只会冻结显示的第3个广告。 ios8 it'll show the 3rd ad for a second then go to a black screen? ios8它会显示第三个广告,然后转到黑屏? Has anyone dealt with something like this? 有没有人处理过这样的事情?

Not sure if when the first ad shows in portrait orientation it works fine, is a clue or not? 不确定当第一个广告以纵向显示时,它是否正常工作,是否有线索?

Also the multiple ads showing are all iAd not rev mob and iAd combined as I have 100 percent fill rate for iAd. 此外,显示的多个广告都是iAd而不是rev​​ mob和iAd组合,因为我有100%的iAd填充率。 at the moment im just trying to get iAds full screen ads to work consistently 目前我只是试图让iAds全屏广告始终如一地运作

I know the delegate is being set as didLoad delegate gets called when the ad loads Also this is an issue for both iPhone and iPad 我知道委托被设置为广告加载后调用didLoad委托同样这对iPhone和iPad都是一个问题

Has anyone else had these problems? 有没有其他人有这些问题?

Using.. 使用..

[interstitial presentFromViewController:self];

Instead of.. 代替..

[interstitial presentInView:self.view];

makes everything work properly..but presentFromViewController: is deprecated now 使一切正常工作presentFromViewController:现在已弃用

在此输入图像描述

Here is my code I use... 这是我用的代码......

-(void)showFullScreenAd {
    //Check if already requesting ad
    if (requestingAd == NO) {
        //[ADInterstitialAd release];
        interstitial = [[ADInterstitialAd alloc] init];
        interstitial.delegate = self;
        self.interstitialPresentationPolicy = ADInterstitialPresentationPolicyManual;
        [self requestInterstitialAdPresentation];
        NSLog(@"interstitialAdREQUEST");
        requestingAd = YES;
    }
}

-(void)interstitialAd:(ADInterstitialAd *)interstitialAd didFailWithError:(NSError *)error {
    interstitial = nil;
    requestingAd = NO;
    NSLog(@"interstitialAd didFailWithERROR");
    NSLog(@"%@", error);

    [revmobFS loadWithSuccessHandler:^(RevMobFullscreen *fs) {
        [fs showAd];
        NSLog(@"Ad loaded");
    } andLoadFailHandler:^(RevMobFullscreen *fs, NSError *error) {
        NSLog(@"Ad error: %@",error);
    } onClickHandler:^{
        NSLog(@"Ad clicked");
    } onCloseHandler:^{
        NSLog(@"Ad closed");
    }];
}

-(void)interstitialAdDidLoad:(ADInterstitialAd *)interstitialAd {
    NSLog(@"interstitialAdDidLOAD");
    if (interstitialAd != nil && interstitial != nil && requestingAd == YES) {
        [interstitial presentInView:self.view];
        NSLog(@"interstitialAdDidPRESENT");
    }//end if
}

-(void)interstitialAdDidUnload:(ADInterstitialAd *)interstitialAd {
    interstitial = nil;
    requestingAd = NO;
    NSLog(@"interstitialAdDidUNLOAD");
}

-(void)interstitialAdActionDidFinish:(ADInterstitialAd *)interstitialAd {
    interstitial = nil;
    requestingAd = NO;
    NSLog(@"interstitialAdDidFINISH");
}

if someone could just post there code that is fully working in there app for me to try will also earn +50 reputation 如果有人可以发布完全在那里工作的代码供我试用也将获得+50声望

No working code from my end, but I have had a look in the Documentation and found a catergory for UIViewController with iAd methods 我没有工作代码,但我查看了文档并找到了一个用于UIViewController的cater使用iAd方法

Here 这里

It appears you are mixing old code with new code. 看来你正在将旧代码与新代码混合在一起。

From what I have seen I would suggest: 从我所看到的,我建议:

        -(void)showFullScreenAd {
        //Check if already requesting ad
        if (requestingAd == NO) {
            [self requestInterstitialAdPresentation];
            requestingAd = YES;
        }
    }

    -(void)viewDidLoad()
{
    [super viewDidLoad];
// Any other setup.
 self.ADInterstitialPresentationPolicy = ADInterstitialPresentationPolicyManual

}

This follows the new iOS7 implementation. 这是在新的iOS7实现之后。 Setting the policy in the viewDidLoad method allows the Framework to pre cache assets and start getting any ads from the iAd Server. 在viewDidLoad方法中设置策略允许Framework预先缓存资产并开始从iAd服务器获取任何广告。 Ready so when the "showFullScreenAd" method is called an ad should be ready. 准备就绪,当调用“showFullScreenAd”方法时,广告应该准备就绪。

You can also call a class method +(void)prepareInterstitialAds when loading the view or doing other data tasks, this lets the Framework pre-cache assets if it can, which can mean subsequent requests are quicker. 您还可以在加载视图或执行其他数据任务时调用类方法+(void)prepareInterstitialAds ,这样可以使Framework预先缓存资产(如果可以),这可能意味着后续请求更快。

For RevMob handling with ad's failing: [self requestInterstitialAdPresentation]; 对于广告失败的RevMob处理: [self requestInterstitialAdPresentation]; returns a boolean, this means you can handle that and tell RevMob it failed, etc. For when the Ad has been closed. 返回一个布尔值,这意味着你可以处理它并告诉RevMob它失败等等。当广告被关闭时。 It may be best to do some KVO on the presentingFullScreenAd property of the ViewController. 这可能是最好做一些志愿的presentingFullScreenAd的视图控制器的性能。 Which states whether it is showing a FullScreenAd, I believe this is only iAd, Full Ad's. 其中说明它是否显示FullScreenAd,我相信这只是iAd,Full Ad's。

The reason you have such different results is because you have 2 ways of requesting and presenting ad's within the same view controller. 您有这种不同结果的原因是因为您有两种方法可以在同一个视图控制器中请求和展示广告。

When the ad is presented Portrait, the [self requestInterstitialAdPresentation]; 当广告呈现时,肖像为[self requestInterstitialAdPresentation]; failed to retrieve an ad, but the Instantiation of the ADInterstitialAd instance has sent another request. 无法检索广告,但ADInterstitialAd实例的实例化已发送另一个请求。 This has loaded, because you do not set a frame for the instance's view it does not know it is meant to be landscape and so a portrait version is presented. 这已加载,因为您没有为实例的视图设置框架,因此它不知道它是横向的,因此会显示纵向版本。 As this is now presented in the view, the view doesn't know/care what orientation it is in, so presents the ad view based on it's geometry. 由于现在在视图中显示,视图不知道/关心它的方向,因此基于它的几何呈现广告视图。

When it is landscape that is down to the [self requestInterstitialAdPresentation]; 当它是风景,直到[self requestInterstitialAdPresentation]; succeeding. 成功。 That top Ad is the ad from this call. 该热门广告是此次通话中的广告。 I'm not sure why the rest of the ad's display landscape, unless that is something from the Framework, ie the [self requestInterstitialAdPresentation]; 我不确定为什么广告的其余部分会显示出来,除非这是来自框架的东西,即[self requestInterstitialAdPresentation]; internally decides it must be landscape from the ViewControllers layout, so all subsequent ad requests fit this, unless the VC orientation changes again. 内部决定它必须是ViewControllers布局中的横向,因此除非VC方向再次更改,否则所有后续广告请求都符合此要求。

[EDIT] - I have thrown together a basic example piece. [编辑] - 我把一个基本的例子拼凑在了一起。 This has been done from memory/documentation so will probably not be 100% correct and will most likely not work from a direct copy and paste. 这是通过内存/文档完成的,因此可能不会100%正确,很可能无法直接复制和粘贴。 This is to give an idea, which also includes support for versions pre iOS7 这是为了给出一个想法,其中还包括对iOS7之前的版本的支持

//.h 

@import UIKit;
@import iAd;

@interface MyInterstitialViewController : UIViewController <ADInterstitialAdDelegate>
{

}
@property (strong) ADInterstitialAd *fullScreenAd;

@end

//.m

#include MyInterstitialViewController.h

@implementation MyInterstitialViewController
{
    - (instancetype)initWithNibName:(NSString *)nibName bundle:(NSBundle *)nibBundle
    {
        if(self = [super initWithNibName:nibName bundle:nibBundle])
        {

        }
        return self;
    }


    -(void)viewDidLoad()
    {
        [super viewDidLoad];

        if([self respondsToSelector:@selector(requestInterstitialAdPresentation)] == YES)
        {
            self.ADInterstitialPresentationPolicy = ADInterstitialPresentationPolicyManual;
        }
    }

    -(void)viewWillDisappear
    {
        @try 
        {
                    **[self  removeObserver:self forKeyPath:@"isPresentingFullScreenAd"];**
                }
                @catch (NSException * __unused exception) 
        {
        }
    }

    -(void)showFullScreenAd()
    {
        if([self respondsToSelector:@selector(requestInterstitialAdPresentation)] == NO)
        {
            self.fullScreenAd = [[ADInterstitialAd alloc] init];
            self.fullScreenAd.delegate = self;
        }
        else
        {
            if([self requestInterstitialAdPresentation] == NO)
            {
                //Report back to RevMob Controller that the Ad Failed.
                [revmobFS loadWithSuccessHandler:^(RevMobFullscreen *fs) 
                { 
                    [fs showAd]; 
                    NSLog(@"Ad loaded"); 
                } andLoadFailHandler:^(RevMobFullscreen *fs, NSError *error) 
                { 
                    NSLog(@"Ad error: %@",error); 
                } onClickHandler:^{
                    NSLog(@"Ad clicked"); 
                } onCloseHandler:^{
                    NSLog(@"Ad closed"); 
                }]; 
            }
            else
            {
                **[self addObserver:self forKeyPath:@"isPresentingFullScreenAd" options:NSKeyValueObservingOptions.NSKeyValueObservingOptionNew context:nil];**
            }
        }
    }

//ADInterstitialAd Delegate Methods.
-(void)interstitialAd:(ADInterstitialAd *)interstitialAd didFailWithError:(NSError *)error 
{
    interstitial = nil; 
    NSLog(@"interstitialAd didFailWithERROR"); 
    NSLog(@"%@", error); 
    [revmobFS loadWithSuccessHandler:^(RevMobFullscreen *fs) 
        { 
            [fs showAd]; 
            NSLog(@"Ad loaded"); 
        } andLoadFailHandler:^(RevMobFullscreen *fs, NSError *error) 
        { 
            NSLog(@"Ad error: %@",error); 
        } onClickHandler:^{
            NSLog(@"Ad clicked"); 
        } onCloseHandler:^{
            NSLog(@"Ad closed"); 
        }]; 
} 
-(void)interstitialAdDidLoad:(ADInterstitialAd *)interstitialAd 
{
    NSLog(@"interstitialAdDidLOAD"); 
    if (self.fullScreenAd != nil) 
    { 
                   CGRect interstitialFrame = self.view.bounds;
 interstitialFrame.origin = self.view.origin;
 UIView *view = [[UIView alloc] initWithFrame:interstitialFrame];
 [self.view addSubview:view];
[self.fullScreenAd presentInView:view];


        NSLog(@"interstitialAdDidPRESENT"); 
    }//end if
}
-(void)interstitialAdDidUnload:(ADInterstitialAd *)interstitialAd 
{
    NSLog(@"interstitialAdDidUNLOAD");
}
-(void)interstitialAdActionDidFinish:(ADInterstitialAd *)interstitialAd
{
    NSLog(@"interstitialAdDidFINISH"); 
}


//KVO Responding

- (void)observeValueForKeyPath:(NSString *)keyPath
                      ofObject:(id)object
                        change:(NSDictionary *)change
                       context:(void *)context
{
    **if([keyPath isEqualTo:"isPresentingFullScreenAd"] == YES)
    {
        if([object === self])
        {
          if([self isPresentingFullScreenAd] == false)
          {
             //Handle logic for your app. New Screen etc.
          }
          else
          {
            //Handle logic for your app. Pause current activity etc.
          }
        }
    }**
}

}

For reference. 以供参考。

The changes I have made allow for the Ad Framework to work as you are expecting it to on all versions of iOS from 4.3 - 8.X 我所做的更改允许广告框架在4.3 - 8.X的所有版本的iOS上按预期工作

From iOS 4.3 - 6.X the general flow was: 从iOS 4.3 - 6.X开始,一般流程如下:

Create an Ad, set it's delegate, present and handle in the delegate methods. 在委托方法中创建广告,设置其委托,呈现和处理。

From 7 - 8.X (The previous way of presenting in a UIViewController was deprecated in iOS 7, but deprecation means previous methods work until the next X.0 release, generally.) 从7到8.X(之前在UIViewController中呈现的方式在iOS 7中已弃用,但弃用意味着以前的方法一直有效,直到下一个X.0版本,通常。)

For this case you ask the Framework for an ad through the [UIViewController requestInterstitialAdPresentation]; 对于这种情况,您可以通过[UIViewController requestInterstitialAdPresentation]向Framework询问广告; method. 方法。 The Controller will create a View and Present it if it has got an ad. 如果有广告,Controller将创建一个视图并显示它。 You don't get the delegate methods anymore, the "- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context" 你不再获得委托方法,“ - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)对象改变:(NSDictionary *)change context:(void *)context”

method allows you to essentially get the delegate call for when the Ad has finished displaying so you can continue with the logic of your app. 方法允许您在广告完成显示时基本上获得委托调用,以便您可以继续使用应用程序的逻辑。 Essentially the "AdDidFinish" delegate call. 基本上是“AdDidFinish”委托电话。 But as we don't remove the observer until the Controller is unloaded, there is logic to handle if a new ad has been displayed. 但是,由于我们在卸载Controller之前不删除观察者,因此如果显示了新广告,则需要处理逻辑。

This means that the logic for your VC doesn't have to check if it is presenting a full screen ad all the time. 这意味着VC的逻辑不必检查它是否一直呈现全屏广告。

You can still use the flow from iOS 4.3 - 6.X but using the presentInView Method. 您仍然可以使用iOS 4.3 - 6.X中的流程,但使用presentInView方法。 As is described in iAd Programming guide, this should be used if you have a content view inside, what I have set out is a "Transition Ad" Methodology. 正如iAd编程指南中所述,如果你有一个内容视图,我应该使用这个,我已经列出了一个“过渡广告”方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM