GADInterstitial presented too often - swift

I am having problems with my interstitial ads popping up too often. The full screen ads comes on after every game over screen, meaning each time the player loses the ad pops up which i feel will get annoying. Is there a way to stop this happening after each failure to maybe after every 2 or 3 gameovers?
I have attached my code below, any help would be greatly appreciated.
import UIKit
import AVFoundation
import GoogleMobileAds
import Social
class ViewController: UIViewController {
#IBOutlet var bannerView: GADBannerView!
var admobInterstitial : GADInterstitial?
var timerAds : NSTimer?
var player:AVAudioPlayer = AVAudioPlayer()
var score = 0
var timer = NSTimer()
var seconds = 8
var watch = true
var watch1 = true
var gameActive = true
var hiScore = 0
var counter = 1
var turn = 0
var timer_anim = NSTimer()
#IBOutlet var btn: UIButton!
#IBOutlet var scr: UILabel!
#IBOutlet var scoreLabel: UILabel!
#IBOutlet var again: UIButton!
#IBOutlet var highScore: UILabel!
#IBOutlet var gameTimer: UILabel!
#IBOutlet var startView: UIImageView!
#IBOutlet var startButton: UIButton!
#IBOutlet var game_over: UIImageView!
#IBOutlet var twBtn: UIButton!
#IBAction func twitterBtn(sender: AnyObject) {
if SLComposeViewController.isAvailableForServiceType(SLServiceTypeTwitter)
{
var twShare:SLComposeViewController = SLComposeViewController(forServiceType: SLServiceTypeTwitter)
twShare.setInitialText("I dare you get a higher score than mine : ( \(score) ) GET it NOW on IOS : https://itunes.apple.com/us/app/oscar-cookie/id1099453391?mt=8")
twShare.addImage(UIImage(named: "start.png"))
self.presentViewController(twShare, animated: true, completion: nil)
}
else
{
var alert = UIAlertController(title: "Account", message: "Please login to Twitter to Tweet", preferredStyle: UIAlertControllerStyle.Alert)
alert.addAction(UIAlertAction(title: "Ok", style: UIAlertActionStyle.Default, handler: nil))
self.presentViewController(alert, animated: true, completion: nil)
}
}
#IBOutlet var fbBtn: UIButton!
#IBAction func facebookBtn(sender: AnyObject) {
if SLComposeViewController.isAvailableForServiceType(SLServiceTypeFacebook)
{
var fbShare:SLComposeViewController = SLComposeViewController(forServiceType: SLServiceTypeFacebook)
fbShare.setInitialText("I dare you get a higher score than mine : ( \(score) ) GET it NOW on IOS : https://itunes.apple.com/us/app/oscar-cookie/id1099453391?mt=8")
fbShare.addImage(UIImage(named: "start.png"))
self.presentViewController(fbShare, animated: true, completion: nil)
}
else
{
var alert = UIAlertController(title: "Account", message: "Please login to Facebook to share", preferredStyle: UIAlertControllerStyle.Alert)
alert.addAction(UIAlertAction(title: "Ok", style: UIAlertActionStyle.Default, handler: nil))
self.presentViewController(alert, animated: true, completion: nil)
}
}
#IBAction func startButtonFun(sender: AnyObject) {
startButton.hidden = true
startView.hidden = true
btn.hidden = false
player.pause()
}
#IBAction func playAgain(sender: AnyObject) {
player.pause()
//gameOverLbl.hidden = true
scoreLabel.hidden = true
again.hidden = true
btn.hidden = false
highScore.hidden = true
scr.hidden = false
game_over.hidden = true
fbBtn.hidden = true
twBtn.hidden = true
gameActive = true
watch = true
score = 0
scr.text = "0"
gameTimer.text = "8"
if watch1 == false
{
timer_anim.invalidate()
watch1 = true
}
}
#IBAction func button(sender: AnyObject) {
if score % 5 == 0
{
let audioPath = NSBundle.mainBundle().pathForResource("chew2", ofType: "mp3")!
do
{
try player = AVAudioPlayer(contentsOfURL: NSURL(fileURLWithPath : audioPath))
player.play()
}
catch
{
}
}
else
{
let audioPath = NSBundle.mainBundle().pathForResource("chew1", ofType: "mp3")!
do
{
try player = AVAudioPlayer(contentsOfURL: NSURL(fileURLWithPath : audioPath))
player.play()
}
catch
{
}
}
keepPlaying()
}
// func to locate the bottong randomly to all sizes
func randomLocating () {
var randomH = Int()
var randomW = Int()
if UIDevice().userInterfaceIdiom == .Phone {
switch UIScreen.mainScreen().nativeBounds.height {
case 480:
//print("iPhone Classic")
randomH = Int(arc4random_uniform(380))
randomW = Int(arc4random_uniform(260))
while randomH < 50 || randomW < 40
{
randomH = Int(arc4random_uniform(380))
randomW = Int(arc4random_uniform(260))
}
case 960:
//print("iPhone 4 or 4S")
randomH = Int(arc4random_uniform(380))
randomW = Int(arc4random_uniform(270))
while randomH < 50 || randomW < 40
{
randomH = Int(arc4random_uniform(380))
randomW = Int(arc4random_uniform(270))
}
case 1136:
// print("iPhone 5 or 5S or 5C")
randomH = Int(arc4random_uniform(520))
randomW = Int(arc4random_uniform(300))
while randomH < 40 || randomW < 40
{
randomH = Int(arc4random_uniform(520))
randomW = Int(arc4random_uniform(300))
}
case 1334:
// print("iPhone 6 or 6S")
randomH = Int(arc4random_uniform(550))
randomW = Int(arc4random_uniform(300))
while randomH < 35 || randomW < 40
{
randomH = Int(arc4random_uniform(550))
randomW = Int(arc4random_uniform(300))
}
case 2208:
// print("iPhone 6+ or 6S+")
randomH = Int(arc4random_uniform(700))
randomW = Int(arc4random_uniform(350))
while randomH < 40 || randomW < 40
{
randomH = Int(arc4random_uniform(700))
randomW = Int(arc4random_uniform(350))
}
default:
print("unknown")
}
}
else if UIDevice().userInterfaceIdiom == .Pad {
switch UIScreen.mainScreen().nativeBounds.height {
case 1024:
//print("iPad Classic")
randomH = Int(arc4random_uniform(950))
randomW = Int(arc4random_uniform(700))
while randomH < 50 || randomW < 40
{
randomH = Int(arc4random_uniform(950))
randomW = Int(arc4random_uniform(700))
}
case 2048:
//print("iPad Retina")
randomH = Int(arc4random_uniform(700))
randomW = Int(arc4random_uniform(350))
while randomH < 100 || randomW < 100
{
randomH = Int(arc4random_uniform(700))
randomW = Int(arc4random_uniform(350))
}
default:
print("unknown")
}
}
btn.frame.origin = CGPoint(x: randomW, y: randomH)
}
// func to end the game when someone loses
func endGame() {
btn.hidden = true
scoreLabel.text = "\(score)"
if hiScore < score
{
hiScore = score
highScore.text = "\(hiScore)"
}
else
{
highScore.text = "\(hiScore)"
}
NSUserDefaults.standardUserDefaults().setObject(hiScore, forKey: "high")
scoreLabel.hidden = false
again.hidden = false
highScore.hidden = false
scr.hidden = true
game_over.hidden = false
fbBtn.hidden = false
twBtn.hidden = false
let audioPath = NSBundle.mainBundle().pathForResource("end", ofType: "mp3")!
do
{
try player = AVAudioPlayer(contentsOfURL: NSURL(fileURLWithPath : audioPath))
player.play()
}
catch
{
}
}
func animating()
{
if counter < 5
{
counter += 1
}
startView.image = UIImage(named: "start-\(counter).png")
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
//gameOverLbl.hidden = true
scoreLabel.hidden = true
again.hidden = true
highScore.hidden = true
btn.hidden = true
game_over.hidden = true
game_over.hidden = true
fbBtn.hidden = true
twBtn.hidden = true
if watch1 == true
{
timer_anim = NSTimer.scheduledTimerWithTimeInterval(0.2, target: self, selector: Selector("animating"), userInfo: nil, repeats: true)
watch1 = false
}
if NSUserDefaults.standardUserDefaults().objectForKey("high") != nil
{
var returnHigh = NSUserDefaults.standardUserDefaults().objectForKey("high") as! Int
hiScore = returnHigh
}
else
{
}
let audioPath = NSBundle.mainBundle().pathForResource("start", ofType: "mp3")!
do
{
try player = AVAudioPlayer(contentsOfURL: NSURL(fileURLWithPath : audioPath))
player.play()
}
catch
{
}
self.bannerView.adUnitID = "ca-app-pub-8964973200415729/4584433890"
self.bannerView.rootViewController = self
var request:GADRequest = GADRequest()
self.bannerView.loadRequest(request)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
/// to make the screen not rotate
override func shouldAutorotate() -> Bool {
return false
}
func keepPlaying()
{
score += 1
scr.text = "\(score)"
randomLocating()
if score < 5
{
seconds = 8
}
else
{
seconds = 5
}
if watch == true
{
timer = NSTimer.scheduledTimerWithTimeInterval(0.1, target: self, selector: Selector("click1"), userInfo: nil, repeats: true)
}
watch = false
gameTimer.text = "\(seconds)"
}
func click1 ()
{
gameTimer.text = "\(seconds)"
if seconds == 0 && gameActive == false
{
timer.invalidate()
endGame()
btn.hidden = true
turn += 1
if turn == 1
{
admobInterstitial = createAndLoadInterstitial()
timerAds = NSTimer.scheduledTimerWithTimeInterval(1, target:self, selector: Selector("presentInterstitial"), userInfo: nil, repeats: false)
turn = 0
}
}
else if seconds == 1
{
btn.hidden = true
gameActive = false
}
else
{
btn.hidden = false
}
seconds -= 1
}
func createAndLoadInterstitial()->GADInterstitial {
var interstitial = GADInterstitial(adUnitID: "ca-app-pub-8964973200415729/8720255492")
///interstitial.delegate = self
interstitial.loadRequest(GADRequest())
return interstitial
}
func presentInterstitial() {
if let isReady = admobInterstitial?.isReady {
admobInterstitial?.presentFromRootViewController(self)
}
}
func interstitial(ad: GADInterstitial!, didFailToReceiveAdWithError error: GADRequestError!) {
print("interstitialDidFailToReceiveAdWithError:\(error.localizedDescription)")
admobInterstitial = createAndLoadInterstitial()
}
}

