2015-09-07 30 views
1

我在Swift 2中制作了一个使用Xcode 7 beta和SpriteKit的iAd插页式游戏,我尝试使用一个函数来移除它们,但它不起作用。我使用两个不同的文件,GameScene.swiftGameViewController.swift。我在文件中使用如何从Swift 2中使用SpriteKit和Xcode 7 beta应用程序中删除iAd?

代码,GameScene.swift

func gameOver() { 
    isGameOver = true 
    print("Game Over") 

    loadAd() 
} 
//iAd 
func close(sender: UIButton) { 
    closeButton.removeFromSuperview() 
    interAdView.removeFromSuperview() 
} 


func loadAd() { 
    print("load ad") 
    interAd = ADInterstitialAd() 
    interAd.delegate = self 

    closeButton.frame = CGRectMake(15, 15, 22, 22) 
    closeButton.layer.cornerRadius = 11 
    closeButton.setTitle("x", forState: .Normal) 
    closeButton.setTitleColor(UIColor.blackColor(), forState: .Normal) 
    closeButton.backgroundColor = UIColor.whiteColor() 
    closeButton.layer.borderColor = UIColor.blackColor().CGColor 
    closeButton.layer.borderWidth = 1 
    closeButton.addTarget(self, action: "close:", forControlEvents: UIControlEvents.TouchDown) 

} 

func interstitialAdDidLoad(interstitialAd: ADInterstitialAd!) { 
    print("ad did load") 

    interAdView = UIView() 
    interAdView.frame = self.view!.bounds 
    view!.addSubview(interAdView) 

    interAd.presentInView(interAdView) 
    UIViewController.prepareInterstitialAds() 

    interAdView.addSubview(closeButton) 
} 

func interstitialAdDidUnload(interstitialAd: ADInterstitialAd!) { 

} 

func interstitialAd(interstitialAd: ADInterstitialAd!, didFailWithError error: NSError!) { 
    print("failed to receive") 
    print(error.localizedDescription) 

    closeButton.removeFromSuperview() 
    interAdView.removeFromSuperview() 

} 

GameViewController.swift是在应用程序内购买去除广告(购买Pro版本):

@IBAction func removeAds(sender: UIButton) { 
    print("Remove Ads Button pressed") 
    for product in list { 
     let prodID = product.productIdentifier 
     if(prodID == "Squares.RemoveAds") { 
      p = product 
      buyProduct() 
      break; 
     } 
    } 
    SKPaymentQueue.defaultQueue().addTransactionObserver(self) 
    SKPaymentQueue.defaultQueue().restoreCompletedTransactions() 
} 


func removeAds() { 

} 

override func prefersStatusBarHidden() -> Bool { 
    return true 
} 

//Remove Ads Payment 
var list = [SKProduct]() 
var p = SKProduct() 


//Squares.regular.removeAds 
//Squares.6Plus.removeAds 


func buyProduct() { 
    print("Buy" + p.productIdentifier) 
    let pay = SKPayment(product: p) 
    SKPaymentQueue.defaultQueue().addTransactionObserver(self) 
    SKPaymentQueue.defaultQueue().addPayment(pay as SKPayment) 
} 

func productsRequest(request: SKProductsRequest, didReceiveResponse response: SKProductsResponse) { 
    print("Product Request") 
    let myProduct = response.products 

    for product in myProduct { 
     print("Product Added") 
     print(product.productIdentifier) 
     print(product.localizedTitle) 
     print(product.localizedDescription) 
     print(product.price) 

     list.append(product as SKProduct) 
    } 
    removeAdsButton.enabled = true 
    removeAdsIPhone6Plus.enabled = true 
} 

