Closed NCrusher74 closed 4 years ago
What you have is probably what I would have settled on. (Unless the list became just too cumbersome and I decided just to vend raw strings and let the client sort it out.)
As far as I can tell, the Apple/Quicktime metadata is mostly centered around the genreID
number, so I've had to redo things so that the rawValue
(whether declared at the top of the enum because the enum is at the lowest level, or synthesized with a computed property) is the genreID
and then ALSO add a stringValue
variable to produce a readable string when/if appropriate (I'm not even sure it will be; I could be doing all this for nothing.)
It would be nice if enums with associated types could still conform to CaseIterable
, as I haven't figured out how to synthesize that in this sort of situation, where the associated type is another enum, which may have its own associated types as well. I'm not sure how it's going to work, trying to use these as a data source for a combo box when I get back to working on the user-facing stuff, if I can't use them as arrays.
Is there some way to extend enum
to make synthesizing raw type comformance and/or case iterable conformance easier in a situation where there's an associated type?
You just have to supply the conformance to CaseIterable
manually.
enum LatinLetter: CaseIterable {
case a, b, c // ...
}
enum GreekLetter: CaseIterable {
case α, β, γ // ...
}
enum Letter: CaseIterable {
case latin(LatinLetter)
case greek(GreekLetter)
static var allCases: [Letter] {
return LatinLetter.allCases.map({ Letter.latin($0) })
+ GreekLetter.allCases.map({ Letter.greek($0) })
}
}
Ah okay, it was the map
thing I was missing. I've seen it a few times, and implemented other people's code with it, but I still haven't grasped how or when to use it myself. Hopefully that will click soon. But then I just got the hang of using {where: $0}
when iterating through collections in the last month, so I guess we'll see.
Okay, I'm finally back to this, working my way toward resuming work on Audiobook Liberator, but I could use some advice on how to organize the genre data.
Back when we were first working on AudiobookLiberator, we implemented the genre/subgenre system as a bunch of arrays-- one array for the genre, and then an bunch of subgenre arrays that correspond with each item within the genre array. This was before I knew anything about how to use enums, and if I had to do it over again at this point, I probably would have used enums for it all. And since it's never actually worked properly (I don't remember what the error is, but I know something doesn't work right with it) now, when I'm working on handling genres in AudiobookTagger, is probably the best time to lay the groundwork for re-working that.
However. I've also realized since then that the Audible genre/subgenre options aren't the only ones out there. The iTunes store--from which people may also acquire audiobooks--has their own genre/subgenre/sub-subgenre, etc, system:
I don't know how old or out of date the listing I found of the genres in the iTunes store is, and if there's a library for it that you can access directly from Swift/XCode, I don't know where it is or how to find it. But it's a really, really long list, even when filtering out the music, iTunesU, AppStore, etc entries.
As far as books go, there are three categories: Books (presumably ebooks, since this is the iTunes store), audiobooks, and textbooks. While it would seem all I would really want to mess with is the audiobooks portion, that particular portion is general almot to the point of uselessness(it's got a fairly brief list of general genres, and no subgenres), and I wouldn't be surprised if the version I've got here is really old and they've added a sub-genre system more in-line with the books portion.
The Books genre system is much more informative, but also more complex, because not only are there subgenres, there are sub-subgenres:
Books|Young Adult|Holidays & Celebrations|Birthdays
(i.e. genre: Young Adult, subgenre: Holidays & Celebrations, sub-subgenre: Birthdays).I spent about twelve hours breaking this out into a bunch of nested enums before I thought to ask you if there was a better way:
I'm... not entirely sure what my precise question here is. Mostly I just need ideas for what is the best way to implement this data, I guess?
GenreID
in iTunes. In my Genre enum inSwiftTaggerMP4
this integer is actually the rawValue, and the strings you see above are implemented in a computed property in the enum.