Expression pattern of type 'String' cannot match values of type 'NSStoryboardSegue.Identifier
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
}
Expression pattern cannot match
Turns out, if I change the game: Game
to game: _
, it works as well since I'm not using the game at that moment, it's just part of the syntax
Switching on UIButton title: Expression pattern of type 'String' cannot match values of type 'String?!'
currentTitle
is an optional so you need to unwrap it. Also, the type of sender
should be UIButton
since you are accessing the currentTitle
property.
@IBAction func buttonClick(sender: UIButton) {
if let theTitle = sender.currentTitle {
switch theTitle {
case "Button1":
print("Clicked Button1")
case "Button2":
print("Clicked Button2")
default:
break
}
}
}
Expression pattern of type 'String' cannot match values of type 'AVMetadataKey'
Please ⌘-click on commonKey
and you will see that the argument is of type AVMetadataKey
rather than String
.
You are encouraged to read the documentation. It's worth it and you can fix yourself an issue like this in seconds.
I added a guard
statement to exit the method immediately if commonKey
is nil
.
private extension JukeboxItem.Meta {
func process(metaItem item: AVMetadataItem) {
guard let commonKey = item.commonKey else { return }
switch commonKey
{
case .commonKeyTitle :
title = item.value as? String
case .commonKeyAlbumName :
album = item.value as? String
case .commonKeyArtist :
artist = item.value as? String
case .commonKeyArtwork :
processArtwork(fromMetadataItem : item)
default :
break
}
}
}
expression pattern of type 'Int' cannot match values of type 'uint?' (aka 'Optional UInt32 ')
Sounds like report.level
is an optional value. You need to unwrap it or you need your switch to have optional patterns.
Unwrapping it would look like this:
class func shareLevelUp(toFacebook level: uint, from vc: UIViewController?) {
let report = GymStatusReport.statusReportForLevel(level)
guard let level = report.level else {
return
}
switch level {
case 1:
// something
case 2:
// something
case 3:
// something
case 4:
// something
default:
return
}
}
Matching optionals would look like this:
class func shareLevelUp(toFacebook level: uint, from vc: UIViewController?) {
let report = GymStatusReport.statusReportForLevel(level)
switch report.level {
case .some(1):
// something
case .some(2):
// something
case .some(3):
// something
case .some(4):
// something
default:
return
}
}
Expression pattern of type 'Roll' cannot match values of type 'Requests.RawValue' (aka 'Roll')
That's because of your structure Roll
doesn't conform Equatable
protocol and you're trying to make a comparison of it, just change it to
struct Roll: Equatable {
let times: String
init(with times: String) {
self.times = times
}
}
NSCollectionView, Swift 4 - Cannot invoke register
In Swift 4, you need to use NSUserInterfaceItemIdentifier
instead of a String
to identify a user interface element.
You should define static constants for identifiers and reference them when registering nibs.
Example:
extension NSUserInterfaceItemIdentifier {
static let collectionViewItem = NSUserInterfaceItemIdentifier("CollectionViewItem")
}
collectionView.register(item, forItemWithIdentifier: .collectionViewItem)
Why does Apple choose to use nested struct types to replace 'String' type parameter?
The point is to avoid scattering strings throughout your code. What you should do is define your constant for a given nib just once in your code. Then anywhere you need to use that nib name, you reference that one constant instead of retyping (possibly incorrectly) the hardcoded string.
You can define something like:
public struct MyNibs {
public static let TagCellView = NSNib.Name("TagCellView")
}
And then use it as:
let nib = NSNib(nibNamed: MyNibs.TagCellView, bundle: nil)
Even cleaner is to add the constant as an extension to NSNib.Name
:
extension NSNib.Name {
public static let TagCellView = NSNib.Name("TagCellView")
}
Then your use is shorter:
let nib = NSNib(nibNamed: .TagCellView, bundle: nil)
This way you only enter the hardcoded string "TagCellView"
once in your codebase. Everywhere else in your code you use MyNibs.TagCellView
. If you rename the nib in Interface Builder, you only need to update one line of code instead of several.
Of course nothing prevents you from typing NSNib.Name("TagCellView")
everywhere you need to reference that nib but the extra baggage may be incentive to create a constant.
Related Topics
How to Remove Space Above and Below Text View in Swiftui
Lottieanimationview Size Won't Change/Is Too Small (Ios/Swift)
Stack Overflow When Defining Subscript on Ckrecord in Swift
Navigationview Swiftui Shows Split View in iPad
Overloads for '...' Exist with These Result Types: Closedrange<Bound>, Countableclosedrange<Bound>
How to Use Implicitly Unwrapped Optionals
Why Is Uint64 Max Equal -1 in Swift
Swift 3 - How to Write Functions with No Initialisers Like the New Uicolors
How to Extend Float3 or Any Other Built-In Type to Conform to the Codable Protocol
Swift Variable Declaration and Initialize
Navigationlink Is Grayed Out and Does Not Perform Any Action
Why Specify [Unowned Self] in Blocks Where You Depend on Self Being There
Is There *Any* Situation Under Which "For _ in [1,2,3]" Will Not Loop at All