Label intValue not show for greater than (>) to work - swift

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)

Related

How to separate values from an array using Swift 4

How to separate values from an array using Swift 4. Following are my data:
arrWeekly == (
{
date = "2018-04-30";
units = "g/dL";
value = 12;
},
{
date = "2017-06-27";
units = "g/dL";
value = "14.5";
}
)
My Code:
if let arrMonthly = dictPeriod["monthly"] as? [Any], arrMonthly.count > 0
{
self.arrMonth = NSMutableArray(array: arrMonthly)
print("arrMonthly == ",self.arrMonth)
}else{
self.arrMonth = NSMutableArray()
}
I want to separate both dates & Values.
if let arrMonthly = dictPeriod["monthly"] as? [[AnyHasahble:String]], ! arrMonthly.isEmpty {
for disc in arrMonthly{
if let date = disc["date"] as? String{
}
if let units = disc["units"] as? String{
}
if let value = disc["value"] as? String{
}
}
}else{
}
let dictPeriod = YOUR_DICTIONARY
guard let arrMonthly = dictPeriod["monthly"] as? [[String: Any]], !arrMonthly.isEmpty else { return }
let dateArr = arrMonthly.map({ $0["date"] as! String })
let unitsArr = arrMonthly.map({ $0["units"] as! String })
let valueArr = arrMonthly.map({ $0["value"] as! String })

Swift 4 function returning 0 for multiple return values

I have been searching around but couldn't find a solution. can someone please let me know what I am doing wrong.
here is my function code: in my database I have hour=5 as Int and Minute=45 as Int
but when I print, the values of the function prints 0,0
var docRefF : DocumentReference!
func getTime()-> (Int, Int){
var FHour = Int()
var FMinute = Int()
docRefF = Firestore.firestore().document("sampleTime/worktime")
dataListener = docRefF.addSnapshotListener { (docSnapshot, error) in
guard let docSnapshot = docSnapshot, docSnapshot.exists else { return }
let data = docSnapshot.data()
let Hour:Int = data["Hour"]! as! Int
let Minute: Int = data["Minute"]! as! Int
FHour = Hour
FMinute = Minute
}
return (FHour, FMinute)
}
let time = getTime()
print("\(time.0),\(time.1)" )
//printed 0,0
Clearly its issue of asynchronous execution. Use * function with Closure* Instead of function with returning value.
Please refer following code
var docRefF : DocumentReference!
func getTime(_ then:(_ first:Int, _ second:Int)->()){
var FHour = Int()
var FMinute = Int()
docRefF = Firestore.firestore().document("sampleTime/worktime")
dataListener = docRefF.addSnapshotListener { (docSnapshot, error) in
guard let docSnapshot = docSnapshot, docSnapshot.exists else { return }
let data = docSnapshot.data()
let Hour:Int = data["Hour"]! as! Int
let Minute: Int = data["Minute"]! as! Int
FHour = Hour
FMinute = Minute
//TODO:- Use other firebase related task same as your code, so that uncomment other lines same as your origional
then(FHour, FMinute) // This is closure call back line
}
}
//Calling your function
getTime { (first, second) in
print(first,second)
}

Swift 2.0 Guard Statement Fails Struct Initializer

