DeveloperFeaturediOS DeveloperObject Oriented TechnologyObjective CProgramming Language

เขียนแอพ iPhone การใช้ Global Session เก็บค่าสถานะด้วย NSUserDefaults

วิธีการใช้งาน Session สำหรับเก็บค่าสถานะการเข้าระบบบนแอพพลิเคชัน iPhone อย่างง่ายประกาศแบบ Global ด้วย NSUserDefaults เหมือนการเก็บ Session บนเว็บไซต์ครับการทำงานของมันนั้นไม่ยากมากครับเหมือนการประกาศตัวแปร Session สำหรับ สถานะการเข้าระบบของผู้ใช้งาน ปรกติครับ เช่น หากผมจะเข้าใช้งานระบบผมก็จะมี Username และ Password ในการเข้าระบบ ข้อมูล Username ของผมจะถูกเก็บใน Session ค้างในระบบ เป็นการระบุตัวตนผู้ใช้ได้ครับ หลักการก็เหมือนเว็บไซต์ปรกติเลย เพียงแค่มันมาอยู่บน แอพพลิเคชัน

มาเริ่มเขียนกันหน่อยดีกว่าครับ

สร้าง New Project เป็น Single View Application ครับ ตั้งชื่อ Project ให้เรียบร้อย

ตั้งชื่อ Project
ตั้งชื่อ Project

ต่อมาเปิด MainStoryBoard ขึ้นมา ตกแต่งหน้าจอตามนี้ครับ UITextFields ทั้ง Email, Password และมี UIButton ในการกด เข้าระบบ

ให้ลาก UIView ไปวางก่อนครับปรับขนาดให้พอดีแล้ว เอา UITextFields และ UIButton ไปวางบน UIVew ตัวนั้น

Screen Shot 2557-03-28 at 6.47.48 PM

เชื่อม IBOutlet ของ UIView

#import <UIKit/UIKit.h>

@interface ViewController : UIViewController
@property (strong, nonatomic) IBOutlet UIView *viewLogin;
ตกแต่งหน้าจอประมาณนี้
ตกแต่งหน้าจอประมาณนี้

สว่นของ UITextField ของ Password ต้องตั้งค่าเป็น Secure ครับ

ตั้งค่า Secure
ตั้งค่า Secure

ทำการสร้าง IBOutlet และ IBAction ทั้งหมดสำหรับ UITextFiled และ UIButton ให้หมดครับ

Link IBOutlet ทุกตัว
Link IBOutlet ทุกตัว
IBAction สำหรับปุ่ม Login ครับ
IBAction สำหรับปุ่ม Login ครับ

ไฟล์ ViewController.h จะได้ดังนี้

#import <UIKit/UIKit.h>

@interface ViewController : UIViewController
@property (strong, nonatomic) IBOutlet UIView *viewLogin;
@property (strong, nonatomic) IBOutlet UITextField *txtEmail;
@property (strong, nonatomic) IBOutlet UITextField *txtPassword;

@property (strong, nonatomic) IBOutlet UIView *viewSession;
- (IBAction)btnLogin:(id)sender;
@end

อย่าลืมประกาศ Synthesize ใน ViewController.m

@implementation ViewController
@synthesize txtEmail;
@synthesize txtPassword;
@synthesize viewLogin;

ทำการ Embed Navigation Controller ให้กับ ViewController บน MainStoryBoard ครับ

Screen Shot 2557-03-28 at 6.53.37 PM

เขียน  Code ส่วนของ ViewController.m ดังนี้ครับ เพิ่ม เมธอด ใหม่เข้าไป

- (IBAction)btnLogin:(id)sender {

    NSLog(@"%@",txtEmail.text);
    NSLog(@"%@",txtPassword.text);
    [session setObject:txtEmail.text forKey:@"session_email"];
    [session setObject:txtPassword.text forKey:@"session_password"];

}

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{

    [self.txtEmail resignFirstResponder];
    [self.txtPassword resignFirstResponder];

}

ลองพิมพ์ Email ในช่อง Email และ ​Password ในช่อง Password ลงไปครับ แล้วกด Signin จะเห็น Log ดังนี้

