Value of type 'String?' has no member 'rawValue'; did you mean 'hashValue'?"

I have this code for Coredata saving, and I'm trying to implement groups enumeration from another example but I fail with multiple errors every tine I try.

"Value of type 'String?' has no member 'rawValue'; did you mean 'hashValue'?"
"Value of type 'Any' has no member 'group'

Im very confused after so many tries, I will post the code from where I started.

struct ChannelController {
            
    static func create(Group: String, Title: String, Url: URL, Logo: URL, Playlist: Playlist) {
        let _ = Channel(Group: Group, Title: Title, Url: Url, Logo: Logo, Playlist: Playlist)
    }
}

extension Channel {
    
    @discardableResult convenience init(Group: String, Title: String, Url: URL, Logo: URL, Playlist: Playlist, context: NSManagedObjectContext = CoreDataStack.context) {
        self.init(context: context)
        
        // MARK: Properties
        self.group = Group
		self.title = Title
		self.url = Url
        self.logo = Logo
		self.playlist = Playlist
        
	}
}

Here is the example I want to implement.

struct DataItem: Equatable {
    // MARK: Types
    
    enum Group: String {
        case Scenery
        case Iceland
        case Lola
        case Baby
        
        static let allGroups: [Group] = [.Scenery, .Iceland, .Lola, .Baby]
    }
    
    // MARK: Properties
    
    let group: Group
    
    let number: Int
    
    let title: String
    
    var identifier: String {
        return "\(group.rawValue).\(number)"

    }
}

What I want to archive is to be able to map and filter objects stored in Group categories.

Some help will be very apreciated.

First of, I don’t know how DataItem is related to Channel, but I’ll assume that Channel.group is of type DataItem.Group also I don’t know what you’ve tried, since you simply tell the error, and your starting point. Starting from there.

  • In Channel.init, Group is of type String, so you’re forcing type String onto type Group, which isn’t allowed, but since Group has rawValue, compiler would suggest that you use Group(rawValue: Group).
  • Say you rename Group to something else, say groupRawValue the initialization becomes
    group = Group(rawValue: groupRawValue). The return type is still Group? since groupRawValue can have strange value. If groupRawValue is ”Spaghetti” then there would be no Group value associated with it and it would return nil.
    • If you know that groupValue will always be valid at this point from your programming logic, you can force unwrap the value by
      group = Group(rawValue: groupRawValue)!
      
    • If groupRawValue may indeed be strange value, you should check if the return type is nil and handle it appropriately.
1 Like

On a sidenote, you don’t need to make Group.allGroups yourself. You can have Swift synthesize it for you via CaseIterable protocol.

enum Group: String, CaseIterable {
    case ...
}

Group.allCases // [.Scenery, .Iceland, .Lola, .Baby]
2 Likes

It is a good note to make all variables camelCase rather than PascalCase.

"Value of type 'Any' has no member 'group'
Because Any is a non-nominal, type-erased protocols that everything conforms to. It has no methods or properties.