Skip to content

Instantly share code, notes, and snippets.

@zyuanming
Created October 3, 2017 17:22
Show Gist options
  • Select an option

  • Save zyuanming/fe44e30acee43155c066a490a81e93ab to your computer and use it in GitHub Desktop.

Select an option

Save zyuanming/fe44e30acee43155c066a490a81e93ab to your computer and use it in GitHub Desktop.
UIKonf 2017 – Day 2 – Chris Eidhof & FlorianKugler – Intermediate Types
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