Simply change your turn counter. Instead of if turn == 1 change it to something else. Want an ad every 3 gameovers? Change it to 3. For example:
turn = turn + 1
if turn == 3 {
admobInterstitial = createAndLoadInterstitial()
timerAds = NSTimer.scheduledTimerWithTimeInterval(1, target:self, selector: #selector(ViewController.presentInterstitial), userInfo: nil, repeats: false)
turn = 0
}

Related

Array Issue with Display Label

Everything appears to be working in this tic tac toe game, except for displaying the "draw" label when there is no winner. The label will switch when Cross or circles wins, but not when there is a tie.
I'm stumped. E
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var label: UILabel!
var count = 1
var activePlayer = 1 //Cross
var gameState = [0,0,0,0,0,0,0,0,0]
var gameIsActive = true
let winningCombinations = [[0,1,2], [3,4,5], [6,7,8], [0,3,6], [1,4,7], [2,5,8], [0,4,8], [2,4,6]]
#IBAction func action(_ sender: AnyObject) {
if (gameState[sender.tag-1] == 0 && gameIsActive == true) {
gameState[sender.tag-1] = activePlayer
if (activePlayer == 1) {
sender.setImage(UIImage(named: "cross.png"), for: UIControl.State())
activePlayer = 2
} else {
sender.setImage(UIImage(named: "nought.png"), for: UIControl.State())
activePlayer = 1
}
}
for combination in winningCombinations {
if gameState[combination[0]] != 0 &&
gameState[combination[0]] == gameState[combination[1]] &&
gameState[combination[1]] == gameState[combination[2]] {
gameIsActive = false
if gameState[combination[0]] == 1 {
label.text = "Cross has won!"
} else {
label.text = "Circle has won!"
}
if gameIsActive == true {
for i in gameState {
count = i*count
}
if count != 0 {
label.text = "It was a draw."
label.isHidden = false
playAgainButton.isHidden = false
}
}
playAgainButton.isHidden = false
label.isHidden = false
}
}
} // End Button Action
#IBOutlet weak var playAgainButton: UIButton!
#IBAction func playAgain(_ sender: Any) {
gameState = [0,0,0,0,0,0,0,0,0]
gameIsActive = true
activePlayer = 1
playAgainButton.isHidden = true
label.isHidden = true
for i in 1...9 {
let button = view.viewWithTag(i) as! UIButton
button.setImage(nil, for: UIControl.State())
}
}
override func viewDidLoad() {
super.viewDidLoad()
playAgainButton.isHidden = true
label.isHidden = true
}
} // End ViewController
You are saying
gameIsActive = false
// ... some other stuff ...
if gameIsActive == true {
// check for a draw
}
But gameIsActive is not true, because you just set it to false. Therefore we never perform the check for a draw.
Thanks for the help everyone! I finally got it working correctly.
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var playAgainButton: UIButton!
#IBOutlet weak var label: UILabel!
var count = 1
var activePlayer = 1 //Cross
var gameState = [0,0,0,0,0,0,0,0,0]
var gameIsActive = true
let winningCombinations = [[0,1,2], [3,4,5], [6,7,8], [0,3,6], [1,4,7], [2,5,8], [0,4,8], [2,4,6]]
#IBAction func action(_ sender: AnyObject) {
count = 1;
if (gameState[sender.tag-1] == 0 && gameIsActive == true) {
if (activePlayer == 1) {
gameState[sender.tag-1] = activePlayer
sender.setImage(UIImage(named: "cross.png"), for: UIControl.State())
activePlayer = 2
} else {
sender.setImage(UIImage(named: "nought.png"), for: UIControl.State())
gameState[sender.tag-1] = activePlayer
activePlayer = 1
}
}
for combination in winningCombinations {
if gameState[combination[0]] != 0 && gameState[combination[0]] ==
gameState[combination[1]] && gameState[combination[1]] ==
gameState[combination[2]]{
gameIsActive = false
if gameState[combination[0]] == 1 {
label.text = "Cross has won!"
} else {
label.text = "Circle has won!"
}
playAgainButton.isHidden = false
label.isHidden = false
}
}
if gameIsActive == true{
for i in gameState{
count = i * count
}
if count != 0{
label.text = "DRAW!"
playAgainButton.isHidden = false
label.isHidden = false
}
}
}
#IBAction func playAgain(_ sender: Any) {
gameState = [0,0,0,0,0,0,0,0,0]
gameIsActive = true
activePlayer = 1
playAgainButton.isHidden = true
label.isHidden = true
for i in 1...9
{
let button = view.viewWithTag(i) as! UIButton
button.setImage(nil, for: UIControl.State())
}
}
override func viewDidLoad() {
super.viewDidLoad()
playAgainButton.isHidden = true
label.isHidden = true
}
}

