Expression Pattern of Type 'String' Cannot Match Values of Type 'Nsstoryboardsegue.Identifier

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



Leave a reply



Submit