Skip to content
17 changes: 12 additions & 5 deletions Sources/ParseSwift/API/API+Command.swift
Original file line number Diff line number Diff line change
Expand Up @@ -59,11 +59,18 @@ internal extension API {

case .success(let urlRequest):
if method == .POST || method == .PUT || method == .PATCH {
let task = URLSession.parse.uploadTask(withStreamedRequest: urlRequest)
ParseSwift.sessionDelegate.uploadDelegates[task] = uploadProgress
ParseSwift.sessionDelegate.streamDelegates[task] = stream
ParseSwift.sessionDelegate.taskCallbackQueues[task] = callbackQueue
task.resume()
let synchronizationQueue = DispatchQueue(label: "parseSwift.executeStream.\(UUID())",
qos: .default,
attributes: .concurrent,
autoreleaseFrequency: .inherit,
target: nil)
synchronizationQueue.sync(flags: .barrier) {
let task = URLSession.parse.uploadTask(withStreamedRequest: urlRequest)
ParseSwift.sessionDelegate.uploadDelegates[task] = uploadProgress
ParseSwift.sessionDelegate.streamDelegates[task] = stream
ParseSwift.sessionDelegate.taskCallbackQueues[task] = callbackQueue
task.resume()
}
return
}
case .failure(let error):
Expand Down
34 changes: 24 additions & 10 deletions Sources/ParseSwift/API/ParseURLSessionDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -49,14 +49,21 @@ class ParseURLSessionDelegate: NSObject, URLSessionDelegate, URLSessionDataDeleg
didSendBodyData bytesSent: Int64,
totalBytesSent: Int64,
totalBytesExpectedToSend: Int64) {
if let callBack = uploadDelegates[task],
let queue = taskCallbackQueues[task] {
let synchronizationQueue = DispatchQueue(label: "parseSwift.didSendBodyData.\(UUID())",
qos: .default,
attributes: .concurrent,
autoreleaseFrequency: .inherit,
target: nil)
synchronizationQueue.sync(flags: .barrier) {
if let callback = uploadDelegates[task],
let queue = taskCallbackQueues[task] {

queue.async {
callBack(task, bytesSent, totalBytesSent, totalBytesExpectedToSend)
queue.async {
callback(task, bytesSent, totalBytesSent, totalBytesExpectedToSend)

if totalBytesSent == totalBytesExpectedToSend {
self.uploadDelegates.removeValue(forKey: task)
if totalBytesSent == totalBytesExpectedToSend {
self.uploadDelegates.removeValue(forKey: task)
}
}
}
}
Expand All @@ -68,10 +75,10 @@ class ParseURLSessionDelegate: NSObject, URLSessionDelegate, URLSessionDataDeleg
totalBytesWritten: Int64,
totalBytesExpectedToWrite: Int64) {

if let callBack = downloadDelegates[downloadTask],
if let callback = downloadDelegates[downloadTask],
let queue = taskCallbackQueues[downloadTask] {
queue.async {
callBack(downloadTask, bytesWritten, totalBytesWritten, totalBytesExpectedToWrite)
callback(downloadTask, bytesWritten, totalBytesWritten, totalBytesExpectedToWrite)
if totalBytesWritten == totalBytesExpectedToWrite {
self.downloadDelegates.removeValue(forKey: downloadTask)
}
Expand All @@ -89,8 +96,15 @@ class ParseURLSessionDelegate: NSObject, URLSessionDelegate, URLSessionDataDeleg
func urlSession(_ session: URLSession,
task: URLSessionTask,
needNewBodyStream completionHandler: @escaping (InputStream?) -> Void) {
if let stream = streamDelegates[task] {
completionHandler(stream)
let synchronizationQueue = DispatchQueue(label: "parseSwift.needNewBodyStream.\(UUID())",
qos: .default,
attributes: .concurrent,
autoreleaseFrequency: .inherit,
target: nil)
synchronizationQueue.sync(flags: .barrier) {
if let stream = streamDelegates[task] {
completionHandler(stream)
}
}
}

Expand Down
29 changes: 22 additions & 7 deletions Sources/ParseSwift/Extensions/URLSession.swift
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ internal extension URLSession {
return .failure(parseError)
}
if var responseData = responseData {
print("responseData Error: \(String(decoding: responseData, as: UTF8.self))")
if let error = try? ParseCoding.jsonDecoder().decode(ParseError.self, from: responseData) {
return .failure(error)
}
Expand Down Expand Up @@ -220,9 +221,16 @@ internal extension URLSession {
completion(.failure(ParseError(code: .unknownError, message: "data and file both can't be nil")))
}
if let task = task {
ParseSwift.sessionDelegate.uploadDelegates[task] = progress
ParseSwift.sessionDelegate.taskCallbackQueues[task] = notificationQueue
task.resume()
let synchronizationQueue = DispatchQueue(label: "parseSwift.uploadTask.\(UUID())",
qos: .default,
attributes: .concurrent,
autoreleaseFrequency: .inherit,
target: nil)
synchronizationQueue.sync(flags: .barrier) {
ParseSwift.sessionDelegate.uploadDelegates[task] = progress
ParseSwift.sessionDelegate.taskCallbackQueues[task] = notificationQueue
task.resume()
}
}
}

Expand All @@ -245,7 +253,7 @@ internal extension URLSession {
let data = try? ParseCoding.jsonEncoder().encode(fileLocation) else {
completion(result)
return
}
}
if URLSession.parse.configuration.urlCache?.cachedResponse(for: request) == nil {
URLSession.parse.configuration.urlCache?
.storeCachedResponse(.init(response: response,
Expand All @@ -255,9 +263,16 @@ internal extension URLSession {
}
completion(result)
}
ParseSwift.sessionDelegate.downloadDelegates[task] = progress
ParseSwift.sessionDelegate.taskCallbackQueues[task] = notificationQueue
task.resume()
let synchronizationQueue = DispatchQueue(label: "parseSwift.downloadTask.\(UUID())",
qos: .default,
attributes: .concurrent,
autoreleaseFrequency: .inherit,
target: nil)
synchronizationQueue.sync(flags: .barrier) {
ParseSwift.sessionDelegate.downloadDelegates[task] = progress
ParseSwift.sessionDelegate.taskCallbackQueues[task] = notificationQueue
task.resume()
}
}

func downloadTask<U>(
Expand Down
58 changes: 37 additions & 21 deletions Sources/ParseSwift/LiveQuery/LiveQuerySocket.swift
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,15 @@ final class LiveQuerySocket: NSObject {

func createTask(_ url: URL, taskDelegate: LiveQuerySocketDelegate) -> URLSessionWebSocketTask {
let task = session.webSocketTask(with: url)
delegates[task] = taskDelegate
receive(task)
let synchronizationQueue = DispatchQueue(label: "parseSwift.liveQuerySocket.createTask.\(UUID())",
qos: .default,
attributes: .concurrent,
autoreleaseFrequency: .inherit,
target: nil)
synchronizationQueue.sync(flags: .barrier) { [weak self] in
self?.delegates[task] = taskDelegate
self?.receive(task)
}
return task
}

Expand Down Expand Up @@ -92,27 +99,36 @@ extension LiveQuerySocket {
// Receive has already been called for this task
return
}
receivingTasks[task] = true
let synchronizationQueue = DispatchQueue(label: "parseSwift.liveQuerySocket.receive.\(UUID())",
qos: .default,
attributes: .concurrent,
autoreleaseFrequency: .inherit,
target: nil)
synchronizationQueue.sync(flags: .barrier) { [weak self] in
self?.receivingTasks[task] = true
}
task.receive { result in
self.receivingTasks.removeValue(forKey: task)
switch result {
case .success(.string(let message)):
if let data = message.data(using: .utf8) {
self.delegates[task]?.received(data)
} else {
let parseError = ParseError(code: .unknownError,
message: "Couldn't encode LiveQuery string as data")
self.delegates[task]?.receivedError(parseError)
synchronizationQueue.sync(flags: .barrier) { [weak self] in
self?.receivingTasks.removeValue(forKey: task)
switch result {
case .success(.string(let message)):
if let data = message.data(using: .utf8) {
self?.delegates[task]?.received(data)
} else {
let parseError = ParseError(code: .unknownError,
message: "Couldn't encode LiveQuery string as data")
self?.delegates[task]?.receivedError(parseError)
}
self?.receive(task)
case .success(.data(let data)):
self?.delegates[task]?.receivedUnsupported(data, socketMessage: nil)
self?.receive(task)
case .success(let message):
self?.delegates[task]?.receivedUnsupported(nil, socketMessage: message)
self?.receive(task)
case .failure(let error):
self?.delegates[task]?.receivedError(error)
}
self.receive(task)
case .success(.data(let data)):
self.delegates[task]?.receivedUnsupported(data, socketMessage: nil)
self.receive(task)
case .success(let message):
self.delegates[task]?.receivedUnsupported(nil, socketMessage: message)
self.receive(task)
case .failure(let error):
self.delegates[task]?.receivedError(error)
}
}
}
Expand Down