func paymentQueueRestoreCompletedTransactionsFinished(queue: SKPaymentQueue) { 
    print("Transactions Restored") 

    var purchasedItemIDS = [] 
    for transaction in queue.transactions { 
     let t: SKPaymentTransaction = transaction as SKPaymentTransaction 

     let prodID = t.payment.productIdentifier as String 

     switch prodID { 
     case "Squares.RemoveAds": 
      print("Remove Ads") 
      removeAds() 
     case "Squares.RemoveAds": 
      print("Remove Ads for iPhone 6 Plus") 
      removeAds() 
     default: 
      print("IAP not setup") 
     } 

    } 
} 

func paymentQueue(queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) { 
    print("Add Payment") 

    for transaction:AnyObject in transactions { 
     let trans = transaction as! SKPaymentTransaction 
     print(trans.error) 

     switch trans.transactionState { 

     case .Purchased: 
      print("Buy, Ok unlock Squares here") 
      print(p.productIdentifier) 

      let prodID = p.productIdentifier as String 
      switch prodID { 
       case "Squares.RemoveAds": 
       print("Remove Ads") 
       removeAds() 
       case "Squares.RemoveAds": 
       print("Remove Ads for iPhone 6 Plus") 
       removeAds() 
      default: 
       print("IAP not Setup") 
      } 

      queue.finishTransaction(trans) 
      break; 
     case .Failed: 
      print("Buy Error") 
      queue.finishTransaction(trans) 
      break; 
     default: 
      print("Default") 
      break; 

     } 
    } 
} 

func finishTransaction(trans:SKPaymentTransaction){ 
    print("Finish Transaction") 
} 

func paymentQueue(queue: SKPaymentQueue, removedTransactions transactions: [SKPaymentTransaction]) { 
    print("Remove Transaction") 
} 

如果您阅读文件中的代码,GameViewController.swift函数removeAds()为空,并在同一个fi中的某些代码中调用le,所以它会永远删除广告,我需要做的是将功能removeAds()中的代码永久删除广告,问题是我不知道如何调用它以及以何种方式删除它们,因为函数在不同的文件中,我尝试了很多方法,但不起作用。 你能告诉我更多的细节如何做到这一点?

回答

2

好吧,基本上有了更好的代码的新方法。 首先制作一份您的项目,只需要一份。 其次,请仔细聆听并遵守我的指示。

所以我发布了一个已经与购买代码的答案。检查你是否按照我所说的完全按照指示。删除GameScene中关于广告的所有代码。所有它像NSNotifcationCenter,函数,ADInterstitialAdDelegate(在gamescene的顶部)等 比你在你的项目中创建一个新的swift文件,并输入此代码。

这是我的助手的瘦身版本,它现在包括互动广告和横幅广告。要设置横幅,请执行以下操作。在根据进口UIKit的应用程序委托你写

import iAd 
let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate 
中的appDelegate

仍然类实现下你必须创建这个属性

var bannerAdView = ADBannerView() 

之所以这样进入的appDelegate是因为我们正在创建一个共享iAdBanner 。 spritekit并不是真的需要1个viewController,但是这对于具有多个viewController的应用程序来说是正确的方式,所以你不妨使用它。 比以前复制到您的项目。

import iAd 

class Ads: NSObject { 

    // MARK: - Properties 
    static let sharedInstance = Ads() 

    var presentingViewController: UIViewController! 

    var interAd = ADInterstitialAd() 
    var interAdView = UIView() 
    var interAdCloseButton = UIButton.buttonWithType(UIButtonType.System) as! UIButton 

    override init() { 
     super.init() 

     print("Ads Helper init") 

     preloadInterAd() // preload first interAd, they will preload automatically afterwards. 
    } 
     // MARK: - User Methods 
     class func showBannerAd() { 
     Ads.sharedInstance.loadBannerAd() 
     } 

     class func showInterAd() { 
      Ads.sharedInstance.showInterAd() 
     } 

     class func removeBannerAds() { 
      Ads.sharedInstance.removeBannerAds() 
     } 

     class func removeAllAds() { 
     Ads.sharedInstance.removeAllAds() 
     } 


     //MARK: - Internal Methods 

