Swift Switch case not
Since all patterns are checked sequentially (and the first match "wins"),
you could do the following:
switch (serverState, tlState) {
case (.Connecting, .Connecting): return true // Both connecting
case (.Connecting, _): return false // First connecting, second something else
case (.Closed, .Disconnected(.None)): return true
case (.Closed, _): return false
// and so on ...
So generally, matching a case where one of the state is not a specific state can be done with two patterns: The first matches the state,
and the second is the wildcard pattern (_
) which then matches all other
cases.
How to express not equal to with a Swift switch statement with tuple pattern matching
You should be able to write it as:
switch (source, type, status) {
case (.cashVoucher, _, let st) where st == .awaitingValidation:
return cashVoucherAwaitingValidationMessageComponants
case (.cashVoucher, _, let st) where st != .awaitingValidation:
return validatedCashVoucherMessageComponants
default:
fatalError("")
}
So assign the third value of the tuple to a constant (here st
) and use where
to check for equality.
What to put in switch cases that have nothing to do?
Use a break statement:
switch createAppDirectory(searchPath) {
case .success:
break
case .failure(let error): return .failure(error)
}
EDIT:
As Mojtaba pointed out, if you're not going to use the associated value for a particular case of your enum you can simply skip it. I've edited my answer above to remove the (_)
from the .success
case
Swift switch statement not covering all cases
As you've discovered, your cases don't cover all of the numerical possibilities. Also, your color
should likely be a computed property based on the current state of the Binding
, rather than something you set in init
:
struct ProgressBar: View {
@Binding var progress: Double
var color: Color {
switch progress {
case 0.0..<0.20:
return .blue
case 0.20..<0.40:
return .green
case 0.40..<0.60:
return .yellow
case 0.60...1.0:
return .red
default:
return .black
}
}
var body: some View {
color
}
}
Swift Switch statement fails to match strings: What could cause this?
I suspect the problem is actually in your getWatchModel
method, specifically in the line:
var machine = CChar()
This allocates a single byte. You need to allocate size
bytes.
Here's one way of doing it:
func getWatchModel() -> String? {
var size: size_t = 0
sysctlbyname("hw.machine", nil, &size, nil, 0)
var machine = [CChar](repeating: 0, count: size)
sysctlbyname("hw.machine", &machine, &size, nil, 0)
return String(cString: machine, encoding: .utf8)
}
I suspect this lead to the String
containing garbage. I'm actually surprised you did not see any crashes.
I've searched and search SwiftUI Switch Case Menu Cycle?
You can add an Identifier to your Option class and use this for currentSelection
, if you want to set an option, just set currentSelection
to option.id
:
Also:
1: If you want answers, it's best to format your code, before you post it (select in Xcode and ctrl+i should do it), so it's easy to read and understand
2: A minimal, reproducible example is not just posting your entire code, create an example, that contains only as much code as necessary to show the problem you're experiencing. The code I posted would be a better example, it will work without having to change anything. Your code includes references to objects that are not on here, so a possible helper would have to remove those, before he could even test your issue
here is a guide on how to create a minimal, reproducible example:
struct Option: Hashable, Identifiable {
// Identifier for Option !! MUST be unique
let id: Int
let title: String
let imageName: String
}
struct ContentView: View {
@State var currentOption: Int = 0
let options: [Option] = [
.init(id: 1, title: "DART Meadow", imageName: "sun.max.fill"),
.init(id: 2, title: "Research", imageName: "flame"),
.init(id: 3, title: "Navigation", imageName: "moon.stars.fill"),
]
var body: some View {
GeometryReader { geo in
HStack {
ListView(options: options, currentSelection: $currentOption)
.frame(width: geo.size.width / 2, height: geo.size.height)
switch (currentOption) {
case 1: Text("OrbitNodeView")
case 2: Text("ATM26NodeView")
case 3: Text("NozzleNodeView")
default: Text("MainView")
}
}
}
}
}
struct ListView: View {
let options: [Option]
@Binding var currentSelection: Int
var body: some View{
VStack(alignment: .leading) {
ForEach(options, id: \.self) {option in
HStack {
Image(systemName: option.imageName)
.frame(width: 20)
Text(option.title)
// Don't even have to use current = options[currentSelection] anymore:
.foregroundColor(currentSelection == option.id ? .accentColor : .primary)
}
.padding(8)
.onTapGesture {
// Set the currentSelection to the ID of the option
currentSelection = option.id
}
}
}
}
}
switch and case statement is not working after updating from Swift 2.2
In Swift 2, date components in NSDateComponents
were
represented as Int
, and undefined components were set to the special value NSDateComponentUndefined
.
In Swift 3, date components in DateComponents
are represented as
optionals (Int?
) and undefined components are nil
.
So weekday
in your code is an optional and you need to unwrap it
(which is safe because you requested that component):
switch weekday! {
case 1:
// ...
}
Or you can match against the "optional pattern":
switch weekday {
case 1?:
// ...
}
(Apparently Xcode "Fix-it" does not work correctly, it suggestscase ?1:
instead of case 1?:
. This happens in both Xcode 8
and Xcode 9 and looks like a bug.)
However, an easier solution is to use thecomponent(_:from:)
method of Calendar
:
let weekday = Calendar(identifier: .gregorian).component(.weekday, from: Date())
which gives you a single date component as a (non-optional) Int
.
Note that the cast to NSCalendar
is not needed.
Does Swift have a Switch *expression* (as opposed to a Switch *statement*) like C#?
Unfortunately, Swift does not have switch
expressions, only switch
statements. The Swift language grammar currently supports the following as expressions:
- References to identifiers
- Literals
- Self expressions (
self.<whatever>
,self[<whatever>]
, etc.) - Superclass expressions (
super.<whatever>
,super[<whatever>]
, etc.) - Closures
- Parenthesized expressions (expressions, in parentheses)
- Tuples
- Implicit member expressions (references to functions or variables that would reference
self
, but based on context, are allowed to skip referencingself
— e.g.foo(123)
as opposed toself.foo(123)
) - Wildcards (
_
) - Key paths, selectors, and key path strings
Note that things like control flow statements, do
statements, and others are not included in this list — Swift only allows those as full statements. Currently, statements can be composed of:
- Expressions
- Declarations
- Loop statements
- Branch statements (
if
/guard
/switch
) - Labeled statements (
label: <some statement>
) - Control transfer statements (
break
,continue
, etc.) - Defer statements
- Do statements
- Compiler control statements (
#if ...
,#error
,#warning
, etc.)
This is something currently intimately tied to the core of the language, so changing it would be no small feat! For this reason, this feature is also at the top of the list of the Swift "commonly rejected changes" list for control flow:
if
/else
andswitch
as expressions: These are conceptually interesting things to support, but many of the problems solved by making these into expressions are already solved in Swift in other ways. Making them expressions introduces significant tradeoffs, and on balance, we haven't found a design that is clearly better than what we have so far.
Despite this, this is something that comes up periodically on the forums, and has been discussed extensively (e.g. If / else expressions, which contains a lot of discussion of switch
expressions too). This is something that plenty of folks want, so I'd recommend getting an understanding the latest state of things by reading through some of the threads on the forums for ideas on what/how to constructively propose, if you're interested!
How to return a function from inside a switch-case statement
following @JoakimDanielson advice I changed myServerFunction to throw instead of failing a completion handler:
func myServerFunction(finishesSuccessful:Bool) throws {
if finishesSuccessful {
print("Upload to Server successful")
} else {
throw MyError.serverError
}
}
Now I can catch the error in myMainFunction
if uploadToServer {
do {
try myServerFunction(finishesSuccessful: false)
} catch {
completionHandler(.failure(.serverError))
return
}
}
Related Topics
Cross Platform Aes Encryption Between iOS and Kotlin/Java Using Apples Cryptokit
How to Open a Screen Directly in Xcuitest
Making Parts of Text Bold in Swiftui
How to Read a Property List from Data in Swift 3
Swift: When Should I Use "Var" Instead of "Let"
Swift: Providing a Default Protocol Implementation in a Protocol Extension
Arkit -Drop a Shadow of 3D Object on the Plane Surface
Why Swift Throws Error When Using Optional Param in Closure Func
How to Bring Nswindow to Front and to the Current Space
Modal View Closes When Selecting an Image in Uiwebview iOS
Iphonex Not Call Prefersstatusbarhidden
Gcd with Static Functions of a Struct
How to Say "If X == a or B or C" as Succinctly in Swift as Possible