Skip to content

Updating PR 299 (NSURLSession) to work with the latest Foundation #426

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

Merged
merged 1 commit into from
Aug 23, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CoreFoundation/Base.subproj/ForSwiftFoundationOnly.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include <CoreFoundation/CFXMLInterface.h>
#include <CoreFoundation/CFRegularExpression.h>
#include <CoreFoundation/CFLogUtilities.h>
#include <CoreFoundation/CFURLSessionInterface.h>
#include <CoreFoundation/ForFoundationOnly.h>
#include <fts.h>
#include <pthread.h>
Expand Down
609 changes: 609 additions & 0 deletions CoreFoundation/URL.subproj/CFURLSessionInterface.c

Large diffs are not rendered by default.

605 changes: 605 additions & 0 deletions CoreFoundation/URL.subproj/CFURLSessionInterface.h

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions Foundation/NSData.swift
Original file line number Diff line number Diff line change
Expand Up @@ -164,11 +164,11 @@ open class NSData : NSObject, NSCopying, NSMutableCopying, NSSecureCoding {
if url.isFileURL {
try self.init(contentsOfFile: url.path, options: readOptionsMask)
} else {
let session = URLSession(configuration: URLSessionConfiguration.defaultSessionConfiguration())
let session = URLSession(configuration: URLSessionConfiguration.default)
let cond = NSCondition()
var resError: NSError?
var resData: Data?
let task = session.dataTaskWithURL(url, completionHandler: { (data: Data?, response: URLResponse?, error: NSError?) -> Void in
let task = session.dataTask(with: url, completionHandler: { (data: Data?, response: URLResponse?, error: NSError?) -> Void in
resData = data
resError = error
cond.broadcast()
Expand Down
805 changes: 0 additions & 805 deletions Foundation/NSURLSession.swift

This file was deleted.

137 changes: 137 additions & 0 deletions Foundation/NSURLSession/Configuration.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
// Foundation/NSURLSession/Configuration.swift - NSURLSession & libcurl
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See http://swift.org/LICENSE.txt for license information
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
// -----------------------------------------------------------------------------
///
/// These are libcurl helpers for the URLSession API code.
/// - SeeAlso: https://curl.haxx.se/libcurl/c/
/// - SeeAlso: NSURLSession.swift
///
// -----------------------------------------------------------------------------


internal extension URLSession {
/// This is an immutable / `struct` version of `URLSessionConfiguration`.
struct _Configuration {
/// identifier for the background session configuration
let identifier: String?

/// default cache policy for requests
let requestCachePolicy: NSURLRequest.CachePolicy

/// default timeout for requests. This will cause a timeout if no data is transmitted for the given timeout value, and is reset whenever data is transmitted.
let timeoutIntervalForRequest: TimeInterval

/// default timeout for requests. This will cause a timeout if a resource is not able to be retrieved within a given timeout.
let timeoutIntervalForResource: TimeInterval

/// type of service for requests.
let networkServiceType: NSURLRequest.NetworkServiceType

/// allow request to route over cellular.
let allowsCellularAccess: Bool

/// allows background tasks to be scheduled at the discretion of the system for optimal performance.
let discretionary: Bool

/// The proxy dictionary, as described by <CFNetwork/CFHTTPStream.h>
let connectionProxyDictionary: [AnyHashable : Any]?

/// Allow the use of HTTP pipelining
let httpShouldUsePipelining: Bool

/// Allow the session to set cookies on requests
let httpShouldSetCookies: Bool

/// Policy for accepting cookies. This overrides the policy otherwise specified by the cookie storage.
let httpCookieAcceptPolicy: HTTPCookie.AcceptPolicy

/// Specifies additional headers which will be set on outgoing requests.
/// Note that these headers are added to the request only if not already present.

let httpAdditionalHeaders: [String : String]?
/// The maximum number of simultanous persistent connections per host
let httpMaximumConnectionsPerHost: Int

/// The cookie storage object to use, or nil to indicate that no cookies should be handled
let httpCookieStorage: HTTPCookieStorage?

/// The credential storage object, or nil to indicate that no credential storage is to be used
let urlCredentialStorage: URLCredentialStorage?

/// The URL resource cache, or nil to indicate that no caching is to be performed
let urlCache: URLCache?

/// Enable extended background idle mode for any tcp sockets created.
let shouldUseExtendedBackgroundIdleMode: Bool

let protocolClasses: [AnyClass]?
}
}
internal extension URLSession._Configuration {
init(URLSessionConfiguration config: URLSessionConfiguration) {
identifier = config.identifier
requestCachePolicy = config.requestCachePolicy
timeoutIntervalForRequest = config.timeoutIntervalForRequest
timeoutIntervalForResource = config.timeoutIntervalForResource
networkServiceType = config.networkServiceType
allowsCellularAccess = config.allowsCellularAccess
discretionary = config.discretionary
connectionProxyDictionary = config.connectionProxyDictionary
httpShouldUsePipelining = config.httpShouldUsePipelining
httpShouldSetCookies = config.httpShouldSetCookies
httpCookieAcceptPolicy = config.httpCookieAcceptPolicy
httpAdditionalHeaders = config.httpAdditionalHeaders.map { convertToStringString(dictionary: $0) }
httpMaximumConnectionsPerHost = config.httpMaximumConnectionsPerHost
httpCookieStorage = config.httpCookieStorage
urlCredentialStorage = config.urlCredentialStorage
urlCache = config.urlCache
shouldUseExtendedBackgroundIdleMode = config.shouldUseExtendedBackgroundIdleMode
protocolClasses = config.protocolClasses
}
}

// Configure NSURLRequests
internal extension URLSession._Configuration {
func configure(request: NSMutableURLRequest) {
httpAdditionalHeaders?.forEach {
guard request.value(forHTTPHeaderField: $0.0) == nil else { return }
request.setValue($0.1, forHTTPHeaderField: $0.0)
}
}
func setCookies(on request: NSMutableURLRequest) {
if httpShouldSetCookies {
//TODO: Ask the cookie storage what cookie to set.
}
}
}
// Cache Management
private extension URLSession._Configuration {
func cachedResponse(forRequest request: NSURLRequest) -> CachedURLResponse? {
//TODO: Check the policy & consult the cache.
// There's more detail on how this should work here:
// <https://developer.apple.com/library/prerelease/ios/documentation/Cocoa/Reference/Foundation/Classes/NSURLRequest_Class/index.html#//apple_ref/swift/enum/c:@E@URLRequestCachePolicy>
switch requestCachePolicy {
default: return nil
}
}
}

private func convertToStringString(dictionary: [AnyHashable:Any]) -> [String: String] {
//TODO: There's some confusion about [NSObject:AnyObject] vs. [String:String] for headers.
// C.f. <https://github.com/apple/swift-corelibs-foundation/pull/287>
var r: [String: String] = [:]
dictionary.forEach {
let k = String(describing: $0.key as! NSString)
let v = String(describing: $0.value as! NSString)
r[k] = v
}
return r
}
Loading