Swift - Detect when variable goes past a point - swift

I've searched on Stack Overflow and of course Google and nothing has come up (which surprises me).
I have an integer variable which constantly changes, and I want to run a certain function when the variable goes past a certain number. Infinite while loops will obviously just slow the phone down and possibly crash.
This variable is the acceleration variable from CMMotionManager, which gives the accelerometer data when displayed/printed. It is NOT a variable set by me.
For example:
if Example > 2 { // Example being the integer variable from another module
// do stuff here
}
Edit: No, waiting a few seconds and then checking again will NOT work in my situation.
Edit2: It is not a variable set by me, but a variable from another module.

Have you checked willSet and didSet options?
var _test : Int = 0 {
//First this
willSet {
println("Old value is \(_test), new value is \(newValue)")
}
//value is set
//Finaly this
didSet {
println("Old value is \(oldValue), new value is \(_test)")
}
}
More details here.

Related

Trying to assign variable using + swiftUI

I'm creating a math app and am trying to assign the correct answer to a variable. I've tried these two options below
#State private var correctAnswer1: Int {
number1L1 + number2L1
}
With this, I receive the error "Property wrapper cannot be applied to a computed property".
if currentLevel == 1
{
Text(" \(number1L1)")
.font(.system(size:70))
Text("+ \(number2L1)")
.font(.system(size:70))
Text("____")
.font(.system(size:70))
correctAnswer = number1L1 + number2L1
}
With this I receive the error "Type () cannot conform to 'View'"
How do I assign this variable without running into an error?
You really have two questions here. In the first case you have a property that is a computed property.
private var correctAnswer1: Int {
number1L1 + number2L1
}
Says that every time you ask for yourObject.correctAnswer1 the system should compute its value by running the code in the block.
Something a property that is attributed with #State, in contrast, is a box that holds a single value. You don't have a single value, you have a mechanism for computing a value. The compiler complains.
I the second case, you're laying out a View.
When you are working inside the body block of a SwiftUI View you are in a special environment called a ViewBuilder. Within that environment, each expression is expected to return some kind of View. The compiler collects them in a special way and will combine them together to make a user interface. (The environment also allows you some control-flow structures like if statements that are treated specially. If you are really curious you can search the web for information about Swift Result Builders)
In your case, you've included an expression that doesn't return a View in a place where Swift expects each expression to return one and Swift complains.

Change variable value with what is in a function

I have values in my function that I want to put into the labels that I have linked to my viewController. I tried to do currentTempLabel.text = result.main.temp but it did not want to do that in the function. So I moved that to the viewDidLoad and made some variables, var temp: String = "". In my function I have it set the variable to the value that I get from the API in that function but it doesn't set it to the value. When I run the app it just comes up with the default values that I put into it.
Right now I have the values printing to the console but I need the to go to the actual app and display. This is probably something very simple but I just can't figure it out.
In the function I have:
self.temp = String(result.main.temp)
And in viewDidLoad I have:
currentTempLabel.text = temp
In my mind this should work but not in Swift's mind.
The API to get the weather data works asynchronously. Assign the value to the label in the completion handler on the main thread
DispatchQueue.main.async {
self.currentTempLabel.text = String(result.main.temp)
}

Use of Unresolved Identifier for Function // Swift