    // loading banner 
    private func loadBannerAd() { 
     printDebug("iAd banner loading...") 
     appDelegate.bannerAdView = ADBannerView(frame: presentingViewController.view.bounds) 
     appDelegate.bannerAdView.delegate = self 
     appDelegate.bannerAdView.center = CGPoint(x: CGRectGetMidX(presentingViewController.view.frame), y: CGRectGetMaxY(presentingViewController.view.frame) + (appDelegate.bannerAdView.frame.size.height/2)) 
    } 

    // preloading inter 
    private func preloadInterAd() { 
     print("iAds Inter preloading") 
     interAd = ADInterstitialAd() 
     interAd.delegate = self 

     interAdCloseButton.frame = CGRectMake(13, 13, 22, 22) 
     interAdCloseButton.layer.cornerRadius = 12 
     interAdCloseButton.setTitle("X", forState: .Normal) 
     interAdCloseButton.setTitleColor(UIColor.grayColor(), forState: .Normal) 
     interAdCloseButton.backgroundColor = UIColor.whiteColor() 
     interAdCloseButton.layer.borderColor = UIColor.grayColor().CGColor 
     interAdCloseButton.layer.borderWidth = 2 
     interAdCloseButton.addTarget(self, action: "pressedCloseButton:", forControlEvents: UIControlEvents.TouchDown) // function such as this with content in brackets need : for selector. VIP 
    } 

    private func showInterAd() { 
     if interAd.loaded { 
      print("iAds Inter showing") 
      presentingViewController.view.addSubview(interAdView) 
      interAd.presentInView(interAdView) 
      UIViewController.prepareInterstitialAds() 
      interAdView.addSubview(interAdCloseButton) 

      // pause game, music etc here 
     } else { 
      print("iAds Inter cannot be shown, reloading") 
      preloadInterAd() 
     } 
    } 

    // closed inter ad 
    func pressedCloseButton(sender: UIButton) { 
     interAdCloseButton.removeFromSuperview() 
     interAdView.removeFromSuperview() 
     interAd.delegate = nil 

     preloadInterAd() 
    } 

    // remove banner ads 
    private func removeBannerAds() { 
     appDelegate.bannerAdView.delegate = nil 
     appDelegate.bannerAdView.removeFromSuperview() 
    } 

    // remove all ads 
    private func removeAllAds() { 
     // banners 
     appDelegate.bannerAdView.delegate = nil 
     appDelegate.bannerAdView.removeFromSuperview() 

     // inter 
     interAdCloseButton.removeFromSuperview() 
     interAdView.removeFromSuperview() 
     interAd.delegate = nil 
    } 
} 

// MARK: iAds Banner Delegates 
extension Ads: ADBannerViewDelegate { 

    func bannerViewWillLoadAd(banner: ADBannerView!) { 
     printDebug("iAds banner will load") 
    } 

    func bannerViewDidLoadAd(banner: ADBannerView!) { 
     printDebug("iAds banner did load, showing") 
     presentingViewController.view.addSubview(appDelegate.bannerAdView) 
     UIView.beginAnimations(nil, context: nil) 
     UIView.setAnimationDuration(1.5) 
     appDelegate.bannerAdView.center = CGPoint(x: CGRectGetMidX(presentingViewController.view.frame), y: CGRectGetMaxY(presentingViewController.view.frame) - (appDelegate.bannerAdView.frame.size.height/2)) 
     UIView.commitAnimations() 
    } 

    func bannerViewActionShouldBegin(banner: ADBannerView!, willLeaveApplication willLeave: Bool) -> Bool { 
     printDebug("iAds banner clicked") 
     // pause game , music etc here 
     return true 
    } 

    func bannerViewActionDidFinish(banner: ADBannerView!) { 
     printDebug("iAds banner closed") 
     // resume game, music here 
    } 

    func bannerView(banner: ADBannerView!, didFailToReceiveAdWithError error: NSError!) { 
     printDebug("iAds banner error") 
     UIView.beginAnimations(nil, context: nil) 
     UIView.setAnimationDuration(1.5) 
     appDelegate.bannerAdView.center = CGPoint(x: CGRectGetMidX(presentingViewController.view.frame), y: CGRectGetMaxY(presentingViewController.view.frame) + (appDelegate.bannerAdView.frame.size.height/2)) 
     appDelegate.bannerAdView.hidden = true 
     UIView.commitAnimations() 

    } 
} 


// MARK: - iAds Inter Delegates 
extension Ads: ADInterstitialAdDelegate { 

    func interstitialAdDidLoad(interstitialAd: ADInterstitialAd!) { 
     print("iAds Inter did preload") 
     interAdView = UIView() 
     interAdView.frame = presentingViewController.view.bounds 
    } 

    func interstitialAdDidUnload(interstitialAd: ADInterstitialAd!) { 
     print("iAds Inter did unload") 
    } 

    func interstitialAd(interstitialAd: ADInterstitialAd!, didFailWithError error: NSError!) { 
     print("iAds Inter error") 
     print(error.localizedDescription) 
     interAdCloseButton.removeFromSuperview() 
     interAdView.removeFromSuperview() 
     interAd.delegate = nil 

     preloadInterAd() 
    } 
} 

好的。现在,所有你需要做的就是写一行代码来初始化这个助手和预加载第一国际(他们会自动预载之后。)

在viewDidLoad中你gameViewController调用此

// this tells the ad helper that this is the GameViewController that shows ads. 
    // This step also inits the adHelper and preloads the first inter ad. 
    Ads.sharedInstance.presentingViewController = self 

而这就是它。在FUNC GAMEOVER()或任何你想要你的GameScene你现在简单地说

Ads.showInterAd() 
Ads.showBannerAd() 

您可以在控制台中经常检查广告是否预装,因为我的每一步都做prinln。如果广告未预加载,则无法显示。这有助于你理解发生了什么。

在您的申购代码gameViewController你现在简单地说

Ads.removeAllAds() 

和所有的广告都被删除。

如果你只是想删除BannerAds,例如在游戏过程中,简单地说

Ads.removeBannerAds() 

,只要你有 Ads.showBannerAd()

要保存购买你做的比再次加载它们这个。

在功能removeAllAds()在结尾

NSUserDefaults.standardUserDefaults().setBool(true, forKey: "your product ID") 

任何地方在你的代码,你会说Ads.showInterAd()或Ads.showBannerAd()之类FUNC GAMEOVER()你写的这个权利说

// You can use your product Id as a key, and you dont actually have to set a var. So its the easiest this way. If it cannot find a bool for your product ID it will automatically set it to false. Very nice. 
    // A reason I made the structs with the product ID is so its easier to reference it so you dont have to type it out every time. 
    if NSUserDefaults.standardUserDefaults().boolForKey("your product ID") == false { 
     Ads.showInterAd() 
    } 

完成

+0

现在我将清理意见,现在,很高兴它为你工作。未来还有一件事你可能会考虑将数据保存在Keychain而不是NSUserDefaults中,尤其是在应用程序购买等方面。否则,如果您拥有越狱设备,则很容易解锁。这是我使用的帮手,它非常简单。 https://github.com/jrendel/SwiftKeychainWrapper – crashoverride777

+0

这里是我用于Game Center的代码,我也有一些问题。 http://stackoverflow.com/questions/32145090/how-to-make-high-score-of-game-to-be-saved-on-leaderboard-with-swift 检查答案呢! 如果你想添加我在Facebook上这是它: https://www.facebook.com/Emin.Rma.Emini.Im.Madridista.A.JoCcKeR.Rma – Emm

+2

太棒了。我想你应该真的只是得到我的全部帮手,因为你已经使用了一半。我还会说约20-30%的下载来自不支持iAd的国家。另外,iAds有时会失败,所以你总是把Google作为备份。它非常值得,特别是像我们这样的独立开发者。它可能会让你最多30分钟设置你的谷歌帐户等我做了一步一步的指示,所以应该没有问题。 https://github.com/crashoverride777/Swift-iAds-and-AdMob-Helper – crashoverride777

