4 Replies
      Latest reply: Apr 25, 2017 12:59 AM by eskimo RSS
      nitisha Level 1 Level 1 (0 points)

        Hi,

        I'm getting strange behaviour when posting to get response from server which requires Basic Authorization.my token gets gets expired after every two hours.Every things works fine but some times i dn't knw but getting reponse from server "Parameter not null" error.i debuged there is nothing going null.i go through document-https://developer.apple.com/reference/foundation/nsmutableurlrequest

        where mentioned some http headers could not be modified using methods

        addValue(_:forHTTPHeaderField:) or setValue(_:forHTTPHeaderField:)

        i cannot figure where is going wrong and more when i'm setting Content & Accept type for json addValue(_:forHTTPHeaderField:) workds gud to set authorization and for xml  setValue(_:forHTTPHeaderField:) works but still .sometimes  they breaks.Below is my code

        //for json rsponse
        func callWebserviceForJSON(_ urlStr: String ,callback:@escaping (_ data: Dictionary<String,String>) -> Void)
            {
                  
                let url1 = URL(string: urlStr)
                var request = URLRequest(url: url1!)
              
                 let tokenId = fileMgr.getCacheData(constants.defaultsKeys.TOKEN_KEY) as! String
              
                let authorizationKey = "Basic ".appending(tokenId)
                request.httpMethod = "POST"
                request.addValue("application/json", forHTTPHeaderField: "Content-Type")
                request.addValue("application/json", forHTTPHeaderField: "Accept")
                request.addValue(authorizationKey, forHTTPHeaderField: "Authorization")
                request.timeoutInterval = 20000.0
              
                var dict = Dictionary<String,String>()
                let task = URLSession.shared.dataTask(with: request)
                  {
                    data, response, error -> Void in
             }
        //for xml response
        
        /
            func callPostWebservice(_ urlStr: String, callback:@escaping (_ data: Dictionary<String,String>) -> Void)
            {
               
                 
               
                let url1 = URL(string: urlStr)
                var request = URLRequest(url: url1!)
               
                 let tokenId = fileMgr.getCacheData(constants.defaultsKeys.TOKEN_KEY) as! String
               
                print("tokenId >> \(tokenId) , urlStr >> \(urlStr)")
                request.httpMethod = "POST"
                request.addValue("application/xml", forHTTPHeaderField: "Content-Type")
                request.addValue("application/xml", forHTTPHeaderField: "Accept")
                request.setValue("Basic \(tokenId)", forHTTPHeaderField: "Authorization")
                request.timeoutInterval = 20000.0
               
                var dict = Dictionary<String,String>()
                let task = URLSession.shared.dataTask(with: request)
                {data, response, error  in }
        

        Please advice

        • Re: How to set Authorization to URlRequest in swift 3.0
          eskimo Apple Staff Apple Staff (7,550 points)

          I’m not sure what’s going on with your specific code but setting the Authorization header manually is not the right approach.  Rather, you should set up your session to handle authentication challenges via the -URLSession:task:didReceiveChallenge:completionHandler: delegate callback.

          Share and Enjoy

          Quinn “The Eskimo!”
          Apple Developer Relations, Developer Technical Support, Core OS/Hardware
          let myEmail = "eskimo" + "1" + "@apple.com"

            • Re: How to set Authorization to URlRequest in swift 3.0
              nitisha Level 1 Level 1 (0 points)

              you are right but i've to set Authorization manually because i'm getting token in log in process,and it have to use that token for further post request.

              please advice

              • Re: How to set Authorization to URlRequest in swift 3.0
                algal Level 1 Level 1 (0 points)

                Is there a working example of this anywhere?

                 

                I've implemented various kinds of authentication with the URLSession:task:didReceiveChallenge:completionHandler: callback, but every time I have tried to use it for plain old HTTP Basic Authentication I have found it difficult. The documentation sometimes gives the impression the API is only intended for responding to challenges (rather than volunteering credentials as part of the request). I always end up manually building the HTTP headers, which feels wrong.

                 

                What's the Right Way to do plain old HTTP Basic Auth with the URLSession and friends?

                  • Re: How to set Authorization to URlRequest in swift 3.0
                    eskimo Apple Staff Apple Staff (7,550 points)

                    What's the Right Way to do plain old HTTP Basic Auth with the URLSession and friends?

                    The right way to handle Basic and Digest authentication is to implement the per-task authentication challenge handler and respond to those challenges.  Pasted in below is a snippet.

                    Share and Enjoy

                    Quinn “The Eskimo!”
                    Apple Developer Relations, Developer Technical Support, Core OS/Hardware
                    let myEmail = "eskimo" + "1" + "@apple.com"

                    func basicAuthTrip(didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {
                        if challenge.previousFailureCount < 3 {
                            let credential = URLCredential(user: "bbbb", password: "BBBB", persistence: .forSession)
                            completionHandler(.useCredential, credential)
                        } else {
                            completionHandler(.cancelAuthenticationChallenge, nil)
                        }
                    }
                    
                    func digestAuthTrip(didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {
                        if challenge.previousFailureCount < 3 {
                            let credential = URLCredential(user: "dddd", password: "DDDD", persistence: .forSession)
                            completionHandler(.useCredential, credential)
                        } else {
                            completionHandler(.cancelAuthenticationChallenge, nil)
                        }
                    }
                    
                    func urlSession(_ session: URLSession, task: URLSessionTask, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {
                    
                        // Look for specific authentication challenges and dispatch those to various helper methods.
                        //
                        // IMPORTANT: It's critical that, if you get a challenge you weren't expecting,
                        // you resolve that challenge with `.performDefaultHandling`.
                    
                        switch (challenge.protectionSpace.authenticationMethod, challenge.protectionSpace.host) {
                            case (NSURLAuthenticationMethodHTTPBasic, "httpbin.org"):
                                self.basicAuthTrip(didReceive: challenge, completionHandler: completionHandler)
                            case (NSURLAuthenticationMethodHTTPDigest, "httpbin.org"):
                                self.digestAuthTrip(didReceive: challenge, completionHandler: completionHandler)
                            default:
                                completionHandler(.performDefaultHandling, nil)
                        }
                    }