Property is accessed but result is unused - ios

I saw there another similar one to my question but that was very old! , So I have an UIActivityIndicatorView but when i try to call the .hidesWhenStopped it just warns Property is accessed but result is unused for no reason?
What could be the problem?
I tried under viewDidLoad too but same :(
This is a part of my code:
Timer.scheduledTimer(withTimeInterval: 3, repeats: false) { [self] _ in
monitorimiTableView.reloadData()
configureTableView()
loaderMonitorimi.hidesWhenStopped // Property is accessed but result is unused
}

You need to assign a value to the property:
loaderMonitorimi.hidesWhenStopped = true
(or false if you don't want to hide it)
If you just write loaderMonitorimi.hidesWhenStopped without any assignment, this expression will result in the boolean value stored in the hidesWhenStopped property, but the result of the expression is not used, hence the warning.

Related

collectionView.indexPathsForSelectedItems.contains(x)

I am trying to run collectionView.selectItem(at: indexPath, animated: false, scrollPosition: []) if if(!collectionView.indexPathsForSelectedItems?.contains(x)) returns true. But I can't seem to get it to work.
I thought it had something to do with optionals, but it doesn't seem to.
I have tried if let, ? ?? ! etc. I have created an optional index_path object and still cannot get it to work.
You can't have an optional Bool? as the only member of an if condition. That's because the compiler (with good reason) refuses to infer what it must do when it gets a nil value.
You have several ways to solve this, the important thing is: make sure you're handling the nil case the way you intend it to.
From a quick look at the documentation we learn that indexPathsForSelectedItems returns nil if there are no selected items. In that case your condition must yield a true value, because when there are no selected items, x is most certainly not contained in the array of selected values.
So, a first solution might be to tell the compiler to treat a nil value from indexPathsForSelectedItems as an empty array, which seems quite reasonable: if there are no selected items the array that represents the selected items' indexPath should be empty:
// solution 1
if !(collectionView.indexPathsForSelectedItems ?? []).contains(x) {
// select item..
}
You have a second way to solve this if you consider that you can't have an optional Bool? inside an if condition, but you can always compare a Bool? with a Bool and thus explicitly tell the compiler the only case among the three you are interested in:
let isXSelected = collectionView.indexPathsForSelectedItems?.contains(x)
isXSelected returns nil → no items selected, i should select x
isXSelected returns true → nothing to do
isXSelected returns false → i should select x
You want to execute the "select x" code in both case 1 and 3, so you want to check if isXSelected is not true. In conclusion:
// solution 2
if collectionView.indexPathsForSelectedItems?.contains(x) != true {
// select item..
}
Result of
collectionView.indexPathsForSelectedItems?.contains(x)
is optional bool value: Bool?. Swift does not allow implicit cast to Bool type. To solve it, create unwrapping of optional array to non optional array indexPathsForSelectedItems :
if !(collectionView.indexPathsForSelectedItems?.contains(x) ?? false) {
//TODO:select item
}

Inout variable set in in UIAlertAction closure not changing value

I have a function with an inout paramter: enabled: Bool
The object I'm referencing (I know inout isn't technically a reference...) and setting using this method is a stored property on a UIViewController
var enabled = false
I have multiple booleans triggering different things, and I want to use one method to set them.
So I call the method:
self.determineEnabled(&self.enabled)
Below is the code, and I've used comments to explain whats happening
Code:
func determineEnabled(inout enabled: Bool) {
if enabled == false {
enabled = true
//self.enabled equals true now. This works. Its not in a closure...
} else {
let delete = UIAlertAction(title: "Disable", style: .Destructive, handler: { (action) -> Void in
enabled = false
print(self.enabled)
//This doesn't work. the inout variable equals FALSE
//self.enabled equals true
//If I set self.enabled = false.. Then it works, but I'm using a method because my app could have dozens of these enabled bools on this view controller.
let alertController = UIAlertController(title: "Change Bool", message: "", preferredStyle: UIAlertControllerStyle.Alert)
alertController.addAction(delete)
self.presentViewController(alertController, animated: true, completion: nil)
}
}
My app is obviously a more complex than this chunk of code, but I can verify this problem exists within this chuck of code.
I'll be honest that I don't thoroughly understand closures as much as I'd like..
But if I can use self.enabled to correctly change the value of enabled, what is stopping swift from changing setting the inout enabled variable?
UPDATE:
Here is a link from the docs that specifically mention my problem:
https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Declarations.html#//apple_ref/doc/uid/TP40014097-CH34-ID545
"There is no copy-out at the end of closures or nested functions. This means if a closure is called after the function returns, any changes that closure makes to the in-out parameters do not get copied back to the original."
Swift evolution on the topic:
https://github.com/apple/swift-evolution/blob/master/proposals/0035-limit-inout-capture.md
In Swift, functions are closures. Closures capture state. At the time we encounter the anonymous function containing the code print(self.enabled), self.enabled is true. We know that, because if it were not, we wouldn't be here at all (we'd be in the first wing of the condition, if enabled == false). Therefore when print(self.enabled) is later actually executed, it will print true, because that was the state of things when it captured its value.
You said it yourself in your question;
I know inout isn't technically a reference
From the Apple Swift book
An in-out parameter has a value that is passed in to the function,
is modified by the function and is passed back out of the function
to replace the original value.
You are modifying the value in a closure that executes some time later when the user interacts with the alert. At this point determineEnabled has already returned and stored the value of the inout parameter.
If an inout parameter was a reference, like a C-style pointer, then enabled would be pointing to a chunk of memory that stores self.enabled and when the value was modified in the closure, self.enabled would be modified.
You can see how this works if you create a simple class with a boolean property and then pass an instance of this class to your determineEnabled function (without using inout). Since objects are passed by reference, a subsequent update to the object's property in the closure will be visible anywhere that same object reference is used;

Access Optional property in multiple function for calculations - Swift

I have a NSObject Subclass. Say CityWalks
class CityWalks{
var totalCount:Int?
}
How do I use this property further? Should I check the nil coalescing every time this value is accessed.
example:
let aObject =
say in one fucntion (function1()) , I need to access this value, then it would like (aObject!.totalCount ?? 0)
func function1(){
...Some Access code for the object....
(aObject!.totalCount ?? 0)
}
Similarly in every other function(function2()) , I will have to write the same code.
func function2(){
...Some Access code for the object....
(aObject!.totalCount ?? 0)
}
So, what could be a better approach for such field, considering this property might receive a value from server or might not.
If you have a default value for this property just assign this value as default value.
class YourClass {
var totalCount = 0
}
I'd recommend you avoid using an optional value if it's possible. Because optional values its a first place when you can get an error.
As stated in the comments and the other answer using an optional is not really optimal in your case. It seems like you might as well use a default value of 0.
However, to clarify, you have to check the value when unwrapping the optional.
Sometimes it's possible to pass an optional to UIElement etc and then you don't really need to do anything with them
There are pretty ways of checking for nil in optional values built into swift so you can build pretty neat code even though you work with optional.
Look in to guard let and if let if you want to know more about unwrapping values safely.
if let
if let totalWalks = aObject?.totalCount {
//operate on totalWalks
}
guard
guard let totalWalks = aObject?.totalCount else { return }
//operate on totalWalks
There are also cases where you will want to call a function on an optional value and in this case you can do so with ?
aObject?.doSomething()
Any return values this function might have will now be wrapped in an optional and you might have to unwrap them as well with an if let or guard
When working with optionals you should try to avoid forcing the unwrap with ! as even though you at the moment know that the value is not null that might after a change in the code not be true anymore.

Setting UITableView editing in Swift

I'm just trying to perform a very simple system API call, setting a UITableView to editing.
However I have no idea what the compiler is complaining about:
let isEditing = self.tableView?.editing
self.tableView?.setEditing(!isEditing, animated: true)
Error Message:
Optional type '_' cannot be used as a boolean; test for '!= nil' instead
Thankful for any advice!
You can just unwrap optional and use !isEditing!, but I believe this approach will be much safer:
if let isEditing = self.tableView?.editing {
self.tableView?.setEditing(!isEditing, animated: true)
}
The question mark next to tableView means that if the property tableView is nil then tableView?.editing must return nil. This results in an optional Bool for the statement let isEditing = self.tableView?.editing
You can fix this using an exclamation mark instead of a question mark (if you are sure 100% that tableView exists), or more cleaner
if let isEditing = self.tableView?.editing {
//If isEditing exists, than self.tableView exists for sure! If it doesn't
//the only possible reason is that tableView is nil so there is no point
//to try to call setEditing on a nil object. If isEditing is nil, the if
//condition will fail and you will not get in this scope.
self.tableView!.setEditing(!isEditing, animated: true)
}
Your isEditing variable type is Bool optional so apart true and false , it may have nil value as well and thats because of question mark used in self.tableView?.editing. To make it work you will need to force unwrap its value by using ! in either self.tableView!.editing or self.tableView?.setEditing(!isEditing!, animated: true).
Be aware that force unwrapping may be harmful and lead to runtime exceptions, so try avoiding it by using optional unwrapping

Access to AVAudioRecorder's meterEnabled give error

I'm trying to ON meter with AVAudioRecorder, but it give error as
Cann't assign to the result of expression
Declaration:
var recorder : AVAudioRecorder?
..
Definition
self.recorder?.meteringEnabled = true // Error here
You need to unwrap the self.recorder variable like so:
self.recorder!.meteringEnabled = true
Optional chaining does not support the setting of property values. It is only used for querying (see: getting) properties, and calling methods.
So code should be
if let recorder = self.recorder?{
recorder.meteringEnabled = true
}
This will only set the properties on the object if it has a value. Since your ivar is most likely defined as var player: AVAudioPlayer?, the compiler doesn't actually know whether it will have a value.
As mentioned in the language guide, under the Calling Properties Through Optional Chaining section:
You cannot, however, set a property’s value through optional chaining.

Resources