Saving HighScore in Swift 4

This code has all my labels Im trying to use. I can't save the High score and implement it into the game. Now its saying I need to type more so i'm just going to keep typing until it tells me i'm good. It still hasn't told me i'm goo i'm actually very surprised wow.
import UIKit
import CoreData
import SpriteKit
var timer:Timer?
var seconds:Int = 5
var maxSeconds: Int = 5
var totalPoints:Int = 0
var high:Int = 0
let userDefaults = UserDefaults.standard
let defaults = UserDefaults.standard
class ViewController: UIViewController {
#IBOutlet weak var menu: UIButton!
var i = 0
var point = 0
#IBOutlet weak var highScore: UILabel!
#IBOutlet weak var timeLabel:UILabel?
#IBOutlet weak var points:UILabel?
#IBOutlet weak var totalPoint: UILabel!
#objc func tapped(){
i += 1
switch i {
case 1:
let generator = UINotificationFeedbackGenerator()
generator.notificationOccurred(.error)
case 2:
let generator = UINotificationFeedbackGenerator()
generator.notificationOccurred(.success)
case 3:
let generator = UINotificationFeedbackGenerator()
generator.notificationOccurred(.warning)
case 4:
let generator = UIImpactFeedbackGenerator(style: .light)
generator.impactOccurred()
case 5:
let generator = UIImpactFeedbackGenerator(style: .medium)
generator.impactOccurred()
case 6:
let generator = UIImpactFeedbackGenerator(style: .heavy)
generator.impactOccurred()
default:
let generator = UISelectionFeedbackGenerator()
generator.selectionChanged()
i = 0
}
}
func updateTimeLabel()
{
if(timeLabel != nil)
{
let sec:Int = seconds % 30
let sec_p:String = String(format: "%02d", sec)
timeLabel!.text = "\(sec_p)"
}
}
#objc func onUpdateTimer() -> Void
{
if(seconds > 0 && seconds <= maxSeconds)
{
seconds -= 1
updateTimeLabel()
}
else if(seconds == 0)
{
if(timer != nil)
{
timer!.invalidate()
timer = nil
userDefaults.set(totalPoints, forKey: "totalPoints")
let alertController = UIAlertController(title: "Time Up!", message: "Your time is up! You got a score of \(point) points and your total coins now is \(totalPoints). You Can Do Better", preferredStyle: .alert)
let restartAction = UIAlertAction(title: "Play Again!", style: .default, handler: nil)
alertController.addAction(restartAction)
let FirstSubview = alertController.view.subviews.first
let AlertContentView = FirstSubview?.subviews.first
for subview in (AlertContentView?.subviews)! {
subview.backgroundColor = UIColor(red: 226/255.0, green: 158/255.0, blue: 152/255.0, alpha: 5.0)
subview.layer.cornerRadius = 1
subview.alpha = 1
}
self.present(alertController, animated: true, completion: nil)
point = 0
seconds = maxSeconds
updateTimeLabel()
menu.isHidden = false
defaults.set(high, forKey: "high")
}
}
}
#IBAction func Restart(_ sender: Any) {
}
#IBAction func adder(_ sender: Any)
{
point += 1
points?.text = "\(point)"
if point % 10 == 0 {
totalPoints = 10 + totalPoints
totalPoint?.text = String(totalPoints)
}
if(timer == nil)
{
timer = Timer.scheduledTimer(timeInterval: 1.0, target:self, selector:#selector(onUpdateTimer), userInfo:nil, repeats:true)
}
tapped()
menu.isHidden = true
}
override func viewDidLoad() {
points?.text = "\(point)"
let total = userDefaults.integer(forKey: "totalPoints")
if total != 0 {
totalPoints = total
} else {
totalPoints = 0
}
let score = defaults.integer(forKey: "high")
if high < point {
high = score
} else {
high = 0
}
totalPoint?.text = String(totalPoints)
updateTimeLabel()
highScore.text = String(high)
}
}
Do I need to put something at the end? Well it looks like that didn't work either!
#for example
func saveHighScore() {
UserDefaults.standard.set(score, forKey: "HIGHSCORE")
}

