Swift Protocols & Extensions
Posted on Wed 19 February 2020 in swift
Another late day of 100 Days of Swift today, I spent all day grinding on iNat vision stuff. Hopefully some of the visualizations from that will make their way into a new blog post soon.
Today was protocols & extensions, super awesome features in Swift. I was lucky to be at the WWDC talk on protocol-oriented programming a few years ago, and I was blown away by it at the time. Still seems like a great language feature, and I can see great uses for it for iNat.
Here's a long code example:
enum TaxonRank: Int {
case Species = 10
case Genus = 20
case Family = 30
// ... etc
func nameForCase() -> String {
switch self {
case .Species:
return "Species"
case .Genus:
return "Genus"
case .Family:
return "Family"
}
}
func isGenusOrHigher() -> Bool {
return self.rawValue >= 20
}
}
protocol Taxon {
var rank: TaxonRank { get set }
var scientificName: String { get set }
var commonName: String? { get set }
func isGenusOrHigher() -> Bool
func displayName() -> String
}
// doesn't even address localization or user preferences for scientific or common names
extension Taxon {
// can also be used for italicization rules, if I remember right
func isGenusOrHigher() -> Bool {
return rank.isGenusOrHigher()
}
func displayName() -> String {
if let displayName = commonName {
return displayName
} else {
if isGenusOrHigher() {
return "\(rank.nameForCase()) \(scientificName)"
} else {
return scientificName
}
}
}
}
// from an api
struct TaxonFromJson: Decodable, Taxon {
...
}
// realm, for example
class TaxonPersistent: Object, Taxon {
...
}
let sls = TaxonPersistent(rank: .Genus, scientificName: "Deroceras", commonName: "Smooth Land Slugs")
print(sls.displayName())
let oxy = TaxonPersistent(rank: .Genus, scientificName: "Oxychilus", commonName: nil)
print(oxy.displayName())
let trl = TaxonPersistent(rank: .Species, scientificName: "Tritonia lineata", commonName: nil)
print(trl.displayName())
The lack of a console in Swift Playgrounds continues to annoy me, as does the subpar text editing. Why can't I select text that's below the screen, ie why can't the selector scroll?