Last active
August 7, 2016 18:48
-
-
Save cbess/86d5753dcb76ed75fe291f47d1a4ab5c to your computer and use it in GitHub Desktop.
Custom network Fetcher that accepts a key, rather than using the URL.
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
// | |
// NetworkFetcher.swift | |
// | |
// Created by C. Bess on 8/7/16. | |
// Pulled from original NetworkFetcher (cleaned up and updated) | |
import Haneke | |
public class NetworkFetcher<T: DataConvertible>: Fetcher<T> { | |
let URL: NSURL | |
public init(URL: NSURL, key: String) { | |
self.URL = URL | |
super.init(key: key) | |
} | |
public var session: NSURLSession { | |
return NSURLSession.sharedSession() | |
} | |
var task: NSURLSessionDataTask? = nil | |
var cancelled = false | |
// MARK: Fetcher | |
public override func fetch(failure fail: ((NSError?) -> ()), success succeed: (T.Result) -> ()) { | |
cancelled = false | |
task = session.dataTaskWithURL(URL) { [weak self] (data, response, error) -> Void in | |
self?.onReceiveData(data, response: response, error: error, failure: fail, success: succeed) | |
} | |
task?.resume() | |
} | |
public override func cancelFetch() { | |
task?.cancel() | |
cancelled = true | |
} | |
// MARK: Private | |
private func onReceiveData(data: NSData!, response: NSURLResponse!, error: NSError!, failure fail: ((NSError?) -> ()), success succeed: (T.Result) -> ()) { | |
if cancelled { | |
return | |
} | |
if let error = error { | |
if error.domain == NSURLErrorDomain | |
&& error.code == NSURLErrorCancelled { | |
return | |
} | |
dispatch_async(dispatch_get_main_queue()) { | |
fail(error) | |
} | |
return | |
} | |
if let httpResponse = response as? NSHTTPURLResponse where httpResponse.statusCode != 200 { | |
let description = NSHTTPURLResponse.localizedStringForStatusCode(httpResponse.statusCode) | |
failWithCode(.InvalidStatusCode, localizedDescription: description, failure: fail) | |
return | |
} | |
if !response.hnk_validateLengthOfData(data) { | |
let localizedFormat = NSLocalizedString("Request expected %ld bytes and received %ld bytes", comment: "Error description") | |
let description = String(format: localizedFormat, response.expectedContentLength, data.length) | |
failWithCode(.MissingData, localizedDescription: description, failure: fail) | |
return | |
} | |
guard let value = T.convertFromData(data) else { | |
let localizedFormat = NSLocalizedString("Failed to convert value from data at URL %@", comment: "Error description") | |
let description = String(format: localizedFormat, URL.absoluteString) | |
failWithCode(.InvalidData, localizedDescription: description, failure: fail) | |
return | |
} | |
dispatch_async(dispatch_get_main_queue()) { | |
succeed(value) | |
} | |
} | |
private func failWithCode(code: HanekeGlobals.NetworkFetcher.ErrorCode, localizedDescription: String, failure fail: ((NSError?) -> ())) { | |
let error = NSError.init(domain: "cache", code: code.rawValue, userInfo: [NSLocalizedDescriptionKey: localizedDescription]) | |
dispatch_async(dispatch_get_main_queue()) { | |
fail(error) | |
} | |
} | |
} | |
extension Cache { | |
/// Fetches the data from the specified `URL`, caching it under the give `key` | |
func fetch(URL URL: NSURL, key: String, failure fail: Fetch<T>.Failer? = nil, success succeed: Fetch<T>.Succeeder? = nil) -> Fetch<T> { | |
let fetcher = NetworkFetcher<T>(URL: URL, key: key) | |
return self.fetch(fetcher: fetcher, formatName: HanekeGlobals.Cache.OriginalFormatName, failure: fail, success: succeed) | |
} | |
} | |
extension NSURLResponse { | |
func hnk_validateLengthOfData(data: NSData) -> Bool { | |
if expectedContentLength > -1 { | |
return Int64(data.length) >= expectedContentLength | |
} | |
return true | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment