Reputation: 4268
I'm trying to convert my Swift 3 code to Swift 4. I get this error message:
Expression pattern of type 'String' cannot match values of type 'NSStoryboardSegue.Identifier
This is my code:
override func prepare(for segue: NSStoryboardSegue, sender: Any?) {
switch segue.identifier {
case "showVC1":
// DO SOMETHING
break
default:
break
}
}
Which type should I use instead of "String"?
Upvotes: 1
Views: 4826
Reputation: 726799
Swift 4 switched the type of identifier
property from String?
to NSStoryboardSegue.Identifier?
. The type is RawRepresentable
, RawType
of String
. You may need to change your code to a chain of if
statements, or use rawValue
explicitly:
switch segue.identifier {
case let x where x.rawValue == "showVC1":
// DO SOMETHING
break
default:
break
}
Upvotes: 0
Reputation: 539925
As of Swift 4, the storyboard identifier is a optional NSStoryboardSegue.Identifier
, which is defined as
extension NSStoryboardSegue {
public struct Identifier : RawRepresentable, Equatable, Hashable {
public init(_ rawValue: String)
public init(rawValue: String)
}
}
You can switch on its rawValue
:
switch segue.identifier?.rawValue {
case "showVC1"?:
// do something ...
default:
break
}
The recommended pattern however is to define constants for each storyboard identifier:
extension NSStoryboardSegue.Identifier {
static let showVC1 = NSStoryboardSegue.Identifier("showVC1")
// other storyboard identifiers ...
}
which can then be matched against:
switch segue.identifier {
case .showVC1?:
// do something ...
default:
break
}
In both examples, the "optional pattern" x?
(a shortcut for .some(x)
)
is used to match against an optional value.
Similar types were introduced for other "identifiers", e.g.
NSImage.Name
, which is the argument type of NSImage(named:)
in Swift 4.
For more information, see the discussion on the swift-users mailing list, starting at
The general idea (as I understand it) is to create separate types for each kind of identifier. In particular (from https://lists.swift.org/pipermail/swift-users/Week-of-Mon-20170717/005940.html):
... We are deliberately discouraging the string literal of the name. The string literal should be in only one place: the definition of the name constant. Everything else should use the constant. The compiler can provide autocompletion and typo detection of the constant. The string literal doesn't get that.
Upvotes: 8