ค่า NSlog
ค่า NSlog ปล. Password ปลอมนะไม่ต้องทะลึ่ง HACK

ไปที่ MainStoryBoard ครับสร้าง ViewController ใหม่ขึ้นมา สร้างไฟล์ใหม่ชื่อ PageViewController มาเป็น คลาสของมันครับ

Screen Shot 2557-03-28 at 5.49.50 PM

ตั้งชื่อ Storyboard ID ตัวอย่างนี้ใช้เดียวกัน “PageViewController”

วาง UILabel ลงไปตามนี้ครับ
วาง UILabel ลงไปตามนี้ครับ

เปิดไฟล์ PageViewController.h ขึ้นมาเชื่อม IBOutlet ดังนี้ครับ

#import <UIKit/UIKit.h>

@interface PageViewController : UIViewController
@property (strong, nonatomic) IBOutlet UILabel *txtSession;
@end

ทำการ Synthesize ตัวแปลที่ PageViewController.m ขึ้นมา

@implementation PageViewController

@synthesize txtSession;

กลับไปที่ ViewController.m เพิ่ม #import ไฟล์ PageViewController เข้าไปที่ Header

#import "ViewController.h"
#import "PageViewController.h"

และแก้ไขที่ เมธอด btnLogin() ให้มีการ เปลี่ยนหน้าเมื่อมีการกดปุ่มเข้าระบบ ด้วย คำสั่ง  self.navigationController pushViewController ตามนี้

UIStoryboard * storyboard = self.storyboard;
PageViewController * detail = [storyboard instantiateViewControllerWithIdentifier: @"PageViewController"];
[self.navigationController pushViewController: detail animated: YES];

ประกาศคลาสของ NSUserDefaults ขึ้นมาเพื่อเก็บ Session ครับ วิธีใช้คือ

NSUserDefaults *ตัวแปรsession = [NSUserDefaults standardUserDefaults];
session setObject:@"ค่าที่ต้องการเก็บ" forKey:@"ชื่อKeyของSession"];

ดังนั้นสิ่งที่ผมจะทำคือ ตั้งค่า Key ของ Session เป็น session_email และ session_password(ตัวอย่างจะขอใช้ตัวเดียวนะ) คำสั่งเมธอด btnLogin() ทั้งหมดก็จะเป็นดังนี้

- (IBAction)btnLogin:(id)sender {&nbsp;&nbsp;

&nbsp; &nbsp; NSUserDefaults *session = [NSUserDefaults standardUserDefaults];
&nbsp; &nbsp; //Saving Session with NSString
&nbsp; &nbsp; NSLog(@"%@",txtEmail.text);
&nbsp; &nbsp; NSLog(@"%@",txtPassword.text);
&nbsp; &nbsp; [session setObject:txtEmail.text forKey:@"session_email"];
&nbsp; &nbsp; [session setObject:txtPassword.text forKey:@"session_password"];&nbsp;&nbsp; &nbsp;

&nbsp; &nbsp; UIStoryboard * storyboard = self.storyboard;
&nbsp; &nbsp; PageViewController * detail = [storyboard instantiateViewControllerWithIdentifier: @"PageViewController"];
&nbsp; &nbsp; [self.navigationController pushViewController: detail animated: YES];

}

แปลว่าถ้ามีกรอกข้อมูล แล้ว Signin ตัวแปร Email จะถูกเก็บ Session ที่ชื่อ Key ว่า session_email ทันทีครับ และหน้าจอจะเลื่อนไปยังหน้า PageViewController ทันทีด้วย Navigation Controller ดังนั้นหน้า PageViewController.m นั้นในส่วนของ ViewDidLoad() ผมก็ต้องไปรับค่า Session ทันทีที่นั่น

วิธีการรับค่าคือ

//Retrieving Session
NSUserDefaults *ตัวแปรรับค่าsession = [NSUserDefaults standardUserDefaults];
NSString *ตัวแปรแสดงผล = [ตัวแปรรับค่าsession stringForKey:@"ชื่อKeyของSession"];

ดังนั้น เมธอด viewDidLoad() ของ PageViewController.m จะเป็นดังนี้ครับ

- (void)viewDidLoad
{

    [super viewDidLoad];
    //Retrieving Session
    NSUserDefaults *get_session = [NSUserDefaults standardUserDefaults];
    NSString *session_email = [get_session stringForKey:@"session_email"];
    NSLog(@"Global Session: %@",session_email);
    txtSession.text=session_email;

}

การทำงานจะเกิดขึ้นก็คือ เมื่อเข้าระบบจะมารับค่า Session ที่หน้า PageViewController ครับเห็นค่าตัวแปรแล้ว เราก็ย้อนกลับไปหน้า ViewController ทันที โดยการกด < Back กลับไป

มี Session เก็บแบบ Global แล้ว
มี Session เก็บแบบ Global แล้ว

สิ่งที่ผมจะทำคือ หน้า ViewController จะต้องจำได้ว่าเคย Login ไว้แล้ว ถ้า Login ค้าง Session อยู่ก็จะต้องไม่มีการถามให้เข้าระบบอีกต่อไป

หมายเหตุ: สำหรับ NSUserDefaults นั้นจะเก็บ Session ไว้จนกว่าเราจะลบ หรือ Un install แอพพลิเคชันของเราออกไปครับ จึงจะต้องเก็บ Session ใหม่

เพิ่ม UIView อีกตัวขึ้นมาที่ ViewController ครับบน MainStoryBoard ทำการเชื่อม IBOutlet เพิ่มเข้าไปคือ viewSession และ resultLabel ครับ

เพิ่ม UIView เข้าไปตั้ง IBOutlet ว่า viewSession
เพิ่ม UIView เข้าไปตั้ง IBOutlet ว่า viewSession

วาง UILabel เข้าไป เชื่อม IBOutlet ชื่อ resultLabel ครับ

เอา IBOutlet ของ UILabel มาด้วย
เอา IBOutlet ของ UILabel มาด้วย

ดังนั้นไฟล์ ViewController.h จะต้องเป็นดังนี้ครับ ในขั้นตอนสุดท้าย

#import <UIKit/UIKit.h>

@interface ViewController : UIViewController
@property (strong, nonatomic) IBOutlet UIView *viewLogin;
@property (strong, nonatomic) IBOutlet UITextField *txtEmail;
@property (strong, nonatomic) IBOutlet UITextField *txtPassword;
@property (strong, nonatomic) IBOutlet UILabel *resultLabel;
@property (strong, nonatomic) IBOutlet UIView *viewSession;

- (IBAction)btnLogin:(id)sender;

@end

กลับไปแก้ไขไฟล์ ViewController.m ครับ ทำการ Synthesize ดังนี้

@synthesize resultLabel;
@synthesize viewSession;

แก้ไข เมธอด viewDidLoad()  เข้าไป เพิ่มคำสั่งรับค่า Session

//Retrieving Session

NSUserDefaults *get_session = [NSUserDefaults standardUserDefaults];
NSString *session_email = [get_session stringForKey:@"session_email"];

เขียนคำสั่ง แสดงผลตามเงื่อนไขว่า ถ้ามี Session หน้า UIVew ที่มี ฟอร์ม Signin ซ่อนไป และแสดงหน้าฟอร์มเข้าระบบแล้ว

         //Session Do

        viewLogin.hidden=TRUE;
        viewSession.hidden=FALSE;
        resultLabel.text=session_email;

ถ้าไม่มี Session หน้า UIVew ที่มี ฟอร์ม Signin ซถูกแสดง และหน้าฟอร์มเข้าระบบแล้ว ถูกซ่อนไป

       //Empty Session

        viewLogin.hidden=FALSE;
        viewSession.hidden=TRUE;

เอามาเช็คเงื่อนไขดังนี้ครับ

if(session_email){
        //Session Do

        viewLogin.hidden=TRUE;
        viewSession.hidden=FALSE;
        resultLabel.text=session_email;

    }else{
        //Empty Session

        viewLogin.hidden=FALSE;
        viewSession.hidden=TRUE;
    }

