Skip to content

Instantly share code, notes, and snippets.

@casperzandbergenyaacomm
Last active May 11, 2018 10:18
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save casperzandbergenyaacomm/ead5568c8801765e4c5b8a49596044ab to your computer and use it in GitHub Desktop.
Save casperzandbergenyaacomm/ead5568c8801765e4c5b8a49596044ab to your computer and use it in GitHub Desktop.
Implicit Member Expression, Global Constants, and categories Swift
// I wanted to use IME with my global constants (https://medium.com/@maxcampolo/fun-with-global-constants-in-swift-3e012aaec0c7)
// but not lose the functionality of catogories in my constants
// Problem:
extension String {
static let string1 = "Test string."
}
let a: String = String.string1
let b: String = .string1
let c: String = String.string1.description
let d: String = .string1.description // Type of expression is ambiguous without more context
// Meaning this is not possible:
extension String {
static let category1 = Category1()
struct Category1 {
static var string1: String { return "Test string." }
}
}
let e: String = .category1.string1 // Type of expression is ambiguous without more context
// Simple solution:
// This allows for IME(as close as it gets) with categories containing strings
// disadvantage: can't handle categories containing categories
extension String {
enum CategoryStrings: String {
case string1 = "Test string."
}
static func category(_ string: CategoryStrings) -> String {
return string.rawValue
}
}
let f: String = .category(.string1)
// Advanced solution:
// This allows for IME with categories containing categories or strings
// disadvantage: adds loads of code and possibly overcomplicated
protocol Category {
func rawValue() -> String
}
extension Category where Self: RawRepresentable, Self.RawValue == String {
func rawValue() -> String {
return rawValue
}
}
extension String {
// -
enum SuperParentCatStrings: Category {
case parent(ParentCategoryStrings)
func rawValue() -> String {
switch self {
case .parent(let s): return .anycategory(s)
}
}
}
// --
enum ParentCategoryStrings: Category {
case category1(Category1Strings)
case category2(Category2Strings)
func rawValue() -> String {
// I wish there I knew a better way to do this
switch self {
case .category1(let s): return .anycategory(s)
case .category2(let s): return .anycategory(s)
}
}
}
// ---
enum Category1Strings: String, Category {
case string1 = "Test string 1."
}
enum Category2Strings: String, Category {
case string1 = "Test string 2."
}
// Generic value resolver
private static func anycategory(_ string: Category) -> String {
return string.rawValue()
}
// Entry functions
static func parentcategory(_ parent: ParentCategoryStrings) -> String {
return parent.rawValue()
}
static func superparentcategory(_ parent: SuperParentCatStrings) -> String {
return parent.rawValue()
}
}
let g: String = .parentcategory(.category1(.string1))
let h: String = .superparentcategory(.parent(.category2(.string1)))
// What I ended up doing:
enum HomeStrings: String {
case title
}
enum PollStrings: String {
case test
}
extension String {
static func localizedStringForKey(_ key: String) -> String {
return key // TODO: language implementation
}
// Entry functions
static func k(home local: HomeStrings) -> String {
return .localizedStringForKey(local.rawValue)
}
static func k(polls local: PollStrings) -> String {
return .localizedStringForKey(local.rawValue)
}
}
let i: String = .k(home: .title)
// How is this better?
// now when a string is added I just add a case with the id instead of:
var homeTitleString: String { get { return String.localizedStringForKey("homeTitleString") } }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment