Search code examples
iosswiftalamofirensurlsessionnsurlcache

How to disable the URLCache completely with Alamofire


Using Xcode 7.3 iOS 9.2 all in Swift none of that horrible Objective C I have been working on this for a while and been around the block three times now. I have tried this post here and it didn't work http://www.mzan.com/article/32199494-alamofire-how-remove-cache.shtml

I have also try to use apple documentation but that is so crappy I cannot make sense of if.

So what I am doing is making two Alamofire calls to my server. One to test the credentials of the login information to see if the input is right. The second is to download and return the customer information for there viewing. Both are working fine when I call it the first time. The problem is when I logout of the app i clear all the user information from the page. But when I logbook in during the same session, it calls the first one right so if I put in the wrong username or password it returns false even if I login correctly the first time. But when I download the customer data, it keeps downloading the old information from the first time I accessed the user information. It uses the new username and password but still downloads the old stuff.

This is my Login and Logout functions:

//MARK: ButtonControllers
@IBAction func onLoginClick(sender: AnyObject) {

    errorMessageUI.text = "Checking Creditials"
    email = userNameInput.text!
    password = passwordInput.text!
    buildLoginUrl = checkLoginUrl + emailTag + email + passwordTag + password
    print(buildLoginUrl)
    print("Login Cred")
    checkLoginCredentials(buildLoginUrl)
}

@IBAction func onLogoutClick(sender: AnyObject) {

    //null out everything for logout
    email = ""
    password = ""
    self.loginInformation.setObject(self.email, forKey: "email")
    self.loginInformation.setObject(self.password, forKey: "password")
    self.loginInformation.synchronize()
    performSegueWithIdentifier("logoutSegue", sender: self)
    //self.view = LoginView
}

And this is the alamofire calls

//MARK: Check Credentials Method
//Function to log into the server and retrive data
func checkLoginCredentials(myUrl : String)
{
    Alamofire.request(.GET, myUrl)
        .validate(statusCode: 200..<300)
        .responseString { response in
            print("Cred Success: \(response.result.isSuccess)")
            print("Cred Check: \(response.result.value)")
            //clear all url chache
            NSURLCache.sharedURLCache().removeAllCachedResponses()

            if response.result.value != nil
            {
                let checker : String = response.result.value!
                if checker.lowercaseString.rangeOfString("false") != nil {
                    self.canILogin = false
                    self.errorMessageUI.text = "Wrong username or Password try again"
                }else{
                    self.canILogin = true
                    print("Downloading Json file for customer info")
                    self.loadingImage.hidden = false
                    self.downlaodCustomerinfo(self.customerInfoUrl, myUser: self.email, myPass: self.password)
                    //defaults.setBool(textColorSwitch.on, forKey: "DarkText")
                    self.loginInformation.setObject(self.email, forKey: "email")
                    self.loginInformation.setObject(self.password, forKey: "password")
                    self.loginInformation.synchronize()
                }

                print("Login? " + self.canILogin.description ?? "none" )
            }else
            {
                //Stop the program from downloading anything to avoid crashes
                self.loadingImage.hidden = true
                print("I cannot download User Info")
                self.errorMessageUI.text = "A connection error occured"
                //set the json to be empty to avoid a crash
                //reset the json file incase there is anythig in it
                self.downloadJson = ""


            }

    }
}//end of checkLoginCredentials function

//MARK: Download Customer Infoamtion
func downlaodCustomerinfo(myUrl : String, myUser : String, myPass : String)
{

    //clear all url chache
    NSURLCache.sharedURLCache().removeAllCachedResponses()
    print("Username: " + myUser)
    print("Password: " + myPass)
    print("Download Url: " + myUrl )
    print("Jsonfile before download: " + self.downloadJson)
    Alamofire.request(.GET, myUrl)
        .authenticate(user: myUser, password: myPass)
        .validate(statusCode: 200..<300)
        .responseString { response in
            //print("Success: \(response.result.isSuccess)")
            print("Info Download: \(response.result.value)")


            if response.result.value != nil{

                self.downloadJson = response.result.value!
                print("Json file: " + self.downloadJson)
                self.parseCustomerInfo(self.downloadJson)
            }else
            {
                self.loadingImage.hidden = true
                print("I cannot download User Info")
                self.errorMessageUI.text = "A connection error occured"
                //set the json to be empty to avoid a crash
                self.downloadJson = "{}"
            }

    }
}//end of download

UPDATED Code: Cause the system to return false from the Alamofire response

  //Create a non-caching configuration.
    let config = NSURLSessionConfiguration.defaultSessionConfiguration()
    config.requestCachePolicy = .ReloadIgnoringLocalAndRemoteCacheData
    config.URLCache = nil
    //Create a manager with the non-caching configuration that you created above.
    let manager = Alamofire.Manager(configuration: config)

    print("Username for download: " + myUser)
    print("Password: " + myPass)
    manager.request(.GET, myUrl)
        .authenticate(user: myUser, password: myPass)
        .validate(statusCode: 200..<300)
        .responseString { response in
            //print("Success: \(response.result.isSuccess)")
            print("Info Download: \(response.result.value)")

            if response.result.value != nil{

                self.downloadJson = response.result.value!
                print("Json file: " + self.downloadJson)
                self.parseCustomerInfo(self.downloadJson)
            }else
            {
                self.loadingImage.hidden = true
                print("I cannot download User Info")
                self.errorMessageUI.text = "A connection error occured"
                //set the json to be empty to avoid a crash
                self.downloadJson = "{}"
            }

    }


}//end of downloadCustomer function

Solution

  • Why are you not configuring the session? If you configure the session correctly, there will be no caching.

    Example:

    //Create a non-caching configuration.
    let config = NSURLSessionConfiguration.defaultSessionConfiguration()
    config.requestCachePolicy = .ReloadIgnoringLocalAndRemoteCacheData
    config.URLCache = nil
    
    //Allow cookies if needed.     
    config.HTTPCookieStorage = NSHTTPCookieStorage.sharedHTTPCookieStorage()
    
    
    //Create a manager with the non-caching configuration that you created above.
    self.manager = Alamofire.Manager(configuration: config)
    
    
    //Examples of making a request using the manager you created:
    
    //Regular HTML GET request:
    self.manager.request(.GET, "https://stackoverflow.com")
        .validate(statusCode: 200..<300)
        .validate(contentType: ["text/html"])
        .responseString { (response) in
            guard response.result.isSuccess else {
                print("Error: \(response.result.error)")
                return
            }
        print("Result: \(response.result.value)")
    }
    
    
    //JSON GET request:
    self.manager.request(.GET, "someURL", parameters: params, encoding: .URL, headers: headers)
        .validate(statusCode: 200..<300)
        .validate(contentType: ["application/json"])
        .responseJSON { (response) in
            guard response.result.isSuccess else {
                print("Error: \(response.result.error)")
                return
            }
    
            print(response.result.value as? [String: AnyObject])
    }
    

    Edit:

    let manager = {() -> Alamofire.Manager in
        struct Static {
            static var dispatchOnceToken: dispatch_once_t = 0
            static var instance: Alamofire.Manager!
        }
    
        dispatch_once(&Static.dispatchOnceToken) {
            let config = NSURLSessionConfiguration.defaultSessionConfiguration()
            config.requestCachePolicy = .ReloadIgnoringLocalAndRemoteCacheData
            config.URLCache = nil
    
            let cookies = NSHTTPCookieStorage.sharedHTTPCookieStorage()
            config.HTTPCookieStorage = cookies
            Static.instance = Alamofire.Manager(configuration: config)
        }
    
        return Static.instance
    }()
    
    manager.request(.GET, "https://stackoverflow.com")
        .validate(statusCode: 200..<300)
        .validate(contentType: ["text/html"])
        .responseString { (response) in
            guard response.result.isSuccess else {
                print("Error: \(response.result.error)")
                return
            }
        print("Result: \(response.result.value)")
    }
    

    P.S. You can also look into:

    NSURLSessionConfiguration.ephemeralSessionConfiguration() - Returns a session configuration that uses no persistent storage for caches, cookies, or credentials.