Skip to content

Commit 05bcbcd

Browse files
committed
Basic NSURLSession API.
1 parent 6488630 commit 05bcbcd

25 files changed

+8437
-806
lines changed

CoreFoundation/Base.subproj/ForSwiftFoundationOnly.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,11 @@
2323
#include <CoreFoundation/CFXMLInterface.h>
2424
#include <CoreFoundation/CFRegularExpression.h>
2525
#include <CoreFoundation/CFLogUtilities.h>
26+
#include <CoreFoundation/CFURLSessionInterface.h>
2627
#include <CoreFoundation/ForFoundationOnly.h>
2728
#include <fts.h>
2829

30+
2931
_CF_EXPORT_SCOPE_BEGIN
3032

3133
struct __CFSwiftObject {

CoreFoundation/URL.subproj/CFURLSessionInterface.c

Lines changed: 747 additions & 0 deletions
Large diffs are not rendered by default.

CoreFoundation/URL.subproj/CFURLSessionInterface.h

Lines changed: 748 additions & 0 deletions
Large diffs are not rendered by default.

Foundation.xcodeproj/project.pbxproj

Lines changed: 84 additions & 2 deletions
Large diffs are not rendered by default.

Foundation/NSData.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -334,7 +334,7 @@ extension NSData {
334334
let cond = NSCondition()
335335
var resError: NSError?
336336
var resData: NSData?
337-
let task = session.dataTaskWithURL(url, completionHandler: { (data: NSData?, response: NSURLResponse?, error: NSError?) -> Void in
337+
let task = session.dataTask(with: url, completionHandler: { (data: NSData?, response: NSURLResponse?, error: NSError?) -> Void in
338338
resData = data
339339
resError = error
340340
cond.broadcast()

Foundation/NSURLResponse.swift

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,13 @@ public class NSHTTPURLResponse : NSURLResponse {
183183
/// `[NSObject: AnyObject]` type that Darwin Foundation uses.
184184
public let allHeaderFields: [String: String]
185185

186+
/// The value of a specific header field
187+
///
188+
/// Uses case-insensitive matching to find the header field with the name.
189+
internal func value(forHeaderField field: String) -> String? {
190+
return valueForCaseInsensitiveKey(field, fields: allHeaderFields)
191+
}
192+
186193
/*!
187194
@method localizedStringForStatusCode:
188195
@abstract Convenience method which returns a localized string

Foundation/NSURLSession.swift

Lines changed: 0 additions & 801 deletions
This file was deleted.
Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
// Foundation/NSURLSession/Configuration.swift - NSURLSession & libcurl
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See http://swift.org/LICENSE.txt for license information
9+
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
// -----------------------------------------------------------------------------
12+
///
13+
/// These are libcurl helpers for the NSURLSession API code.
14+
/// - SeeAlso: https://curl.haxx.se/libcurl/c/
15+
/// - SeeAlso: NSURLSession.swift
16+
///
17+
// -----------------------------------------------------------------------------
18+
19+
20+
internal extension NSURLSession {
21+
/// This is an immutable / `struct` version of `NSURLSessionConfiguration`.
22+
struct Configuration {
23+
/// identifier for the background session configuration
24+
let identifier: String?
25+
26+
/// default cache policy for requests
27+
let requestCachePolicy: NSURLRequestCachePolicy
28+
29+
/// 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.
30+
let timeoutIntervalForRequest: NSTimeInterval
31+
32+
/// default timeout for requests. This will cause a timeout if a resource is not able to be retrieved within a given timeout.
33+
let timeoutIntervalForResource: NSTimeInterval
34+
35+
/// type of service for requests.
36+
let networkServiceType: NSURLRequestNetworkServiceType
37+
38+
/// allow request to route over cellular.
39+
let allowsCellularAccess: Bool
40+
41+
/// allows background tasks to be scheduled at the discretion of the system for optimal performance.
42+
let discretionary: Bool
43+
44+
/// The proxy dictionary, as described by <CFNetwork/CFHTTPStream.h>
45+
let connectionProxyDictionary: [NSObject : AnyObject]?
46+
47+
/// Allow the use of HTTP pipelining
48+
let httpShouldUsePipelining: Bool
49+
50+
/// Allow the session to set cookies on requests
51+
let httpShouldSetCookies: Bool
52+
53+
/// Policy for accepting cookies. This overrides the policy otherwise specified by the cookie storage.
54+
let httpCookieAcceptPolicy: NSHTTPCookieAcceptPolicy
55+
56+
/// Specifies additional headers which will be set on outgoing requests.
57+
/// Note that these headers are added to the request only if not already present.
58+
59+
let httpAdditionalHeaders: [String : String]?
60+
/// The maximum number of simultanous persistent connections per host
61+
let httpMaximumConnectionsPerHost: Int
62+
63+
/// The cookie storage object to use, or nil to indicate that no cookies should be handled
64+
let httpCookieStorage: NSHTTPCookieStorage?
65+
66+
/// The credential storage object, or nil to indicate that no credential storage is to be used
67+
let urlCredentialStorage: NSURLCredentialStorage?
68+
69+
/// The URL resource cache, or nil to indicate that no caching is to be performed
70+
let urlCache: NSURLCache?
71+
72+
/// Enable extended background idle mode for any tcp sockets created.
73+
let shouldUseExtendedBackgroundIdleMode: Bool
74+
75+
let protocolClasses: [AnyClass]?
76+
}
77+
}
78+
internal extension NSURLSession.Configuration {
79+
init(URLSessionConfiguration config: NSURLSessionConfiguration) {
80+
identifier = config.identifier
81+
requestCachePolicy = config.requestCachePolicy
82+
timeoutIntervalForRequest = config.timeoutIntervalForRequest
83+
timeoutIntervalForResource = config.timeoutIntervalForResource
84+
networkServiceType = config.networkServiceType
85+
allowsCellularAccess = config.allowsCellularAccess
86+
discretionary = config.discretionary
87+
connectionProxyDictionary = config.connectionProxyDictionary
88+
httpShouldUsePipelining = config.httpShouldUsePipelining
89+
httpShouldSetCookies = config.httpShouldSetCookies
90+
httpCookieAcceptPolicy = config.httpCookieAcceptPolicy
91+
httpAdditionalHeaders = config.httpAdditionalHeaders.map { convertToStringString(dictionary: $0) }
92+
httpMaximumConnectionsPerHost = config.httpMaximumConnectionsPerHost
93+
httpCookieStorage = config.httpCookieStorage
94+
urlCredentialStorage = config.urlCredentialStorage
95+
urlCache = config.urlCache
96+
shouldUseExtendedBackgroundIdleMode = config.shouldUseExtendedBackgroundIdleMode
97+
protocolClasses = config.protocolClasses
98+
}
99+
}
100+
101+
// Configure NSURLRequests
102+
internal extension NSURLSession.Configuration {
103+
func configure(request: NSMutableURLRequest) {
104+
httpAdditionalHeaders?.forEach {
105+
guard request.value(forHTTPHeaderField: $0.0) == nil else { return }
106+
request.setValue($0.1, forHTTPHeaderField: $0.0)
107+
}
108+
}
109+
func setCookies(on request: NSMutableURLRequest) {
110+
if httpShouldSetCookies {
111+
//TODO: Ask the cookie storage what cookie to set.
112+
}
113+
}
114+
}
115+
// Cache Management
116+
private extension NSURLSession.Configuration {
117+
func cachedResponse(forRequest request: NSURLRequest) -> NSCachedURLResponse? {
118+
//TODO: Check the policy & consult the cache.
119+
// There's more detail on how this should work here:
120+
// <https://developer.apple.com/library/prerelease/ios/documentation/Cocoa/Reference/Foundation/Classes/NSURLRequest_Class/index.html#//apple_ref/swift/enum/c:@E@NSURLRequestCachePolicy>
121+
switch requestCachePolicy {
122+
default: return nil
123+
}
124+
}
125+
}
126+
127+
private func convertToStringString(dictionary: [NSObject:AnyObject]) -> [String: String] {
128+
//TODO: There's some confusion about [NSObject:AnyObject] vs. [String:String] for headers.
129+
// C.f. <https://github.com/apple/swift-corelibs-foundation/pull/287>
130+
var r: [String: String] = [:]
131+
dictionary.forEach {
132+
let k = String($0.key as! NSString)
133+
let v = String($0.value as! NSString)
134+
r[k] = v
135+
}
136+
return r
137+
}

0 commit comments

Comments
 (0)