Last active
November 22, 2016 00:20
-
-
Save annjose/5e7da181c54284bbd8c579cd5fc08aae to your computer and use it in GitHub Desktop.
Code sample demonstrated in Rob Napier video on writing clean Swift code
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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