There was a similarly named topic but the example was an error due to user mistake. I believe this example is an actual XCode issue.
I was following a treehouse tutorial and in the spirit of swift 2.0 I used guard statements instead of if lets in the initializer. My code was identical to the instruction except for the use of guard statements. It had one error that said "return from initializer without initializing all stored properties". Once I changed it to if let statements, it worked. Perhaps I made a mistake somewhere but I stared at it for atleast an hour, no properties were left un-initialized.
I made the properties equal to nil in the else clauses just in case but that didnt affect anything.
struct DailyWeather {
let maxTemp: Int?
let minTemp: Int?
let humidity: Int?
let precipChance: Int?
var summary: String?
var icon: UIImage? = UIImage(named: "default.png")
var largeIcon: UIImage? = UIImage(named: "default_large.png")
var sunriseTime: String?
var sunsetTime: String?
var day: String?
let dateFormatter = NSDateFormatter()
init(dailyWeatherDictionary: [String:AnyObject]) {
minTemp = dailyWeatherDictionary["temperatureMin"] as? Int
maxTemp = dailyWeatherDictionary["temperatureMax"] as? Int
guard let humidityFloat = dailyWeatherDictionary["humidity"] as? Double else { humidity = nil ; return }
humidity = Int(humidityFloat * 100)
guard let precipFloat = dailyWeatherDictionary["precipProbability"] as? Double else { precipChance = nil ; return }
precipChance = Int(precipFloat * 100)
summary = dailyWeatherDictionary["summary"] as? String
guard let
iconString = dailyWeatherDictionary["icon"] as? String,
iconEnum = Icon(rawValue: iconString) else { icon = nil ; largeIcon = nil ; return }
(icon, largeIcon) = iconEnum.toImage()
guard let sunriseDate = dailyWeatherDictionary["sunriseTime"] as? Double else { sunriseTime = nil ; return }
sunriseTime = timeStringFromUnixTime(sunriseDate)
guard let sunsetDate = dailyWeatherDictionary["sunsetTime"] as? Double else { sunsetTime = nil ; return }
sunsetTime = timeStringFromUnixTime(sunsetDate)
guard let time = dailyWeatherDictionary["time"] as? Double else { day = nil ; return }
day = dayStringFromUnixTime(time)
}
func timeStringFromUnixTime(unixTime: Double) -> String {
let date = NSDate(timeIntervalSince1970: unixTime)
dateFormatter.dateFormat = "hh:mm a"
return dateFormatter.stringFromDate(date)
}
func dayStringFromUnixTime(unixTime: Double) -> String {
let date = NSDate(timeIntervalSince1970: unixTime)
dateFormatter.locale = NSLocale(localeIdentifier: NSLocale.currentLocale().localeIdentifier)
dateFormatter.dateFormat = "EEEE"
return dateFormatter.stringFromDate(date)
}
}
let's have
struct S {
var i: Int?
init(b: Bool){
guard b == false else { return }
//if b == true { return }
i = 0 // if b == true, this statement doesn't execute
}
}
let s1 = S(b: true)
let s2 = S(b: false)
print(s1, s2) // S(i: nil) S(i: Optional(0))
because var i: Int? has a default value nil, even though i = 0 is not reachable if parameter of init is true, the compiler doesn't complain.
struct S {
let i: Int?
init(b: Bool){
guard b == false else { return }
//if b == true { return }
i = 0 // if b == true, this statement doesn't execute
}
}
will NOT compile, with error: return from initializer without initializing all stored properties and note: 'self.i' not initialized, because constant let i: Int? doesn't have any default value
Your trouble is, that you return from init. Normally, avoid return from an initializer if your initializer is not fail-able / init? /. In case of fail-able init? the only accepted return value is nil.

extension of Int needs an explicit call to init

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)")

Is it possible to cast Any to an Optional?

Let's say I have a piece of code like this:
let x: Int? = 10
let y: Any = x
Now I want to cast y to Int?:
let z = y as Int? // Error: Cannot downcast from 'Any' to a more optional type 'Int?'
Is this just not possible or is there another way?
For Swift 2.0, you can use the following:
let x: Int? = 10
let y: Any = x
let z = Mirror(reflecting: y).descendant("Some") as? Int
Or as a function:
func castToOptional<T>(x: Any) -> T? {
return Mirror(reflecting: x).descendant("Some") as? T
}
let x: Int? = 10
let y: Any = x
let z: Int? = castToOptional(y)
Or you can do this if you don't like Reflection:
func castToOptional<T>(x: Any) -> T {
return x as! T
}
let x: Int? = 10
let y: Any = x
let z: Int? = castToOptional(y)
func castAsOptionalInt(value: Any)->Int? {
let mirror = Mirror(reflecting:value)
if mirror.subjectType == Optional<Int>.self {
let ret = mirror.children.first?.1
return ret as? Int
} else {
return nil
}
}
let x: Int? = 10
let y: Any = x
let z = castAsOptionalInt(y) // 10
let a: Double? = 10
let b: Any = a
let c = castAsOptionalInt(b) // nil
You can do this to get an optional out on Any
func unwrap(any:Any) -> Any? {
let mi:MirrorType = reflect(any)
if mi.disposition != .Optional {
return any
}
if mi.count == 0 { return nil } // Optional.None
let (name,some) = mi[0]
return some.value
}
So in your case,
let z = unwrap(y) as? Int
Reference : How to unwrap an optional value from Any type?
how about this solution, I made a generic version of previous answer.
fileprivate func unwrap<T>(value: Any)
-> (unwraped:T?, isOriginalType:Bool) {
let mirror = Mirror(reflecting: value)
let isOrgType = mirror.subjectType == Optional<T>.self
if mirror.displayStyle != .optional {
return (value as? T, isOrgType)
}
guard let firstChild = mirror.children.first else {
return (nil, isOrgType)
}
return (firstChild.value as? T, isOrgType)
}
let value: [Int]? = [0]
let value2: [Int]? = nil
let anyValue: Any = value
let anyValue2: Any = value2
let unwrappedResult:([Int]?, Bool)
= unwrap(value: anyValue) // ({[0]}, .1 true)
let unwrappedResult2:([Int]?, Bool)
= unwrap(value: anyValue2) // (nil, .1 true)
let unwrappedResult3:([UInt]?, Bool)
= unwrap(value: anyValue) // (nil, .1 false)
let unwrappedResult4:([NSNumber]?, Bool)
= unwrap(value: anyValue) ({[0]}, .1 false)
The following is code on Playground.
In case anyone's looking for a plug-and-play Dictionary solution, something like this:
extension Dictionary where Value == Any {
func typedValue<T>(forKey key: Key) -> T? {
if let anyValue: Any = self[key] {
return (anyValue as! T)
}
return nil
}
func optionalTypedValue<T>(forKey key: Key) -> T?? {
return self.typedValue(forKey: key)
}
}