UPDATE BELOW
I am currently in an introductory Swift course at my college and am struggling with functions. I thought I followed the instructions clearly, but I am getting a certain error about "use of an unresolved identifier."
This is the full error:
error: My Functions Playground 2 2.playground:23:8: error: use of unresolved identifier 'newGPA'
switch newGPA {
Here is my code (the original instructions are below):
var gpa: Int
var attemptedHours: Int
var earnedGradePoints: Int
// create your function here
func gpaUpdater(hours moreHours: Int, grade moreGPA: Int) {
let _: Int = attemptedHours + moreHours
let newGPA: Int = gpa + moreGPA
print(newGPA)
}
// call the function
gpaUpdater(hours: 16, grade: 60)
// add the new hours and grade points here and call the function again
switch newGPA {
case 0...1.8:
print("You will be placed on suspension")
case 1.8...2.0:
print("You will be placed on probation")
case 3.5...3.8:
print("You will be put on the dean's list.")
case 3.9:
print("You will be put on the president's list.")
default:
print("Carry on. Nothing to see here.")
}
Instructions:
We're going to track your GPA from one semester to the next. Assume at the end of your sophomore years, you have attempted 60 hours and have earned 222.5 grade points. Assign attempted hours and grade points to variables. Write a function that updates your current GPA and assigns it to the GPA var (you'll update it along the way). Label your function arguments. Print your new GPA from within the function.
At the end of the current semester, add 16 hours and 60 grade points to your record. Call the gpa function to update your overall gpa.
Test your gpa at the end of the year to see if any administrative action needs to be taken. If the gpa is less than 1.8, the student will need to be placed on suspension. If less than 2.0, we need to put the student on probation. If over 3.5, we'll put the student on the dean's list, and if over 3.9, we'll put the student on the president's list. Create a switch that prints the recommended adminstrative action. If no action is required, print, "Carry on. Nothing to see here." Create internal and external labels for your arguments.
Thank You for your help!
UPDATE
The function part of my Swift code is now correct, thank you all for the help. Now I am trying to fix my switch statement. Here is my code:
// add the new hours and grade points here and call the function again
switch gpa {
case gpa > 1.8:
print("You will be placed on suspension")
case 1.8...2.0:
print("You will be placed on probation")
case 3.5...3.8:
print("You will be put on the dean's list.")
case gpa > 3.9:
print("You will be put on the president's list.")
default:
print("Carry on. Nothing to see here.")
}
The problem, I think, is that my teacher wants GPA to be an int, but if I want to use values like 1.9 for the gpa, then it needs to be a double. Here is an error that I am getting:
error: My Functions Playground 2 2.playground:26:10: error: binary operator '>' cannot be applied to operands of type 'Int' and 'Double'
case gpa > 1.8
Scope. Scope. Scope.
newGPA is declared locally in the scope of gpaUpdater. It's not visible on the top level.
You could do
// create your function here
func gpaUpdater(hours moreHours: Int, grade moreGPA: Int) -> Int {
// let _: Int = attemptedHours + moreHours
return gpa + moreGPA
}
// call the function
let newGPA = gpaUpdater(hours: 16, grade: 60)
// add the new hours and grade points here and call the function again
switch newGPA { ...
No comment about the (unused) first parameter of gpaUpdater and the floating point cases switching over an Int 😉
I'm going to answer this from an assignment perspective; the other answers regarding returning the local variable value are correct for accessing your newGPA variable.
You missed the point in the assignment by creating the "newGPA" variable. The assignment states to "update" the global gpa variable with the new value from within the function.
If this is introductory coding, you may not have come across the concept of recursion. This is basically assigning some value by including itself in the calculation.
Instead of
let newGPA: Int = gpa + moreGPA
print(newGPA)
think
gpa = gpa + moreGPA
print(gpa)
which can also be written as
gpa += moreGPA
and then use gpa in your switch function.
What this does is updates your global gpa variable to a new value (by adding the moreGPA to it). This is one of the main strengths of a global variable. It can be accessed and modified from anywhere in your program.
That's my understanding based on the assignment instructions. That said, returning a value from a function is cleaner (in my opinion) since global variables can become conflicts in more complicated programs.

Setter for Bool in Swift

I'm using a custom getter like so
var currentShowLiked: Bool {
get {
return [some condition met] ? true : false
}
set {
self.currentShowLiked = newValue
}
}
and it works fine. However, I would expect to be able to set true or false value back to my variable, but Swift forced my to implement a setter, which does not produce any warnings, but at runtime if I'm to change value of my variable, app crashes with no apparent reason or sane explanation pointing to setter line with EXC_BAD_ACCESS (code=2...) and a message in console warning: could not load any Objective-C class information. This will significantly reduce the quality of type information available.
Why do I do?
You are in recursive context.
You can't use currentShowLiked in the currentShowLiked property body as below:
// Recursive, Infinite loop
self.currentShowLiked = newValue
To fix this:
private var _currentShowLiked : Bool
var currentShowLiked: Bool {
get {
return [ some condition met on _currentShowLiked ] ? true : false
}
set {
self._currentShowLiked = newValue
}
}
A Swift property that defines a custom getter and / or setter operation is a computed property which does not actually stores a value. The custom setter can be used to modify the internal state of other properties.
See also: "The Swift Programming Language" page 180
You can not set value in its setter because you are creating a recursion -method calling itself because:
self.currentShowLiked = newValue
will call set method you defined which will go and go. If you are overriding setter and getter you probably want to have some backing store property which will be private.
Moreover you defined a getter which base on some condition so anyway you are not using the value you set on this property. I think you do not need this set
The error here is caused by a misunderstanding.
When you declare a
var a:Type
A member value a is allocated inside the object, and accessors and mutators are automatically created to allow you to read and write that variable.
However, when you declare
var a:Type { get { ... } set { ... } }
No member value is allocated - you have indicated that when the value is accessed (read) or mutated (written) from a user of the object, your code will do all necessary action to respond to it. If you ultimately want the value to be stored, you will need to store it to an actual value, (which will need a different name).
Since you are invoking the mutator of the object inside the mutator of the object, you have set up an infinite loop, which causes your program to crash due to stack overflow (all function call memory is used to store the record of the function calling itself over and over again).
The code you have above will crash because it causes an infinite loop - your setter for currentShowLiked sets currentShowLiked to the new value, so then that calls the setter again, and so on.
You don't have to implement a setter, but you then don't use get - the syntax is like this:
var currentShowLiked: Bool {
return [some condition met]
}

How to move an object up with an action?

Wasn't exactly sure how to title this, but I need to count up how many enemies a player killed before they die and respawn for my point and health system.
My idea is to set up a variable that gets 1 added to it on each collide and then when the player is killed it takes the amount of that stored score variable and uses it for the point and for my health system, which is to move something up on the screen up.
Some super pseudo code would look like:
var storedPlayerScore = 0
var HealthPlus = SKAction.moveBy(CGVectorMake(0, (10 * storedPlayerScore)), duration: 0.05)
I've got both of those defined in my Gamescene.
and then down in my didbegincontact I'd just do like storedplayerscore++ whenever the two correct objects collide.
So before when I was just making sure the health going up worked, I had a number in where the stored variable was, but when I use this it gives me "Gamescene.type doesn't have a variable named storedPlayerScore"
Am I on the right track here? How do I clear the error I'm getting?
You are trying to access something on the type itself rather than on an instance of that type.
class GameScene {
var storedPlayerScore: Int = 0
}
var score1 = GameScene.storedPlayerScore // Error
let myGameScene = GameScene()
var score2 = myGameScene.storedPlayerScore // Works
This confusion is probably brought on by the names you're choosing for your variables. In your code above, you have a variable called HealthPlus which is named with a capital first letter. That makes it look like a type instead of an instance. The convention for variable names is start with a lowercase letter, while type declarations start with a capital letter. So it should be healthPlus instead.