How to judge enum value in Swift? - ios

Here is example code:
enum DownloadItemStatus: Int {
case Unstart, Prepare, Downloading, Paused, Finished, Failured
}
if status == .Unstart || status == .Paused || status == .Failured {
}
Is there a better method to judge the enum Value?

You can use the switch statement :
switch (status) {
case .Unstart, .Paused, .Failured :
// Do something
break
case .Finished:
// Do something else
break
default:
// Handle all the others cases here
break
}
Please note that in Swift, the break statement are not mandatory in order to avoid the fall through the next case block. I've only added them because you need at least one executable statement after each case test.
More infos about Switch statement available on the Swift Programming guide.

Related

updating flag value in Singleton class

I am having viewcontroller with 10 Switch cases.
In one of the case I am setting flag value of one of the flag in sigelton class as "true", whose default value is false.
Now I want to have that flag value as true only for given case, for rest of the time it should always have default value, so after executing the case the flag value should be back to default one in singelton class.
I don't want to write flagvalue to false in rest 9 cases.
What will be the best way to achieve this?
Sample code I need...
singeltonClass
class singeltonDemo{
let checkRegularAccount = false
}
ViewControllerClass
class AccountView {
switch(accountType){
case 0: // execute case
case 1: // execute case
case 2: // execute case
case 3: // execute case
case 4: // execute case
case 5: // execute case
case 6: // execute case
case 7:
singeltonDemo.shared.checkRegularAccount = true
case 8: // execute case
case 9: // execute case
default: // execute default case
}
}
I don't want to set singeltonDemo.shared.checkRegularAccount = false in each remaining case.
what will be the option available for this.
Help will be appreciated.
Thanks.
You setting it to true to do some piece of work right? after this piece of work is finished then just set it back to false.
You can write just outside the SWITCH CASE.
class singeltonDemo{
let checkRegularAccount = false
}
ViewControllerClass
class AccountView {
switch(accountType){
case 0: // execute case
case 1: // execute case
case 2: // execute case
case 3: // execute case
case 4: // execute case
case 5: // execute case
case 6: // execute case
case 7:
singeltonDemo.shared.checkRegularAccount = true
case 8: // execute case
case 9: // execute case
default: // execute default case
}
//Outside switch
singeltonDemo.shared.checkRegularAccount = false
}

Use of unresolved identifier when using StoreKit constants with iOS 9.3/Xcode 7.3

I get the error "Use of unresolved identifier" when trying to use one of these StoreKit constants:
SKErrorClientInvalid
SKErrorPaymentCancelled
SKErrorPaymentInvalid
SKErrorPaymentNotAllowed
SKErrorStoreProductNotAvailable
SKErrorUnknown
Your code may look like this:
if transaction.error!.code == SKErrorPaymentCancelled {
print("Transaction Cancelled: \(transaction.error!.localizedDescription)")
}
What changed? Is there a new module I need to import?
As of iOS 9.3 certain StoreKit constants have been removed from the SDK. See StoreKit Changes for Swift for the full list of changes.
These constants have been replaced in favor of the SKErrorCode enum and associated values:
SKErrorCode.ClientInvalid
SKErrorCode.CloudServiceNetworkConnectionFailed
SKErrorCode.CloudServicePermissionDenied
SKErrorCode.PaymentCancelled
SKErrorCode.PaymentInvalid
SKErrorCode.PaymentNotAllowed
SKErrorCode.StoreProductNotAvailable
SKErrorCode.Unknown
You should check be checking your transaction.error.code with the enum's rawValue. Example:
private func failedTransaction(transaction: SKPaymentTransaction) {
print("failedTransaction...")
if transaction.error?.code == SKErrorCode.PaymentCancelled.rawValue {
print("Transaction Cancelled: \(transaction.error?.localizedDescription)")
}
else {
print("Transaction Error: \(transaction.error?.localizedDescription)")
}
SKPaymentQueue.defaultQueue().finishTransaction(transaction)
}
You should be checking against these error codes rather than the legacy constants if creating a new application using StoreKit on iOS 9.3 and above.
Adding to #JAL answer heres a switch variant
switch (transaction.error!.code) {
case SKErrorCode.Unknown.rawValue:
print("Unknown error")
break;
case SKErrorCode.ClientInvalid.rawValue:
print("Client Not Allowed To issue Request")
break;
case SKErrorCode.PaymentCancelled.rawValue:
print("User Cancelled Request")
break;
case SKErrorCode.PaymentInvalid.rawValue:
print("Purchase Identifier Invalid")
break;
case SKErrorCode.PaymentNotAllowed.rawValue:
print("Device Not Allowed To Make Payment")
break;
default:
break;
}
None of the above answers worked for me. What solved it was prepending StoreKit to the SKError.
My switch looked something like this:
switch (transaction.error!.code) {
case StoreKit.SKErrorCode.Unknown.rawValue:
print("Unknown error")
break;
}
No idea why.

