I am new at Swift the code builds just fine but the greater than (>) dose not work. I'm trying to producing at a number in the "totalCoal" label, but never goes over the "coalPileHolding" Second label. I know that this code can be way better But i am trying to get the basic first. I also know that the timeDiffernt ">" dose not work also so somehow I am missing something. Thank you for your help
#IBOutlet weak var coalPileHoldingLabel: UILabel!
func loadBigCoalPile () {
var coalPileHolding = Int ()
if UserDefaults.standard.object(forKey: "coalPileResearch") == nil {
coalPileHolding = 0 } else {
coalPileHolding = UserDefaults.standard.object(forKey: "coalPileResearch") as! Int}
if coalPileHolding == 1 {
let coalPileHolding = 200
coalPileHoldingLabel.text = String(coalPileHolding) }
if coalPileHolding == 2 {
let coalPileHolding = 300
coalPileHoldingLabel.text = String(coalPileHolding) }
if coalPileHolding == 3 {
let coalPileHolding = 400
coalPileHoldingLabel.text = String(coalPileHolding) }
#objc func buttonIsInAction(){
}
#IBOutlet weak var coalRunButton: UIButton!
#IBAction func coalRunButton(_ sender: Any) {
func getMillisecondsNow() -> Int64{
let currentDate = Date()
return getMillisecondsFromDate(date: currentDate)
}
func getMillisecondsFromDate(date: Date) -> Int64{
var d : Int64 = 0
let interval = date.timeIntervalSince1970
d = Int64(interval * 1000)
return d
}
func getTimeDifferenceFromNowInMilliseconds(time: Int64) -> Int64{
let now = getMillisecondsNow()
let diff: Int64 = now - time
return diff
}
var terminationTime = Int64()
if UserDefaults.standard.object(forKey: "latestTerminationDate") == nil {
terminationTime = getMillisecondsNow()
UserDefaults.standard.set(terminationTime, forKey:"latestTerminationDate")
}
else {
terminationTime = UserDefaults.standard.object(forKey: "latestTerminationDate") as! Int64 }
let timeDiff = getTimeDifferenceFromNowInMilliseconds(time: terminationTime)
let timeDiffernt = Int(timeDiff)
let now = getMillisecondsNow()
UserDefaults.standard.set (now, forKey: "latestTerminationDate")
if timeDiffernt > 86400000 { _ = 86400000}
var methodOfCut = Int ()
var machineryButton = Int ()
var qualityOfWorkers = Int ()
if UserDefaults.standard.object(forKey: "methodOfCut") == nil {
methodOfCut = 0 } else {
methodOfCut = UserDefaults.standard.object(forKey: "methodOfCut") as! Int}
if UserDefaults.standard.object(forKey: "machineryButton") == nil {
machineryButton = 0 } else {
machineryButton = UserDefaults.standard.object(forKey: "machineryButton") as! Int}
if UserDefaults.standard.object(forKey: "qualityOfWorkers") == nil {
qualityOfWorkers = 0 } else {
qualityOfWorkers = UserDefaults.standard.object(forKey: "qualityOfWorkers") as! Int}
let coalMayham = (machineryButton) + (qualityOfWorkers) + (methodOfCut)
let (dailyCoalAccumulate) = ((timeDiffernt) * (coalMayham) + 1) / 10000
var coalPileHolding2 = 0
if let coalPile = Int(coalPileLabel.text!) {
let totalCoal = (dailyCoalAccumulate) + coalPile
coalPileHolding2 = Int(coalPileHoldingLabel.text!) ?? 0
if totalCoal > coalPileHolding2 { coalPileHolding2 = totalCoal }
coalPileLabel.text = String(totalCoal)
UserDefaults.standard.set(totalCoal, forKey:"totalCoal")}
callOutLabel.text = String(dailyCoalAccumulate)}}
That mix of numeric types (Int32, Float, Int) is rather confusing. In general you want to use Int or Double. All other variants should only be used when absolutely necessary, for example if an API requires a different type. So lets assume that dailyCoalAccumulate is Int and switch everything else to Int too:
let coalPileHolding = 0
if let coalPile = Int(coalPileLabel.text!) {
let totalCoal = dailyCoalAccumulate + coalPile
let coalPileHolding = Int((coalPileHoldingLabel.text as! NSString).intValue)
if totalCoal > coalPileHolding {
let coalPileHolding = totalCoal
}
coalPileLabel.text = String(totalCoal)
UserDefaults.standard.set(totalCoal, forKey:"totalCoal")
}
callOutLabel.text = String(dailyCoalAccumulate)
Here the intValue API of NSString returns Int32 but I immediately convert it to a regular Int. But of course there is a better way to do this without having to bridge to the Objective-C NSString. If the string doesn't contain a number intValue simply returns zero. We can produce the same behavior when we use the Int initializer to convert the string and then replace the nil value with zero: Int(coalPileHoldingLabel.text!) ?? 0.
Then we have three different variables named coalPileHolding. Since they are defined in different scopes they can share the same name, but are still different variables. My guess is that you want to actually update the coalPileHolding variable. Otherwise the assignment in the inner if makes no sense - the compiler even warns about that.
So lets change coalPileHolding to var and update its value.
var coalPileHolding = 0
if let coalPile = Int(coalPileLabel.text!) {
let totalCoal = dailyCoalAccumulate + coalPile
coalPileHolding = Int(coalPileHoldingLabel.text!) ?? 0
if totalCoal > coalPileHolding {
coalPileHolding = totalCoal
}
coalPileLabel.text = String(totalCoal)
UserDefaults.standard.set(totalCoal, forKey:"totalCoal")
}
callOutLabel.text = String(dailyCoalAccumulate)
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")
I have a generator that generates a circle(SKShapeNode) every 2 seconds from the y-axis. (Moves up). I would like to know if it is possible to populate this generator uniformly(every x number of points.
Here is my code for said generator:
class CircleGen: SKShapeNode {
var circles = [WhiteCircles]()
var circleTracker = [WhiteCircles]()
var generationTimer: NSTimer!
var circ: WhiteCircles!
func generateCircles() {
for var i = 0; i < 4; i++ {
var scale: CGFloat
let rand = arc4random_uniform(10)
if rand == 0 {
scale = -15.0
} else {
scale = 15.0
}
let circle = WhiteCircles()
circle.position.x = lineGen.position.x
circle.physicsBody?.affectedByGravity = false
circle.position.y = 35
self.circles.append(circle)
circleTracker.append(circle)
foregroundNode.addChild(circle)
}
}
func startGeneratingEvery(seconds: NSTimeInterval) {
let callGenerateAction = SKAction.runBlock { () -> Void in
self.generateCircles()
}
let waitOneSecond = SKAction.waitForDuration(seconds)
let sequenceAction = SKAction.sequence([callGenerateAction, waitOneSecond])
let circleGenerateAction = SKAction.repeatActionForever(sequenceAction)
self.runAction(circleGenerateAction, withKey: "generateCircles")
}
}
Will post more code if necessary. Thank you in advance.
My code remove randomly only one coin. How i can remove randomly from 1 to 3 coins?
#IBAction func endTurn(sender: UIButton!) {
if coins.count > 0 { // #IBOutlet var coins: [UIButton]! (21 coins)
let index: Int = Int(arc4random_uniform(UInt32(coins.count)))
coins[index].hidden = true
self.coins.removeAtIndex(index)
if coins.isEmpty {
println("GameOver")
}
}
}
For randoms I recommend this extension:
extension Int {
static func random(range: Range<Int> ) -> Int {
var offset = 0
if range.startIndex < 0 {
offset = abs(range.startIndex)
}
let min = UInt32(range.startIndex + offset)
let max = UInt32(range.endIndex + offset)
return Int(min + arc4random_uniform(max - min)) - offset
}
}
And then:
var i = Int.random(1...5)
Try this
let numberToDelete = Int(arc4random_uniform(UInt32(3))) + 1
for i in 0..<numberToDelete{
let indexToDelete = Int(arc4random_uniform(UInt32(coins.count)))
coins.removeAtIndex(indexToDelete)
if coins.isEmpty{
break;
}
}
if coins.isEmpty{
println("GameOver")
}
I am creating an extension of Int with my own init but I cannot use the init implicitly. Can somebody please explain why? I can however call the init explicitly as shown below.
extension Int {
init?(fromHexString: String) {
let HexRadix:Int = 16
let DigitsString = "0123456789abcdefghijklmnopqrstuvwxyz"
let digits = DigitsString
var result = Int(0)
for digit in fromHexString.lowercaseString {
if let range = digits.rangeOfString(String(digit)) {
let val = Int(distance(digits.startIndex, range.startIndex))
if val >= Int(HexRadix) {
return nil
}
result = result * Int(HexRadix) + val
} else {
return nil
}
}
self = result
}
}
let firstString = "ff"
//This works
let parsedInt:Int = Int.init(fromHexString: firstString)!
println("\(parsedInt)")
//But this does not ; Error: Int is not identical to Int? Why??
let parsedInt1:Int = Int(fromHexString: firstString)!
println("\(parsedInt1)")