ดังนั้นเมธอด ViewDidLoad() จะเป็นดังนี้

- (void)viewDidLoad
{

    [super viewDidLoad];
    //Retrieving Session
    NSUserDefaults *get_session = [NSUserDefaults standardUserDefaults];
    NSString *session_email = [get_session stringForKey:@"session_email"];
    if(session_email){
        //Session Do

        viewLogin.hidden=TRUE;
        viewSession.hidden=FALSE;
        resultLabel.text=session_email;

    }else{

        //Empty Session

        viewLogin.hidden=FALSE;
        viewSession.hidden=TRUE;
    }
}

ลอง Run ตัวแอพพลิเคชันของเราดูครับ จะเห็นว่า มันทำงานเกี่ยวกับ Session ได้แล้ว และถ้าเราเอาไปประยุกต์ใช้กับ Web Server อย่าง JSON มาช่วยเหลือในการเก็บข้อมูล Session แบบง่ายอีกตัวก็จะทำให้เราได้แอพพลิเคชันที่สมบูรณ์มากขึ้นครับ

รันดูก็โอเคเลยถ้าเคย Login ค้างไว้ ไม่ต้อง Login ใหม่
รันดูก็โอเคเลยถ้าเคย Login ค้างไว้ ไม่ต้อง Login ใหม่

ตัวอย่างที่นี้คือ Basic นะครับ แม้จะอธิบายยาวก็ตามเถอะ

ดาวน์โหลด Source Code สำหรับคนมักง่าย และคนที่ต้องการศึกษา ดาวน์โหลดที่นี่: https://www.daydev.com/download/SessionGlobal.zip

[AdSense-A]

[Comment ขอบคุณ หรือ Share แบ่งปัน ความรู้กันบ้างนะครับไม่ใช่สูบ แล้วมาคอยดักถามผมใน Fan Page โดยไม่ไล่ Code เลย]

เพิ่มเติม

วิธีการเรียก ดูค่าต่างๆ ของตัวแปรต่างๆ แบบ Session นั้นสามารถทำได้ตามตัวอย่างนี้

วิธีเก็บค่า

NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];

// saving an NSString
[prefs setObject:@"TextToSave" forKey:@"keyToLookupString"];

// saving an NSInteger
[prefs setInteger:42 forKey:@"integerKey"];

// saving a Double[fb_embed_post href="null/" width="null"/]
[prefs setDouble:3.1415 forKey:@"doubleKey"];

// saving a Float
[prefs setFloat:1.2345678 forKey:@"floatKey"];

// This is suggested to synch prefs, but is not needed (I didn't put it in my tut)
[prefs synchronize];

 วิธีรับค่า

NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];

// getting an NSString
NSString *myString = [prefs stringForKey:@"keyToLookupString"];

// getting an NSInteger
NSInteger myInt = [prefs integerForKey:@"integerKey"];

// getting an Float
float myFloat = [prefs floatForKey:@"floatKey"];

สุขสันต์หรรษาครับ 🙂

ฝากผลงานหนังสือของ เว็บไซต์นี้ทีนะครับ สำหรับคนที่ต้องการพัฒนาแอพพลิเคชันบน iOS7.1

[fb_embed_post href=”https://www.facebook.com/photo.php?fbid=777971808913916&set=a.390784317632669.96833.323517721025996&type=1/” width=”550″/]

Asst. Prof. Banyapon Poolsawas

อาจารย์ประจำสาขาวิชาการออกแบบเชิงโต้ตอบ และการพัฒนาเกม วิทยาลัยครีเอทีฟดีไซน์ & เอ็นเตอร์เทนเมนต์เทคโนโลยี มหาวิทยาลัยธุรกิจบัณฑิตย์ ผู้ก่อตั้ง บริษัท Daydev Co., Ltd, (เดย์เดฟ จำกัด)

Related Articles

Back to top button

Adblock Detected

เราตรวจพบว่าคุณใช้ Adblock บนบราวเซอร์ของคุณ,กรุณาปิดระบบ Adblock ก่อนเข้าอ่าน Content ของเรานะครับ, ถือว่าช่วยเหลือกัน