Created
October 3, 2017 17:22
-
-
Save zyuanming/fe44e30acee43155c066a490a81e93ab to your computer and use it in GitHub Desktop.
UIKonf 2017 – Day 2 – Chris Eidhof & FlorianKugler – Intermediate Types
This file contains hidden or 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
| struct KeyboardWillShowPayload { | |
| let endFrame: CGRect | |
| init(userInfo: [AnyHashable: Any]) { | |
| endFrame = userInfo[UIKeyboardFrameEndUserInfoKey] as! CGRect | |
| } | |
| } | |
| struct NotificationDescriptor<A> { | |
| let name: Notification.Name | |
| let parse: ([AnyHashable: Any]) -> A | |
| } | |
| let keyboardWillShow = NotificationDescriptor(name: .UIKeyboardWillShow, parse: KeyboardWillShowPayload.init) | |
| extension NotificationCenter { | |
| @discardableResult | |
| func addObserver<A>(for descriptor: NotificationDescriptor<A>, object obj: Any?, queue: OperationQueue?, using block: @escaping (A) -> Void) -> NSObjectProtocol { | |
| return addObserver(forName: descriptor.name, object: obj, queue: queue, using: { (note) in | |
| block(descriptor.parse(note.userInfo!)) | |
| }) | |
| } | |
| } | |
| class ViewController: UIViewController { | |
| @IBOutlet weak var bottomLayoutConstrait: NSLayoutConstraint! | |
| override func viewDidLoad() { | |
| super.viewDidLoad() | |
| NotificationCenter.default.addObserver(for: keyboardWillShow, object: nil, queue: nil) { [weak self] (payload) in | |
| self?.bottomLayoutConstrait?.constant = payload.endFrame.height | |
| } | |
| } | |
| } | |
| struct Episode { | |
| } | |
| let url = URL(string: "http://localhost:8000/episodes.json")! | |
| final class Webservice { | |
| func loadAllEpisodes(completion: @escaping ([Episode]?) -> ()) { | |
| let url = URL(string: "http://localhost:8000/episodes.json")! | |
| URLSession.shared.dataTask(with: url) { (data, _, _) in | |
| guard | |
| let data = data, | |
| let json = try? JSONSerialization.jsonObject(with: data), | |
| let dicts = json as? [JSONDictionary] | |
| else { | |
| completion(nil) | |
| return | |
| } | |
| let episodes = dicts.flatMap(Episode.init) | |
| completion(episodes) | |
| }.resume() | |
| } | |
| func loadEpisodeWithID(_ id: String, completion: @escaping ([Episode]?) -> ()) { | |
| let url = URL(string: "http://localhost:8000/episodes/\(id).json")! | |
| URLSession.shared.dataTask(with: url) { (data, _, _) in | |
| guard | |
| let data = data, | |
| let json = try? JSONSerialization.jsonObject(with: data), | |
| let dicts = json as? [JSONDictionary] | |
| else { | |
| completion(nil) | |
| return | |
| } | |
| let episodes = dicts.flatMap(Episode.init) | |
| completion(episodes) | |
| }.resume() | |
| } | |
| func load<A>(_ resource: Resource<A>, completion: @escaping (A?) -> ()) { | |
| let url = URL(string: "http://localhost:8000/episodes.json")! | |
| URLSession.shared.dataTask(with: url) { (data, _, _) in | |
| guard | |
| let data = data, | |
| let json = try? JSONSerialization.jsonObject(with: data), | |
| else { | |
| completion(nil) | |
| return | |
| } | |
| completion(resource.parse(json)) | |
| }.resume() | |
| } | |
| } | |
| struct Resource<A> { | |
| let url: URL | |
| let parse: (Any) -> A? | |
| } | |
| let allEpisodes = Resource<[Episode]>(url: url) { (json) -> [Episode]? in | |
| guard let dicts = json as? [JSONDictionary] else { return nil } | |
| return dicts.flatMap(Episode.init) | |
| } | |
| func episodeResource(for id: String) -> Resource<Episode> { | |
| let url = URL(string: "http://localhost:8000/episodes/\(id).json")! | |
| return Resource<Episode>(url: url) { json in | |
| guard let dicts = json as? [JSONDictionary] else { return nil } | |
| return Episode(dictionary: dicts) | |
| } | |
| } | |
| Webservice().load(allEpisodes) { print($0) } | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment