0

session设置.init(configuration:..., delegate:self, delegateQueue:NSOperationQueue.mainQueue())为代理服务器重定向时,NSURLSessionDataTask.resume()不会导致执行task. 当session设置为.sharedSession()时,task按预期执行。

**kCFStreamPropertyHTTPProxyHost等已被弃用。也许这会NSURLSessionConfiguration以一种阻止执行的方式影响task

class ConnectionManager: NSURLSession, NSURLSessionDelegate {
    .
    .
    .
    if shouldUseProxy {
            let proxyEnable = NSNumber(int: 1) as CFNumber
            let  proxyDict: [NSObject:AnyObject] = [
                kCFNetworkProxiesHTTPEnable: proxyEnable,
                kCFStreamPropertyHTTPProxyHost: proxyHost,
                kCFStreamPropertyHTTPProxyPort: proxyPort,
                kCFStreamPropertyHTTPSProxyHost: proxyHost,
                kCFStreamPropertyHTTPSProxyPort: proxyPort,
                kCFProxyTypeKey: kCFProxyTypeHTTPS,
                kCFProxyUsernameKey: proxyUser,
                kCFProxyPasswordKey: proxyPW
            ]

            let config = NSURLSessionConfiguration.ephemeralSessionConfiguration()
            config.connectionProxyDictionary = proxyDict
            self.session = NSURLSession.init(configuration: config, delegate: self, delegateQueue: NSOperationQueue.mainQueue())
    } else {
        self.session = NSURLSession.sharedSession()
    }

        self.task = self.session.dataTaskWithRequest(request) {
            (data, response, error) in
            if error == nil {
                self.cookies = NSHTTPCookieStorage.sharedHTTPCookieStorage().cookiesForURL(response!.URL!)!

                self.httpResponse = (response as? NSHTTPURLResponse)!
                self.statusCode = (self.httpResponse!.statusCode)
                guard error == nil && data != nil else {
                    print(error)
                    return
                }

                do {
                    if self.statusCode == 200 {
                        self.contentsOfURL = try NSString(contentsOfURL: self.URL, encoding: NSUTF8StringEncoding) as String
                    }
                } catch {

                }
            }
        }

        self.task?.resume()
        .
        .
        .
}
4

1 回答 1

0

设置配置

在大多数情况下,除非您需要特殊配置,否则默认配置会起作用。

let sessionConfiguration = NSURLSessionConfiguration.defaultSessionConfiguration()

let session = NSURLSession(configuration: sessionConfiguration,
                           delegate: self,
                           delegateQueue: operationQueue)

请参考 Apple 的文档:https ://developer.apple.com/library/ios/documentation/Foundation/Reference/NSURLSession_class/#//apple_ref/doc/uid/TP40013435-CH1-SW7

重定向响应

NSURLSessionDelegate具有以下提到的函数,该函数在发生重定向时被调用。

func URLSession(session: NSURLSession, task: NSURLSessionTask, willPerformHTTPRedirection response: NSHTTPURLResponse, newRequest request: NSURLRequest, completionHandler: (NSURLRequest?) -> Void) {
    
    //self.completionHandler is some completion handler you have defined, it is call back function.

    if cancelled {
        self.completionHandler(nil, redirectRequest:nil, wasCancelled: true)
    }
    else {
        self.completionHandler(nil, redirectRequest:request, wasCancelled: false)
    }
    
    finished = true
    executing = false
}

有一个名为的参数request包含新的 URLRequest。现在您必须使用这个新请求启动一个新的会话任务

挑战

该功能是NSURLSessionDelegate

每当收到挑战时,都会调用以下函数。根据挑战的类型,您必须适当地处理它。

请参阅注释掉的代码NSURLAuthenticationMethodHTTPBasicNSURLAuthenticationMethodHTTPDigest

func URLSession(session: NSURLSession,
    didReceiveChallenge challenge: NSURLAuthenticationChallenge,
    completionHandler: (NSURLSessionAuthChallengeDisposition, NSURLCredential?) -> Void) {
        
        print("Challenge:")
        
        if(challenge.previousFailureCount == 0) {
            
            let credential = credentialForChallenge(challenge)
            print("Use Credential ....\n")
            completionHandler(.UseCredential, credential)
        }
        else {
            print("Previous Failure Count = \(challenge.previousFailureCount)")
            print("Cancelling Challenge\n")
            challenge.sender?.cancelAuthenticationChallenge(challenge)
        }
}

//Custom method to get the credential for the challenge
//In your case you would be interested in NSURLAuthenticationMethodHTTPBasic
func credentialForChallenge(challenge : NSURLAuthenticationChallenge) -> NSURLCredential? {
    
    //https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/URLLoadingSystem/Articles/AuthenticationChallenges.html
    //challenge knows:
    //what triggered the challenge
    //how many attempts were made for the challenge - previousFailureCount
    //any previous attempted credentials - proposedCredential
    //the NSURLProtectionSpace that requires the credentials
    //sender of the challenge
    
    //#Respond
    //Get authentication method
    
    let credential : NSURLCredential?
    
    print("Method = \(challenge.protectionSpace.authenticationMethod)")
    
    switch(challenge.protectionSpace.authenticationMethod) {
        
    case NSURLAuthenticationMethodHTTPBasic:
        //            HTTP basic authentication
        //            prompt user for username and password
        //            let credential = NSURLCredential(user: <#T##String#>, password: <#T##String#>, persistence: <#T##NSURLCredentialPersistence#>)
        credential = nil
        
        
    case NSURLAuthenticationMethodHTTPDigest:
        //            HTTP digest authentication
        //            prompt user for username and password
        //            let credential = NSURLCredential(user: <#T##String#>, password: <#T##String#>, persistence: <#T##NSURLCredentialPersistence#>)
        
        credential = nil
        
        
    case NSURLAuthenticationMethodClientCertificate:
        //            Client certificate authentication
        //            let credential = NSURLCredential(identity: <#T##SecIdentity#>, certificates: <#T##[AnyObject]?#>, persistence: <#T##NSURLCredentialPersistence#>)
        credential = nil
        
        
    case NSURLAuthenticationMethodServerTrust:
        //            Server trust authentication
        if let serverTrustExists = challenge.protectionSpace.serverTrust {
            credential = NSURLCredential(trust: serverTrustExists)
        }
        else {
            credential = nil
        }
        
    default:
        credential = nil
    }
    
    return credential
}
于 2016-05-04T14:56:11.407 回答