从admobs中显示GADInterstitial后出现问题。
我的工作是:
现在应用程序因 SIGSEGV错误而崩溃,原因为
objc_msgSend()选择器名称:_setContentMargin:
。它接缝我的记忆有一些问题,它是新的安排或什么的。它现在有一个新对象,它没有选择器的响应器。但它只发生在我打开一次GADInterstitial之后。如果我没有打开GADInterstitial,它会毫无问题地运行。
我加载并在示例中显示像Google一样的插页式广告...我不知道会发生什么......
我有一个全局的UIViewController决定是否要显示广告。如果没有,它将contenViewController直接包装为ChildViewController。如果必须显示广告,其childviewController将是“AdViewContoller”。然后,它将内容包装为ChildViewController:
所以我有以下结构:
这是我的AdViewController:
import UIKit
import GoogleMobileAds
let kAD_UNIT_ID_BANNER_AD: String = "ca-app-pub-3940256099942544/2934735716"
let kAD_UNIT_ID_INTERSTITIAL_AD: String = "ca-app-pub-3940256099942544/4411468910"
let kVIEW_CONTROLLER_ALLOWS_TO_SHOW_INTERSTITIAL_NOTIFICATION: String = "kviewcontrollerallowstoshowinterstitialnotification"
class AdViewController: UIViewController, GADBannerViewDelegate {
var childController: UIViewController? {
didSet {
if self.childController != nil {
self.addChildViewController(self.childController!)
}
}
}
var contentView: UIView = UIView()
var adLayoutConstraint: NSLayoutConstraint?
let adView: UIView = UIView();
let gadAdView: GADBannerView = GADBannerView(adSize: kGADAdSizeSmartBannerPortrait)
var intAdView: GADInterstitial?
override func viewDidLoad() {
super.viewDidLoad()
if self.childController != nil {
self.view.addSubview(self.childController!.view)
self.contentView = self.childController!.view
self.contentView.translatesAutoresizingMaskIntoConstraints = false
}
self.view.addSubview(self.adView)
self.adView.translatesAutoresizingMaskIntoConstraints = false
self.adView.backgroundColor = UIColor.blackColor()
self.view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:|[content]|", options: NSLayoutFormatOptions(rawValue: 0), metrics: nil, views: ["content":self.contentView]))
self.view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:|[ad]|", options: NSLayoutFormatOptions(rawValue: 0), metrics: nil, views: ["ad":self.adView]))
self.view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|[content][ad]|", options: NSLayoutFormatOptions(rawValue: 0), metrics: nil, views: ["ad":self.adView, "content":self.contentView]))
self.adLayoutConstraint = NSLayoutConstraint(item: self.adView, attribute: .Height, relatedBy: .Equal, toItem: nil, attribute: .NotAnAttribute, multiplier: 1, constant: 50
)
self.adView.addConstraint(self.adLayoutConstraint!)
self.adView.addSubview(self.gadAdView)
self.gadAdView.translatesAutoresizingMaskIntoConstraints = false
self.adView.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:[gad]|", options: NSLayoutFormatOptions(rawValue: 0), metrics: nil, views: ["gad":self.gadAdView]))
self.adView.addConstraint(NSLayoutConstraint(item: self.gadAdView, attribute: .CenterX, relatedBy: .Equal, toItem: self.adView, attribute: .CenterX, multiplier: 1, constant: 0))
//self.adView.addConstraint(NSLayoutConstraint(item: self.gadAdView, attribute: .Width, relatedBy: .Equal, toItem: nil, attribute: .NotAnAttribute, multiplier: 1, constant: 320))
gadAdView.adUnitID = kAD_UNIT_ID_BANNER_AD
gadAdView.rootViewController = self
gadAdView.loadRequest(GADRequest())
gadAdView.delegate = self
self.hideBanner()
NSNotificationCenter.defaultCenter().addObserver(self, selector: "askedForInterstitial:", name: kVIEW_CONTROLLER_ALLOWS_TO_SHOW_INTERSTITIAL_NOTIFICATION, object: nil)
NSNotificationCenter.defaultCenter().addObserver(self, selector: "initInterstitial", name: UIApplicationDidBecomeActiveNotification, object: nil)
// Do any additional setup after loading the view.
}
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
}
func hideBanner() -> Void {
self.adLayoutConstraint?.constant = 0
self.view.layoutIfNeeded()
}
func showBanner() -> Void {
self.adLayoutConstraint?.constant = 50
self.view.layoutIfNeeded()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func initInterstitial() -> Void {
print("UIApplicationDidBecomeActiveNotification called!")
self.intAdView = GADInterstitial(adUnitID: kAD_UNIT_ID_INTERSTITIAL_AD)
let request = GADRequest()
self.intAdView?.loadRequest(request)
}
init(subController: UIViewController) {
super.init(nibName: nil, bundle: nil)
self.childController = subController
self.addChildViewController(self.childController!)
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
func adViewDidReceiveAd(bannerView: GADBannerView!) {
self.showBanner()
}
func adView(bannerView: GADBannerView!, didFailToReceiveAdWithError error: GADRequestError!) {
self.hideBanner()
}
func askedForInterstitial(notification:NSNotification) -> Void {
if notification.userInfo != nil {
if let c = notification.userInfo!["controller"] as? UIViewController {
self.showInterstitialInController(c)
} else {
self.showInterstitialInController(self)
}
} else {
self.showInterstitialInController(self)
}
}
class func presentInterstitial() -> Void {
AdViewController.presentInterstitialInController(nil)
}
class func presentInterstitialInController(c: UIViewController?) {
if c == nil {
NSNotificationCenter.defaultCenter().postNotificationName(kVIEW_CONTROLLER_ALLOWS_TO_SHOW_INTERSTITIAL_NOTIFICATION, object: nil)
}
else {
NSNotificationCenter.defaultCenter().postNotificationName(kVIEW_CONTROLLER_ALLOWS_TO_SHOW_INTERSTITIAL_NOTIFICATION, object: nil, userInfo: ["controller": c!])
}
}
private func showInterstitialInController(c: UIViewController) -> Void {
if self.intAdView != nil && self.intAdView!.isReady {
self.intAdView!.presentFromRootViewController(c)
}
}
/*
// MARK: - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
// Get the new view controller using segue.destinationViewController.
// Pass the selected object to the new view controller.
}
*/
}
此控制器也有横幅。但是当我试图告诉你我的整个过程时,我想你也必须看到它。
我有两个类函数presentInterstitial
和presentInterstitialInController
,所有hirarchy的childview控制器都可以要求显示插页式广告。这很好用,但正如我所说的那样,应用程序在后台运行后会出现问题。
感谢您的帮助
阿图尔
答案 0 :(得分:0)
好的,我已经解决了......
问题不在于插页式广告,而是我为UIApplicationDidBecomeActiveNotification
通知名称添加观察者的行:
我有一个功能:
func initInterstitial() -> Void {
print("UIApplicationDidBecomeActiveNotification called!")
self.intAdView = GADInterstitial(adUnitID: kAD_UNIT_ID_INTERSTITIAL_AD)
let request = GADRequest()
self.intAdView?.loadRequest(request)
}
我添加此功能作为
的观察者NSNotificationCenter.defaultCenter().addObserver(self, selector: "initInterstitial", name: UIApplicationDidBecomeActiveNotification, object: nil)
第二次调用通知后,我的应用程序没有崩溃。
现在,如果我将该功能重命名为createInterstital
:
func createInterstitial() -> Void {
print("UIApplicationDidBecomeActiveNotification called!")
self.intAdView = GADInterstitial(adUnitID: kAD_UNIT_ID_INTERSTITIAL_AD)
let request = GADRequest()
self.intAdView?.loadRequest(request)
}
我添加了这样的观察者:
NSNotificationCenter.defaultCenter().addObserver(self, selector: "createInterstitial", name: UIApplicationDidBecomeActiveNotification, object: nil)
所有作品都很完美......
我不知道为什么,但NotificationCenter似乎不喜欢使用init的函数。
希望这可以帮助一些人。
问候
阿图尔