App Only Crashes for Iphone 6 and IPad in IOS 11 using Vision & Machine Learning API

I made a live translation app that identifies an object and translates it using the user's camera. It works just fine on my iPhone 6s and doesn't crash in any of the simulators, but when I run it on an iPhone 6, it crashes as soon I try to segue to the camera feed. Apple also says it crashes on the iPad as well.
Do certain devices just not support Vision API or is something wrong with my code?
import UIKit
import AVKit
import Vision
var lang = ""
var lang2 = ""
class ViewController: UIViewController, AVCaptureVideoDataOutputSampleBufferDelegate, AVCapturePhotoCaptureDelegate {
#IBAction func screenshotB(_ sender: Any) {
//screenshot camera screen view
}
#IBOutlet weak var screenshotBOutlet: UIButton!
#IBOutlet weak var swirlyGuy: UIActivityIndicatorView!
#IBOutlet weak var title1: UILabel!
#IBOutlet weak var settingsButtonOutlet: UIButton!
#IBOutlet weak var launchScreen: UIViewX!
#IBOutlet weak var launchScreenLogo: UIImageView!
func stopSwirlyGuy(){
swirlyGuy.stopAnimating()
}
let identifierLabel: UILabel = {
let label = UILabel()
label.backgroundColor = UIColor(red: 0, green: 0, blue:0, alpha: 0.4)
label.textColor = .white
label.textAlignment = .center
label.translatesAutoresizingMaskIntoConstraints = false
return label
}()
#IBAction func prepareForUnwind (segue:UIStoryboardSegue) {
}
override func viewDidLoad() {
super.viewDidLoad()
launchScreen.alpha = 1
launchScreenLogo.alpha = 1
swirlyGuy.startAnimating()
// start up the camera
let captureSession = AVCaptureSession()
captureSession.sessionPreset = .hd4K3840x2160
guard let captureDevice = AVCaptureDevice.default(for: .video) else { return }
guard let input = try? AVCaptureDeviceInput(device: captureDevice) else { return }
captureSession.addInput(input)
captureSession.startRunning()
let previewLayer = AVCaptureVideoPreviewLayer(session: captureSession)
view.layer.addSublayer(previewLayer)
previewLayer.frame = view.frame
let dataOutput = AVCaptureVideoDataOutput()
dataOutput.setSampleBufferDelegate(self, queue: DispatchQueue(label: "videoQueue"))
captureSession.addOutput(dataOutput)
setupIdentifierConfidenceLabel()
setupSettingsButton()
setupTitle()
setupSwirlyGuy()
setupScreenshot()
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
UIView.animate(withDuration: 1.5) {
self.launchScreen.alpha = 0
self.launchScreenLogo.alpha = 0
}
}
fileprivate func setupSettingsButton() {
view.addSubview(settingsButtonOutlet)
}
fileprivate func setupScreenshot() {
view.addSubview(screenshotBOutlet)
}
fileprivate func setupSwirlyGuy() {
view.addSubview(swirlyGuy)
}
fileprivate func setupTitle() {
view.addSubview(title1)
}
fileprivate func setupIdentifierConfidenceLabel() {
view.addSubview(identifierLabel)
identifierLabel.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true
identifierLabel.leftAnchor.constraint(equalTo: view.leftAnchor).isActive = true
identifierLabel.rightAnchor.constraint(equalTo: view.rightAnchor).isActive = true
identifierLabel.heightAnchor.constraint(equalToConstant: 100).isActive = true
identifierLabel.numberOfLines = 0
}
func captureOutput(_ output: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection) {
// print("Camera was able to capture a frame:", Date())
guard let pixelBuffer: CVPixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer) else { return }
// model
guard let model = try? VNCoreMLModel(for: Resnet50().model) else { return }
let request = VNCoreMLRequest(model: model) { (finishedReq, err) in
//perhaps check the err
// print(finishedReq.results)
guard let results = finishedReq.results as? [VNClassificationObservation] else { return }
guard let firstObservation = results.first else { return }
print(firstObservation.identifier, firstObservation.confidence)
let x = (firstObservation.confidence)
let y = (x * 10000).rounded() / 10000
let z = (firstObservation.identifier)
let s = (self.translateSpanish(object1: firstObservation.identifier))
let f = (self.translateFrench(object1: firstObservation.identifier))
// var lang = ""
// var lang2 = ""
if language == "English" {
lang = z
}
else if language == "Spanish" {
lang = s
}
else {
lang = f
}
if language2 == "Spanish" {
lang2 = s
}
else if language2 == "English" {
lang2 = z
}
else {
lang2 = f
}
DispatchQueue.main.async {
self.identifierLabel.text = "\(lang)" + " = " + "\(lang2) \n \(y * 100)% accuracy"
self.stopSwirlyGuy()
}
}
try? VNImageRequestHandler(cvPixelBuffer: pixelBuffer, options: [:]).perform([request])
}
//Translation fucntions omitted for brevity
This is the code for the view controller that segues into the main screen where the camera feed and Vision processing take place.
import UIKit
class FirstLaunchViewController: UIViewController {
#IBOutlet weak var title1: UILabelX!
#IBOutlet weak var logo1: UIImageView!
#IBOutlet weak var description1: UILabel!
#IBOutlet weak var buttonOutlet: UIButtonX!
#IBOutlet weak var initialBackground: UIViewX!
#IBOutlet weak var initialLogo: UIImageView!
#IBAction func toVC(_ sender: Any) {
UserDefaults.standard.set(false, forKey: "name")
performSegue(withIdentifier: "toMain", sender: self)
}
override func viewDidLoad() {
super.viewDidLoad()
initialLogo.alpha = 1
initialBackground.alpha = 1
title1.alpha = 0
logo1.alpha = 0
description1.alpha = 0
buttonOutlet.alpha = 0
// Do any additional setup after loading the view.
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
UIView.animate(withDuration: 1.5, animations: {
self.initialLogo.alpha = 0
self.initialBackground.alpha = 0
}) { (true) in
self.initialBackgroundGone()
}
}
func initialBackgroundGone() {
UIView.animate(withDuration: 1.5, animations: {
self.title1.alpha = 1
}) { (true) in
self.showBackgroundAgain()
}
}
func showBackgroundAgain() {
UIView.animate(withDuration: 1.3, animations: {
self.logo1.alpha = 1
}) { (true) in
self.showTitle()
}
}
func showTitle() {
UIView.animate(withDuration: 1.5, animations: {
self.description1.alpha = 1
}) { (true) in
self.showEverythingElse()
}
}
func showEverythingElse() {
UIView.animate(withDuration: 3.5) {
self.buttonOutlet.alpha = 1
}
}
}
This is a lot of code but I think your issue comes from the video preset your are using as iPhone 6 doesn't have support for 4K video recording.
When setting the session preset you should test that it is supported by all the targeted devices:
if captureSession.canSetSessionPreset(.hd4K3840x2160) {
captureSession.sessionPreset = .hd4K3840x2160
} else {
captureSession.sessionPreset = .high // or any other preset that suits your needs
}

