How to save a session in objective-c?

So, I had the following problem:

I have a login view manager and a form manager. In the login view manager, I send a POST request to a PHP script that checks if the user has access. The script simply returns 1 or 0. Therefore, I can choose to fire or support the view manager. When the credentials are passed correctly, the user will see the form controller. This controller received a button to receive the form.

The button to retrieve the form makes a POST request to another PHP script that will return an XML document with user values. I need a way to remember the username and password that the user passed. Therefore, I can use them in another (view) controller.

Does anyone know a way to achieve this?

+4
source share
4 answers

If you use NSURLConnection and the session is cookie-based, this will be done automatically. So, all you would need to write would be like this

NSMutableURLRequest *request = nil; request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"http://server.com/login.php"]]; NSString *post = [NSString stringWithFormat:@"username=%@&password=%@", @"<username>", @"<password>"]; NSData *postData = [post dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES]; [request setValue:[NSString stringWithFormat:@"%d", [postData length]] forHTTPHeaderField:@"Content-Length"]; [request setTimeoutInterval: 15]; [request setHTTPMethod:@"POST"]; [request setHTTPBody:postData]; _urlConnection = [[NSURLConnection alloc] initWithRequest:request delegate:self]; [_urlConnection start]; 

And you will also have to implement NSURLConnectionDelegate methods

 - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data { [_responseData appendData:data]; } - (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error { //Oops! handle failure here } - (void)connectionDidFinishLoading:(NSURLConnection *)connection { if (_statusCode >= 200 && _statusCode < 400) { //Things look ok NSString *responseString = [[[NSString alloc] initWithData:_responseData] autorelease]; //Send this to an xml lib and parse } [_responseData release]; _responseData = nil; [connection autorelease]; } 

If you have other information in the headings that you need to send back with subsequent requests, you can read it from an answer like this

 - (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response { if ([response isKindOfClass:[NSHTTPURLResponse class]]) { NSDictionary *headerFields = [(NSHTTPURLResponse*)response allHeaderFields]; //This would give you all the header fields; } } 

And set the header fields for the next request, such as

  [request setValue:[NSString stringWithFormat:@"%d", [postData length]] forHTTPHeaderField:@"Content-Length"]; 

To save information , be it a username and / or password or session information, you can use NSUserDefaults

  //To save NSUserDefaults *standardUserDefaults = [NSUserDefaults standardUserDefaults]; if (standardUserDefaults) { [standardUserDefaults setObject:@"<username>" forKey:@"username"]; [standardUserDefaults setObject:@"<pass>" forKey:@"password"]; [standardUserDefaults synchronize]; } //To retrieve NSUserDefaults *standardUserDefaults = [NSUserDefaults standardUserDefaults]; NSString *val = nil; if (standardUserDefaults) val = [standardUserDefaults objectForKey:@"username"]; 

Finally, it would be wise to build a model to map the XML API using [For example: user class with username and passwords].

Google for Apple docs in MVC.

Hope this helps!

+8
source

Create a "model" object for your program (look at the model-view-controller template , which is ubiquitous in cocoa), then in your login controller, save the username and password in the model; where you need to access this data from, you read it from the model.

+2
source

Yes, the ASI HTTP request was received mainly from the NSURL class only. No need to worry about HTTP callback. Just store these values ​​in sqlite use plist for complex and huge data usage.

0
source

I will give you an exhaustive answer with Swift.

Do not use NSUserDefaults or store a password, this is a bad solution

NSUserDefaults data is not encrypted; this may cause a security problem.

Create a structured custom class instead

When the user is logged in, you need to make sure that you have access to user data throughout the application so that you can receive data on any screen when you need it.

To achieve this, we need to create an excellent structure in order to organize it correctly. Remember that the current user and other users are β€œusers”, so we will use the same class.

Create a class and name it "EDUser" (you can choose a different name if you want).
This class will contain user information (current user or another user).
Moreover, this class will be able to register the user.

Here is an image of what the class might look like:

 class EDUser { var firstName: String var lastName: String? var birthDate: NSDate? init(firstName: String, lastName: String?, birthDate: NSDate?) { self.firstName = firstName self.lastName = lastName self.birthDate = birthDate } } // MARK: - Accessor extension EDUser { class var currentUser: EDUser? { get { return loadCurrentUserFromDisk() } set { saveCurrentUserToDiskWithUser(newValue) } } } // MARK: - Log in and out extension EDUser { class func loginWithUsername(username: String, andPassword password: String, callback: (EDUser?, NSError) -> Void) { // Access the web API var parameters = [ "username": username, "password": password ] YourNetworkingLibrary.request(.POST, "https://api.yourwebsite.com/login", parameters: parameters).responseJSON { response in if response.statusCode == .Success { let user = EDUser(firstName: response["firstName"], lastName: response["lastName"], birthDate: NSDate.dateFromString(response["birthDate"])) currentUser = user callback(currentUser, nil) } else { callback(nil, yourError) } } } class func logout() { deleteCurrentUserFromDisk() } } // MARK: - Data extension EDUser { class private func saveCurrentUserToDiskWithUser(user: EDUser) { // In this process, you encode the user to file and store it } class private func loadCurrentUserFromDisk() -> EDUser? { // In this process, you get the file and decode that to EDUser object // This function will return nil if the file is not exist } class private func deleteCurrentUserFromDisk() { // This will delete the current user file from disk } } // MARK: - Helper extension NSDate { class func dateFromString(string: String) -> NSDate { // convert string into NSDate } } 

Use case

Now with everything in place we can use it like this

Non-blocking logging in progress

 EDUser.loginWithUsername(username: " edward@domain.com ", password: "1234") { user, error in if error == nil { // Login succeeded } else { // Login failed } } 

Sign Out

 EDUser.logout() 

Check if user is registered

 if EDUser.currentUser != nil { // The user is logged in } else { // No user logged in // Show the login screen here } 

Get current user data on any screen

 if let currentUser = EDUser.currentUser { // do something with current user data } 

Save another user as an object

 let user = EDUser(firstName: "Edward", lastName: "Anthony", birthDate: NSDate()) 
0
source

All Articles