简体   繁体   中英

How to set a class variable with value from Alamofire call in swift?

I am new to iOS development, and I have a class that I am using to retrieve data from a server. I would like to store a value from an Alamofire request as class variable for use with subsequent requests. I understand that Alamofire requests have completion handlers with them, but it is still not very clear to me how these work.

In setSessionID , I would like to store the String from generateNewSessionID into sessionID . This obviously isn't the correct way to do this, as I get an unwrapped nil optional error in the print statement.

import Alamofire
import Foundation

class DataRetriever {
    private var sessionID: String?
    private let baseUrl: String?
    private let endPoints = ["session": "/session", "population": "/population/"]

    init() {
        let dict = NSDictionary(contentsOfFile: NSBundle.mainBundle().pathForResource("Config", ofType: "plist")!)
        baseUrl = dict!["baseUrl"] as? String
        setSessionID()
    }

    private func generateNewSessionID(completionHandler: (NSError?, String?) -> ()) {
         let params = [ "stuff": "stuff", "morestuff": "moreStuff" ]

        Alamofire.request(.POST, baseUrl! + endPoints["session"]!, parameters: params, encoding:ParameterEncoding.URL, headers: getSessionHeaders()).responseJSON { response in
            switch response.result{
            case .Success:
                completionHandler(nil, String(response.response!))
            case .Failure(let error):
                completionHandler(error, nil)
            }
        }
    }

    func setSessionID() {
        generateNewSessionID() { (error, session) in
            if error != nil {
                // handle error
            } else {
                self.sessionID = session
            }
        }

        print(self.sessionID!)
    }
}

I've looked through other examples, but I can't see how I would be able to do this within the scope of my class.

In your setSessionID if you check if error != nil that's mean if theres an error handle it, so you should change it like this

if error == nil {
   // No error
   self.sessionID = session
} else {
   //handle Error
}

You're actually printing the sessionID outside of your completion block, which means it's trying to print the value before the network request has completed. You need to move it inside your completion block like so:

 func setSessionID() {
    generateNewSessionID() { (error, session) in
        if error != nil {
            // handle error
        } else {
            self.sessionID = session
        }

        // moved print here
        print(self.sessionID!)
    }
}

You should, of course, guard against the possibility that session could be nil:

guard let id = self.sessionID else {
    return
}

print(id)

But assuming it's not, the first code block should work.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM