Created
July 6, 2018 06:47
-
-
Save 1hakr/6e7efcd72a0fa5d5dbebc3ab62972d3c to your computer and use it in GitHub Desktop.
Network Helper for iOS with custom caching and bootstrapping suppory
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
// | |
// NetworkHelper.swift | |
// acrypto | |
// | |
// Created by HaKr on 21/10/17. | |
// Copyright © 2017 DWorkS. All rights reserved. | |
// | |
import Foundation | |
import Alamofire | |
public protocol NetworkCompletionDelegate { | |
func onResponse(_ response: Any) | |
func onErrorResponse(_ error: Error) | |
} | |
class NetworkHelper: NSObject { | |
static var sessionManager: SessionManager! | |
static var sessionConfiguration: URLSessionConfiguration! | |
static var sessionManagerMaster: SessionManager! | |
static var sessionConfigurationMaster: URLSessionConfiguration! | |
static func getSessionManger() -> SessionManager { | |
if(nil == sessionManager) { | |
let capacity = 50 * 1024 * 1024 // MBs | |
let urlCache = SmartUrlCache(memoryCapacity: capacity, diskCapacity: capacity, diskPath: nil) | |
sessionConfiguration = URLSessionConfiguration.default | |
sessionConfiguration.requestCachePolicy = .returnCacheDataElseLoad | |
sessionConfiguration.urlCache = urlCache | |
sessionConfiguration.timeoutIntervalForRequest = 10 | |
sessionManager = Alamofire.SessionManager(configuration: sessionConfiguration) | |
} | |
return sessionManager | |
} | |
static func getSessionMangerMaster() -> SessionManager { | |
if(nil == sessionManagerMaster) { | |
let capacity = 50 * 1024 * 1024 // MBs | |
let urlCache = SmartUrlMasterCache(memoryCapacity: capacity, diskCapacity: capacity, diskPath: nil) | |
sessionConfigurationMaster = URLSessionConfiguration.default | |
sessionConfigurationMaster.requestCachePolicy = .returnCacheDataElseLoad | |
sessionConfigurationMaster.urlCache = urlCache | |
sessionManagerMaster = Alamofire.SessionManager(configuration: sessionConfigurationMaster) | |
} | |
return sessionManagerMaster | |
} | |
static func removeCachedUrl(url: String, parameters: Parameters? = nil) { | |
let headers: HTTPHeaders? = nil | |
var originalRequest: URLRequest | |
do { | |
originalRequest = try URLRequest(url: url, method: .get, headers: headers) | |
let encodedURLRequest = try URLEncoding.default.encode(originalRequest, with: parameters) | |
sessionConfiguration.urlCache?.removeCachedResponse(for: encodedURLRequest) | |
addCache(url: url, data: Data(), parameters: parameters) | |
} catch { | |
Log.info(error) | |
} | |
} | |
static func removeMasterCachedUrl(url: String, parameters: Parameters? = nil) { | |
let headers: HTTPHeaders? = nil | |
var originalRequest: URLRequest | |
do { | |
originalRequest = try URLRequest(url: url, method: .get, headers: headers) | |
let encodedURLRequest = try URLEncoding.default.encode(originalRequest, with: parameters) | |
sessionConfiguration.urlCache?.removeCachedResponse(for: encodedURLRequest) | |
addMasterCache(url: url, data: Data(), parameters: parameters) | |
} catch { | |
Log.info(error) | |
} | |
} | |
static func removeAllCached() { | |
sessionConfigurationMaster.urlCache?.removeAllCachedResponses() | |
} | |
static func addCache(url: String, data: Data, parameters: Parameters? = nil) { | |
let headers: HTTPHeaders? = nil | |
do { | |
let originalRequest = try URLRequest(url: url, method: .get, headers: headers) | |
let encodedURLRequest = try URLEncoding.default.encode(originalRequest, with: parameters) | |
let newResponse = HTTPURLResponse(url: URL(string: url)!, statusCode: 200, httpVersion: "HTTP/1.1", headerFields: ["Cache-Control":"private, max-age=0, s-maxage=0"]) | |
let cachedResponse = CachedURLResponse(response: newResponse!, data: data) | |
sessionConfiguration.urlCache?.storeCachedResponse(cachedResponse, for: encodedURLRequest) | |
} catch { | |
Log.info(error) | |
} | |
} | |
static func addMasterCache(url: String, data: Data, parameters: Parameters? = nil) { | |
let headers: HTTPHeaders? = nil | |
do { | |
let originalRequest = try URLRequest(url: url, method: .get, headers: headers) | |
let encodedURLRequest = try URLEncoding.default.encode(originalRequest, with: parameters) | |
let newResponse = HTTPURLResponse(url: URL(string: url)!, statusCode: 200, httpVersion: "HTTP/1.1", headerFields: ["Cache-Control":"private, max-age=0, s-maxage=0"]) | |
let cachedResponse = CachedURLResponse(response: newResponse!, data: data) | |
sessionConfigurationMaster.urlCache?.storeCachedResponse(cachedResponse, for: encodedURLRequest) | |
} catch { | |
Log.info(error) | |
} | |
} | |
static func requestJSON(_ url: String, _ parameters: Parameters, _ completionDelegate: NetworkCompletionDelegate){ | |
getSessionManger().request(url, method: .get, parameters: parameters) | |
.validate() | |
.responseJSON { response in | |
switch response.result { | |
case .success: | |
Log.info("Request: \(String(describing: response.request))") | |
completionDelegate.onResponse(response) | |
break | |
case .failure(let error): | |
Log.info("Error: \(error)") | |
completionDelegate.onErrorResponse(error) | |
} | |
} | |
} | |
static func requestJSON(_ url: String, _ parameters: Parameters, _ completionHandler: @escaping (DataResponse<Any>) -> Void) { | |
getSessionManger().request(url, method: .get, parameters: parameters).validate().responseJSON(completionHandler: completionHandler) | |
} | |
static func requestString(_ url: String, _ parameters: Parameters, _ completionDelegate: NetworkCompletionDelegate){ | |
getSessionManger().request(url, method: .get, parameters: parameters) | |
.validate() | |
.responseString { response in | |
switch response.result { | |
case .success: | |
Log.info("Request: \(String(describing: response.request))") | |
completionDelegate.onResponse(response) | |
break | |
case .failure(let error): | |
Log.info("Error: \(error)") | |
completionDelegate.onErrorResponse(error) | |
} | |
} | |
} | |
static func requestString(_ url: String, _ parameters: Parameters, _ completionHandler: @escaping (DataResponse<String>) -> Void) { | |
getSessionManger().request(url, method: .get, parameters: parameters).validate().responseString(completionHandler: completionHandler) | |
} | |
static func requestJSONMaster(_ url: String, _ parameters: Parameters, _ completionDelegate: NetworkCompletionDelegate){ | |
getSessionMangerMaster().request(url, method: .get, parameters: parameters, headers: getHeaders()) | |
.validate() | |
.responseJSON { response in | |
switch response.result { | |
case .success: | |
Log.info("Request: \(String(describing: response.request))") | |
completionDelegate.onResponse(response) | |
break | |
case .failure(let error): | |
Log.info("Error: \(error)") | |
completionDelegate.onErrorResponse(error) | |
} | |
} | |
} | |
static func requestJSONMaster(_ url: String, _ parameters: Parameters, _ completionHandler: @escaping (DataResponse<Any>) -> Void) { | |
getSessionMangerMaster().request(url, method: .get, parameters: parameters, headers: getHeaders()).validate().responseJSON(completionHandler: completionHandler) | |
} | |
static func requestStringMaster(_ url: String, _ parameters: Parameters, _ completionDelegate: NetworkCompletionDelegate){ | |
getSessionMangerMaster().request(url, method: .get, parameters: parameters, headers: getHeaders()) | |
.validate() | |
.responseString { response in | |
switch response.result { | |
case .success: | |
Log.info("Request: \(String(describing: response.request))") | |
completionDelegate.onResponse(response) | |
break | |
case .failure(let error): | |
Log.info("Error: \(error)") | |
completionDelegate.onErrorResponse(error) | |
} | |
} | |
} | |
static func requestStringMaster(_ url: String, _ parameters: Parameters, _ completionHandler: @escaping (DataResponse<String>) -> Void) { | |
getSessionMangerMaster().request(url, method: .get, parameters: parameters, headers: getHeaders()).validate().responseString(completionHandler: completionHandler) | |
} | |
static func getHeaders() -> HTTPHeaders{ | |
var headers: HTTPHeaders = [:] | |
headers.updateValue(Constants.AUTH, forKey: Constants.AUTH_HEADER) | |
headers.updateValue(AppHelper.versionName ?? "", forKey: Constants.CLIENT_HEADER) | |
return headers | |
} | |
} | |
class SmartUrlCache: URLCache { | |
let CACHE_EXPIRY = "cache_expiry"; | |
let cacheExpireInterval: TimeInterval = 60*60; | |
override func cachedResponse(for request: URLRequest) -> CachedURLResponse? { | |
var response: CachedURLResponse? = nil | |
if let cachedResponse = super.cachedResponse(for: request) { | |
if let userInfo = cachedResponse.userInfo { | |
if let cacheDate = userInfo[CACHE_EXPIRY] as! NSDate? { | |
// check if the cache data are expired | |
let count = cachedResponse.data.count | |
if (cacheDate.timeIntervalSinceNow < -cacheExpireInterval) || count == 0 { | |
self.removeCachedResponse(for: request) | |
} else { | |
response = cachedResponse | |
} | |
} | |
} | |
} | |
return response; | |
} | |
override func removeCachedResponse(for request: URLRequest) { | |
super.removeCachedResponse(for: request) | |
} | |
override func storeCachedResponse(_ cachedResponse: CachedURLResponse, for request: URLRequest) { | |
var userInfo = NSMutableDictionary() | |
if let cachedUserInfo = cachedResponse.userInfo { | |
userInfo = NSMutableDictionary(dictionary: cachedUserInfo) | |
} | |
if let cacheDate = userInfo[CACHE_EXPIRY] as! NSDate? { | |
// check if the cache data are expired | |
if (cacheDate.timeIntervalSinceNow < -cacheExpireInterval) { | |
userInfo[CACHE_EXPIRY] = NSDate() | |
} | |
} else { | |
userInfo[CACHE_EXPIRY] = NSDate() | |
} | |
let newCachedResponse = CachedURLResponse(response: cachedResponse.response, data: cachedResponse.data, userInfo: userInfo as [NSObject : AnyObject], storagePolicy: cachedResponse.storagePolicy) | |
super.storeCachedResponse(newCachedResponse, for: request) | |
} | |
} | |
class SmartUrlMasterCache: URLCache { | |
override func cachedResponse(for request: URLRequest) -> CachedURLResponse? { | |
var response: CachedURLResponse? = nil | |
if let cachedResponse = super.cachedResponse(for: request) { | |
let count = cachedResponse.data.count | |
if count == 0 { | |
self.removeCachedResponse(for: request) | |
} else { | |
response = cachedResponse | |
} | |
} | |
return response; | |
} | |
override func removeCachedResponse(for request: URLRequest) { | |
super.removeCachedResponse(for: request) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment