I want to integrate an iAd Pre-Roll video Ad to my application. When I run this application, it gives me this error:
Domain=ADErrorDomain Code=0 "The operation couldn’t be completed. (ADErrorDomain error 0.)
I want to know if this code is correct or incorrect. Thanks for your help.
import UIKit
import MediaPlayer
import iAd
class ViewController: UIViewController {
var moviePlayer : MPMoviePlayerController!
override func viewDidLoad() {
super.viewDidLoad()
let url = NSBundle.mainBundle().URLForResource("intro", withExtension: "mp4")
moviePlayer = MPMoviePlayerController(contentURL: url)
moviePlayer!.view.frame = view.frame
moviePlayer!.prepareToPlay()
view.addSubview(moviePlayer!.view!)
moviePlayer.playPrerollAdWithCompletionHandler { (error) -> Void in
NSLog("\(error)")
self.moviePlayer.play()
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
This is one of my modified App Delegate function:
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
// Override point for customization after application launch.
MPMoviePlayerController.preparePrerollAds()
return true
}
You're trying to display your Pre-Roll Video Ad before your application has had any time to download it. Fire your moviePlayer.playPrerollAdWithCompletionHandler after a few seconds or move the video to a later point in your intro so your application has time to download the ad. Check my example:
import UIKit
import MediaPlayer
import iAd
class ViewController: UIViewController {
// Create our MPMoviePlayerController
var moviePlayer = MPMoviePlayerController()
override func viewDidLoad() {
super.viewDidLoad()
// Preload ad
MPMoviePlayerController.preparePrerollAds()
// Setup our MPMoviePlayerController
moviePlayer.view.frame = self.view.bounds
moviePlayer.setFullscreen(true, animated: true)
}
#IBAction func playVideoButton(sender: AnyObject) {
// Add our MPMoviePlayerController to our view
self.view.addSubview(moviePlayer.view)
// Path of video you want to play
let videoURL = NSBundle.mainBundle().URLForResource("videoName", withExtension:"MOV")
// Set the contents of our MPMoviePlayerController to our video path
moviePlayer.contentURL = videoURL
// Prepare our movie for playback
moviePlayer.prepareToPlay()
// Play our video with a prerolled ad
moviePlayer.playPrerollAdWithCompletionHandler { (error) -> Void in
if (error) != nil {
NSLog("\(error)")
}
self.moviePlayer.play()
}
}
Tapping the UIButton playVideoButton a few seconds after application launch will play the prerolled video advertisement and then the desired video.
Also, If you're testing on your device go to Settings>Developer>Fill Rate> and make sure it is set to 100%.
Related
I'm dealing with the Admob interstitials and in particular I'm trying to display an interstitial when a particular ViewController of my app loads. I used the code provided by the official Admob Interstitial guide but it doesn't work :https://developers.google.com/admob/ios/interstitial?hl=it. I also followed this video here :https://youtu.be/ahmQQ3OeY0Y?t=787 (minute 13.04 stop the video). If you look at the code is the same as in the guide. My objective is to display the ad when the RequestViewController appears so I try to present the ad in the viewDidAppear function. Anyway it doesn't work, the console displays this error:
To get test ads on this device, call: request.testDevices =
#[ kGADSimulatorID ]
AppDelegate.swift
import UIKit
import UserNotifications
import GoogleMobileAds
#UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate,GADInterstitialDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
GADMobileAds.configure(withApplicationID: "ca-app-pub-*******")
}
}
This is the ViewController where I present the ad:
RequestviewController.swift
class RequestViewController: UIViewController {
var myInterstitial : GADInterstitial?
override func viewDidLoad() {
super.viewDidLoad()
}
override func viewDidAppear(_ animated: Bool) {
//display ad
myInterstitial = createAndLoadInterstitial()
if (myInterstitial?.isReady)!{
print("\n\n\n\n\nReady")
myInterstitial?.present(fromRootViewController: self)
}else { print("\n\n\n\nAd wasn't ready") }
}
func createAndLoadInterstitial()->GADInterstitial {
let interstitial = GADInterstitial(adUnitID: "ca-app-pub-3940256099942544/4411468910") //test Ad unit id
interstitial.delegate = self
interstitial.load(GADRequest())
return interstitial
}
func interstitialDidReceiveAd(ad: GADInterstitial!) {
print("interstitialDidReceiveAd")
}
func interstitial(ad: GADInterstitial!, didFailToReceiveAdWithError error: GADRequestError!) {
print(error.localizedDescription)
}
func interstitialDidDismissScreen(ad: GADInterstitial!) {
print("\n\n\n\n\n\ninterstitialDidDismissScreen")
myInterstitial = createAndLoadInterstitial()
}
you need to write it like,
appDelegate.createAndLoadInterstitial()
in place of,
appDelegate.myInterstitial?.present(fromRootViewController: self)
It looks like the root problem is this section of RequestViewController:
myInterstitial = createAndLoadInterstitial()
if (myInterstitial?.isReady)!{
print("\n\n\n\n\nReady")
myInterstitial?.present(fromRootViewController: self)
}else { print("\n\n\n\nAd wasn't ready") }
Interstitials are loaded asynchronously, which means the call to load() will return before the ad is loaded and ready to display. If your app is calling load() in createAndLoadInterstitial and then checking isReady immediately afterwards, there's no time for the ad to actually load, and isReady will always be false.
A good way to deal with this could be to create the interstitial in your first view controller, and then show it before transitioning to RequestViewController. That would give the ad time to load, and would still display it during the same transition.
FWIW, transition time between ViewControllers is a great place in the flow of your app to use an interstitial, so well done there.
Also, the line:
To get test ads on this device, call: request.testDevices = #[ kGADSimulatorID ]
isn't an error. The Android and iOS SDKs always print that to the log so publishers will know how to get test ads for a particular device or emulator. If you were running on a hardware device instead of the iOS simulator, you'd see a unique identifier for the device in that line, which you could then use in your code to get test ads.
good morning
How to write code to stop multiple audio files in this code
I looked for it and did not find anything useful please help me
import UIKit
import AVFoundation
class ViewController: UIViewController {
let soundFilenames = ["001" , "002" , "003" , "004" , "005" , "006" , "007" , "008"]
var Audios = [AVAudioPlayer]()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
for sound in soundFilenames {
do {
let url = NSURL(fileURLWithPath: NSBundle.mainBundle().pathForResource(sound, ofType: "mp3")!)
let audioPlayer = try AVAudioPlayer(contentsOfURL: url)
Audios.append(audioPlayer)
}catch{
Audios.append(AVAudioPlayer())
}
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBAction func buttun001(sender: UIButton) {
let audioplayer = Audios [sender.tag]
audioplayer.play()
}
}
Use a normal loop, check if is playing and stop the ones playing
func stopAudios(){
for audioPLayer in Audios{
if audioPLayer.playing{
audioPLayer.stop()
}
}
}
Also don't forget to prepare your AVAudioPlayer
audioPlayer.prepareToPlay()
I'm a beginner on TVOS.
I'd like to create an hybrid app on AppleTV using a native app and TVMLKIT.
My native application is just a simple native app with buttons (using swift).
When we click on a button, I launch a a javascript app using TVLMKIT and TVJS.
My TVJS as uses the Player to display a video.
When the video is over, I want to close the TVJS app and back to the native ViewController.
My problem is that when I back to native app, I loose the focus on my native View (the app is frozen).
native ViewController:
import UIKit
import TVMLKit
class ViewController: UIViewController, TVApplicationControllerDelegate {
var window: UIWindow?
var appController: TVApplicationController?
var appControllerContext = TVApplicationControllerContext();
static let TVBaseURL = "http://localhost:9001/"
static let TVBootURL = "\(ViewController.TVBaseURL)/client/js/application.js"
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBOutlet weak var label: UILabel!
#IBOutlet weak var viewAd: UIView!
#IBAction func clickOnlaunchAd(sender: AnyObject) {
window = UIWindow(frame: UIScreen.mainScreen().bounds)
guard let javaScriptURL = NSURL(string: ViewController.TVBootURL) else {
fatalError("unable to create NSURL")
}
appControllerContext.javaScriptApplicationURL = javaScriptURL
appControllerContext.launchOptions["BASEURL"] = ViewController.TVBaseURL
appController = TVApplicationController(context: appControllerContext, window: window,delegate: self)
}
#IBAction func clickOnChangeText(sender: AnyObject) {
label.text = "changed";
}
func appController(appController: TVApplicationController, didStopWithOptions options: [String : AnyObject]?) {
self.setNeedsFocusUpdate()
self.updateFocusIfNeeded()
}
func appController(appController: TVApplicationController, evaluateAppJavaScriptInContext jsContext: JSContext){
let notifyEventToNative : #convention(block) (NSString!) -> Void = {
(string : NSString!) -> Void in
print("[log]: \(string)\n")
self.appController?.stop()
}
jsContext.setObject(unsafeBitCast(notifyEventToNative, AnyObject.self), forKeyedSubscript: "notifyEventToNative")
}
}
Just before calling "notifyEventToNative" from my TVJS, I call "navigationDocument.clear();" to clear the TVML view.
I can see my native app but I can't interact with it.
Any ideas?
Thanks.
I also had the same problem. I was opened a TVML document from the UIViewController. And I also lost the focus. So, first of all I can advice you to override var called preferredFocusedView in your ViewController. In this method you can return reference to viewAd. But the better solution would be to wrap your ViewController into the TVML-item (with the TVMLKit framework). In that case I hope that you will have no problems with focus because you will use TVML during the whole application.
I used the example in how to play a local video and tried to modify for use on .m3u8 file. I am unable to make it work. I get a blank screen. I confirmed that the file was ok by testing on VLC. Any help would be appreciated.
Here is the code:
import UIKit
import MediaPlayer
class ViewController: UIViewController {
var moviePlayer : MPMoviePlayerController?
override func viewDidLoad() {
super.viewDidLoad()
playVideo()
// Do any additional setup after loading the view.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
private func playVideo() {
let path = "http://qthttp.apple.com.edgesuite.net/1010qwoeiuryfg/sl.m3u8"
if let
//path = NSBundle.mainBundle().pathForResource("movie", ofType:"m4v"),
url = NSURL(fileURLWithPath: path),
moviePlayer = MPMoviePlayerController(contentURL: url) {
self.moviePlayer = moviePlayer
moviePlayer.view.frame = self.view.bounds
moviePlayer.prepareToPlay()
moviePlayer.scalingMode = .AspectFill
self.view.addSubview(moviePlayer.view)
} else {
debugPrintln("Ops, something wrong when playing .m3u8 file")
}
}
}
You've specified your url incorrectly. Change it to this:
url = NSURL(string:path)
There don't seem to be any SO posts on dismissMoviePlayerViewControllerAnimated in Swift so I guess I'll kick things off.
I have a table cell, when you do a long press on it, it displays a video. When the video ends, my goal is to take the user back to the table view. That last piece is the bit that's not working.
Any help here would be greatly appreciated. I've read through the Apple docs and some posts about this in Objective-C. Seems that the answer is to run dismissMoviePlayerViewControllerAnimated, a method on UIViewController but it's not working.
import UIKit
import MediaPlayer
class ViewController: UIViewController {
var moviePlayer:MPMoviePlayerController!
#IBOutlet weak var longPressView: UIView!
let longPressRec = UILongPressGestureRecognizer()
func longPressedView() {
playVideo()
}
func videoHasFinishedPlaying(notification: NSNotification){
println("Video finished playing")
self.dismissMoviePlayerViewControllerAnimated()
// not returning me to the ViewController
}
func playVideo() {
// get path and url of movie
let path = NSBundle.mainBundle().pathForResource("IMG_8602", ofType:"MOV")
let url = NSURL.fileURLWithPath(path!)
moviePlayer = MPMoviePlayerController(contentURL: url)
// construct the views
moviePlayer.view.frame = self.view.bounds
self.view.addSubview(moviePlayer.view)
moviePlayer.fullscreen = true
// remove controls at top and bottom of video
moviePlayer.controlStyle = MPMovieControlStyle.None
// add event observer for videoHasFinsihedPlaying
NSNotificationCenter.defaultCenter().addObserver(self, selector: "videoHasFinishedPlaying:",
name: MPMoviePlayerPlaybackDidFinishNotification, object: nil)
}
override func viewDidLoad() {
super.viewDidLoad()
longPressRec.addTarget(self, action: "longPressedView")
longPressView.addGestureRecognizer(longPressRec)
longPressView.userInteractionEnabled = true
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
Your code does not work because you are using MPMoviePlayerController instead of MPMoviePlayerViewController.
You are calling:
self.dismissMoviePlayerViewControllerAnimated()
but there is no MPMoviePlayerViewController to dismiss. That's why nothing happens.
If you prefer to use MPMoviePlayerController (as in the code you posted), after adding manually its view, you also have to manually remove it.