1

您可以使用NSNotifcationCenter。

在你的viewController

所以在removeAds功能,你会说

NSNotificationCenter.defaultCenter().addObserver(self, selector: "removeAds", name: "RemoveAdsKey", object: nil) 

不是每当你想调用这个函数,你会说

NSNotificationCenter.defaultCenter().postNotificationName("RemoveAdsKey", object: nil) 

在问候的功能removeAds()本身。你需要写这样的东西。

closeButton.removeFromSuperview() 
    interAdView.removeFromSuperview() 
    interAd.delegate = nil 

您应该尽快添加SKpayment交易观察员并且只能添加一次,而不是每次购买。 只有在游戏关闭时才能移除观察者。很多教程向您展示了Apple不推荐的方式。 https://developer.apple.com/library/ios/technotes/tn2387/_index.html

为了让您的生活更轻松,为什么不检查一下我在gitHub上发布的iAds和Admob帮助器,它主要是为SpriteKit制作的。 https://github.com/crashoverride777/Swift-iAds-and-AdMob-Helper

即使你不想使用它,这应该会给你一个如何使用委托等的想法。没有什么复杂的,只是使用广告的基本方式。它还会向您展示如何预加载interAds,使其显示速度更快。

1

我用苹果链接更新了我的第一个答案。这并不是说你的方式是错误的,但苹果专门给出了一个好的和不好的实现例子,不幸的是大多数教程都是这样做的不好的方式。 在您的具体情况下,您可以执行以下操作。

添加2个NSNotification中心观察员您的viewController

NSNotificationCenter.defaultCenter().addObserver(self, selector: "addTransactionObserver", name: "AddObserverKey", object: nil) 
NSNotificationCenter.defaultCenter().addObserver(self, selector: "removeTransactionObserver", name: "RemoveObserverKey", object: nil) 

建立在你的viewController 2层的功能。

func addTransactionObserver() { 
SKPaymentQueue.defaultQueue().addTransactionObserver(self) 
// you could put this in view Did Load but I prefer apples way 
} 

func removeTransactionObserver() { 
SKPaymentQueue.defaultQueue().removeTransactionObserver(self) 
} 

比的方法didFinishLaunching您的appDelegate ...使用

NSNotificationCenter.defaultCenter().postNotificationName("AddObserverKey", object: nil) 

比在appWillTerminate你的appDelegate ...使用

NSNotificationCenter.defaultCenter().postNotificationName("RemoveObserverKey", object: nil) 

你真的应该考虑把你的将代码购买到帮助文件中以使事情变得更容易。例如,这是一个好的开始。

http://masteringios.com/blog/2015/02/17/in-app-purchase-how-to-retrieve-the-list-of-products-from-the-app-store/

https://github.com/Vitaa/IAPurchaseManager/blob/master/IAPManager.swift

有了广告,只检查我的帮手,它会给你,你出了问题的想法。

1

您游戏 - 视图 - 控制器可能看起来像这样

class gameViewController: ..... 

    struct ProductID { 
static let removeAds = "squares.RemoveAds" 
static let removeAds6Plus = "squares.RemoveAds6Plus" // really needed? 
} 

struct NSNotificationKey { 
static let addObserver = "AddObserver" 
static let removeObserver = "RemoveObserver" 
} 




    func ViewDidLoad() { 


    NSNotificationCenter.defaultCenter().addObserver(self, selector: "addTransactionObserver", name: NSNotificationKey.addObserver, object: nil) 
    NSNotificationCenter.defaultCenter().addObserver(self, selector: "removeTransactionObserver", name: NSNotificationKey.removeObserver, object: nil) 

     .... 
    } 

func addTransactionObserver() { 
SKPaymentQueue.defaultQueue().addTransactionObserver(self) 
// you could put this in view Did Load but I prefer apples way 
} 

func removeTransactionObserver() { 
SKPaymentQueue.defaultQueue().removeTransactionObserver(self) 
} 



@IBAction func removeAds(sender: UIButton) { 
    print("Remove Ads Button pressed") 
    for product in list { 
     let prodID = product.productIdentifier 
     if(prodID == ProductID.removeAds) { 
      p = product 
      buyProduct() 
      break 
     } 
    } 

    SKPaymentQueue.defaultQueue().restoreCompletedTransactions() 
} 

func removeAds() { 
    interAd.delegate = nil 
    closeButton.removeFromSuperView() 
    interAdView.removeFromSuperView()   

} 

override func prefersStatusBarHidden() -> Bool { 
    return true 
} 

//Remove Ads Payment 
var list = [SKProduct]() 
var p = SKProduct() 



//Squares.regular.removeAds 
//Squares.6Plus.removeAds 


func buyProduct() { 
    print("Buy" + p.productIdentifier) 
    let pay = SKPayment(product: p) 
    SKPaymentQueue.defaultQueue().addPayment(pay as SKPayment) 
} 

func productsRequest(request: SKProductsRequest, didReceiveResponse response: SKProductsResponse) { 
    print("Product Request") 
    let myProduct = response.products 

    for product in myProduct { 
     print("Product Added") 
     print(product.productIdentifier) 
     print(product.localizedTitle) 
     print(product.localizedDescription) 
     print(product.price) 

     list.append(product as SKProduct) 
    } 
    removeAdsButton.enabled = true 
    removeAdsIPhone6Plus.enabled = true 
} 

func paymentQueueRestoreCompletedTransactionsFinished(queue: SKPaymentQueue) { 
    print("Transactions Restored") 

    var purchasedItemIDS = [] 
    for transaction in queue.transactions { 
     let t: SKPaymentTransaction = transaction as SKPaymentTransaction 

     let prodID = t.payment.productIdentifier as String 

     switch prodID { 
     case ProductID.removeAds: 
      print("Remove Ads") 
      removeAds() 
     case ProductID.removeAds6Plus: 
      print("Remove Ads for iPhone 6 Plus") 
      removeAds() 
     default: 
      print("IAP not setup") 
     } 

    } 
} 

func paymentQueue(queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) { 
    print("Add Payment") 

    for transaction:AnyObject in transactions { 
     let trans = transaction as! SKPaymentTransaction 
     print(trans.error) 

     switch trans.transactionState { 

     case .Purchased: 
      print("Buy, Ok unlock Squares here") 
      print(p.productIdentifier) 

      let prodID = p.productIdentifier as String 
      switch prodID { 
       case ProductID.removeAds: 
       print("Remove Ads") 
       removeAds() 
       case ProductID.removeAds6Plus: // really needed? 
       print("Remove Ads for iPhone 6 Plus") 
       removeAds() 
      default: 
       print("IAP not Setup") 
      } 

      queue.finishTransaction(trans) 
      break; 
     case .Failed: 
      print("Buy Error") 
      queue.finishTransaction(trans) 
      break; 
     default: 
      print("Default") 
      break; 

     } 
    } 
} 

func finishTransaction(trans:SKPaymentTransaction){ 
    print("Finish Transaction") 
} 

func paymentQueue(queue: SKPaymentQueue, removedTransactions transactions: [SKPaymentTransaction]) { 
    print("Remove Transaction") 
} 

比你appDelegate.swift在didFinishLaunchingWithOptions你说

NSNotificationCenter.defaultCenter().postNotificationName(GameViewController.NSNotificationKey.addObserver, object: nil) 

和appWillTerminate你说

NSNotificationCenter.defaultCenter().postNotificationName(GameViewController.NSNotificationKey.removeObserver, object: nil) 

如果仍然无法检查您的产品ID。您正在使用Squares.RemoveAds产品ID,但不是进一步向下行,你有这些意见

//Squares.regular.removeAds

//Squares.6Plus.removeAds

仔细检查您的ID。

相关问题