How can I access the associated values of SwiftyDropbox errors?

I’ve been working with SwiftyDropbox and I’m having a curious problem with errors. Specifically, I’m not sure how to manipulate errors in the closure callbacks provided after responses are received so that I can get at their associated values.
For instance, the completion handler for Dropbox.authorizedClient.filesListFolder provides a
CallError<(Files.ListFolderError)>?
to work with. How would I go about checking if it is a
CallError.HTTPError
, so that I can get the HTTP error code out of it? Right now I’m just sucking that information out of the error’s .description but that doesn’t seem like the right way to do it.
This is what I’ve tried. I suspect I’m failing to understand something with the generics involved.
client.filesListFolder(path: "", recursive: false).response({ (listFolderResult, listFolderError) -> Void in
switch listFolderError {
case let .HTTPError(code, message, requestId):
print("http error")
default:
print("not a http error")
}
Enum case 'HTTPError' not found in type 'CallError?'
The problem here is that we're trying to switch on an optional. This simpler example highlights the exact same problem:
enum Foo {
case a
case b
}
let x: Foo? = nil
switch x {
case .a:
print("a")
case .b:
print("b")
}
Enum case 'a' not found in type 'Foo?'
We can switch over optionals because Optional is itself an Enum, with two cases: None and Some(T).
So when we're switching over an optional, Swift expects some code like this:
switch someOptional {
case .Some(someValue):
print("do some things")
case .None:
print("someOptional was nil")
}
But that's probably not necessarily particularly useful to use. We have an optional enum, and ultimately, if we dealt with our optional in a switch, we'd just have nested switch statements. Instead, we should deal with our optional in the normal Swift way of dealing with optionals:
if let error = listFolderError {
switch error {
case let .HTTPError(code, message, requestID):
print("http error")
default:
print("some other error")
}
} else {
print("there was no error")
}

Enum case switch not found in type

Can someone please help me with this.
I have the following public enum
public enum OfferViewRow {
case Candidates
case Expiration
case Description
case Timing
case Money
case Payment
}
And the following mutableProperty:
private let rows = MutableProperty<[OfferViewRow]>([OfferViewRow]())
In my init file I use some reactiveCocoa to set my MutableProperty:
rows <~ application.producer
.map { response in
if response?.application.status == .Applied {
return [.Candidates, .Description, .Timing, .Money, .Payment]
} else {
return [.Candidates, .Expiration, .Description, .Timing, .Money, .Payment]
}
}
But now the problem, when I try to get the value of my enum inside my rows it throws errors. Please look at the code below.
func cellViewModelForRowAtIndexPath(indexPath: NSIndexPath) -> ViewModel {
guard
let row = rows.value[indexPath.row],
let response = self.application.value
else {
fatalError("")
}
switch row {
case .Candidates:
// Do something
case .Expiration:
// Do something
case .Description:
// Do something
case .Timing:
// Do something
case .Money:
// Do something
case .Payment:
// Do something
}
}
It throws an error: Enum case 'some' not found in type 'OfferViewRow on the line let row = rows.value[indexPath.row]
And on every switch statements it throws: Enum case 'Candidates' not found in type '<<Error type>>
Can someone help me with this?
The guard statement wants an optional, as hinted by "Enum case 'some'" in the error message.
But rows.value[indexPath.row] is not Optional<OfferViewRow>, it is a raw OfferViewRow. So it won't enter a guard statement.
Move let row = rows.value[indexPath.row] one line up: Swift takes care of bounds checking, and will crash if indexPath.row is out of bounds.

Swift: Handling login error states properly?

I've been trying to find a better way to handle my error states.
Currently I have about 10 if else statements, which clearly is an inefficient way to handle my errors.
From what I've been able to find, it looks like enumerations are the way to go. But I havn't been able to implement it successfully.
Every example I've been able to find follow this form:
enum Result<T> {
case Success(T)
case Failure(String)
}
var result = divide(2.5, by:3)
switch result {
case Success(let quotient):
doSomethingWithResult(quotient)
case Failure(let errString):
println(errString)
}
But I don't quite see how this can work for my error states.
There's no if statements, not to mention explanation of where to implement these, and they all only have 1 "action" In the above example a println.
I have several lines of code I need to run for every error state.
Here's an example of my errorhandling for an email textfield.
if textField == emailTextField {
emailTextField.textColor = UIColor.formulaBlackColor()
emailIcon.setTitleColor(UIColor.formulaBlackColor(), forState: .Normal)
emailTextField.resignFirstResponder()
if textField.text.isEmpty {
emailIcon.setTitleColor(UIColor.formulaRedColor(), forState: .Normal)
emailState.text = ""
emailTextField.attributedPlaceholder = NSAttributedString(string:"Email Address",
attributes:[NSForegroundColorAttributeName: UIColor.formulaRedColor()])
showError("Please enter your email.")
} else if emailTextField.text.isValidEmail() == false {
emailIcon.setTitleColor(UIColor.formulaRedColor(), forState: .Normal)
emailTextField.textColor = UIColor.formulaRedColor()
emailState.text = ""
showError("Please enter a valid email address")
} else {
emailIcon.setTitleColor(UIColor.formulaBlackColor(), forState: .Normal)
emailState.textColor = UIColor.formulaGreenColor()
emailState.text = ""
hideError()
}
}
I've been trying to make an enum like this:
enum Login {
case NoInternetConnection
case NoEmail
case InvalidEmail
case NoPassword
case WrongEmailOrPassword
case Success
}
But I havn't found a way to make this work.
When I added a switch case, I was presented with an error "Expected Declaration",
I tried putting it in a function, and the error went away. But I havn't been able to figure out how to do anything with the cases.
switch Login {
case Success:println("CASE SUCCESS")
case NoEmail:println("CASE NoEmail")
}
Obviously I still have to implement my if statements in some way to check e.g. if the emailTextField is empty? But how can I set the case to NoEmail. And make it run several lines of code?
You need to have a value of that enumeration first, that you can check, like so:
enum Login {
case NoInternetConnection
case NoEmail
case InvalidEmail
case NoPassword
case WrongEmailOrPassword
case Success
}
// Here you get your result, e.g. from a function.
let loginResult = Login.Success
switch loginResult {
case let .NoInternetConnection:
println("No internet connection")
case let .NoEmail:
println("No email specified")
case let .InvalidEmail:
println("Email invalid")
case let .NoPassword:
println("No password specified")
case let .WrongEmailOrPassword:
println("Email or password wrong")
case let .Success:
println("Success")
}
Remember that there is also another way to go, which is Optional Chaining.
In my opinion, it is always best to break such conditional chains up into several functions (see also Clean Code), but unfortunately Swift does not support catching exceptions, so we have to go this way.

Resources