Skip to content

Commit

Permalink
Merge pull request #5 from ialimz/save-modifiers-on-disk
Browse files Browse the repository at this point in the history
Persist modifiers on disk
  • Loading branch information
mehdiimrz authored Sep 28, 2021
2 parents e83bfa3 + 53bc9a6 commit 334946b
Show file tree
Hide file tree
Showing 6 changed files with 144 additions and 11 deletions.
5 changes: 4 additions & 1 deletion Sources/NetShears/NetShears.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,10 @@ public final class NetShears: NSObject {

public static let shared = NetShears()
let networkRequestInterceptor = NetworkRequestInterceptor()
var config: NetworkInterceptorConfig = NetworkInterceptorConfig(modifiers: [])
lazy var config: NetworkInterceptorConfig = {
var savedModifiers = [RequestEvaluatorModifier]().retrieveFromDisk()
return NetworkInterceptorConfig(modifiers: savedModifiers)
}()


public func startRecording(){
Expand Down
12 changes: 8 additions & 4 deletions Sources/NetShears/NetworkInterceptorConfig.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

import Foundation

public struct RedirectedRequestModel: Equatable {
public struct RedirectedRequestModel: Codable, Equatable {
public let originalUrl: String
public let redirectUrl: String

Expand All @@ -17,7 +17,7 @@ public struct RedirectedRequestModel: Equatable {
}
}

public struct HeaderModifyModel: Equatable {
public struct HeaderModifyModel: Codable, Equatable {
public let key: String
public let value: String

Expand All @@ -28,7 +28,11 @@ public struct HeaderModifyModel: Equatable {
}

public final class NetworkInterceptorConfig {
var modifiers: [RequestEvaluatorModifier] = []
var modifiers: [RequestEvaluatorModifier] = [] {
didSet {
modifiers.store()
}
}

init(modifiers: [RequestEvaluatorModifier] = []) {
self.modifiers = modifiers
Expand All @@ -46,7 +50,7 @@ public final class NetworkInterceptorConfig {
guard index <= modifiers.count - 1 else { return }
modifiers.remove(at: index)
}

}


105 changes: 105 additions & 0 deletions Sources/NetShears/Protocols/PersistHelper.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
//
// PersistHelper.swift
//
//
// Created by Ali Moazenzadeh on 9/23/21.
//

import Foundation

public class PersistHelper {

fileprivate init() { }

/// Returns URL constructed from specified directory
static fileprivate func getURL() -> URL {
let searchPathDirectory: FileManager.SearchPathDirectory = .documentDirectory

if let url = FileManager.default.urls(for: searchPathDirectory, in: .userDomainMask).first {
return url
} else {
fatalError("Could not create URL for specified directory!")
}
}


/// Store an encodable struct to the specified directory on disk
///
/// - Parameters:
/// - object: the encodable struct to store
/// - directory: where to store the struct
/// - fileName: what to name the file where the struct data will be stored
static func store<T: Encodable>(_ object: T, as fileName: String) {
let url = getURL().appendingPathComponent(fileName, isDirectory: false)

let encoder = JSONEncoder()
do {
let data = try encoder.encode(object)
if FileManager.default.fileExists(atPath: url.path) {
try FileManager.default.removeItem(at: url)
}
FileManager.default.createFile(atPath: url.path, contents: data, attributes: nil)
} catch {
fatalError(error.localizedDescription)
}
}

/// Retrieve and convert a struct from a file on disk
///
/// - Parameters:
/// - fileName: name of the file where struct data is stored
/// - directory: directory where struct data is stored
/// - type: struct type (i.e. Message.self)
/// - Returns: decoded struct model(s) of data
static func retrieve<T: Decodable>(_ fileName: String, as type: T.Type) -> T? {
let url = getURL().appendingPathComponent(fileName, isDirectory: false)

if !FileManager.default.fileExists(atPath: url.path) {
return nil
}

if let data = FileManager.default.contents(atPath: url.path) {
let decoder = JSONDecoder()
do {
let model = try decoder.decode(type, from: data)
return model
} catch {
fatalError(error.localizedDescription)
}
} else {
fatalError("No data at \(url.path)!")
}
}

/// Remove all files at specified directory
static func clear() {
let url = getURL()
do {
let contents = try FileManager.default.contentsOfDirectory(at: url, includingPropertiesForKeys: nil, options: [])
for fileUrl in contents {
try FileManager.default.removeItem(at: fileUrl)
}
} catch {
fatalError(error.localizedDescription)
}
}

/// Remove specified file from specified directory
static func remove(_ fileName: String) {
let url = getURL().appendingPathComponent(fileName, isDirectory: false)
if FileManager.default.fileExists(atPath: url.path) {
do {
try FileManager.default.removeItem(at: url)
} catch {
fatalError(error.localizedDescription)
}
}
}

/// Returns BOOL indicating whether file exists at specified directory with specified file name
static func fileExists(_ fileName: String) -> Bool {
let url = getURL().appendingPathComponent(fileName, isDirectory: false)
return FileManager.default.fileExists(atPath: url.path)
}
}

18 changes: 17 additions & 1 deletion Sources/NetShears/RequestModifier/NetShearsModfierProtocol.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,22 @@ public protocol RequestModifier {
func modify(request: inout URLRequest)
}

public protocol RequestEvaluatorModifier : RequestEvaluator, RequestModifier {}
public protocol RequestEvaluatorModifier : RequestEvaluator, RequestModifier, Codable {
static var storeFileName: String { get }
}

extension Array where Element == RequestEvaluatorModifier {
func store() {
let headers: [RequestEvaluatorModifierHeader] = compactMap { $0 as? RequestEvaluatorModifierHeader }
let endpoints: [RequestEvaluatorModifierEndpoint] = compactMap { $0 as? RequestEvaluatorModifierEndpoint }
PersistHelper.store(headers, as: RequestEvaluatorModifierHeader.storeFileName)
PersistHelper.store(endpoints, as: RequestEvaluatorModifierEndpoint.storeFileName)
}

func retrieveFromDisk() -> [RequestEvaluatorModifier] {
var modifiers = [RequestEvaluatorModifier]()
modifiers.append(contentsOf: PersistHelper.retrieve(RequestEvaluatorModifierHeader.storeFileName, as: [RequestEvaluatorModifierHeader].self) ?? [])
modifiers.append(contentsOf: PersistHelper.retrieve(RequestEvaluatorModifierEndpoint.storeFileName, as: [RequestEvaluatorModifierEndpoint].self) ?? [])
return modifiers
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,13 @@

import Foundation

public struct RequestEvaluatorModifierEndpoint: RequestEvaluatorModifier, Equatable {
public struct RequestEvaluatorModifierEndpoint: RequestEvaluatorModifier, Equatable, Codable {

public var redirectedRequest: RedirectedRequestModel

public static var storeFileName: String {
"Modifier.txt"
}

public init(redirectedRequest: RedirectedRequestModel) {
self.redirectedRequest = redirectedRequest
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,22 +7,23 @@

import Foundation

public struct RequestEvaluatorModifierHeader: RequestEvaluatorModifier, Equatable {

public struct RequestEvaluatorModifierHeader: RequestEvaluatorModifier, Equatable, Codable {

public var header: HeaderModifyModel

public static var storeFileName: String {
"Header.txt"
}

public init(header: HeaderModifyModel) {
self.header = header
}

public func modify(request: inout URLRequest) {

request.modifyURLRequestHeader(header: header)
}

public func isActionAllowed(urlRequest: URLRequest) -> Bool {
return true
}

}

0 comments on commit 334946b

Please sign in to comment.