Fatal Error: Index Out of Range(UIPickerView)

I have a UIPickerView that is used to play the game Go Fish so data in it is continuously changing. AFter a few selections with the array I eventually get the error "Fatal Error: Index Out of Range" in the console and the error "thread 1 exc_bad_instruction (code=exc_i386_invop subcode=0x0)" on another line. Any idea on what is causing this and how to fix it.
Code:
import UIKit
class ViewController: UIViewController, UIPickerViewDelegate, UIPickerViewDataSource {
///Main Section///
//Game
#IBOutlet weak var GameCardsLeft: UILabel!
//CPU
#IBOutlet weak var CPUCardsLeft: UILabel!
#IBOutlet weak var CPUPairs: UILabel!
//Player
#IBOutlet weak var UserPairs: UILabel!
#IBOutlet weak var pickerView: UIPickerView!
//Variables
var deck = [Card]()
//Creates a deck of cards
func createDeck() {
var i = 0 //Suite
while(i < 2) {
var s = "" //suite
var x = 1 //Value
if(i == 0) {
s = "Clubs"
}/* else if(i == 1) {
s = "Spades"
} else if(i == 2) {
s = "Diamonds"
}*/ else {
s = "Hearts"
}
while(x < 14) {
let tempCard = Card()
tempCard.value = x
tempCard.suite = s
tempCard.assignRank(value: tempCard.value)
tempCard.setDescription(rank: tempCard.rank, suite: tempCard.suite)
x += 1
deck.append(tempCard)
}
i += 1
}
}
//Shuffles the deck
func shuffle() {
var tempDeck = [Card]()
while deck.count > 0 {
let random = Int(arc4random_uniform(UInt32(deck.count)))
let card = deck.remove(at: random)
tempDeck.append(card)
}
deck = tempDeck
}
///Go Fish Section///
var drawDeck = [Card]()
var playerDeck = [Card]()
var playerPairsArray = [Card]()
var cpuDeck = [Card]()
var cpuPairsArray = [Card]()
var selectedCard = Card()
var gameOver = false
var randomIndex = 0
func deal() {
for card in deck {
if(playerDeck.count < 5) {
playerDeck.append(card)
} else if(cpuDeck.count < 5) {
cpuDeck.append(card)
} else {
drawDeck.append(card)
}
}
}
//Player draw card
func playerDraw() {
if(playerDeck.count == 0) {
while(playerDeck.count != 7) {
if(drawDeck.count > 0) {
playerDeck.append(drawDeck[0])
drawDeck.remove(at: 0)
} else {
break
}
}
} else {
if(drawDeck.count > 0) {
playerDeck.append(drawDeck[0])
drawDeck.remove(at: 0)
}
}
}
//CPU draw card
func cpuDraw() {
if(cpuDeck.count == 0) {
while(cpuDeck.count != 7) {
if(drawDeck.count > 0) {
cpuDeck.append(drawDeck[0])
drawDeck.remove(at: 0)
} else {
break
}
}
} else {
if(drawDeck.count > 0) {
cpuDeck.append(drawDeck[0])
drawDeck.remove(at: 0)
}
}
}
//Player's turn check cpu hand
func checkCPUHand(selectedCard: Card) {
var x = 0
while(x < cpuDeck.count) {
if(selectedCard.value == cpuDeck[x].value) {
playerDeck.append(cpuDeck[x])
cpuDeck.remove(at: x)
checkForPlayerPairs()
return
} else {
x += 1
}
}
playerDraw()
}
//CPU's turn check player hand
func checkPlayerHand(selectedCard: Card) {
var x = 0
while(x < playerDeck.count) {
if(selectedCard.value == playerDeck[x].value) {
cpuDeck.append(playerDeck[x])
playerDeck.remove(at: x)
checkForCPUPairs()
return
} else {
x += 1
}
}
cpuDraw()
}
//Check for player Pairs
func checkForPlayerPairs() {
var i = 0
var k = 0
var pairFound = false
while(i < playerDeck.count) {
pairFound = false
k = i + 1
while(k < playerDeck.count) {
if(playerDeck[i].value == playerDeck[k].value) {
pairFound = true
break
} else {
k += 1
}
}
if(pairFound) {
playerPairsArray.append(playerDeck[i])
playerDeck.remove(at: k)
playerDeck.remove(at: i)
} else {
i += 1
}
}
}
//Check for cpu pairs
func checkForCPUPairs() {
var i = 0
var k = 0
var pairFound = false
while(i < cpuDeck.count) {
pairFound = false
k = i + 1
while(k < cpuDeck.count) {
if(cpuDeck[i].value == cpuDeck[k].value) {
pairFound = true
break
} else {
k += 1
}
}
if(pairFound) {
cpuPairsArray.append(cpuDeck[i])
cpuDeck.remove(at: k)
cpuDeck.remove(at: i)
} else {
i += 1
}
}
}
/* Start of PickerView Stuff */
//Returns the number of columns
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 1
}
//Returns the number of rows
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return playerDeck.count
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
return playerDeck[row].description //Error is in this line(thread 1 exc_bad_instruction (code=exc_i386_invop subcode=0x0))
}
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
selectedCard = playerDeck[row]
//have var = pickerData[row]
}
/* End of PickerView Stuff */
func organizeCardDeck() {
playerDeck = playerDeck.sorted { $0.value < $1.value }
cpuDeck = cpuDeck.sorted { $0.value < $1.value }
}
func start() {
createDeck()
shuffle()
shuffle()
deal()
organizeCardDeck()
checkForPlayerPairs()
checkForCPUPairs()
GameCardsLeft.text = "\(drawDeck.count)"
CPUCardsLeft.text = "\(cpuDeck.count)"
CPUPairs.text = "\(cpuPairsArray.count)"
UserPairs.text = "\(playerPairsArray.count)"
}
func checkGameOver() {
if(cpuDeck.count == 0 && playerDeck.count == 0 && drawDeck.count == 0) {
let cpuPairCount = cpuPairsArray.count
let playerPairCount = playerPairsArray.count
playerDeck.removeAll()
cpuDeck.removeAll()
deck.removeAll()
cpuPairsArray.removeAll()
playerPairsArray.removeAll()
/*if(playerPairCount > cpuPairCount) {
let alertController = UIAlertController(title: "Game Over", message: "You win", preferredStyle: .alert)
let defaultAction = UIAlertAction(title: "Restart", style: .default, handler: nil)
alertController.addAction(defaultAction)
} else if(playerPairCount < cpuPairCount) {
let alertController = UIAlertController(title: "Game Over", message: "You lose", preferredStyle: .alert)
let defaultAction = UIAlertAction(title: "Restart", style: .default, handler: nil)
alertController.addAction(defaultAction)
} else if(playerPairCount == cpuPairCount) {
let alertController = UIAlertController(title: "Game Over", message: "Tie game", preferredStyle: .alert)
let defaultAction = UIAlertAction(title: "Restart", style: .default, handler: nil)
alertController.addAction(defaultAction)
}*/
}
}
override func viewDidLoad() {
super.viewDidLoad()
self.pickerView.delegate = self
self.pickerView.dataSource = self
/*var alert = UIAlertController(title: "Go FIsh Go", message: "", preferredStyle: .alert)
var startAlert = UIAlertAction(title: "Start", style: .default, handler: nil)
alert.addAction(startAlert)
present(alert, animated: true, completion: nil)*/
start()
}
#IBAction func SelectCard(_ sender: UIButton) {
checkCPUHand(selectedCard: selectedCard)
checkForPlayerPairs()
pickerView.reloadAllComponents()
pickerView.selectRow(0, inComponent: 0, animated: true)
if(playerDeck.count == 0 && drawDeck.count > 0) {
playerDraw()
}
GameCardsLeft.text = "\(drawDeck.count)"
CPUCardsLeft.text = "\(cpuDeck.count)"
CPUPairs.text = "\(cpuPairsArray.count)"
UserPairs.text = "\(playerPairsArray.count)"
randomIndex = Int(arc4random_uniform(UInt32(cpuDeck.count)))
checkPlayerHand(selectedCard: cpuDeck[randomIndex])
checkForCPUPairs()
if(cpuDeck.count == 0 && drawDeck.count > 0) {
cpuDraw()
}
GameCardsLeft.text = "\(drawDeck.count)"
CPUCardsLeft.text = "\(cpuDeck.count)"
CPUPairs.text = "\(cpuPairsArray.count)"
UserPairs.text = "\(playerPairsArray.count)"
checkGameOver()
}
}
Change return playerDeck[row].description to: return (row < playerDeck.count ? playerDeck[row].description : nil), and change selectedCard = playerDeck[row] to:
if row < playerDeck.count {
self.selectedCard = playerDeck[row]
}
Also, call self.pickerView.reloadAllComponents() right before returning from your deal, playerDraw, checkCPUHand, checkPlayerHand, checkForPlayerPairs, organizeCardDeck, and checkGameOver functions, and any other functions that modify playerDeck.

Using NSCore and NSKeyedArchiver with SWIFT

I been trying to get persistent data on my app to have a history of user entries. After I store my data in to array I want to archive it, and after I unarchive it i get weird value instead of what i want to see.
Here is my class for where i store my data
import Foundation
class MyHistory: NSObject, NSCoding {
var kicksNumber: Int
var durationNumber: Int
init(kicksNumber: Int,durationNumber: Int) {
self.kicksNumber = kicksNumber
self.durationNumber = durationNumber
}
required init(coder decoder: NSCoder) {
kicksNumber = decoder.decodeObjectForKey("kicksNumber") as! Int
durationNumber = decoder.decodeObjectForKey("durationNumber") as! Int
}
func encodeWithCoder(coder: NSCoder) {
coder.encodeObject(self.kicksNumber, forKey: "kicksNumber")
coder.encodeObject(self.durationNumber, forKey: "durationNumber")
}
}
Then here is my class where things happen, And where I am testing out the save and load process.
class Kicks: UIViewController {
var myHistoryArray: [MyHistory] = []
var currentMyHistory: MyHistory!
var newHistory = [MyHistory]()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
self.view.backgroundColor = UIColor(patternImage: UIImage(named: "background13.png")!)
let defaults = NSUserDefaults.standardUserDefaults()
if let savedPeople = defaults.objectForKey("MyHistory") as? NSData {
newHistory = NSKeyedUnarchiver.unarchiveObjectWithData(savedPeople) as! [MyHistory]
//print("this is archived ", newHistory[0])
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
var count = 0 as Int
var countKicks = 0 as Int
var kickReached = false as Bool
var pressedOnce = true as Bool
var timer = NSTimer()
var test: MyHistory!
#IBOutlet var timerLabel: UITextField!
#IBOutlet var kicksLabel: UITextField!
#IBAction func kickButton() {
//currentMyHistory.kicksNumber = 5
if pressedOnce {
pressedOnce = false
timer = NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: Selector("counter"), userInfo: nil, repeats: true)
} else if kickReached {
// let date = NSDate()
// let calendar = NSCalendar.currentCalendar()
// let timer_total = calendar.components([ .Hour, .Minute, .Second], fromDate: date)
} else if !pressedOnce {
countKicks++
kicksLabel.text = "\(countKicks)"
if countKicks == 10 {
kickReached = true
timer.invalidate()
congratsAlert()
currentMyHistory = MyHistory(kicksNumber: 5, durationNumber: 10)
print("this is currentMyHistory", currentMyHistory.kicksNumber )
myHistoryArray.append(currentMyHistory)
test = myHistoryArray[0]
print("this is myHistoryArray0", test.kicksNumber)
//save data
let savedData = NSKeyedArchiver.archivedDataWithRootObject(myHistoryArray)
let defaults = NSUserDefaults.standardUserDefaults()
defaults.setObject(savedData, forKey: "MyHistory")
//load data
//let defaults = NSUserDefaults.standardUserDefaults()
// let person = people[indexPath.item]
//let historyUnarchived = NSKeyedUnarchiver.unarchiveObjectWithFile("/path/to/archive") as? [MyHistory]
// let data1 = NSUserDefaults.standardUserDefaults().objectForKey("myHistoryArray")
print("this is unrachived",newHistory[0])
clear()
}
}
}
// save countKicks, count, and stamp i
func congratsAlert() {
let alert = UIAlertController(title: "Congratulation", message: "Yay!!! Angelina kicked 10 times in less than 2 hours.",preferredStyle: .Alert)
let okAction = UIAlertAction(title: "Ok",style: .Default,handler:{(action:UIAlertAction) -> Void in})
alert.addAction(okAction)
presentViewController(alert,animated: true,completion: nil)
}
func clear() {
count = 0
countKicks = 0
kickReached = false
pressedOnce = true
timerLabel.text = "00:00:0\(count)"
kicksLabel.text = "\(countKicks)"
}
func counter() {
++count
let (hour,minutes,seconds) = secondsToHoursMinutesSeconds(count)
if seconds < 10 && minutes < 10 {
timerLabel.text = "0\(hour):0\(minutes):0\(seconds)"
} else if seconds > 9 && minutes < 10 {
timerLabel.text = "0\(hour):0\(minutes):\(seconds)"
} else if seconds > 9 && minutes > 9 {
timerLabel.text = "0\(hour):\(minutes):\(seconds)"
} else if seconds < 10 && minutes > 9 {
timerLabel.text = "0\(hour):\(minutes):0\(seconds)"
}
}
func secondsToHoursMinutesSeconds (seconds : Int) -> (Int, Int, Int) {
return (seconds / 3600, (seconds % 3600) / 60, (seconds % 3600) % 60)
}
/*
func savePlaces() {
let placesArray = [myHistory(kicksNumber: 420, durationNumber: 89)]
let placesData = NSKeyedArchiver.archivedDataWithRootObject(placesArray)
NSUserDefaults.standardUserDefaults().setObject(placesData, forKey: "kicks")
}
func loadPlaces() {
let placesData = NSUserDefaults.standardUserDefaults().objectForKey("kicks") as? NSData
if let placesData = placesData {
let placesArray = NSKeyedUnarchiver.unarchiveObjectWithData(placesData) as? [myHistory]
if let placesArray = placesArray {
// do something…
}
}
}*/
}
My output is like this:
this is currentMyHistory 5
this is myHistoryArray0 5
this is unrachived
Message from debugger: Terminated due to signal 15
why is unarchived is weird value?
In your MyHistory class you are using ints, so in your encodeWithCoder function you should be using
coder.encodeInteger(self.kicksNumber, forKey: "kicksNumber")
coder.encodeInteger(self.durationNumber, forKey: "durationNumber")
Likewise for your decoder you should be using decodeIntForKey, not decodeObjectForKey.
kicksNumber = decoder.decodeIntegerForKey("kicksNumber")
durationNumber = decoder.decodeIntegerForKey("durationNumber")