From d58153c3f6e7e3e4c64c15b5b999055602fee4ff Mon Sep 17 00:00:00 2001 From: Guillaume Lagorce Date: Tue, 8 Mar 2016 21:46:36 +0100 Subject: [PATCH 1/3] [Custom logger] Add a closure to get the ability to perform logging through a custom logger (like CocoaLumberJack for example) --- Source/Timberjack.swift | 33 +++++++++++++++++++-------------- 1 file changed, 19 insertions(+), 14 deletions(-) diff --git a/Source/Timberjack.swift b/Source/Timberjack.swift index 885cd5a..b8ad3a7 100644 --- a/Source/Timberjack.swift +++ b/Source/Timberjack.swift @@ -28,12 +28,17 @@ public enum Style { case Light } +public typealias TimberjackPrint = ((String) -> Void) + public class Timberjack: NSURLProtocol { var connection: NSURLConnection? var data: NSMutableData? var response: NSURLResponse? var newRequest: NSMutableURLRequest? - + + public static var printLog: TimberjackPrint = { log in + print(log) + } public static var logStyle: Style = .Verbose public class func register() { @@ -117,21 +122,21 @@ public class Timberjack: NSURLProtocol { //MARK: - Logging public func logDivider() { - print("---------------------") + Timberjack.printLog("---------------------") } public func logError(error: NSError) { logDivider() - print("Error: \(error.localizedDescription)") + Timberjack.printLog("Error: \(error.localizedDescription)") if Timberjack.logStyle == .Verbose { if let reason = error.localizedFailureReason { - print("Reason: \(reason)") + Timberjack.printLog("Reason: \(reason)") } if let suggestion = error.localizedRecoverySuggestion { - print("Suggestion: \(suggestion)") + Timberjack.printLog("Suggestion: \(suggestion)") } } } @@ -140,7 +145,7 @@ public class Timberjack: NSURLProtocol { logDivider() if let url = request.URL?.absoluteString { - print("Request: \(request.HTTPMethod!) \(url)") + Timberjack.printLog("Request: \(request.HTTPMethod!) \(url)") } if Timberjack.logStyle == .Verbose { @@ -154,12 +159,12 @@ public class Timberjack: NSURLProtocol { logDivider() if let url = response.URL?.absoluteString { - print("Response: \(url)") + Timberjack.printLog("Response: \(url)") } if let httpResponse = response as? NSHTTPURLResponse { let localisedStatus = NSHTTPURLResponse.localizedStringForStatusCode(httpResponse.statusCode).capitalizedString - print("Status: \(httpResponse.statusCode) - \(localisedStatus)") + Timberjack.printLog("Status: \(httpResponse.statusCode) - \(localisedStatus)") } if Timberjack.logStyle == .Verbose { @@ -169,7 +174,7 @@ public class Timberjack: NSURLProtocol { if let startDate = Timberjack.propertyForKey(TimberjackRequestTimeKey, inRequest: newRequest!) as? NSDate { let difference = fabs(startDate.timeIntervalSinceNow) - print("Duration: \(difference)s") + Timberjack.printLog("Duration: \(difference)s") } guard let data = data else { return } @@ -179,23 +184,23 @@ public class Timberjack: NSURLProtocol { let pretty = try NSJSONSerialization.dataWithJSONObject(json, options: .PrettyPrinted) if let string = NSString(data: pretty, encoding: NSUTF8StringEncoding) { - print("JSON: \(string)") + Timberjack.printLog("JSON: \(string)") } } catch { if let string = NSString(data: data, encoding: NSUTF8StringEncoding) { - print("Data: \(string)") + Timberjack.printLog("Data: \(string)") } } } } public func logHeaders(headers: [String: AnyObject]) { - print("Headers: [") + Timberjack.printLog("Headers: [") for (key, value) in headers { - print(" \(key) : \(value)") + Timberjack.printLog(" \(key) : \(value)") } - print("]") + Timberjack.printLog("]") } } From 7289a51774967c409cbf2158e050f420d0052673 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Prohaszka?= Date: Thu, 17 Mar 2016 15:30:19 +0100 Subject: [PATCH 2/3] Add filtered mode --- Source/Timberjack.swift | 31 +++++++++++- Tests/TimberjackTests.swift | 95 +++++++++++++++++++++++++++++++------ 2 files changed, 110 insertions(+), 16 deletions(-) diff --git a/Source/Timberjack.swift b/Source/Timberjack.swift index b8ad3a7..888e43c 100644 --- a/Source/Timberjack.swift +++ b/Source/Timberjack.swift @@ -36,11 +36,19 @@ public class Timberjack: NSURLProtocol { var response: NSURLResponse? var newRequest: NSMutableURLRequest? + public enum FilterListMode { + case Black + case White + } + public static var printLog: TimberjackPrint = { log in print(log) } public static var logStyle: Style = .Verbose - + public static var filteredMode: FilterListMode = .Black + public static var whiteListUrl: [NSURL]? + public static var blackListUrl: [NSURL]? + public class func register() { NSURLProtocol.registerClass(self) } @@ -142,6 +150,10 @@ public class Timberjack: NSURLProtocol { } public func logRequest(request: NSURLRequest) { + if !shouldLog(request.URL) { + return + } + logDivider() if let url = request.URL?.absoluteString { @@ -156,6 +168,10 @@ public class Timberjack: NSURLProtocol { } public func logResponse(response: NSURLResponse, data: NSData? = nil) { + if !shouldLog(response.URL) { + return + } + logDivider() if let url = response.URL?.absoluteString { @@ -203,4 +219,17 @@ public class Timberjack: NSURLProtocol { } Timberjack.printLog("]") } + + func shouldLog(url: NSURL?) -> Bool { + switch (Timberjack.filteredMode, url) { + case (.Black, let url?): + return !(Timberjack.blackListUrl?.contains(url) ?? false) + case (.Black, _): + return true + case (.White, let url?): + return Timberjack.whiteListUrl?.contains(url) ?? false + case (.White, _): + return false + } + } } diff --git a/Tests/TimberjackTests.swift b/Tests/TimberjackTests.swift index 1db2322..0c05465 100644 --- a/Tests/TimberjackTests.swift +++ b/Tests/TimberjackTests.swift @@ -9,28 +9,93 @@ import UIKit import XCTest +@testable import Timberjack + class TimberjackTests: XCTestCase { - + + private var buffer: [String] = [] + override func setUp() { - super.setUp() - // Put setup code here. This method is called before the invocation of each test method in the class. + buffer = [] + Timberjack.printLog = { log in + self.buffer.append(log) + } } - - override func tearDown() { - // Put teardown code here. This method is called after the invocation of each test method in the class. - super.tearDown() + + func testLogDefaultBehavior() { + // Given + let urlRequested = NSURL(string: "http://www.example.com") + let request = NSURLRequest(URL: urlRequested!) + + // When + let instance = Timberjack() + instance.logRequest(request) + + // Then + XCTAssert(buffer.count != 0) } - func testExample() { - // This is an example of a functional test case. - XCTAssert(true, "Pass") + func testLogDisableWithBlackList() { + // Given + let urlFiltered = NSURL(string: "http://www.example.com") + let urlRequested = urlFiltered + Timberjack.filteredMode = .Black + Timberjack.blackListUrl = [urlFiltered!] + let request = NSURLRequest(URL: urlRequested!) + + // When + let instance = Timberjack() + instance.logRequest(request) + + // Then + XCTAssert(buffer.count == 0) } - func testPerformanceExample() { - // This is an example of a performance test case. - self.measureBlock() { - // Put the code you want to measure the time of here. - } + func testLogEnableWithBlackList() { + // Given + let urlFiltered = NSURL(string: "http://www.example.com") + let urlRequested = NSURL(string: "http://www.example2.com") + Timberjack.filteredMode = .Black + Timberjack.blackListUrl = [urlFiltered!] + let request = NSURLRequest(URL: urlRequested!) + + // When + let instance = Timberjack() + instance.logRequest(request) + + // Then + XCTAssert(buffer.count != 0) } + func testLogEnableWithWhiteList() { + // Given + let urlFiltered = NSURL(string: "http://www.example.com") + let urlRequested = urlFiltered + Timberjack.filteredMode = .White + Timberjack.whiteListUrl = [urlFiltered!] + let request = NSURLRequest(URL: urlRequested!) + + // When + let instance = Timberjack() + instance.logRequest(request) + + // Then + XCTAssert(buffer.count != 0) + } + + func testLogDisableWithWhiteList() { + // Given + let urlFiltered = NSURL(string: "http://www.example.com") + let urlRequested = NSURL(string: "http://www.example2.com") + Timberjack.filteredMode = .White + Timberjack.whiteListUrl = [urlFiltered!] + let request = NSURLRequest(URL: urlRequested!) + + // When + let instance = Timberjack() + instance.logRequest(request) + + // Then + XCTAssert(buffer.count == 0) + } } From b1ec4d0a330eb72b77266326b5654bcb6e217e2f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Prohaszka?= Date: Fri, 18 Mar 2016 14:17:53 +0100 Subject: [PATCH 3/3] Add some fix and update README --- README.md | 9 +++++++++ Source/Timberjack.swift | 34 +++++++++++++++++++++++++++------- Tests/TimberjackTests.swift | 6 +++--- 3 files changed, 39 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 463c911..1976e69 100644 --- a/README.md +++ b/README.md @@ -87,6 +87,15 @@ Timberjack has two modes: Verbose and Light. The default style is `Verbose`. To Timberjack.logStyle = .Verbose //Either .Verbose, or .Light ```` +It is also possible to filtered which URL you want to log. +2 modes exist: *Black list mode* and *White list mode*. The default mode is *Black list* + +````swift +Timberjack.filteredMode = .Black +let urlFiltered = NSURL(string: "http://www.example.com") +Timberjack.blackListUrl = [urlFiltered!] // All requests going and coming from example.com will be ignored +```` + ##License MIT, see LICENSE for details. diff --git a/Source/Timberjack.swift b/Source/Timberjack.swift index 888e43c..03f0817 100644 --- a/Source/Timberjack.swift +++ b/Source/Timberjack.swift @@ -221,15 +221,35 @@ public class Timberjack: NSURLProtocol { } func shouldLog(url: NSURL?) -> Bool { - switch (Timberjack.filteredMode, url) { - case (.Black, let url?): - return !(Timberjack.blackListUrl?.contains(url) ?? false) - case (.Black, _): + let filteredList = Timberjack.filteredMode == .Black ? Timberjack.blackListUrl : Timberjack.whiteListUrl + + switch (Timberjack.filteredMode, url, filteredList) { + case (.Black, let url?, let list?): + return !list.contains(url) + case (.Black, _, _): return true - case (.White, let url?): - return Timberjack.whiteListUrl?.contains(url) ?? false - case (.White, _): + case (.White, let url?, let list?): + return list.contains(url) + case (.White, _, _): return false } } } + +extension String { + func contains(aString: String) -> Bool { + return self.rangeOfString(aString) != nil + } +} + +extension NSURL { + func contains(url: NSURL) -> Bool { + return self.absoluteString.contains(url.absoluteString) + } +} + +extension SequenceType where Generator.Element == NSURL { + func contains(element: NSURL) -> Bool { + return self.reduce(false) { return $0 || element.contains($1) } + } +} diff --git a/Tests/TimberjackTests.swift b/Tests/TimberjackTests.swift index 0c05465..a583119 100644 --- a/Tests/TimberjackTests.swift +++ b/Tests/TimberjackTests.swift @@ -24,7 +24,7 @@ class TimberjackTests: XCTestCase { func testLogDefaultBehavior() { // Given - let urlRequested = NSURL(string: "http://www.example.com") + let urlRequested = NSURL(string: "http://www.example.com/sample") let request = NSURLRequest(URL: urlRequested!) // When @@ -38,7 +38,7 @@ class TimberjackTests: XCTestCase { func testLogDisableWithBlackList() { // Given let urlFiltered = NSURL(string: "http://www.example.com") - let urlRequested = urlFiltered + let urlRequested = NSURL(string: "http://www.example.com/sample") Timberjack.filteredMode = .Black Timberjack.blackListUrl = [urlFiltered!] let request = NSURLRequest(URL: urlRequested!) @@ -70,7 +70,7 @@ class TimberjackTests: XCTestCase { func testLogEnableWithWhiteList() { // Given let urlFiltered = NSURL(string: "http://www.example.com") - let urlRequested = urlFiltered + let urlRequested = NSURL(string: "http://www.example.com/sample") Timberjack.filteredMode = .White Timberjack.whiteListUrl = [urlFiltered!] let request = NSURLRequest(URL: urlRequested!)