Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for upload tasks #64

Open
wants to merge 12 commits into
base: master
Choose a base branch
from
12 changes: 7 additions & 5 deletions DVR/Session.swift
Original file line number Diff line number Diff line change
Expand Up @@ -128,17 +128,19 @@ public class Session: NSURLSession {

completedInteractions.append(interaction)

if !recording && outstandingTasks.count == 0 {
finishRecording()
}

if let delegate = delegate as? NSURLSessionDataDelegate, task = task as? NSURLSessionDataTask, data = interaction.responseData {
delegate.URLSession?(self, dataTask: task, didReceiveData: data)
}

if let delegate = delegate as? NSURLSessionTaskDelegate {
let bytes = Int64(interaction.responseData?.length ?? 0)
delegate.URLSession?(self, task: task, didSendBodyData: bytes, totalBytesSent: bytes, totalBytesExpectedToSend: bytes)
delegate.URLSession?(self, task: task, didCompleteWithError: nil)
}

if !recording && outstandingTasks.count == 0 {
finishRecording()
}
}


Expand All @@ -162,7 +164,7 @@ public class Session: NSURLSession {
var modifiedRequest = backingSession.configuration.HTTPAdditionalHeaders.map(request.requestByAppendingHeaders) ?? request
modifiedRequest = data.map(modifiedRequest.requestWithBody) ?? modifiedRequest
let task = SessionUploadTask(session: self, request: modifiedRequest, completion: completionHandler)
addTask(task.dataTask)
addTask(task)
return task
}

Expand Down
30 changes: 25 additions & 5 deletions DVR/SessionDataTask.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,23 @@ class SessionDataTask: NSURLSessionDataTask {
let request: NSURLRequest
let completion: Completion?
private let queue = dispatch_queue_create("com.venmo.DVR.sessionDataTaskQueue", nil)
private var interaction: Interaction?
internal var interaction: Interaction?
private var backingTask: NSURLSessionTask?

private var _taskDescription: String?
override var taskDescription: String? {
get {
return _taskDescription
}
set {
_taskDescription = newValue
}
}

private var _taskIdentifier: Int?
override var taskIdentifier: Int {
return _taskIdentifier ?? 0
}

override var response: NSURLResponse? {
return interaction?.response
Expand All @@ -22,9 +38,10 @@ class SessionDataTask: NSURLSessionDataTask {

// MARK: - Initializers

init(session: Session, request: NSURLRequest, completion: (Completion)? = nil) {
init(session: Session, request: NSURLRequest, backingTask: NSURLSessionTask? = nil, completion: (Completion)? = nil) {
self.session = session
self.request = request
self.backingTask = backingTask
self.completion = completion
}

Expand All @@ -47,7 +64,7 @@ class SessionDataTask: NSURLSessionDataTask {
completion(interaction.responseData, interaction.response, nil)
}
}
session.finishTask(self, interaction: interaction, playback: true)
session.finishTask(self.backingTask ?? self, interaction: interaction, playback: true)
return
}

Expand Down Expand Up @@ -81,9 +98,12 @@ class SessionDataTask: NSURLSessionDataTask {
}

// Create interaction
this.interaction = Interaction(request: this.request, response: response, responseData: data)
this.session.finishTask(this, interaction: this.interaction!, playback: false)
let interaction = Interaction(request: this.request, response: response, responseData: data)
this.interaction = interaction
this.session.finishTask(this.backingTask ?? this, interaction: interaction, playback: false)
}

_taskIdentifier = task.taskIdentifier
task.resume()
}
}
13 changes: 11 additions & 2 deletions DVR/SessionUploadTask.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,24 @@ class SessionUploadTask: NSURLSessionUploadTask {
weak var session: Session!
let request: NSURLRequest
let completion: Completion?
let dataTask: SessionDataTask
var dataTask: SessionDataTask!

override var response: NSURLResponse? {
return dataTask.interaction?.response
}

override var taskIdentifier: Int {
return dataTask.taskIdentifier
}

// MARK: - Initializers

init(session: Session, request: NSURLRequest, completion: Completion? = nil) {
self.session = session
self.request = request
self.completion = completion
dataTask = SessionDataTask(session: session, request: request, completion: completion)
super.init()
dataTask = SessionDataTask(session: session, request: request, backingTask: self, completion: completion)
}

// MARK: - NSURLSessionTask
Expand Down
7 changes: 7 additions & 0 deletions DVR/Tests/SessionTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ class SessionTests: XCTestCase {
func testDataTask() {
let request = NSURLRequest(URL: NSURL(string: "http://example.com")!)
let dataTask = session.dataTaskWithRequest(request)
dataTask.taskDescription = "description"

XCTAssert(dataTask is SessionDataTask)

Expand Down Expand Up @@ -138,6 +139,7 @@ class SessionTests: XCTestCase {
class Delegate: NSObject, NSURLSessionTaskDelegate {
let expectation: XCTestExpectation
var response: NSURLResponse?
var bytes: Int64?

init(expectation: XCTestExpectation) {
self.expectation = expectation
Expand All @@ -147,6 +149,10 @@ class SessionTests: XCTestCase {
response = task.response
expectation.fulfill()
}

@objc private func URLSession(session: NSURLSession, task: NSURLSessionTask, didSendBodyData bytesSent: Int64, totalBytesSent: Int64, totalBytesExpectedToSend: Int64) {
bytes = bytesSent
}
}

let expectation = expectationWithDescription("didCompleteWithError")
Expand All @@ -160,6 +166,7 @@ class SessionTests: XCTestCase {
task.resume()

waitForExpectationsWithTimeout(1, handler: nil)
XCTAssertNotNil(delegate.bytes)
}

func testDataDelegate() {
Expand Down
31 changes: 31 additions & 0 deletions DVR/Tests/SessionUploadTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,37 @@ class SessionUploadTests: XCTestCase {
waitForExpectationsWithTimeout(4, handler: nil)
}

func testUploadDelegate() {
class Delegate: NSObject, NSURLSessionDataDelegate {
var task: NSURLSessionTask?
let expectation: XCTestExpectation

init(expectation: XCTestExpectation) {
self.expectation = expectation
}

@objc func URLSession(session: NSURLSession, dataTask: NSURLSessionDataTask, didReceiveData data: NSData) {
task = dataTask
expectation.fulfill()
}
}

let expectation = expectationWithDescription("didCompleteWithError")
let delegate = Delegate(expectation: expectation)
let config = NSURLSessionConfiguration.defaultSessionConfiguration()
let backingSession = NSURLSession(configuration: config, delegate: delegate, delegateQueue: nil)
let session = Session(cassetteName: "upload-data", backingSession: backingSession)
session.recordingEnabled = false

let data = encodeMultipartBody(NSData(contentsOfURL: testFile)!, parameters: [:])

let task = session.uploadTaskWithRequest(request, fromData: data)
task.resume()

waitForExpectationsWithTimeout(1, handler: nil)
XCTAssertEqual(task, delegate.task)
}

// MARK: Helpers

func encodeMultipartBody(data: NSData, parameters: [String: AnyObject]) -> NSData {
Expand Down