Skip to content

Instantly share code, notes, and snippets.

@annjose
Last active November 22, 2016 00:20
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save annjose/5e7da181c54284bbd8c579cd5fc08aae to your computer and use it in GitHub Desktop.
Save annjose/5e7da181c54284bbd8c579cd5fc08aae to your computer and use it in GitHub Desktop.
Code sample demonstrated in Rob Napier video on writing clean Swift code
// sample code for Rob Napier's video 'Swift Legacy Functional Programming' found in Realm News
// the article also explains how to use Swift to avoid bugs and write cleaner code
// URL: https://realm.io/news/tryswift-rob-napier-swift-legacy-functional-programming/
// ============ Use Enum for OR relationship; use Struct for AND relationship =======================
struct Credential {
let username: String
let password: String
}
struct Token {
let string: String
}
func login(credential: Credential, completion: (Token?, Error?) -> Void) {
if credential.password == "PassMe" {
let token = Token(string: "1234")
completion(token, nil)
} else {
let error = NSError(domain: "Login", code: 401, userInfo: nil)
completion(nil, error)
}
}
// call the login function using Credential
login(credential: Credential(username: "ann", password: "PassMe")) { (token, error) in
if let token = token {
print("Login success. Token = \(token.string)")
} else if let error = error {
print("Login failure")
}
}
// call it once again - this time with failure scenario
login(credential: Credential(username: "ann", password: "SomethingElse")) { (token, error) in
if let token = token {
print("Login success. Token = \(token.string)")
} else if let error = error {
print("Login failure")
}
}
// Look at the completion block - the result with be either Token OR Error - not BOTH
// So we shoudl define it as 'OR' relationship using Enum
// Define an enum Result to indicate Token OR Error
enum Result<Value> {
case success(Value)
case failure(Error)
}
func login_better(credential: Credential, completion: (Result<Token>) -> Void) {
if credential.password == "PassMe" {
let token = Token(string: "1234")
completion(Result.success(token))
} else {
let error = NSError(domain: "Login", code: 401, userInfo: nil)
completion(Result.failure(error))
}
}
login_better(credential: Credential(username: "ann", password: "PassMe")) { (result) in
switch result {
case .success(let token):
print("Login success. Token = \(token.string)")
case .failure(let error):
print("Login failure")
}
}
// ============ Functional programming =======================
struct Person {
let name: String
func isValid() -> Bool {
return name.characters.count <= 5
}
}
Person(name: "John").name
// Convert names to persons
let names = ["John", "LongName", "Short"]
var persons = [Person]()
for name in names {
let p = Person(name: name)
if p.isValid() {
persons.append(p)
}
}
persons
let possiblePersons = names.map { (name) -> Person in
Person(name: name)
}
names.map(Person.init)
names.map(Person.init).filter { (person) -> Bool in
person.isValid()
}
names.map(Person.init).filter { $0.isValid() }
names.map { (name) -> String in
name.uppercased()
}.map(Person.init)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment